From 612f9a56f2fa61b9ef7a035eb44e0ca50d8e9d11 Mon Sep 17 00:00:00 2001 From: Matthew Date: Thu, 19 Oct 2023 14:01:09 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=BB=E6=8E=A7=E6=9D=BF=E6=A0=B8=E5=BF=83?= =?UTF-8?q?=E6=9D=BF=E6=BA=90=E7=A8=8B=E5=BA=8F=20=20communication=20v3.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 20150512_022549.csv | 1 + inc/goahead.h | 3994 + inc/js.h | 348 + inc/me.h | 390 + inc/osdep.h | 1397 + scl_srvr/TEMPLATE.icd | 881 + scl_srvr/datamap.cfg | 438 + scl_srvr/datamapout.cfg | 438 + scl_srvr/lap_out.xml | 2 + scl_srvr/leafmap.xml | 63 + scl_srvr/logcfg.xml | 192 + scl_srvr/osicfg.xml | 307 + scl_srvr/startup.cfg | 7 + src/Makefile | 288 + src/PID_AutoTune.c | 237 + src/PID_AutoTune.h | 52 + src/S71ntpdate | 23 + src/S81srvrd | 23 + src/S90app | 23 + src/S91fileprocess | 23 + src/analysis.c | 2493 + src/analysis.h | 11 + src/app使能开关.rar | Bin 0 -> 340603 bytes src/common.c | 87 + src/common.h | 481 + src/ctrl_process.c | 650 + src/ctrl_process.h | 39 + src/database.c | 283 + src/database.h | 16 + src/database/main.c | 1704 + src/database/main_back2.c | 1724 + src/database/ysp.db | Bin 0 -> 8192 bytes src/database/ysp_cfg.ini | 1597 + src/fileprocess | 7 + src/filter.csv | 4001 + src/goahead.c | 2022 + src/iec61850_process.c | 178 + src/iec61850_process.h | 18 + src/interfaces | 26 + src/left.txt | 3 + src/main.c | 3157 + src/main.h | 16 + src/minGlue.h | 31 + src/minIni.c | 831 + src/minIni.h | 152 + src/mk_ied.sh | 7 + src/msq.c | 52 + src/msq.h | 15 + src/netMr.c | 8 + src/ofilter.csv | 4001 + src/para.c | 143 + src/para.h | 14 + src/rcS | 159 + src/reduce.csv | 4001 + src/result.txt | 21 + src/sample_process.c | 734 + src/sample_process.h | 42 + src/scl_shm.h | 137 + src/scl_srvr.tar.gz | Bin 0 -> 102400 bytes src/serial.c | 208 + src/serial.h | 17 + src/slope.csv | 501 + src/sqlite3.c | 155865 +++++++++++++++++++++++++++++++++++ src/sqlite3.h | 7831 ++ src/sqlite3ext.h | 517 + src/syscfg.ini | 25 + src/sysinfo.c | 250 + src/sysinfo.h | 28 + src/thread.c | 42 + src/thread.h | 7 + src/update.rar | Bin 0 -> 338809 bytes src/update.sh | 42 + src/web.tar.gz | Bin 0 -> 133120 bytes src/ysp.db | Bin 0 -> 1957888 bytes src/ysp_cfg.ini | 2264 + src/ysp_debug.c | 79 + src/ysp_debug.h | 83 + src/新建 文本文档.txt | 6 + test.csv | 5000 ++ tune.csv | 1006 + 80 files changed, 211759 insertions(+) create mode 100644 20150512_022549.csv create mode 100644 inc/goahead.h create mode 100644 inc/js.h create mode 100644 inc/me.h create mode 100644 inc/osdep.h create mode 100644 scl_srvr/TEMPLATE.icd create mode 100644 scl_srvr/datamap.cfg create mode 100644 scl_srvr/datamapout.cfg create mode 100644 scl_srvr/lap_out.xml create mode 100644 scl_srvr/leafmap.xml create mode 100644 scl_srvr/logcfg.xml create mode 100644 scl_srvr/osicfg.xml create mode 100644 scl_srvr/startup.cfg create mode 100644 src/Makefile create mode 100644 src/PID_AutoTune.c create mode 100644 src/PID_AutoTune.h create mode 100644 src/S71ntpdate create mode 100644 src/S81srvrd create mode 100644 src/S90app create mode 100644 src/S91fileprocess create mode 100644 src/analysis.c create mode 100644 src/analysis.h create mode 100644 src/app使能开关.rar create mode 100644 src/common.c create mode 100644 src/common.h create mode 100644 src/ctrl_process.c create mode 100644 src/ctrl_process.h create mode 100644 src/database.c create mode 100644 src/database.h create mode 100644 src/database/main.c create mode 100644 src/database/main_back2.c create mode 100644 src/database/ysp.db create mode 100644 src/database/ysp_cfg.ini create mode 100644 src/fileprocess create mode 100644 src/filter.csv create mode 100644 src/goahead.c create mode 100644 src/iec61850_process.c create mode 100644 src/iec61850_process.h create mode 100644 src/interfaces create mode 100644 src/left.txt create mode 100644 src/main.c create mode 100644 src/main.h create mode 100644 src/minGlue.h create mode 100644 src/minIni.c create mode 100644 src/minIni.h create mode 100644 src/mk_ied.sh create mode 100644 src/msq.c create mode 100644 src/msq.h create mode 100644 src/netMr.c create mode 100644 src/ofilter.csv create mode 100644 src/para.c create mode 100644 src/para.h create mode 100644 src/rcS create mode 100644 src/reduce.csv create mode 100644 src/result.txt create mode 100644 src/sample_process.c create mode 100644 src/sample_process.h create mode 100644 src/scl_shm.h create mode 100644 src/scl_srvr.tar.gz create mode 100644 src/serial.c create mode 100644 src/serial.h create mode 100644 src/slope.csv create mode 100644 src/sqlite3.c create mode 100644 src/sqlite3.h create mode 100644 src/sqlite3ext.h create mode 100644 src/syscfg.ini create mode 100644 src/sysinfo.c create mode 100644 src/sysinfo.h create mode 100644 src/thread.c create mode 100644 src/thread.h create mode 100644 src/update.rar create mode 100644 src/update.sh create mode 100644 src/web.tar.gz create mode 100644 src/ysp.db create mode 100644 src/ysp_cfg.ini create mode 100644 src/ysp_debug.c create mode 100644 src/ysp_debug.h create mode 100644 src/新建 文本文档.txt create mode 100644 test.csv create mode 100644 tune.csv diff --git a/20150512_022549.csv b/20150512_022549.csv new file mode 100644 index 0000000..ca44508 --- /dev/null +++ b/20150512_022549.csv @@ -0,0 +1 @@ +71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147,71.038147 diff --git a/inc/goahead.h b/inc/goahead.h new file mode 100644 index 0000000..10bf5c9 --- /dev/null +++ b/inc/goahead.h @@ -0,0 +1,3994 @@ +/* + goahead.h -- GoAhead Web Server Header + + Copyright (c) All Rights Reserved. See details at the end of the file. + */ + +#ifndef _h_GOAHEAD +#define _h_GOAHEAD 1 + +/************************************ Overrides *******************************/ +/* + Override osdep defaults + */ +#define ME_MAX_IP 64 /**< Maximum IP address size */ + +/************************************ Includes ********************************/ + +#include "me.h" +#include "osdep.h" + +/************************************ Defaults ********************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +#if (ME_COM_MBEDTLS + ME_COM_MATRIXSSL + ME_COM_NANOSSL + ME_COM_OPENSSL) > 1 + #error "Cannot have more than one SSL provider configured" +#endif + +#ifndef ME_GOAHEAD_LOGGING + #define ME_GOAHEAD_LOGGING 1 /**< Default for logging is "on" */ +#endif +#ifndef ME_GOAHEAD_TRACING + #define ME_GOAHEAD_TRACING 1 /**< Default for tracing "on" */ +#endif +#ifndef ME_GOAHEAD_DEBUG + #if ME_DEBUG + #define ME_GOAHEAD_DEBUG 1 /**< Debug logging on in debug builds by default */ + #else + #define ME_GOAHEAD_DEBUG 0 + #endif +#endif +#if ECOS + #if ME_GOAHEAD_CGI + #error "Ecos does not support CGI. Disable ME_GOAHEAD_CGI" + #endif +#endif /* ECOS */ + +#if QNX + typedef long fd_mask; + #define NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */ +#endif + +#if MACOSX + typedef int32_t fd_mask; +#endif +#if WINDOWS + typedef fd_set fd_mask; +#endif + +#if !LINUX + PUBLIC char *basename(char *name); +#endif + +#if VXWORKS + PUBLIC int vxchdir(char *dirname); +#endif + +#if DOXYGEN + typedef int Socket; + typedef int Socklen; + typedef int64 Offset; +#endif + +/** + File status structure + */ +typedef struct stat WebsStat; + +/* + Copyright. The software license requires that this not be modified or removed. + */ +#define EMBEDTHIS_GOAHEAD_COPYRIGHT \ + "Copyright (c) Embedthis Software Inc., 1993-2014. All Rights Reserved." \ + "Copyright (c) GoAhead Software Inc., 2003. All Rights Reserved." + +/************************************* Main ***********************************/ + +#define ME_MAX_ARGC 32 +#if VXWORKS + #define MAIN(name, _argc, _argv, _envp) \ + static int innerMain(int argc, char **argv, char **envp); \ + int name(char *arg0, ...) { \ + va_list args; \ + char *argp, *largv[ME_MAX_ARGC]; \ + int largc = 0; \ + va_start(args, arg0); \ + largv[largc++] = #name; \ + if (arg0) { \ + largv[largc++] = arg0; \ + } \ + for (argp = va_arg(args, char*); argp && largc < ME_MAX_ARGC; argp = va_arg(args, char*)) { \ + largv[largc++] = argp; \ + } \ + return innerMain(largc, largv, NULL); \ + } \ + static int innerMain(_argc, _argv, _envp) +#elif ME_WIN_LIKE + #define MAIN(name, _argc, _argv, _envp) \ + APIENTRY WinMain(HINSTANCE inst, HINSTANCE junk, char *command, int junk2) { \ + extern int main(); \ + char *largv[ME_MAX_ARGC]; \ + int largc; \ + largc = websParseArgs(command, &largv[1], ME_MAX_ARGC - 1); \ + largv[0] = #name; \ + main(largc, largv, NULL); \ + } \ + int main(_argc, _argv, _envp) +#else + #define MAIN(name, _argc, _argv, _envp) int main(_argc, _argv, _envp) +#endif + +PUBLIC int websParseArgs(char *args, char **argv, int maxArgc); + +#if WINDOWS + PUBLIC void websSetInst(HINSTANCE inst); + PUBLIC HINSTANCE websGetInst(); +#endif + +/************************************ Tunables ********************************/ + +#define WEBS_MAX_LISTEN 8 /**< Maximum number of listen endpoints */ +#define WEBS_SMALL_HASH 31 /**< General small hash size */ + +/************************************* Error **********************************/ + +#define WEBS_L __FILE__, __LINE__ +#define WEBS_ARGS_DEC char *file, int line +#define WEBS_ARGS file, line + +PUBLIC_DATA int logLevel; + +/** + Standard logging trace levels are 0 to 9 with 0 being the most verbose. These are ored with the error source + and type flags. The WEBS_LOG_MASK is used to extract the trace level from a flags word. We expect most apps + to run with level 2 trace enabled. +*/ +#define WEBS_ERROR 1 /**< Hard error trace level */ +#define WEBS_WARN 2 /**< Soft warning trace level */ +#define WEBS_CONFIG 2 /**< Configuration settings trace level. */ +#define WEBS_VERBOSE 9 /**< Highest level of trace */ +#define WEBS_LEVEL_MASK 0xF /**< Level mask */ + +/* + Log message flags + */ +#define WEBS_ASSERT_MSG 0x10 /**< Originated from assert */ +#define WEBS_ERROR_MSG 0x20 /**< Originated from error */ +#define WEBS_LOG_MSG 0x100 /**< Originated from logmsg */ +#define WEBS_RAW_MSG 0x200 /**< Raw message output */ +#define WEBS_TRACE_MSG 0x400 /**< Originated from trace */ + + +#if DOXYGEN +#undef assert +/** + Assure that an assert condition is true + @param cond Boolean result of a conditional test + @stability Evolving + */ +extern void assert(bool cond); +#elif ME_GOAHEAD_DEBUG + #define assert(C) if (C) ; else assertError(WEBS_L, "%s", #C) + PUBLIC void assertError(WEBS_ARGS_DEC, char *fmt, ...); +#else + #define assert(C) if (1) ; else +#endif + +// Deprecated 3.1 +#if DEPRECATED +#define traceOpen logOpen +#define traceClose logClose +#define WebsTraceHandler WebLogHandler +#define traceSetPath logSetPath +#define websGetTraceLevel websGetLogLevel +#endif + +/** + Callback for emitting trace log output + @param level Integer between 0 and 9. Zero is the lowest trace level used for the most important messages. + @param msg Message to log + @return Zero if successful + @internal + */ +typedef void (*WebsLogHandler)(int level, char *msg); + +/** + Emit an error message + @return Zero if successful + @stability Evolving +*/ +PUBLIC void error(char *fmt, ...); + +/** + Open the log logging module + @return Zero if successful + @internal + */ +PUBLIC int logOpen(); + +/** + Close the log logging module + @internal + */ +PUBLIC void logClose(); + +/** + Get the log callback + @return handler Callback handler function of type WebsLogHandler + @stability Evolving + */ +PUBLIC WebsLogHandler logGetHandler(); + +/** + Set a log callback + @param handler Callback handler function of type WebsLogHandler + @return The previous callback function + @stability Evolving + */ +PUBLIC WebsLogHandler logSetHandler(WebsLogHandler handler); + +/** + Set the filename to save logging output + @param path Filename path to use + @stability Evolving + */ +PUBLIC void logSetPath(char *path); + +/** + Emit a message to the log + @description This emits a message at the specified level. GoAhead filters logging messages by defining a verbosity + level at startup. Level 0 is the least verbose where only the most important messages will be output. Level 9 is the + Logging support is enabled by the MakeMe setting: "logging: true" which creates the ME_GOAHEAD_LOGGING define in me.h + most verbose. Level 2-4 are the most useful for debugging. + @param level Integer verbosity level (0-9). + @param fmt Printf style format string + @param ... Arguments for the format string + @stability Evolving + */ +PUBLIC void logmsgProc(int level, char *fmt, ...); + +/** + Emit a debug trace message to the log + @description This emits a message at the specified level. GoAhead filters logging messages by defining a verbosity + level at startup. Level 0 is the least verbose where only the most important messages will be output. Level 9 is the + most verbose. Level 2-4 are the most useful for debugging. + Debug trace support is enabled by the MakeMe setting: "tracing: true" which creates the ME_GOAHEAD_TRACING define in + me.h. + @param level Integer verbosity level (0-9). + @param fmt Printf style format string + @param ... Arguments for the format string + @stability Evolving + */ +PUBLIC void traceProc(int level, char *fmt, ...); + +/*********************************** HTTP Codes *******************************/ +/* + Standard HTTP/1.1 status codes + */ +#define HTTP_CODE_CONTINUE 100 /**< Continue with request, only partial content transmitted */ +#define HTTP_CODE_OK 200 /**< The request completed successfully */ +#define HTTP_CODE_CREATED 201 /**< The request has completed and a new resource was created */ +#define HTTP_CODE_ACCEPTED 202 /**< The request has been accepted and processing is continuing */ +#define HTTP_CODE_NOT_AUTHORITATIVE 203 /**< The request has completed but content may be from another source */ +#define HTTP_CODE_NO_CONTENT 204 /**< The request has completed and there is no response to send */ +#define HTTP_CODE_RESET 205 /**< The request has completed with no content. Client must reset view */ +#define HTTP_CODE_PARTIAL 206 /**< The request has completed and is returning partial content */ +#define HTTP_CODE_MOVED_PERMANENTLY 301 /**< The requested URI has moved permanently to a new location */ +#define HTTP_CODE_MOVED_TEMPORARILY 302 /**< The URI has moved temporarily to a new location */ +#define HTTP_CODE_SEE_OTHER 303 /**< The requested URI can be found at another URI location */ +#define HTTP_CODE_NOT_MODIFIED 304 /**< The requested resource has changed since the last request */ +#define HTTP_CODE_USE_PROXY 305 /**< The requested resource must be accessed via the location proxy */ +#define HTTP_CODE_TEMPORARY_REDIRECT 307 /**< The request should be repeated at another URI location */ +#define HTTP_CODE_BAD_REQUEST 400 /**< The request is malformed */ +#define HTTP_CODE_UNAUTHORIZED 401 /**< Authentication for the request has failed */ +#define HTTP_CODE_PAYMENT_REQUIRED 402 /**< Reserved for future use */ +#define HTTP_CODE_FORBIDDEN 403 /**< The request was legal, but the server refuses to process */ +#define HTTP_CODE_NOT_FOUND 404 /**< The requested resource was not found */ +#define HTTP_CODE_BAD_METHOD 405 /**< The request HTTP method was not supported by the resource */ +#define HTTP_CODE_NOT_ACCEPTABLE 406 /**< The requested resource cannot generate the required content */ +#define HTTP_CODE_REQUEST_TIMEOUT 408 /**< The server timed out waiting for the request to complete */ +#define HTTP_CODE_CONFLICT 409 /**< The request had a conflict in the request headers and URI */ +#define HTTP_CODE_GONE 410 /**< The requested resource is no longer available*/ +#define HTTP_CODE_LENGTH_REQUIRED 411 /**< The request did not specify a required content length*/ +#define HTTP_CODE_PRECOND_FAILED 412 /**< The server cannot satisfy one of the request preconditions */ +#define HTTP_CODE_REQUEST_TOO_LARGE 413 /**< The request is too large for the server to process */ +#define HTTP_CODE_REQUEST_URL_TOO_LARGE 414 /**< The request URI is too long for the server to process */ +#define HTTP_CODE_UNSUPPORTED_MEDIA_TYPE 415 /**< The request media type is not supported by the server or resource */ +#define HTTP_CODE_RANGE_NOT_SATISFIABLE 416 /**< The request content range does not exist for the resource */ +#define HTTP_CODE_EXPECTATION_FAILED 417 /**< The server cannot satisfy the Expect header requirements */ +#define HTTP_CODE_NO_RESPONSE 444 /**< The connection was closed with no response to the client */ +#define HTTP_CODE_INTERNAL_SERVER_ERROR 500 /**< Server processing or configuration error. No response generated */ +#define HTTP_CODE_NOT_IMPLEMENTED 501 /**< The server does not recognize the request or method */ +#define HTTP_CODE_BAD_GATEWAY 502 /**< The server cannot act as a gateway for the given request */ +#define HTTP_CODE_SERVICE_UNAVAILABLE 503 /**< The server is currently unavailable or overloaded */ +#define HTTP_CODE_GATEWAY_TIMEOUT 504 /**< The server gateway timed out waiting for the upstream server */ +#define HTTP_CODE_BAD_VERSION 505 /**< The server does not support the HTTP protocol version */ +#define HTTP_CODE_INSUFFICIENT_STORAGE 507 /**< The server has insufficient storage to complete the request */ + +/* + Proprietary HTTP status codes + */ +#define HTTP_CODE_START_LOCAL_ERRORS 550 +#define HTTP_CODE_COMMS_ERROR 550 /**< The server had a communicationss error responding to the client */ + +/************************************* WebsValue ******************************/ +/** + Value types. + */ +typedef enum WebsType { + undefined = 0, + byteint = 1, + shortint = 2, + integer = 3, + hex = 4, + percent = 5, + octal = 6, + big = 7, + flag = 8, + floating = 9, + string = 10, + bytes = 11, + symbol = 12, + errmsg = 13 +} WebsType; + +/** + System native time type + */ +typedef time_t WebsTime; + +/** + Value union to store primitive value types + */ +typedef struct WebsValue { + union { + char flag; + char byteint; + short shortint; + char percent; + long integer; + long hex; + long octal; + long big[2]; +#if ME_FLOAT + double floating; +#endif + char *string; + char *bytes; + char *errmsg; + void *symbol; + } value; + WebsType type; + uint valid : 8; + uint allocated : 8; /* String was allocated */ +} WebsValue; + +/** + The value is a numeric type + */ +#define value_numeric(t) (t >= byteint && t <= big) + +/** + The value is a string type + */ +#define value_str(t) (t >= string && t <= bytes) + +/** + The value is valid supported type + */ +#define value_ok(t) (t > undefined && t <= symbol) + +/** + Allocate strings using malloc + */ +#define VALUE_ALLOCATE 0x1 + +/** + Create an integer value + @param value Integer long value + @return Value object containing the integer + @stability Evolving + */ +PUBLIC WebsValue valueInteger(long value); + +/** + Create an string value + @param value String long value + @param flags Set to VALUE_ALLOCATE to store a copy of the string reference + @return Value object containing the string + @stability Evolving + */ +PUBLIC WebsValue valueString(char *value, int flags); + +/** + Create an symbol value containing an object reference + @param value Value reference + @return Value object containing the symbol reference + @stability Evolving + */ +PUBLIC WebsValue valueSymbol(void *value); + +/** + Free any allocated string in a value + @param value Value object + @stability Evolving + */ +PUBLIC void valueFree(WebsValue *value); + +/************************************* Ringq **********************************/ +/** + A WebsBuf (ring queue) allows maximum utilization of memory for data storage and is + ideal for input/output buffering. This module provides a highly effecient + implementation and a vehicle for dynamic strings. + \n\n + WARNING: This is a public implementation and callers have full access to + the queue structure and pointers. Change this module very carefully. + \n\n + This module follows the open/close model. + \n\n + Operation of a WebsBuf where bp is a pointer to a WebsBuf : + + bp->buflen contains the size of the buffer. + bp->buf will point to the start of the buffer. + bp->servp will point to the first (un-consumed) data byte. + bp->endp will point to the next free location to which new data is added + bp->endbuf will point to one past the end of the buffer. + \n\n + Eg. If the WebsBuf contains the data "abcdef", it might look like : + \n\n + +-------------------------------------------------------------------+ + | | | | | | | | a | b | c | d | e | f | | | | | + +-------------------------------------------------------------------+ + ^ ^ ^ ^ + | | | | + bp->buf bp->servp bp->endp bp->enduf + \n\n + The queue is empty when servp == endp. This means that the queue will hold + at most bp->buflen -1 bytes. It is the fillers responsibility to ensure + the WebsBuf is never filled such that servp == endp. + \n\n + It is the fillers responsibility to "wrap" the endp back to point to + bp->buf when the pointer steps past the end. Correspondingly it is the + consumers responsibility to "wrap" the servp when it steps to bp->endbuf. + The bufPutc and bufGetc routines will do this automatically. + @defgroup WebsBuf WebsBuf + @stability Evolving + */ +typedef struct WebsBuf { + char *buf; /**< Holding buffer for data */ + char *servp; /**< Pointer to start of data */ + char *endp; /**< Pointer to end of data */ + char *endbuf; /**< Pointer to end of buffer */ + ssize buflen; /**< Length of ring queue */ + ssize maxsize; /**< Maximum size */ + int increment; /**< Growth increment */ +} WebsBuf; + +/** + Add a trailing null to the buffer. The end pointer is not changed. + @param bp Buffer reference + @ingroup WebsBuf + @stability Evolving + */ +PUBLIC void bufAddNull(WebsBuf *bp); + +/** + Adjust the endp pointer by the specified size. + @description This is useful after manually copying data into the buffer and needing to adjust the end pointer. + @param bp Buffer reference + @param size Size of adjustment. May be positive or negative value. + @ingroup WebsBuf + @stability Evolving + */ +PUBLIC void bufAdjustEnd(WebsBuf *bp, ssize size); + +/** + Adjust the start (servp) reference + @param bp Buffer reference + @param count Number of bytes to adjust + @ingroup WebsBuf + @stability Evolving + */ +PUBLIC void bufAdjustStart(WebsBuf *bp, ssize count); + +/** + Compact the data in the buffer and move to the start of the buffer + @param bp Buffer reference + @ingroup WebsBuf + @stability Evolving + */ +PUBLIC void bufCompact(WebsBuf *bp); + +/** + Create a buffer + @param bp Buffer reference + @param increment Incremental size to grow the buffer. This will be increased by a power of two each time + the buffer grows. + @param maxsize Maximum size of the buffer + @return Zero if successful + @ingroup WebsBuf + @stability Evolving + */ +PUBLIC int bufCreate(WebsBuf *bp, int increment, int maxsize); + +/** + Flush all data in the buffer and reset the pointers. + @param bp Buffer reference + @ingroup WebsBuf + @stability Evolving + */ +PUBLIC void bufFlush(WebsBuf *bp); + +/** + Free allocated storage for the buffer + @param bp Buffer reference + @return Zero if successful + @ingroup WebsBuf + @stability Evolving + */ +PUBLIC void bufFree(WebsBuf *bp); + +/** + Copy a block of from the buffer and adjust the servp. + @param bp Buffer reference + @param blk Block into which to place the data + @param len Length of the block + @return Number of bytes copied. + @ingroup WebsBuf + @stability Evolving + */ +PUBLIC ssize bufGetBlk(WebsBuf *bp, char *blk, ssize len); + +/** + Return the maximum number of bytes the buffer can provide via a single block copy. + @description Useful if the user is doing their own data retrieval. + @param bp Buffer reference + @return Number of bytes available for copying. + @ingroup WebsBuf + @stability Evolving + */ +PUBLIC ssize bufGetBlkMax(WebsBuf *bp); + +/** + Get a character from the buffer and increment the servp + @param bp Buffer reference + @return The next character or -1 if the buffer is empty + @ingroup WebsBuf + @stability Evolving + */ +PUBLIC int bufGetc(WebsBuf *bp); + +/** + Grow the buffer by at least the required amount of room + @param bp Buffer reference + @param room Available size required after growing the buffer + @return True if the buffer can be grown to have the required amount of room. + @ingroup WebsBuf + @stability Evolving + */ +PUBLIC bool bufGrow(WebsBuf *bp, ssize room); + +/** + Get the length of available data in the buffer + @param bp Buffer reference + @return Size of available data in bytes + @ingroup WebsBuf + @stability Evolving + */ +PUBLIC ssize bufLen(WebsBuf *bp); + +/** + Insert a character to the buffer before the servp position and decrement the servp + @param bp Buffer reference + @param c Character to insert + @return Zero if successful + @ingroup WebsBuf + @stability Evolving + */ +PUBLIC int bufInsertc(WebsBuf *bp, char c); + +/** + Append a character to the buffer at the endp position and increment the endp + @param bp Buffer reference + @param c Character to append + @return Zero if successful + @ingroup WebsBuf + @stability Evolving + */ +PUBLIC int bufPutc(WebsBuf *bp, char c); +/** + Put a block to the buffer. + @param bp Buffer reference + @param blk Block to append to the buffer + @param len Size of the block + @return Length of data appended. Should equal len. + @ingroup WebsBuf + @stability Evolving + */ +PUBLIC ssize bufPutBlk(WebsBuf *bp, char *blk, ssize len); + +/** + Append a formatted string to the buffer at the endp position and increment the endp + @param bp Buffer reference + @param fmt Printf style format string + @param ... Variable arguments for the format string + @return Count of characters appended. Returns negative if there is an allocation error. + @ingroup WebsBuf + @stability Evolving + */ +PUBLIC ssize bufPut(WebsBuf *bp, char *fmt, ...) PRINTF_ATTRIBUTE(2,3); + +/** + Append a string to the buffer at the endp position and increment the endp + @param bp Buffer reference + @param str String to append + @return Count of characters appended. Returns negative if there is an allocation error. + @ingroup WebsBuf + @stability Evolving + */ +PUBLIC ssize bufPutStr(WebsBuf *bp, char *str); + +/** + Reset the buffer pointers to the start of the buffer if empty + @param bp Buffer reference + @ingroup WebsBuf + @stability Evolving + */ +PUBLIC void bufReset(WebsBuf *bp); + +/** + Determine the room available in the buffer. + @description This returns the maximum number of bytes the buffer can absorb in a single block copy. + @param bp Buffer reference + @return Number of bytes of availble space. + @ingroup WebsBuf + @stability Evolving + */ +PUBLIC ssize bufRoom(WebsBuf *bp); + +/** + Get a reference to the start of buffer data + @param bp Buffer reference + @return A string pointer. + @ingroup WebsBuf + @stability Evolving + */ +PUBLIC char *bufStart(WebsBuf *bp); + +/******************************* Malloc Replacement ***************************/ +#if ME_GOAHEAD_REPLACE_MALLOC +/** + GoAhead allocator memory block + Memory block classes are: 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536. + @defgroup WebsAlloc WebsAlloc + @stability Evolving + */ +typedef struct WebsAlloc { + union { + void *next; /**< Pointer to next in q */ + int size; /**< Actual requested size */ + } u; + int flags; /**< Per block allocation flags */ +} WebsAlloc; + +#define WEBS_DEFAULT_MEM (64 * 1024) /**< Default memory allocation */ +#define WEBS_MAX_CLASS 13 /**< Maximum class number + 1 */ +#define WEBS_SHIFT 4 /**< Convert size to class */ +#define WEBS_ROUND ((1 << (B_SHIFT)) - 1) +#define WEBS_MALLOCED 0x80000000 /* Block was malloced */ +#define WEBS_FILL_CHAR (0x77) /* Fill byte for buffers */ +#define WEBS_FILL_WORD (0x77777777) /* Fill word for buffers */ + +/* + Flags. The integrity value is used as an arbitrary value to fill the flags. + */ +#define WEBS_USE_MALLOC 0x1 /**< Okay to use malloc if required */ +#define WEBS_USER_BUF 0x2 /* User supplied buffer for mem */ +#define WEBS_INTEGRITY 0x8124000 /* Integrity value */ +#define WEBS_INTEGRITY_MASK 0xFFFF000 /* Integrity mask */ + +/** + Close the GoAhead memory allocator + @ingroup WebsAlloc + @stability Evolving + */ +PUBLIC void wcloseAlloc(); + +/** + Initialize the walloc module. + @description The wopenAlloc function should be called the very first thing after the application starts and wclose + should be called the last thing before exiting. If wopenAlloc is not called, it will be called on the first allocation + with default values. "buf" points to memory to use of size "bufsize". If buf is NULL, memory is allocated using malloc. + flags may be set to WEBS_USE_MALLOC if using malloc is okay. This routine will allocate * an initial buffer of size + bufsize for use by the application. + @param buf Optional user supplied block of memory to use for allocations + @param bufsize Size of buf + @param flags Allocation flags. Set to WEBS_USE_MALLOC to permit the use of malloc() to grow memory. + @return Zero if successful, otherwise -1. + @ingroup WebsAlloc + @stability Evolving + */ +PUBLIC int wopenAlloc(void *buf, int bufsize, int flags); + +/** + Allocate a block of the requested size + @param size Memory size required + @return A reference to the allocated block + @ingroup WebsAlloc + @stability Evolving + */ +PUBLIC void *walloc(ssize size); + +/** + Free an allocated block of memory + @param blk Reference to the memory block to free. + @ingroup WebsAlloc + @stability Evolving + */ +PUBLIC void wfree(void *blk); + +/** + Reallocate a block of memory and grow its size + @description If the new size is larger than the existing block, a new block will be allocated and the old data + will be copied to the new block. + @param blk Original block reference + @param newsize Size of the new block. + @return Reference to the new memory block + @ingroup WebsAlloc + @stability Evolving + */ +PUBLIC void *wrealloc(void *blk, ssize newsize); + +#else /* !ME_GOAHEAD_REPLACE_MALLOC */ + + #define WEBS_SHIFT 4 + #define walloc(num) malloc(num) + #define wfree(p) if (p) { free(p); } else + #define wrealloc(p, num) realloc(p, num) +#endif /* ME_GOAHEAD_REPLACE_MALLOC */ + +// FUTURE DOC +PUBLIC ssize mtow(wchar *dest, ssize count, char *src, ssize len); +PUBLIC ssize wtom(char *dest, ssize count, wchar *src, ssize len); +PUBLIC wchar *amtow(char *src, ssize *len); +PUBLIC char *awtom(wchar *src, ssize *len); + +/******************************* Hash Table *********************************/ +/** + Hash table entry structure. + @description The hash structure supports growable hash tables with high performance, collision resistant hashes. + Each hash entry has a descriptor entry. This is used to manage the hash table link chains. + @see hashCreate hashFree hashLookup hashEnter hashDelete hashWalk hashFirst hashNext + @defgroup WebsHash WebsHash + @stability Evolving + */ +typedef struct WebsKey { + struct WebsKey *forw; /* Pointer to next hash list */ + WebsValue name; /* Name of symbol */ + WebsValue content; /* Value of symbol */ + int arg; /* Parameter value */ + int bucket; /* Bucket index */ +} WebsKey; + +/** + Hash table ID returned by hashCreate + */ +typedef int WebsHash; /* Returned by symCreate */ + +/** + Create a hash table + @param size Minimum size of the hash index + @return Hash table ID + @ingroup WebsHash + @stability Evolving + */ +PUBLIC WebsHash hashCreate(int size); + +/** + Free a hash table + @param id Hash table id returned by hashCreate + @ingroup WebsHash + @stability Evolving + */ +PUBLIC void hashFree(WebsHash id); + +/** + Lookup a name in the hash table + @param id Hash table id returned by hashCreate + @param name Key name to search for + @return Reference to the WebKey object storing the key and value + @ingroup WebsHash + @stability Evolving + */ +PUBLIC WebsKey *hashLookup(WebsHash id, char *name); + +/** + Enter a new key and value into the hash table + @param id Hash table id returned by hashCreate + @param name Key name to create + @param value Key value to enter + @param arg Optional extra argument to store with the value + @return Reference to the WebKey object storing the key and value + @ingroup WebsHash + @stability Evolving + */ +PUBLIC WebsKey *hashEnter(WebsHash id, char *name, WebsValue value, int arg); + +/** + Delete a key by name + @param id Hash table id returned by hashCreate + @param name Key name to delete + @return Zero if the delete was successful. Otherwise -1 if the key was not found. + @ingroup WebsHash + @stability Evolving + */ +PUBLIC int hashDelete(WebsHash id, char *name); + +/** + Start walking the hash keys by returning the first key entry in the hash + @param id Hash table id returned by hashCreate + @return Reference to the first WebKey object. Return null if there are no keys in the hash. + @ingroup WebsHash + @stability Evolving + */ +PUBLIC WebsKey *hashFirst(WebsHash id); + +/** + Continue walking the hash keys by returning the next key entry in the hash + @param id Hash table id returned by hashCreate + @param last Reference to a WebsKey to hold the current traversal key state. + @return Reference to the next WebKey object. Returns null if no more keys exist to be traversed. + @ingroup WebsHash + @stability Evolving + */ +PUBLIC WebsKey *hashNext(WebsHash id, WebsKey *last); + +/************************************ Socket **********************************/ +/* + Socket flags + */ +#define SOCKET_EOF 0x1 /**< Seen end of file */ +#define SOCKET_CONNECTING 0x2 /**< Connect in progress */ +#define SOCKET_RESERVICE 0x4 /**< Socket needs re-servicing */ +#define SOCKET_ASYNC 0x8 /**< Use async connect */ +#define SOCKET_BLOCK 0x10 /**< Use blocking I/O */ +#define SOCKET_LISTENING 0x20 /**< Socket is server listener */ +#define SOCKET_CLOSING 0x40 /**< Socket is closing */ +#define SOCKET_CONNRESET 0x80 /**< Socket connection was reset */ +#define SOCKET_HANDSHAKING 0x100 /**< Doing SSL handshake */ +#define SOCKET_BUFFERED_READ 0x200 /**< Message pending on this socket */ +#define SOCKET_BUFFERED_WRITE 0x400 /**< Message pending on this socket */ +#define SOCKET_NODELAY 0x800 /**< Disable Nagle algorithm */ + +#define SOCKET_PORT_MAX 0xffff /**< Max Port size */ + +#ifndef ME_MAX_IP + #define ME_MAX_IP 64 /**< Maximum IP address size */ +#endif + +/* + Socket error values + */ +#define SOCKET_WOULDBLOCK 1 /**< Socket would block on I/O */ +#define SOCKET_RESET 2 /**< Socket has been reset */ +#define SOCKET_NETDOWN 3 /**< Network is down */ +#define SOCKET_AGAIN 4 /**< Issue the request again */ +#define SOCKET_INTR 5 /**< Call was interrupted */ +#define SOCKET_INVAL 6 /**< Invalid */ + +/* + Handler event masks + */ +#define SOCKET_READABLE 0x2 /**< Make socket readable */ +#define SOCKET_WRITABLE 0x4 /**< Make socket writable */ +#define SOCKET_EXCEPTION 0x8 /**< Interested in exceptions */ + +/** + Socket I/O callback + @param sid Socket ID handle returned from socketConnect or when a new socket is passed to a SocketAccept + callback.. + @param mask Mask of events of interest. Set to SOCKET_READABLE | SOCKET_WRITABLE | SOCKET_EXCEPTION. + @param data Data argument to pass to the callback function. + @ingroup WebsSocket + @stability Evolving + */ +typedef void (*SocketHandler)(int sid, int mask, void *data); + +/** + Socket accept callback + @param sid Socket ID handle for the newly accepted socket + @param ipaddr IP address of the connecting client. + @param port Port of the connecting client. + @param listenSid Socket ID for the listening socket + @ingroup WebsSocket + @stability Evolving + */ +typedef int (*SocketAccept)(int sid, char *ipaddr, int port, int listenSid); + +/** + Socket control structure + @see socketAddress socketAddressIsV6 socketClose socketCloseConnection socketCreateHandler + socketDeletehandler socketReservice socketEof socketGetPort socketInfo socketIsV6 + socketOpen socketListen socketParseAddress socketProcess socketRead socketWrite socketWriteString + socketSelect socketGetHandle socketSetBlock socketGetBlock socketAlloc socketFree socketGetError + socketSetError socketPtr socketWaitForEvent socketRegisterInterest + @defgroup WebsSocket WebsSocket + @stability Evolving + */ +typedef struct WebsSocket { + WebsBuf lineBuf; /**< Line ring queue */ + SocketAccept accept; /**< Accept handler */ + SocketHandler handler; /**< User I/O handler */ + char *ip; /**< Server listen address or remote client address */ + void *handler_data; /**< User handler data */ + int handlerMask; /**< Handler events of interest */ + int sid; /**< Index into socket[] */ + int port; /**< Port to listen on */ + int flags; /**< Current state flags */ + Socket sock; /**< Actual socket handle */ + int fileHandle; /**< ID of the file handler */ + int interestEvents; /**< Mask of events to watch for */ + int currentEvents; /**< Mask of ready events (FD_xx) */ + int selectEvents; /**< Events being selected */ + int saveMask; /**< saved Mask for socketFlush */ + int error; /**< Last error */ + int secure; /**< Socket is using SSL */ +} WebsSocket; + + +/** + Extract the numerical IP address and port for the given socket info + @param addr Reference to the socket address. + @param addrlen Length of the socket address + @param ipbuf Buffer to contain the parsed IP address + @param ipLen Size of ipbuf + @param port Reference to an integer to hold the parsed port. + @return Zero if successful. Otherwise -1 for parse errors. + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC int socketAddress(struct sockaddr *addr, int addrlen, char *ipbuf, int ipLen, int *port); + +/** + Determine if an IP address is an IPv6 address. + @param ip String IP address. + @return True if the address is an IPv6 address. + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC bool socketAddressIsV6(char *ip); + +/** + Allocate a socket object + @param host String host IP address. + @param port Socket port + @param accept Optional SocketAccept accept callback function + @param flags Control flags + @return Socket ID handle to use with other APIs. + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC int socketAlloc(char *host, int port, SocketAccept accept, int flags); + +/** + Close the socket module + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC void socketClose(); + +/** + Close a socket connection + @param sid Socket ID handle returned from socketConnect or socketAccept. + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC void socketCloseConnection(int sid); + +/** + Connect to a server and create a new socket + @param host Host IP address. + @param port Port number to connect to + @param flags Set to SOCKET_BLOCK for blocking I/O. Otherwise non-blocking I/O is used. + @return True if the address is an IPv6 address. + @ingroup WebsSocket + @internal + @stability Evolving + */ +PUBLIC int socketConnect(char *host, int port, int flags); + +/** + Create a socket handler that will be invoked when I/O events occur. + @param sid Socket ID handle returned from socketConnect or socketAccept. + @param mask Mask of events of interest. Set to SOCKET_READABLE | SOCKET_WRITABLE | SOCKET_EXCEPTION. + @param handler Socket handler function. + @param arg Arbitrary object reference to pass to the SocketHandler callback function. + @return True if the address is an IPv6 address. + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC void socketCreateHandler(int sid, int mask, SocketHandler handler, void *arg); + +/** + Delete a socket handler created via socketCreateHandler + @param sid Socket ID handle returned from socketConnect or socketAccept. + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC void socketDeleteHandler(int sid); + +/** + Determine if the socket is at end-of-file for input. + @param sid Socket ID handle returned from socketConnect or socketAccept. + @return True if the address is at EOF + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC bool socketEof(int sid); + +/** + Free (and close) the socket + @param sid Socket ID handle returned from socketConnect or socketAccept. + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC void socketFree(int sid); + +/** + Get the current blocking mode + @param sid Socket ID handle returned from socketConnect or socketAccept. + @return True if the socket is in blocking mode. + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC int socketGetBlock(int sid); + +/** + Get the error code for the last socket operation on this thread. + @return Integer error code. See errno or GetLastError() on windows. + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC int socketGetError(); + +/** + Get the underlying socket operating system socket/file handle + @param sid Socket ID handle returned from socketConnect or socketAccept. + @return The socket handle + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC Socket socketGetHandle(int sid); + +/** + Get the list of sockets + @return The socket list pointer + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC WebsSocket **socketGetList(); + +/** + Get the IP port associated with this socket. + @param sid Socket ID handle returned from socketConnect or socketAccept. + @return The TCP/IP port for this socket + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC int socketGetPort(int sid); + +/** + Indicate if the system has a dual IPv4 and IPv6 stack + @return True if IPv4 and IPv6 are supported on a single stack + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC bool socketHasDualNetworkStack(); + +/** + Indicate if the system has IPv6 support + @return True if IPv6 is supported on this system + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC bool socketHasIPv6(); + +/** + Indicate that the application layer has buffered data for the socket. + @description This is used by SSL and other network stacks that buffer pending data + @param sp Socket object returned from #socketPtr + @param len Length of buffered data in bytes + @param dir Buffer direction. Set to MPR_READABLE for buffered read data and MPR_WRITABLE for buffered write data. + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC void socketHiddenData(WebsSocket *sp, ssize len, int dir); + +/** + Get a socket address structure for the specified IP:Port + @description This returns address details in *family, *protocol, *addr, and *addrlen. + @param ip IP address to parse + @param port TCP/IP port number + @param family Reference to an integer to hold the address family + @param protocol Reference to an integer to hold the address protocol + @param addr Reference to an integer to hold the address structure + @param addrlen Reference to an integer to hold the address structure length + @return Zero if successful, otherwise -1. + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC int socketInfo(char *ip, int port, int *family, int *protocol, struct sockaddr_storage *addr, Socklen *addrlen); + +/** + Determine if a socket is bound to an IPv6 address. + @param sid Socket ID handle returned from socketConnect or socketAccept. + @return True if the socket is using IPv6. + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC bool socketIsV6(int sid); + +/** + Open a listening socket + @param host Host IP address on which to listen. Set to NULL to listen on all interfaces. + @param port TCP/IP port on which to listen + @param accept SocketAccept callback function to invoke to receive incoming connections. + @param flags Reserved + @return Zero if successful, otherwise -1. + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC int socketListen(char *host, int port, SocketAccept accept, int flags); + +/** + Open the socket module + @return Zero if successful, otherwise -1. + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC int socketOpen(); + +/** + Parse an IP address into its constituent parts. + @description Parse the IP address and return the IP address and port components. Handles ipv4 and ipv6 addresses. + If the IP portion is absent, pip is set to null. If the port portion is absent, port is set to the defaultPort. + If a ":*" port specifier is used, pport is set to -1; + When an address contains an ipv6 port it should be written as + aaaa:bbbb:cccc:dddd:eeee:ffff:gggg:hhhh:iiii + or + [aaaa:bbbb:cccc:dddd:eeee:ffff:gggg:hhhh:iiii]:port + If supplied an IPv6 address, the backets are stripped in the returned IP address. + @param ipAddrPort IP address which may contain an optional ":port" component. + @param pip Returns a reference to an allocated string containing the IP address portion. Caller must free. + @param pport Reference to an integer to hold the port component. + @param secure Reference to an integer to be set to true if the address is using SSL/TLS. + @param defaultPort Default port number to use if no port specifier is included in ipAddrPort. + @return Zero if successful, otherwise -1. + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC int socketParseAddress(char *ipAddrPort, char **pip, int *pport, int *secure, int defaultPort); + +/** + Process pending socket I/O events. + @ingroup WebsSocket + @stability Evolving + @internal + */ +PUBLIC void socketProcess(); + +/** + Read data from a socket + @param sid Socket ID handle returned from socketConnect or socketAccept. + @param buf Buffer to hold read data + @param len Size of the buffer + @return Count of bytes actually read. Returns -1 for errors and EOF. Distinguish between errors and EOF + via socketEof(). + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC ssize socketRead(int sid, void *buf, ssize len); + +/** + Register interest in socket I/OEvents + @param sid Socket ID handle returned from socketConnect or socketAccept. + @param mask Mask of events of interest. Set to SOCKET_READABLE | SOCKET_WRITABLE | SOCKET_EXCEPTION. + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC void socketRegisterInterest(int sid, int mask); + +/** + Request that the socket be reserviced. + @description This routine is useful when upper layers have unprocessed, buffered data for the socket. + This routine will cause the socket I/O callback handler to be invoked soon in the future. + @param sid Socket ID handle returned from socketConnect or socketAccept. + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC void socketReservice(int sid); + +/** + Wait for I/O on a socket + @description This call uses the mask of events of interest defined by socketRegisterInterest. It blocks the caller + until a suitable I/O event or timeout occurs. + @param sid Socket ID handle returned from socketConnect or socketAccept. + @param timeout Timeout in milliseconds. + @return Number of I/O events. + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC int socketSelect(int sid, WebsTime timeout); + +/** + Set the socket blocking mode + @param sid Socket ID handle returned from socketConnect or socketAccept. + @param on Set to 1 to enable blocking + @return The previous blocking mode + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC int socketSetBlock(int sid, int on); + +/** + Set the error code for the last socket operation on this thread. + @param error Integer error code. See errno or GetLastError() on windows. + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC void socketSetError(int error); + +/** + Set the socket delay mode + @description This is used to enable or disable the TCP Nagle algorithm + @param sid Socket ID handle returned from socketConnect or socketAccept. + @param on Set to 1 to disable the Nagle algorithm + @return The previous blocking mode + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC int socketSetNoDelay(int sid, bool on); + +/** + Wait for a socket I/O event + @param sp Socket object + @param mask Mask of events of interest. Set to SOCKET_READABLE | SOCKET_WRITABLE | SOCKET_EXCEPTION. + @return Zero if successful in waiting for the desired event, othewise return -1. + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC int socketWaitForEvent(WebsSocket *sp, int mask); + +/** + Write data to the socket + @param sid Socket ID handle returned from socketConnect or socketAccept. + @param buf Buffer containing data to write + @param len Size of buf + @return Count of bytes written. May be less than len if the socket is in non-blocking mode. + Returns -1 for errors and if the socket cannot absorb any more data. If the transport is saturated, + will return a negative error and errno will be set to EAGAIN or EWOULDBLOCK. + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC ssize socketWrite(int sid, void *buf, ssize len); + +/** + Return the socket object for the socket ID. + @param sid Socket ID handle returned from socketConnect or socketAccept. + @return Corresponding socket object. + @ingroup WebsSocket + @stability Evolving + */ +PUBLIC WebsSocket *socketPtr(int sid); + +/*********************************** Runtime **********************************/ + +/** + GoAhead Web Server Runtime + @description GoAhead provides a secure runtime environment for safe string manipulation and to + help prevent buffer overflows and other potential security traps. + @defgroup WebsRuntime WebsRuntime + @see fmt wallocHandle wallocObject wfreeHandle hextoi itosbuf scaselesscmp scaselessmatch + sclone scmp scopy sfmt sfmtv slen slower smatch sncaselesscmp sncmp sncopy stok strim supper + @stability Evolving + */ + +/** + Format a string into a static buffer. + @description This call format a string using printf style formatting arguments. A trailing null will + always be appended. The call returns the size of the allocated string excluding the null. + @param buf Pointer to the buffer. + @param maxSize Size of the buffer. + @param format Printf style format string + @param ... Variable arguments to format + @return Returns the buffer. + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC char *fmt(char *buf, ssize maxSize, char *format, ...); + +/** + Allocate a handle from a map + @param map Reference to a location holding the map reference. On the first call, the map is allocated. + @return Integer handle index. Otherwise return -1 on allocation errors. + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC int wallocHandle(void *map); + +/** + Allocate an object in a halloc map + @param map Reference to a location holding the map reference. On the first call, the map is allocated. + @param max Reference to an integer that holds the maximum handle in the map. + @param size Size of the object to allocate. + @return Integer handle index. Otherwise return -1 on allocation errors. + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC int wallocObject(void *map, int *max, int size); + +/** + Free a handle in the map + @param map Reference to a location to hold the map reference. + @param handle Handle to free in the map. + @return Integer handle index. Otherwise return -1 on allocation errors. + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC int wfreeHandle(void *map, int handle); + +/** + Convert a hex string to an integer + @description This call converts the supplied string to an integer using base 16. + @param str Pointer to the string to parse. + @return Returns the integer equivalent value of the string. + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC uint hextoi(char *str); + +/** + Convert an integer to a string buffer. + @description This call converts the supplied 64 bit integer into a string formatted into the supplied buffer according + to the specified radix. + @param buf Pointer to the buffer that will hold the string. + @param size Size of the buffer. + @param value Integer value to convert + @param radix The base radix to use when encoding the number + @return Returns a reference to the string. + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC char *itosbuf(char *buf, ssize size, int64 value, int radix); + +/** + Compare strings ignoring case. This is a safe replacement for strcasecmp. It can handle NULL args. + @description Compare two strings ignoring case differences. This call operates similarly to strcmp. + @param s1 First string to compare. + @param s2 Second string to compare. + @return Returns zero if the strings are equivalent, < 0 if s1 sorts lower than s2 in the collating sequence + or > 0 if it sorts higher. + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC int scaselesscmp(char *s1, char *s2); + +/** + Compare strings ignoring case. This is similar to scaselesscmp but it returns a boolean. + @description Compare two strings ignoring case differences. + @param s1 First string to compare. + @param s2 Second string to compare. + @return Returns true if the strings are equivalent, otherwise false. + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC bool scaselessmatch(char *s1, char *s2); + +/** + Clone a string + @description Copy a string into a newly allocated block. + @param str Pointer to the block to duplicate. + @return Returns a newly allocated string. + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC char *sclone(char *str); + +/** + Compare strings. + @description Compare two strings. This is a safe replacement for strcmp. It can handle null args. + @param s1 First string to compare. + @param s2 Second string to compare. + @return Returns zero if the strings are identical. Return -1 if the first string is less than the second. Return 1 + if the first string is greater than the second. + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC int scmp(char *s1, char *s2); + +/** + Copy a string. + @description Safe replacement for strcpy. Copy a string and ensure the destination buffer is not overflowed. + The call returns the length of the resultant string or an error code if it will not fit into the target + string. This is similar to strcpy, but it will enforce a maximum size for the copied string and will + ensure it is always terminated with a null. + @param dest Pointer to a pointer that will hold the address of the allocated block. + @param destMax Maximum size of the target string in characters. + @param src String to copy + @return Returns the number of characters in the target string. + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC ssize scopy(char *dest, ssize destMax, char *src); + +/* + String trim flags + */ +#define WEBS_TRIM_START 0x1 /**< Flag for strim to trim from the start of the string */ +#define WEBS_TRIM_END 0x2 /**< Flag for strim to trim from the end of the string */ +#define WEBS_TRIM_BOTH 0x3 /**< Flag for strim to trim from both the start and the end of the string */ + +/** + Format a string. This is a secure verion of printf that can handle null args. + @description Format the given arguments according to the printf style format. See fmt() for a full list of the + format specifies. This is a secure replacement for sprintf, it can handle null arguments without crashes. + @param format Printf style format string + @param ... Variable arguments for the format string + @return Returns a newly allocated string + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC char *sfmt(char *format, ...); + +/** + Format a string with varargs. This is a secure verion of printf that can handle null args. + @description Format the given arguments according to the printf style format. See fmt() for a full list of the + format specifies. This is a secure replacement for sprintf, it can handle null arguments without crashes. + @param format Printf style format string + @param args Varargs argument obtained from va_start. + @return Returns a newly allocated string + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC char *sfmtv(char *format, va_list args); + +/** + Return the length of a string. + @description Safe replacement for strlen. This call returns the length of a string and tests if the length is + less than a given maximum. It will return zero for NULL args. + @param str String to measure. + @return Returns the length of the string + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC ssize slen(char *str); + +/** + Convert a string to lower case. + @description Convert a string to its lower case equivalent. + @param str String to convert. This string is modified. + @return Reference to the supplied str. + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC char *slower(char *str); + +/** + Compare strings + @description Compare two strings. This is similar to #scmp but it returns a boolean. + @param s1 First string to compare. + @param s2 Second string to compare. + @return Returns true if the strings are equivalent, otherwise false. + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC bool smatch(char *s1, char *s2); + +/** + Compare strings ignoring case. + @description Compare two strings ignoring case differences for a given string length. This call operates + similarly to strncasecmp. + @param s1 First string to compare. + @param s2 Second string to compare. + @param len Length of characters to compare. + @return Returns zero if the strings are equivalent, < 0 if s1 sorts lower than s2 in the collating sequence + or > 0 if it sorts higher. + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC int sncaselesscmp(char *s1, char *s2, ssize len); + +/** + Compare strings. + @description Compare two strings for a given string length. This call operates similarly to strncmp. + @param s1 First string to compare. + @param s2 Second string to compare. + @param len Length of characters to compare. + @return Returns zero if the strings are equivalent, < 0 if s1 sorts lower than s2 in the collating sequence + or > 0 if it sorts higher. + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC int sncmp(char *s1, char *s2, ssize len); + +/** + Copy characters from a string. + @description Safe replacement for strncpy. Copy bytes from a string and ensure the target string is not overflowed. + The call returns the length of the resultant string or an error code if it will not fit into the target + string. This is similar to strcpy, but it will enforce a maximum size for the copied string and will + ensure it is terminated with a null. + @param dest Pointer to a pointer that will hold the address of the allocated block. + @param destMax Maximum size of the target string in characters. + @param src String to copy + @param count Maximum count of characters to copy + @return Returns a reference to the destination if successful or NULL if the string won't fit. + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC ssize sncopy(char *dest, ssize destMax, char *src, ssize count); + +/** + Split a string at a delimiter + @description Split a string and return parts. The string is modified. + This routiner never returns null. If there are leading delimiters, the empty string will be returned + and *last will be set to the portion after the delimiters. + If str is null, an empty string will be returned. + If there are no characters after the delimiter, then *last will be set to the empty string. + @param str String to tokenize. + @param delim Set of characters that are used as token separators. + @param last Reference to the portion after the delimiters. Will return an empty string if is not trailing portion. + @return Returns a pointer to the first part before the delimiters. If the string begins with delimiters, the empty + string will be returned. + @ingroup WebsRuntime + @stability Prototype + */ +PUBLIC char *ssplit(char *str, cchar *delim, char **last); + +/** + Tokenize a string + @description Split a string into tokens. + @param str String to tokenize. + @param delim String of characters to use as token separators. + @param last Last token pointer. + @return Returns a pointer to the next token. + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC char *stok(char *str, char *delim, char **last); + +/** + Trim a string. + @description Trim leading and trailing characters off a string. + @param str String to trim. + @param set String of characters to remove. + @param where Flags to indicate trim from the start, end or both. Use WEBS_TRIM_START, WEBS_TRIM_END, WEBS_TRIM_BOTH. + @return Returns a pointer to the trimmed string. May not equal \a str. + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC char *strim(char *str, char *set, int where); + +/** + Convert a string to upper case. + @description Convert a string to its upper case equivalent. + @param str String to convert. This string is modified. + @return Returns a pointer to the converted string. Will always equal str. + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC char *supper(char *str); + +/** + Callback function for events + @param data Opaque data argument + @param id Event ID + @ingroup WebsRuntime + @stability Evolving + */ +typedef void (*WebsEventProc)(void *data, int id); + +/** + Start a callback event + @description This schedules an event to run once. The event can be rescheduled in the callback by invoking + websRestartEvent. + @param delay Delay in milliseconds in which to run the callback + @param proc Callback procedure function. Signature is: void (*fn)(void *data, int id) + @param data Data reference to pass to the callback + @return A positive integer event ID + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC int websStartEvent(int delay, WebsEventProc proc, void *data); + +/** + Stop an event + @param id Event id allocated by websStartEvent + @return Integer handle index. Otherwise return -1 on allocation errors. + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC void websStopEvent(int id); + +/** + Restart an event + @param id Event id allocated by websStartEvent + @param delay Delay in milliseconds till the event next runs + @ingroup WebsRuntime + @stability Evolving + */ +PUBLIC void websRestartEvent(int id, int delay); + +/** + Run due events + @ingroup WebsRuntime + @return Time till the next event + @internal + */ +PUBLIC WebsTime websRunEvents(); + +/* Forward declare */ +struct WebsRoute; +struct WebsUser; +struct WebsSession; +struct Webs; + +/********************************** Upload ************************************/ +#if ME_GOAHEAD_UPLOAD + +/** + File upload structure + @see websUploadOpen websLookupUpload websGetUpload + @defgroup WebsUpload WebsUpload + */ +typedef struct WebsUpload { + char *filename; /**< Local (temp) name of the file */ + char *clientFilename; /**< Client side name of the file */ + char *contentType; /**< Content type */ + ssize size; /**< Uploaded file size */ +} WebsUpload; + +/** + Open the file upload filter + @ingroup WebsUpload + @stability Evolving + */ +PUBLIC void websUploadOpen(); + +/** + Get the hash of uploaded files for the request + @param wp Webs request object + @return Hash table of uploaded files + @ingroup WebsUpload + @stability Evolving + */ +PUBLIC WebsHash websGetUpload(struct Webs *wp); + +/** + Open the file upload filter + @param wp Webs request object + @param key Form upload name + @return Upload object for the uploaded file + @ingroup WebsUpload + @stability Evolving + */ +PUBLIC WebsUpload *websLookupUpload(struct Webs *wp, char *key); +#endif +/********************************** Defines ***********************************/ + +#define WEBS_MAX_PORT_LEN 16 /* Max digits in port number */ +#define WEBS_HASH_INIT 67 /* Hash size for form table */ +#define WEBS_SESSION_HASH 31 /* Hash size for session stores */ +#define WEBS_SESSION_PRUNE (60*1000) /* Prune sessions every minute */ + +/* + The license agreement stipulates that you must not change this definition. + */ +#define WEBS_NAME "Server: GoAhead-http" + +/* + Request flags + */ +#define WEBS_ACCEPTED 0x1 /**< TLS connection accepted */ +#define WEBS_CHUNKING 0x2 /**< Currently chunking output body data */ +#define WEBS_CLOSED 0x4 /**< Connection closed, ready to free */ +#define WEBS_COOKIE 0x8 /**< Cookie supplied in request */ +#define WEBS_FINALIZED 0x10 /**< Output is finalized */ +#define WEBS_FORM 0x20 /**< Request is a form (url encoded data) */ +#define WEBS_HEADERS_CREATED 0x40 /**< Headers have been created and buffered */ +#define WEBS_HTTP11 0x80 /**< Request is using HTTP/1.1 */ +#define WEBS_JSON 0x100 /**< Request has a JSON payload */ +#define WEBS_KEEP_ALIVE 0x200 /**< HTTP/1.1 keep alive */ +#define WEBS_REROUTE 0x400 /**< Restart route matching */ +#define WEBS_RESPONSE_TRACED 0x800 /**< Started tracing the response */ +#define WEBS_SECURE 0x1000 /**< Connection uses SSL */ +#define WEBS_UPLOAD 0x2000 /**< Multipart-mime file upload */ +#define WEBS_VARS_ADDED 0x4000 /**< Query and body form vars added */ +#if ME_GOAHEAD_LEGACY +#define WEBS_LOCAL 0x8000 /**< Request from local system */ +#endif + +/* + Incoming chunk encoding states. Used for tx and rx chunking. + */ +#define WEBS_CHUNK_UNCHUNKED 0 /**< Data is not transfer-chunk encoded */ +#define WEBS_CHUNK_START 1 /**< Start of a new chunk */ +#define WEBS_CHUNK_HEADER 2 /**< Preparing tx chunk header */ +#define WEBS_CHUNK_DATA 3 /**< Start of chunk data */ + +/* + Webs state + */ +#define WEBS_BEGIN 0 /**< Beginning state */ +#define WEBS_CONTENT 1 /**< Ready for body data */ +#define WEBS_READY 2 /**< Ready to route and start handler */ +#define WEBS_RUNNING 3 /**< Processing request */ +#define WEBS_COMPLETE 4 /**< Request complete */ + +/* + Session names + */ +#define WEBS_SESSION "-goahead-session-" +#define WEBS_SESSION_USERNAME "_:USERNAME:_" /* Username variable */ + +/* + WebsDone flags + */ +#define WEBS_CLOSE 0x20000 /**< Close connection */ +#define WEBS_NOLOG 0x40000 /**< Don't write error to log */ + +/** + Callback for write I/O events + */ +typedef void (*WebsWriteProc)(struct Webs *wp); + +/** + GoAhead request structure. This is a per-socket connection structure. + @defgroup Webs Webs + */ +typedef struct Webs { + WebsBuf rxbuf; /**< Raw receive buffer */ + WebsBuf input; /**< Receive buffer after de-chunking */ + WebsBuf output; /**< Transmit buffer after chunking */ + WebsBuf chunkbuf; /**< Pre-chunking data buffer */ + WebsBuf *txbuf; + WebsTime since; /**< Parsed if-modified-since time */ + WebsHash vars; /**< CGI standard variables */ + WebsTime timestamp; /**< Last transaction with browser */ + int timeout; /**< Timeout handle */ + char ipaddr[ME_MAX_IP]; /**< Connecting ipaddress */ + char ifaddr[ME_MAX_IP]; /**< Local interface ipaddress */ + + int rxChunkState; /**< Rx chunk encoding state */ + ssize rxChunkSize; /**< Rx chunk size */ + char *rxEndp; /**< Pointer to end of raw data in input beyond endp */ + ssize lastRead; /**< Number of bytes last read from the socket */ + bool eof; /**< If at the end of the request content */ + + char txChunkPrefix[16]; /**< Transmit chunk prefix */ + char *txChunkPrefixNext; /**< Current I/O pos in txChunkPrefix */ + ssize txChunkPrefixLen; /**< Length of prefix */ + ssize txChunkLen; /**< Length of the chunk */ + int txChunkState; /**< Transmit chunk state */ + + char *authDetails; /**< Http header auth details */ + char *authResponse; /**< Outgoing auth header */ + char *authType; /**< Authorization type (Basic/DAA) */ + char *contentType; /**< Body content type */ + char *cookie; /**< Request cookie string */ + char *decodedQuery; /**< Decoded request query */ + char *digest; /**< Password digest */ + char *ext; /**< Path extension */ + char *filename; /**< Document path name */ + char *host; /**< Requested host */ + char *inputFile; /**< File name to write input body data */ + char *method; /**< HTTP request method */ + char *password; /**< Authorization password */ + char *path; /**< Path name without query. This is decoded. */ + char *protoVersion; /**< Protocol version (HTTP/1.1)*/ + char *protocol; /**< Protocol scheme (normally http|https) */ + char *putname; /**< PUT temporary filename */ + char *query; /**< Request query. This is decoded. */ + char *realm; /**< Realm field supplied in auth header */ + char *referrer; /**< The referring page */ + char *responseCookie; /**< Outgoing cookie */ + char *url; /**< Full request url. This is not decoded. */ + char *userAgent; /**< User agent (browser) */ + char *username; /**< Authorization username */ + + int sid; /**< Socket id (handler) */ + int listenSid; /**< Listen Socket id */ + int port; /**< Request port number */ + int state; /**< Current state */ + int flags; /**< Current flags -- see above */ + int code; /**< Response status code */ + int routeCount; /**< Route count limiter */ + ssize rxLen; /**< Rx content length */ + ssize rxRemaining; /**< Remaining content to read from client */ + ssize txLen; /**< Tx content length header value */ + int wid; /**< Index into webs */ +#if ME_GOAHEAD_CGI + char *cgiStdin; /**< Filename for CGI program input */ + int cgifd; /**< File handle for CGI program input */ +#endif +#if !ME_ROM + int putfd; /**< File handle to write PUT data */ +#endif + int docfd; /**< File descriptor for document being served */ + ssize written; /**< Bytes actually transferred */ + ssize putLen; /**< Bytes read by a PUT request */ + + struct WebsSession *session; /**< Session record */ + struct WebsRoute *route; /**< Request route */ + struct WebsUser *user; /**< User auth record */ + WebsWriteProc writeData; /**< Handler write I/O event callback. Used by fileHandler */ + int encoded; /**< True if the password is MD5(username:realm:password) */ +#if ME_GOAHEAD_DIGEST + char *cnonce; /**< check nonce */ + char *digestUri; /**< URI found in digest header */ + char *nonce; /**< opaque-to-client string sent by server */ + char *nc; /**< nonce count */ + char *opaque; /**< opaque value passed from server */ + char *qop; /**< quality operator */ +#endif +#if ME_GOAHEAD_UPLOAD + int upfd; /**< Upload file handle */ + WebsHash files; /**< Uploaded files */ + char *boundary; /**< Mime boundary (static) */ + ssize boundaryLen; /**< Boundary length */ + int uploadState; /**< Current file upload state */ + WebsUpload *currentFile; /**< Current file context */ + char *clientFilename; /**< Current file filename */ + char *uploadTmp; /**< Current temp filename for upload data */ + char *uploadVar; /**< Current upload form variable name */ +#endif + void *ssl; /**< SSL context */ +} Webs; + +#if ME_GOAHEAD_LEGACY + #define WEBS_LEGACY_HANDLER 0x1 /* Using legacy calling sequence */ +#endif + + +/** + GoAhead handler service callback + @param wp Webs request object + @return True if the handler serviced the request + @ingroup Webs + @stability Evolving + */ +typedef bool (*WebsHandlerProc)(Webs *wp); + +/** + GoAhead handler close to release memory prior to shutdown. + @description This callback is invoked when GoAhead is shutting down. + @ingroup Webs + @stability Evolving + */ +typedef void (*WebsHandlerClose)(); + +/** + GoAhead handler object + @ingroup Webs + @stability Evolving + */ +typedef struct WebsHandler { + char *name; /**< Handler name */ + WebsHandlerProc match; /**< Handler match callback */ + WebsHandlerProc service; /**< Handler service callback */ + WebsHandlerClose close; /**< Handler close callback */ + int flags; /**< Handler control flags */ +} WebsHandler; + +/** + Action callback + @param wp Webs request object + @ingroup Webs + @stability Evolving + */ +typedef void (*WebsAction)(Webs *wp); + +#if ME_GOAHEAD_LEGACY + typedef void (*WebsProc)(Webs *wp, char *path, char *query); +#endif + +/** + Error code list + @ingroup Webs + @stability Evolving + */ +typedef struct WebsError { + int code; /**< HTTP error code */ + char *msg; /**< HTTP error message */ +} WebsError; + +/** + Mime type list + @ingroup Webs + @stability Evolving + */ +typedef struct WebsMime { + char *type; /**< Mime type */ + char *ext; /**< File extension */ +} WebsMime; + +/** + File information structure. + @ingroup Webs + @stability Evolving + */ +typedef struct WebsFileInfo { + ulong size; /**< File length */ + int isDir; /**< Set if directory */ + WebsTime mtime; /**< Modified time */ +} WebsFileInfo; + +/** + Compiled Rom Page Index + @ingroup Webs + @stability Evolving + */ +typedef struct WebsRomIndex { + char *path; /**< Web page URL path */ + uchar *page; /**< Web page data */ + int size; /**< Size of web page in bytes */ + Offset pos; /**< Current read position */ +} WebsRomIndex; + +#if ME_ROM + /** + List of documents to service when built with ROM support + @ingroup Webs + @stability Evolving + */ + PUBLIC_DATA WebsRomIndex websRomIndex[]; +#endif + +#define WEBS_DECODE_TOKEQ 1 /**< Decode base 64 blocks up to a NULL or equals */ + +/** + Accept a new connection + @param sid Socket ID handle for the newly accepted socket + @param ipaddr IP address originating the connection. + @param port Port number originating the connection. + @param listenSid Socket ID of the listening socket + @return Zero if successful, otherwise -1 + @ingroup Webs + @stability Evolving + */ +PUBLIC int websAccept(int sid, char *ipaddr, int port, int listenSid); + +/** + Open the action handler + @ingroup Webs + @stability Evolving + */ +PUBLIC void websActionOpen(); + +/** + Allocate a new Webs object + @param sid Socket ID handle for the newly accepted socket + @return The webs[] handle index for the allocated Webs object + @ingroup Webs + @stability Evolving + */ +PUBLIC int websAlloc(int sid); + +/** + Cancel the request timeout. + @description Handlers may choose to manually manage the request timeout. This routine will disable the + centralized management of the timeout for this request. + @param wp Webs request object + @ingroup Webs + @stability Evolving + */ +PUBLIC void websCancelTimeout(Webs *wp); + +#if ME_GOAHEAD_CGI +/** + Open the CGI handler + @return Zero if successful, otherwise -1 + @ingroup Webs + @stability Evolving + */ +PUBLIC int websCgiOpen(); + +/** + CGI handler service callback + @param wp Webs object + @return Returns 1 if the request was handled. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websCgiHandler(Webs *wp); + +/** + Poll for output from CGI processes and output. + @return Time delay till next poll + @ingroup Webs + @stability Evolving + */ +PUBLIC WebsTime websCgiPoll(); +#endif /* ME_GOAHEAD_CGI */ + +/** + Close the core GoAhead web server module + @description Invoked when GoAhead is shutting down. + @ingroup Webs + @stability Evolving + */ +PUBLIC void websClose(); + +/** + Close an open file + @param fd Open file handle returned by websOpenFile + @ingroup Webs + @stability Evolving + */ +PUBLIC void websCloseFile(int fd); + +/** + Compare a request variable + @param wp Webs request object + @param var Variable name + @param value Value to compare with + @return True if the value matches. Otherwise return 0 + @ingroup Webs + @stability Evolving + */ +PUBLIC int websCompareVar(Webs *wp, char *var, char *value); + +/** + Consume input from the request input buffer. + @description This is called by handlers when consuming data from the request input buffer. + This call updates the input service pointers and compacts the input buffer if required. + @param wp Webs request object + @param nbytes Number of bytes the handler has consumed from the input buffer. + @ingroup Webs + @stability Evolving + */ +PUBLIC void websConsumeInput(Webs *wp, ssize nbytes); + +/** + Decode the string using base-64 encoding + @description This modifies the original string + @param str String to decode + @return The original string. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websDecode64(char *str); + +/** + Decode a block using base-46 encoding + @param str String to decode. The string must be null terminated. + @param len Reference to an integer holding the length of the decoded string. + @param flags Reserved. + @return The original string. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websDecode64Block(char *str, ssize *len, int flags); + +/** + Decode a URL expanding %NN encoding + @description Supports insitu decoding. i.e. Input and output buffers may be the same. + @param decoded Buffer to hold the decoded URL + @param input Input URL or buffer to decode + @param len Length of the decoded buffer. + @ingroup Webs + @stability Evolving + */ +PUBLIC void websDecodeUrl(char *decoded, char *input, ssize len); + +/** + Define a request handler + @param name Name of the handler + @param match Handler callback match procedure. Invoked to match the request with the handler. + The handler should return true to accept the request. + @param service Handler callback service procedure. Invoked to service each request. + @param close Handler callback close procedure. Called when GoAhead is shutting down. + @param flags Set to WEBS_LEGACY_HANDLER to support the legacy handler API calling sequence. + @return Zero if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websDefineHandler(char *name, WebsHandlerProc match, WebsHandlerProc service, WebsHandlerClose close, int flags); + +/** + Complete a request. + @description A handler should call websDone() to complete the request. + @param wp Webs request object + @ingroup Webs + @stability Evolving + */ +PUBLIC void websDone(Webs *wp); + +/** + Encode a string using base-64 encoding + @description The string is encoded insitu. + @param str String to encode + @return The original string. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websEncode64(char *str); + +/** + Encode a block using base-64 encoding + @description The string is encoded insitu. + @param str String to encode. + @param len Length of string to encode + @return The original string. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websEncode64Block(char *str, ssize len); + +/** + Escape unsafe characters in a string + @param str String to escape + @return An allocated block containing the escaped string. Caller must free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websEscapeHtml(char *str); + +/** + Complete a request with an error response + @param wp Webs request object + @param code HTTP status code + @param fmt Message printf style format + @param ... Format args + @ingroup Webs + @stability Evolving + */ +PUBLIC void websError(Webs *wp, int code, char *fmt, ...); + +/** + Get a message for a HTTP status code + @param code HTTP status code + @return Http status message + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websErrorMsg(int code); + +/** + Open and initialize the file handler + @ingroup Webs + @stability Evolving + */ +PUBLIC void websFileOpen(); + +/** + Flush buffered transmit data and compact the transmit buffer to make room for more data + @description This call initiates sending buffered data. If blocking mode is selected via the block parameter, + this call will wait until all the data has been sent to the O/S for transmission to the client. + If block is false, the flush will be initiated and the call will return immediately without blocking. + @param wp Webs request object + @param block Set to true to wait for all data to be written to the socket. Set to false to + write whatever the socket can absorb without blocking. + @return -1 for I/O errors. Return zero if there is more data remaining in the buffer. Return 1 if the + contents of the transmit buffer are fully written and the buffer is now empty. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websFlush(Webs *wp, bool block); + +/** + Free the webs request object. + @description Callers should call websDone to complete requests prior to invoking websFree. + @param wp Webs request object + @ingroup Webs + @stability Evolving + */ +PUBLIC void websFree(Webs *wp); + +/** + Get the background execution flag + @description If GoAhead is invoked with --background, it will run as a daemon in the background. + @return True if GoAhead is running in the background. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websGetBackground(); + +#if ME_GOAHEAD_CGI +/** + Get a unique temporary filename for CGI communications + @return Filename string + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetCgiCommName(); +#endif /* ME_GOAHEAD_CGI */ + +/** + Get the request cookie if supplied + @param wp Webs request object + @return Cookie string if defined, otherwise null. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetCookie(Webs *wp); + +/** + Get a date as a string + @description If sbuf is supplied, it is used to calculate the date. Otherwise, the current time is used. + @param sbuf File info object + @return An allocated date string. Caller should free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetDateString(WebsFileInfo *sbuf); + +/** + Get the debug flag + @description If GoAhead is invoked with --debugger, the debug flag will be set to true + @return True if GoAhead is running in debug mode. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websGetDebug(); + +/** + Get the base file directory for a request + @description Returns the request route directory if defined, otherwise returns the documents directory. + @param wp Webs request object + @return Path name string. Caller should not free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetDir(Webs *wp); + +/** + Get the GoAhead base documents directory + @description The documents directory is defined at build time and may be overridden by the GoAhead command line. + @return Path string for the documents directory. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetDocuments(); + +/** + Get the request EOF status + @description The request EOF status is set to true when all the request body (POST|PUT) data has been received. + @param wp Webs request object + @return True if all the request body data has been received. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websGetEof(Webs *wp); + +/** + Get the request URI extension + @param wp Webs request object + @return The URI filename extension component. Caller should not free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetExt(Webs *wp); + +/** + Get the request filename + @description The URI is mapped to a filename by decoding and prepending with the request directory. + @param wp Webs request object + @return Filename string. Caller should not free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetFilename(Webs *wp); + +/** + Get the request host + @description The request host is set to the Host HTTP header value if it is present. Otherwise it is set to + the request URI hostname. + @param wp Webs request object + @return Host string. Caller should not free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetHost(Webs *wp); + +/** + Get the request interface address + @param wp Webs request object + @return Network interface string. Caller should not free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetIfaddr(Webs *wp); + +/** + Get the default index document name + @description The default index is "index.html" and can be updated via websSetIndex. + @return Index name string. Caller should not free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetIndex(); + +/** + Get the request method + @param wp Webs request object + @return HTTP method string. Caller should not free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetMethod(Webs *wp); + +/** + Get the request password + @description The request password may be encoded depending on the authentication scheme. + See wp->encoded to test if it is encoded. + @param wp Webs request object + @return Password string. Caller should not free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetPassword(Webs *wp); + +/** + Get the request path + @description The URI path component excludes the http protocol, hostname, port, reference and query components. + It always beings with "/". + @param wp Webs request object + @return Request path string. Caller should not free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetPath(Webs *wp); + +/** + Get the request TCP/IP port + @param wp Webs request object + @return TCP/IP Port integer + @ingroup Webs + @stability Evolving + */ +PUBLIC int websGetPort(Webs *wp); + +/** + Get the request HTTP protocol + @description This will be set to either "http" or "https" + @param wp Webs request object + @return Protocol string. Caller should not free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetProtocol(Webs *wp); + +/** + Get the request query component + @param wp Webs request object + @return Request query string. Caller should not free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetQuery(Webs *wp); + +/** + Get the server host name + @return Host name string. Caller should not free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetServer(); + +/** + Get the server host name with port number. + @return Host name string with port number. Caller should not free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetServerUrl(); + +/** + Get the server IP address + @return Server IP address string. Caller should not free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetServerAddress(); + +/** + Get the server IP address with port number + @return Server IP:PORT address string. Caller should not free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetServerAddressUrl(); + +/** + Get the current trace log level + @return Number between 0 and 9 + @ingroup Webs + @stability Evolving + */ +PUBLIC int websGetLogLevel(); + +/** + Get the request URI + @description This returns the request URI. This may be modified if the request is rewritten via websRewrite + @param wp Webs request object + @return URI string. Caller should not free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetUrl(Webs *wp); + +/** + Get the client User-Agent HTTP header + @param wp Webs request object + @return User-Agent string. Caller should not free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetUserAgent(Webs *wp); + +/** + Get the request username + @description If the request is authenticated, this call returns the username supplied during authentication. + @param wp Webs request object + @return Username string if defined, otherwise null. Caller should not free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetUsername(Webs *wp); + +/** + Get a request variable + @description Request variables are defined for HTTP headers of the form HTTP_*. + Some request handlers also define their own variables. For example: CGI environment variables. + @param wp Webs request object + @param name Variable name + @param defaultValue Default value to return if the variable is not defined + @return Variable value string. Caller should not free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websGetVar(Webs *wp, char *name, char *defaultValue); + +/** + Listen on a TCP/IP address endpoint + @description The URI is mapped to a filename by decoding and prepending with the request directory. + For IPv6 addresses, use the format: [aaaa:bbbb:cccc:dddd:eeee:ffff:gggg:hhhh:iiii]:port. + @param endpoint IPv4 or IPv6 address on which to listen. + @return Positive integer holding a Socket ID handle if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websListen(char *endpoint); + +/** + Get an MD5 digest of a string + @param str String to analyze. + @return Allocated MD5 checksum. Caller should free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websMD5(char *str); + +/** + Get an MD5 digest of a block and optionally prepend a prefix. + @param buf Block to analyze + @param length Length of block + @param prefix Optional prefix to prepend to the MD5 sum. + @return Allocated MD5 checksum. Caller should free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websMD5Block(char *buf, ssize length, char *prefix); + +/** + Normalize a URI path + @description This removes "./", "../" and redundant separators. + @param path URI path to normalize + @return An allocated normalized URI path. Caller must free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websNormalizeUriPath(char *path); + +/** + Take not of the request activity and mark the time. + @description This is used to defer the request timeout whenever there is request I/O activity. + @param wp Webs request object + @ingroup Webs + @stability Evolving + */ +PUBLIC void websNoteRequestActivity(Webs *wp); + +/** + Close the runtime code. + @description Called from websClose + @ingroup Webs + @internal + */ +PUBLIC void websRuntimeClose(); + +/** + Open the runtime code. + @description Called from websOpen + @return Zero if successful + @ingroup Webs + @internal + */ +PUBLIC int websRuntimeOpen(); + +/** + Open the web server + @description This initializes the web server and defines the documents directory. + @param documents Optional web documents directory. If set to null, the build time ME_GOAHEAD_DOCUMENTS value + is used for the documents directory. + @param routes Optional filename for a route configuration file to load. Additional route or + authentication configuration files can be loaded via websLoad. + @param routes Webs request object + @return Zero if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websOpen(char *documents, char *routes); + +/** + Close the O/S dependant code. + @description Called from websClose + @ingroup Webs + @internal + */ +PUBLIC void websOsClose(); + +/** + Open the O/S dependant code. + @description Called from websOpen + @return Zero if successful, otherwise -1. + @ingroup Webs + @internal + */ +PUBLIC int websOsOpen(); + +/** + Open the web page document for the current request + @param path Filename path to open + @param flags File open flags + @param mode Permissions mask + @return Positive file handle if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websOpenFile(char *path, int flags, int mode); + +/** + Open the options handler + @return Zero if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websOptionsOpen(); + +/** + Close the document page + @param wp Webs request object + @ingroup Webs + @stability Evolving + */ +PUBLIC void websPageClose(Webs *wp); + +/** + Test if the document page for the request corresponds to a directory + @param wp Webs request object + @return True if the filename is a directory + @ingroup Webs + @stability Evolving + */ +PUBLIC int websPageIsDirectory(Webs *wp); + +/** + Open a web page document for a request + @param wp Webs request object + @param mode File open mode. Select from O_RDONLY and O_BINARY. Rom files systems ignore this argument. + @param perms Ignored + @return File handle if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websPageOpen(Webs *wp, int mode, int perms); + +/** + Read data from the request page document + @param wp Webs request object + @param buf Buffer for the read data + @param size Size of buf + @return Count of bytes read if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC ssize websPageReadData(Webs *wp, char *buf, ssize size); + +/** + Seek to a position in the request page document + @param wp Webs request object + @param offset Offset of location in the file to seek to. This is relative to the specified origin. + @param origin Set to SEEK_CUR, SEEK_SET or SEEK_END to position relative to the current position, + beginning or end of the document. + @ingroup Webs + @stability Evolving + */ +PUBLIC void websPageSeek(Webs *wp, Offset offset, int origin); + +/** + Get file status for the current request document + @param wp Webs request object + @param sbuf File information structure to modify with file status + @return Zero if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websPageStat(Webs *wp, WebsFileInfo *sbuf); + +#if !ME_ROM +/** + Process request PUT body data + @description This routine is called by the core HTTP engine to process request PUT data. + @param wp Webs request object + @return Zero if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websProcessPutData(Webs *wp); +#endif + +/** + Pump the state machine + @description This routine will advance the connection state machine in response to events. + @param wp Webs request object + @ingroup Webs + @stability Evolving + */ +PUBLIC void websPump(Webs *wp); + +/** + Define an action callback for use with the action handler. + @description The action handler binds a C function to a URI under "/action". + @param name URI path suffix. This suffix is added to "/action" to form the bound URI path. + @param fun Callback function. The signature is void (*WebsAction)(Webs *wp); + @return Zero if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websDefineAction(cchar *name, void *fun); + +/** + Read data from an open file + @param fd Open file handle returned by websOpenFile + @param buf Buffer for the read data + @param size Size of buf + @return Count of bytes read if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC ssize websReadFile(int fd, char *buf, ssize size); + +/** + Read all the data from a file + @param path File path to read from + @return An allocated buffer containing the file data with an appended null. Caller must free. + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websReadWholeFile(char *path); + +/** + Redirect the client to a new URL. + @description This creates a response to the client with a Location header directing the client to a new location. + The response uses a 302 HTTP status code. + @param wp Webs request object + @param url URL to direct the client to. + @ingroup Webs + @stability Evolving + */ +PUBLIC void websRedirect(Webs *wp, char *url); + +/** + Redirect the client to a new URI + @description The routing configuration file can define redirection routes for various HTTP status codes. + This routine will utilize the appropriate route redirection based on the request route and specified status code. + @param wp Webs request object + @param status HTTP status code to use in selecting the route redirection. + @return Zero if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websRedirectByStatus(Webs *wp, int status); + +/** + Create and send a request response + @description This creates a response for the current request using the specified HTTP status code and + the supplied message. + @param wp Webs request object + @param status HTTP status code. + @param msg Response message body + @return Zero if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC void websResponse(Webs *wp, int status, char *msg); + +/** + Rewrite a request + @description Handlers may choose to not process a request but rather rewrite requests and then reroute. + @param wp Webs request object + @param url New request URL. + @return Zero if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websRewriteRequest(Webs *wp, char *url); + +/** + Open the file system module + @return Zero if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websFsOpen(); + +/** + Close the file system module + @ingroup Webs + @stability Evolving + */ +PUBLIC void websFsClose(); + +/** + Seek to a position in the current request page document + @param fd Open file handle returned by websOpenFile + @param offset Location in the file to seek to. + @param origin Set to SEEK_CUR, SEEK_SET or SEEK_END to position relative to the current position, + beginning or end of the document. + @ingroup Webs + @stability Evolving + */ +PUBLIC Offset websSeekFile(int fd, Offset offset, int origin); + +/** + Get file status for a file + @param path Filename path + @param sbuf File information structure to modify with file status + @return Zero if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websStatFile(char *path, WebsFileInfo *sbuf); + +/** + One line embedding API. + @description This call will also open auth.txt and route.txt for authentication and routing configuration. + @param endpoint IP:PORT address on which to listen + @param documents Directory containing web documents to serve + @ingroup Webs + @stability Evolving + */ +PUBLIC int websServer(char *endpoint, char *documents); + +/** + Service I/O events until finished + @description This will wait for socket events and service those until *finished is set to true + @param finished Integer location to test. If set to true, then exit. Note: setting finished will not + automatically wake up the service routine. + @ingroup Webs + @stability Evolving + */ +PUBLIC void websServiceEvents(int *finished); + +/** + Set the background processing flag + @param on Value to set the background flag to. + @ingroup Webs + @internal + */ +PUBLIC void websSetBackground(int on); + +/** + Define a background write I/O event callback + @param wp Webs request object + @param proc Write callback + */ +PUBLIC void websSetBackgroundWriter(Webs *wp, WebsWriteProc proc); + +/* + Flags for websSetCookie + */ +#define WEBS_COOKIE_SECURE 0x1 /**< Flag for websSetCookie for secure cookies (https only) */ +#define WEBS_COOKIE_HTTP 0x2 /**< Flag for websSetCookie for http cookies (http only) */ + +/** + Define a cookie to include in the response + @param wp Webs request object + @param name Cookie name + @param value Cookie value + @param path URI path prefix applicable for this cookie + @param domain Domain applicable for this cookie + @param lifespan Cookie lifespan in secons + @param flags Set to WEBS_COOKIE_SECURE for https only. Set to WEBS_COOKIE_HTTP for http only. + Otherwise the cookie applies to both http and https requests. + @return Zero if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC void websSetCookie(Webs *wp, char *name, char *value, char *path, char *domain, WebsTime lifespan, int flags); + +/** + Set the debug processing flag + @param on Value to set the debug flag to. + @ingroup Webs + @internal + */ +PUBLIC void websSetDebug(int on); + +/** + Set the web documents directory + @description The web documents directory is used when resolving request URIs into filenames. + @param dir Directory path to use + @ingroup Webs + @stability Evolving + */ +PUBLIC void websSetDocuments(char *dir); + +/** + Create the CGI environment variables for the current request. + @param wp Webs request object + @ingroup Webs + @stability Evolving + */ +PUBLIC void websSetEnv(Webs *wp); + +/** + Create request variables for query and POST body data + @description This creates request variables if the request is a POST form (has a Content-Type of + application/x-www-form-urlencoded). The POST body data is consumed from the input buffer. + @param wp Webs request object + @ingroup Webs + @stability Evolving + */ +PUBLIC void websSetFormVars(Webs *wp); + +/** + Define the host name for the server + @param host String host name + @ingroup Webs + @stability Evolving + */ +PUBLIC void websSetHost(char *host); + +/** + Define the host IP address + @param ipaddr Host IP address + @ingroup Webs + @stability Evolving + */ +PUBLIC void websSetIpAddr(char *ipaddr); + +/** + Create and send a request response + @description This creates a response for the current request using the specified HTTP status code and + the supplied message. + @param filename Web document name to use as the index. This should not contain any directory components. + @ingroup Webs + @stability Evolving + */ +PUBLIC void websSetIndex(char *filename); + +/** + Create request variables for query string data + @param wp Webs request object + @ingroup Webs + @stability Evolving + */ +PUBLIC void websSetQueryVars(Webs *wp); + +/** + Set the response HTTP status code + @param wp Webs request object + @param status HTTP status code + @ingroup Webs + @stability Evolving + */ +PUBLIC void websSetStatus(Webs *wp, int status); + +/** + Set the response body content length + @param wp Webs request object + @param length Length value to use + @ingroup Webs + @stability Evolving + */ +PUBLIC void websSetTxLength(Webs *wp, ssize length); + +/** + Set a request variable to a formatted string value + @description Request variables are defined for HTTP headers of the form HTTP_*. + Some request handlers also define their own variables. For example: CGI environment variables. + @param wp Webs request object + @param name Variable name to set + @param fmt Value format string + @param ... Args to format + @ingroup Webs + @stability Evolving + */ +PUBLIC void websSetVarFmt(Webs *wp, char *name, char *fmt, ...); + +/** + Set a request variable to a string value + @description Request variables are defined for HTTP headers of the form HTTP_*. + Some request handlers also define their own variables. For example: CGI environment variables. + @param wp Webs request object + @param name Variable name to set + @param value Value to set + @ingroup Webs + @stability Evolving + */ +PUBLIC void websSetVar(Webs *wp, char *name, char *value); + +/** + Test if a request variable is defined + @param wp Webs request object + @param name Variable name + @return True if the variable is defined + @ingroup Webs + @stability Evolving + */ +PUBLIC bool websTestVar(Webs *wp, char *name); + +/** + Create a temporary filename + This does not guarantee the filename is unique or that it is not already in use by another application. + @param dir Directory to locate the temp file. Defaults to the O/S default temporary directory (usually /tmp) + @param prefix Filename prefix + @return An allocated filename string + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websTempFile(char *dir, char *prefix); + + +/** + Parse a URL into its components + @param url URL to parse + @param buf Buffer to hold storage for various parsed components. Caller must free. NOTE: the parsed components may + point to locations in this buffer. + @param protocol Parsed URL protocol component + @param host Parsed hostname + @param port Parsed URL port + @param path Parsed URL path component + @param ext Parsed URL extension + @param reference Parsed URL reference portion (\#reference) + @param query Parsed URL query component + @return Zero if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websUrlParse(char *url, char **buf, char **protocol, char **host, char **port, char **path, char **ext, + char **reference, char **query); + +/** + Test if a webs object is valid + @description After calling websDone, the websFree routine will have been called and the memory for the webs object + will be released. Call websValid to test an object hand for validity. + @param wp Webs request object + @return True if the webs object is still valid and the request has not been completed. + @ingroup Webs + @stability Evolving + */ +PUBLIC bool websValid(Webs *wp); + +/** + Validate a URI path as expected in a HTTP request line + @description This expects a URI beginning with "/" and containing only valid URI characters. + The URI is decoded, and normalized removing "../" and "." segments. + The URI must begin with a "/" both before and after decoding and normalization. + @param uri URI to validate. + @return A validated, normalized URI path + @ingroup Webs + @stability Evolving + */ +PUBLIC char *websValidateUriPath(char *uri); + +/** + Test if a URI is using only valid characters + Note this does not test if the URI is fully legal. Some components of the URI have restricted character sets + that this routine does not test. This tests if the URI has only characters valid to use in a URI before decoding. + i.e. It will permit %NN encodings. The set of valid characters is: + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=%" + @param uri Uri to test + @return True if the URI string is comprised of legal URI characters. + @ingroup Webs + @stability Prototype + */ +PUBLIC bool websValidUriChars(char *uri); + +/** + Write a set of standard response headers + @param wp Webs request object + @param contentLength Value for the Content-Length header which describes the length of the response body + @param redirect Value for the Location header which redirects the client to a new URL. + @ingroup Webs + @see websSetStatus + @stability Evolving + */ +PUBLIC void websWriteHeaders(Webs *wp, ssize contentLength, char *redirect); + +/** + Signify the end of the response headers + @description This call concludes the response headers and writes a blank line to the response. + @param wp Webs request object + @ingroup Webs + @stability Evolving + */ +PUBLIC void websWriteEndHeaders(Webs *wp); + +/** + Write a response header + @description This routine writes a response header. It should be invoked after calling websWriteHeaders + to write the standard headers and before websWriteEndHeaders. + This routine differs from websWrite in that it traces header values to the log. + @param wp Webs request object + @param key Header key value + @param fmt Header value format string. + @param ... Arguments to the format string. + @return Zero if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websWriteHeader(Webs *wp, char *key, char *fmt, ...); + +/** + Write data to the response + @description The data is buffered and will be sent to the client when the buffer is full or websFlush is + called. + @param wp Webs request object + @param fmt Printf style format string. + @param ... Arguments to the format string. + @return Count of bytes written + @ingroup Webs + @stability Evolving + */ +PUBLIC ssize websWrite(Webs *wp, char *fmt, ...); + +/** + Write data to the open file + @param fd Open file handle returned by websOpenFile + @param buf Buffer for the read data + @param size Size of buf + @return Count of bytes read if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC ssize websWriteFile(int fd, char *buf, ssize size); + +/** + Write a block of data to the response + @description The data is buffered and will be sent to the client when the buffer is full or websFlush is + called. This routine will never return "short", it will always write all the data unless there are errors. + @param wp Webs request object + @param buf Buffer of data to write + @param size Length of buf + @return Count of bytes written or -1. This will always equal size if there are no errors. + @ingroup Webs + @stability Evolving + */ +PUBLIC ssize websWriteBlock(Webs *wp, char *buf, ssize size); + +/** + Write a block of data to the network + @description This bypassed output buffering and is the lowest level write. + @param wp Webs request object + @param buf Buffer of data to write + @param size Length of buf + @return Count of bytes written. May be less than len if the socket is in non-blocking mode. + Returns -1 for errors and if the socket cannot absorb any more data. If the transport is saturated, + will return a negative error and errno will be set to EAGAIN or EWOULDBLOCK. + @ingroup Webs + @stability Evolving + */ +PUBLIC ssize websWriteSocket(Webs *wp, char *buf, ssize size); + +#if ME_GOAHEAD_UPLOAD +/** + Process upload data for form, multipart mime file upload. + @param wp Webs request object + @return Zero if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websProcessUploadData(Webs *wp); + +/** + Free file upload data structures. + @param wp Webs request object + @ingroup Webs + @stability Evolving + */ +PUBLIC void websFreeUpload(Webs *wp); +#endif + +#if ME_GOAHEAD_CGI +/** + Process CGI request body data. + @param wp Webs request object + @return Zero if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websProcessCgiData(Webs *wp); +#endif + +#if ME_GOAHEAD_JAVASCRIPT +/** + Javascript native function + @param jid JavaScript engine ID + @param wp Webs request object + @param argc Count of function arguments + @param argv Array of function arguments + @param defaultValue Default value to return if the variable is not defined + @return Return zero if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +typedef int (*WebsJstProc)(int jid, Webs *wp, int argc, char **argv); + +/** + Define a Javscript native function. + @description This routine binds a C function to a Javascript function. When the Javascript function is called, + the C function is invoked. + @param name Javascript function name + @param fn C function to invoke + @return Zero if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websDefineJst(char *name, WebsJstProc fn); + +/** + Open the Javascript module. + @return Zero if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websJstOpen(); + +/** + Write data to the response + @param jid Javascript ID handle + @param wp Webs request object + @param argc Count of arguments + @param argv Array arguments + @return Zero if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC int websJstWrite(int jid, Webs *wp, int argc, char **argv); +#endif + +#if FUTURE +/* + Accessors + */ +PUBLIC char *websGetCookie(Webs *wp) { return wp->cookie; } +PUBLIC char *websGetDir(Webs *wp) { return wp->route && wp->route->dir ? wp->route->dir : websGetDocuments(); } +PUBLIC int websGetEof(Webs *wp) { return wp->eof; } +PUBLIC char *websGetExt(Webs *wp) { return wp->ext; } +PUBLIC char *websGetFilename(Webs *wp) { return wp->filename; } +PUBLIC char *websGetHost(Webs *wp) { return wp->host; } +PUBLIC char *websGetIfaddr(Webs *wp) { return wp->ifaddr; } +PUBLIC char *websGetIpaddr(Webs *wp) { return wp->ipaddr; } +PUBLIC char *websGetMethod(Webs *wp) { return wp->method; } +PUBLIC char *websGetPassword(Webs *wp) { return wp->password; } +PUBLIC char *websGetPath(Webs *wp) { return wp->path; } +PUBLIC int websGetPort(Webs *wp) { return wp->port; } +PUBLIC char *websGetProtocol(Webs *wp) { return wp->protocol; } +PUBLIC char *websGetQuery(Webs *wp) { return wp->query; } +PUBLIC char *websGetServer() { return websHost; } +PUBLIC char *websGetServerAddress() { return websIpAddr; } +PUBLIC char *websGetServerAddressUrl() { return websIpAddrUrl; } +PUBLIC char *websGetServerUrl() { return websHostUrl; } +PUBLIC char *websGetUrl(Webs *wp) { return wp->url; } +PUBLIC char *websGetUserAgent(Webs *wp) { return wp->userAgent; } +PUBLIC char *websGetUsername(Webs *wp) { return wp->username; } +#endif + +/*************************************** SSL ***********************************/ + +#if ME_COM_SSL +/* + Default MakeMe settings + */ +#ifndef ME_GOAHEAD_SSL_AUTHORITY + #define ME_GOAHEAD_SSL_AUTHORITY "" +#endif +#ifndef ME_GOAHEAD_SSL_CACHE + #define ME_GOAHEAD_SSL_CACHE 512 +#endif +#ifndef ME_GOAHEAD_SSL_CERTIFICATE + #define ME_GOAHEAD_SSL_CERTIFICATE "" +#endif +#ifndef ME_GOAHEAD_SSL_CIPHERS + #define ME_GOAHEAD_SSL_CIPHERS "" +#endif +#ifndef ME_GOAHEAD_SSL_KEY + #define ME_GOAHEAD_SSL_KEY "" +#endif +#ifndef ME_GOAHEAD_SSL_LOG_LEVEL + #define ME_GOAHEAD_SSL_LOG_LEVEL 4 +#endif +#ifndef ME_GOAHEAD_SSL_RENEGOTIATE + #define ME_GOAHEAD_SSL_RENEGOTIATE 1 +#endif +#ifndef ME_GOAHEAD_SSL_REVOKE + #define ME_GOAHEAD_SSL_REVOKE "" +#endif +#ifndef ME_GOAHEAD_SSL_TICKET + #define ME_GOAHEAD_SSL_TICKET 1 +#endif +#ifndef ME_GOAHEAD_SSL_TIMEOUT + #define ME_GOAHEAD_SSL_TIMEOUT 86400 +#endif +#ifndef ME_GOAHEAD_SSL_VERIFY + #define ME_GOAHEAD_SSL_VERIFY 0 +#endif +#ifndef ME_GOAHEAD_SSL_VERIFY_ISSUER + #define ME_GOAHEAD_SSL_VERIFY_ISSUER 0 +#endif + +/** + Open the ssl module + @return Zero if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC int sslOpen(); + +/** + Close the ssl module + @ingroup Webs + @stability Evolving + */ +PUBLIC void sslClose(); + +/** + Free a ssl connection associated with a request + @param wp Webs request object + @ingroup Webs + @stability Evolving + */ +PUBLIC void sslFree(Webs *wp); + +/** + Upgrade a request connection to utilize SSL + @description This routine is invoked on a connection received on a secure listening socket + @param wp Webs request object + @return Zero if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC int sslUpgrade(Webs *wp); + +/** + Read data from a secure socket + @param wp Webs request object + @param buf Buffer into which to read data + @param len Size of buf + @return Count of bytes read if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC ssize sslRead(Webs *wp, void *buf, ssize len); + +/** + WRite data to a secure socket + @param wp Webs request object + @param buf Buffer from which to write data + @param len Size of buf + @return Count of bytes written if successful, otherwise -1. + @ingroup Webs + @stability Evolving + */ +PUBLIC ssize sslWrite(Webs *wp, void *buf, ssize len); +#endif /* ME_COM_SSL */ + +/*************************************** Route *********************************/ +/** + Callback to prompt the user for their password + @param wp Webs request object + @ingroup Webs + @stability Evolving + */ +typedef void (*WebsAskLogin)(Webs *wp); + +/** + Callback to verify the username and password + @param wp Webs request object + @return True if the password is verified + @ingroup Webs + @stability Evolving + */ +typedef bool (*WebsVerify)(Webs *wp); + +/** + Callback to parse authentication details submitted with the web request + @param wp Webs request object + @return True if the details can be parsed + @ingroup Webs + @stability Evolving + */ +typedef bool (*WebsParseAuth)(Webs *wp); + +/** + Request route structure + @defgroup WebsRoute WebsRoute + */ +typedef struct WebsRoute { + char *prefix; /**< Route path prefix */ + ssize prefixLen; /**< Prefix length */ + char *dir; /**< Filesystem base directory for route documents */ + char *protocol; /**< HTTP protocol to use for this route */ + char *authType; /**< Authentication type */ + WebsHandler *handler; /**< Request handler to service requests */ + WebsHash abilities; /**< Required user abilities */ + WebsHash extensions; /**< Permissible URI extensions */ + WebsHash redirects; /**< Response redirections */ + WebsHash methods; /**< Supported HTTP methods */ + WebsAskLogin askLogin; /**< Route path prefix */ + WebsParseAuth parseAuth; /**< Parse authentication details callback*/ + WebsVerify verify; /**< Verify password callback */ + int flags; /**< Route control flags */ +} WebsRoute; + +/** + Add a route to the routing tables + @param uri Matching URI prefix + @param handler Request handler to service routed requests + @param pos Position in the list of routes. Zero inserts at the front of the list. A value of -1 will append to the + end of the list. + @return A route object + @ingroup WebsRoute + @stability Evolving + */ +PUBLIC WebsRoute *websAddRoute(char *uri, char *handler, int pos); + +/** + Close the route module + @ingroup WebsRoute + @stability Evolving + */ +PUBLIC void websCloseRoute(); + +/** + Load routing tables from the specified filename + @param path Route configuration filename + @return Zero if successful, otherwise -1. + @ingroup WebsRoute + @stability Evolving + */ +PUBLIC int websLoad(char *path); + +/** + Open the routing module + @ingroup WebsRoute + @stability Evolving + */ +PUBLIC int websOpenRoute(); + +/** + Remove a route from the routing tables + @param uri Matching URI prefix + @return Zero if successful, otherwise -1. + @ingroup WebsRoute + @stability Evolving + */ +PUBLIC int websRemoveRoute(char *uri); + +/** + Route a request + @description This routine will select a matching route and will invoke the selected route handler to service + the request. In the process, authentication and request rewriting may take place. + This routine is called internally by the request pipeline. + @param wp Webs request object + @ingroup WebsRoute + @stability Evolving + */ +PUBLIC void websRouteRequest(Webs *wp); + +/** + Run a request handler + @description This routine will run the handler and route selected by #websRouteRequest. + This routine is called internally by the request pipeline. + @param wp Webs request object + @return True if the handler serviced the request. Return false to test other routes to handle this request. + This is for legacy handlers that do not have a match callback. + @ingroup WebsRoute + @stability Evolving + */ +PUBLIC bool websRunRequest(Webs *wp); + +/** + Configure a route by adding matching criteria + @param route Route to modify + @param dir Set the route documents directory filename + @param protocol Set the matching HTTP protocol (http or https) + @param methods Hash of permissible HTTP methods. (GET, HEAD, POST, PUT) + @param extensions Hash of permissible URI filename extensions. + @param abilities Required user abilities. The user must be authenticated. + @param abilities Required user abilities. If abilities are required, the user must be authenticated. + @param redirects Set of applicable response redirections when completing the request. + @return Zero if successful, otherwise -1. + @ingroup WebsRoute + @stability Evolving + */ +PUBLIC int websSetRouteMatch(WebsRoute *route, char *dir, char *protocol, WebsHash methods, WebsHash extensions, + WebsHash abilities, WebsHash redirects); + +/** + Set route authentication scheme + @param route Route to modify + @param authType Set to "basic", "digest" or "form". + @return Zero if successful, otherwise -1. + @ingroup WebsRoute + @stability Evolving + */ +PUBLIC int websSetRouteAuth(WebsRoute *route, char *authType); + +/*************************************** Auth **********************************/ +#if ME_GOAHEAD_AUTH + +#define WEBS_USIZE 128 /* Size of realm:username */ + +/** + GoAhead Authentication + @defgroup WebsAuth WebsAuth + */ +/** + User definition structure + @ingroup WebsAuth + @stability Evolving + */ +typedef struct WebsUser { + char *name; /**< User name */ + char *password; /**< User password (encrypted) */ + char *roles; /**< User roles */ + WebsHash abilities; /**< Resolved user abilities */ +} WebsUser; + +/** + Role definition structure + @ingroup WebsAuth + @stability Evolving + */ +typedef struct WebsRole { + WebsHash abilities; /**< Resolved role abilities */ +} WebsRole; + +/** + Add a role + @description The role is added to the list of roles + @param role Role name + @param abilities Hash of abilities for the role + @return The allocated role. + @ingroup WebsAuth + @stability Evolving + */ +PUBLIC WebsRole *websAddRole(char *role, WebsHash abilities); + +/** + Add a user + @description The user is added to the list of users + @param username User name + @param password User password (encrypted) + @param roles Space separated list of roles. This may also contain abilities. + @return User object. + @ingroup WebsAuth + @stability Evolving + */ +PUBLIC WebsUser *websAddUser(char *username, char *password, char *roles); + +/** + Authenticate a user + @description The user is authenticated if required by the selected request route. + @param wp Webs request object + @return True if the route does not require authentication or the user is authenticated successfully. + @ingroup WebsAuth + @stability Evolving + */ +PUBLIC bool websAuthenticate(Webs *wp); + +/** + Test if a user possesses the required ability + @param wp Webs request object + @param ability Set of required abilities. + @return True if the user has the required ability. + @ingroup WebsAuth + @stability Evolving + */ +PUBLIC bool websCan(Webs *wp, WebsHash ability); + +/** + Close the authentication module + @ingroup WebsAuth + @stability Evolving + */ +PUBLIC void websCloseAuth(); + +/** + Compute the abilities for all users by resolving roles into abilities + @ingroup WebsAuth + @stability Evolving + */ +PUBLIC void websComputeAllUserAbilities(); + +/** + Set the password store verify callback + @return verify WebsVerify callback function + @ingroup WebsAuth + @stability Evolving + */ +PUBLIC WebsVerify websGetPasswordStoreVerify(); + +/** + Get the roles hash + @return The roles hash object + @ingroup WebsAuth + @stability Evolving + */ +PUBLIC WebsHash websGetRoles(); + +/** + Get the users hash + @return The users hash object + @ingroup WebsAuth + @stability Evolving + */ +PUBLIC WebsHash websGetUsers(); + +/** + Login a user by verifying the login credentials. + @description This may be called by handlers to manually authenticate a user. + @param wp Webs request object + @param username User name + @param password User password (encrypted) + @return True if the user can be authenticated. + @ingroup WebsAuth + @stability Evolving + */ +PUBLIC bool websLoginUser(Webs *wp, char *username, char *password); + +/** + Logout a user and remove the user login session. + @param wp Webs request object + @return True if successful. + @ingroup WebsAuth + @stability Evolving + */ +PUBLIC bool websLogoutUser(Webs *wp); + +/** + Lookup if a user exists + @param username User name to search for + @return User object or null if the user cannot be found + @ingroup WebsAuth + @stability Evolving + */ +PUBLIC WebsUser *websLookupUser(char *username); + +/** + Remove a role from the system + @param role Role name + @return Zero if successful, otherwise -1 + @ingroup WebsAuth + @stability Evolving + */ +PUBLIC int websRemoveRole(char *role); + +/** + Remove a user from the system + @param name User name + @return Zero if successful, otherwise -1 + @ingroup WebsAuth + @stability Evolving + */ +PUBLIC int websRemoveUser(char *name); + +/** + Open the authentication module + @param minimal Reserved. Set to zero. + @return True if the user has the required ability. + @ingroup WebsAuth + @stability Evolving + */ +PUBLIC int websOpenAuth(int minimal); + +/** + Set the password store verify callback + @param verify WebsVerify callback function + @ingroup WebsAuth + @stability Evolving + */ +PUBLIC void websSetPasswordStoreVerify(WebsVerify verify); + +/** + Set a password for the user + @param username User name + @param password Null terminated password string + @return Zero if successful, otherwise -1. + @ingroup WebsAuth + @stability Evolving + */ +PUBLIC int websSetUserPassword(char *username, char *password); + + +/** + Define the set of roles for a user + @param username User name + @param roles Space separated list of roles or abilities + @return Zero if successful, otherwise -1. + @ingroup WebsAuth + @stability Evolving + */ +PUBLIC int websSetUserRoles(char *username, char *roles); + +/** + User password verification routine from a custom password back-end store. + @param wp Webs request object + @return True if the user password verifies. + @ingroup WebsAuth + @stability Evolving + */ +PUBLIC bool websVerifyPasswordFromCustom(Webs *wp); + +/** + User password verification routine from auth.txt + @param wp Webs request object + @return True if the user password verifies. + @ingroup WebsAuth + @stability Evolving + */ +PUBLIC bool websVerifyPasswordFromFile(Webs *wp); + +#if ME_COMPILER_HAS_PAM +/** + Verify a password using the system PAM password database. + @param wp Webs request object + @return True if the user password verifies. + @ingroup WebsAuth + @stability Evolving + */ +PUBLIC bool websVerifyPasswordFromPam(Webs *wp); +#endif + +#endif /* ME_GOAHEAD_AUTH */ +/************************************** Sessions *******************************/ +/** + Session state storage + @defgroup WebsSession WebsSession + */ +typedef struct WebsSession { + char *id; /**< Session ID key */ + WebsTime lifespan; /**< Session inactivity timeout (msecs) */ + WebsTime expires; /**< When the session expires */ + WebsHash cache; /**< Cache of session variables */ +} WebsSession; + +/** + Test if a user possesses the required ability + @param wp Webs request object + @param id Session ID to use. Set to null to allocate a new session ID. + @param lifespan Lifespan of the session in seconds. + @return Allocated session object + @ingroup WebsSession + @stability Evolving + */ +PUBLIC WebsSession *websAllocSession(Webs *wp, char *id, WebsTime lifespan); + +/** + Get the session ID + @param wp Webs request object + @return The session ID if session state storage is defined for this request. + @ingroup WebsSession + @stability Evolving + */ +PUBLIC char *websGetSessionID(Webs *wp); + +/** + Get the session state object for the current request + @param wp Webs request object + @param create Set to true to create a new session if one does not already exist. + @return Session object + @ingroup WebsSession + @stability Evolving + */ +PUBLIC WebsSession *websGetSession(Webs *wp, int create); + +/** + Get a session variable + @param wp Webs request object + @param name Session variable name + @param defaultValue Default value to return if the variable does not exist + @return Session variable value or default value if it does not exist + @ingroup WebsSession + @stability Evolving + */ +PUBLIC char *websGetSessionVar(Webs *wp, char *name, char *defaultValue); + +/** + Remove a session variable + @param wp Webs request object + @param name Session variable name + @ingroup WebsSession + @stability Evolving + */ +PUBLIC void websRemoveSessionVar(Webs *wp, char *name); + +/** + Set a session variable name value + @param wp Webs request object + @param name Session variable name + @param value Value to set the variable to + @return Zero if successful, otherwise -1 + @ingroup WebsSession + @stability Evolving + */ +PUBLIC int websSetSessionVar(Webs *wp, char *name, char *value); + +/************************************ Macros **********************************/ + +#if ME_GOAHEAD_TRACING + #if ME_COMPILER_HAS_MACRO_VARARGS + #define trace(l, ...) if (((l) & WEBS_LEVEL_MASK) <= websGetLogLevel()) { traceProc(l, __VA_ARGS__); } else + #else + inline void trace(int level, cchar *fmt, ...) { + WebsLogHandler logHandler = logGetHandler(); + if ((level & WEBS_LEVEL_MASK) <= logLevel && logHandler) { + va_list args; va_start(args, fmt); + char *message = sfmtv((char*) fmt, args); + logHandler(level | WEBS_TRACE_MSG, message); + wfree(message); + va_end(args); + } + } + #endif +#else + #define trace(l, ...) if (1) ; else +#endif + +#if ME_GOAHEAD_LOGGING + #if ME_COMPILER_HAS_MACRO_VARARGS + #define logmsg(l, ...) if ((l) <= logLevel) { logmsgProc(l, __VA_ARGS__); } else + #else + inline void logmsg(int level, cchar *fmt, ...) { + WebsLogHandler logHandler = logGetHandler(); + if ((level & WEBS_LEVEL_MASK) <= logLevel && logHandler) { + va_list args; va_start(args, fmt); + char *message = sfmtv((char*) fmt, args); + logHandler(level | WEBS_TRACE_MSG, message); + wfree(message); + va_end(args); + } + } + #endif +#else + #define logmsg(l, ...) if (1) ; else +#endif + +/************************************ Legacy **********************************/ +/* + Legacy mappings for pre GoAhead 3.X applications + This is a list of the name changes from GoAhead 2.X to GoAhead 3.x + To maximize forward compatibility, It is best to not use ME_GOAHEAD_LEGACY except as + a transitional compilation aid. + */ +#if ME_GOAHEAD_LEGACY + #define B_L 0 + #define a_assert assert + #define balloc walloc + #define bclose wcloseAlloc + #define bfree(loc, p) wfree(p) + #define bfreeSafe(loc, p) wfree(p) + #define bopen wopenAlloc + #define brealloc wrealloc + #define bstrdup sclone + #define emfReschedCallback websRestartEvent + #define emfSchedCallback websStartEvent + #define emfSchedProc WebsEventProc + #define emfSchedProcess websRunEvents + #define emfUnschedCallback websStopEvent + #define fmtStatic fmt + #define gassert assert + #define galloc walloc + #define gallocEntry wallocObject + #define gfree wfree + #define gFree wfreeHandle + #define grealloc wrealloc + #define gaccess access + #define gasctime asctime + #define gatoi atoi + #define gchmod chmod + #define wclose close + #define wclosedir closedir + #define gcreat creat + #define gctime ctime + #define gexecvp execvp + #define gfgets fgets + #define gfindclose _findclose + #define gfinddata_t _finddata_t + #define gfindfirst _findfirst + #define gfindnext _findnext + #define gfopen fopen + #define gfprintf fprintf + #define gfputs fputs + #define gfscanf fscanf + #define ggetcwd getcwd + #define ggetenv getenv + #define ggets gets + #define gisalnum isalnum + #define gisalpha isalpha + #define gisdigit isdigit + #define gislower islower + #define gisspace isspace + #define gisupper isupper + #define gisxdigit isxdigit + #define gloadModule loadModule + #define glseek lseek + #define gopendir opendir + #define gprintf printf + #define gread read + #define greaddir readdir + #define gremove remove + #define grename rename + #define gsprintf sprintf + #define gsscanf sscanf + #define gstat stat + #define gstrcat strcat + #define gstrchr strchr + #define gstrcmp strcmp + #define gstrcpy strcpy + #define gstrcspn strcspn + #define gstricmp strcmpci + #define gstritoa stritoa + #define gstrlen strlen + #define gstrlower strlower + #define gstrncat strncat + #define gstrncmp strncmp + #define gstrncpy strncpy + #define gstrnlen strnlen + #define gstrnset strnset + #define gstrrchr strrchr + #define gstrspn strspn + #define gstrstr strstr + #define gstrtok strtok + #define gstrtol strtol + #define gstrupper strupper + #define gtempnam websTempFile + #define gtolower tolower + #define gtoupper toupper + #define gunlink unlink + #define gvsprintf vsprintf + #define gwrite write + #define hAlloc wallocHandle + #define hAllocEntry wallocObject + #define hFree wfreeHandle + #define stritoa gstritoa + #define strlower gstrlower + #define strupper gstrupper + #define websAspDefine websDefineJst + #define websAspOpen websJstOpen + #define websAspRequest websJstRequest + #define websFormDefine websDefineAction + #define websGetDefaultDir websGetDocuments + #define websGetDefaultPage websGetIndex + + #define websGetRequestDir(wp) wp->dir + #define websGetRequestIpAddr(wp) wp->ipaddr + #define websGetRequestFilename(wp) wp->filename + #define websGetRequestFlags(wp) wp->flags + #define websGetRequestLpath(wp) wp->filename + #define websGetRequestPath(wp) wp->path + #define websGetRequestPassword(wp) wp->password + #define websGetRequestUserName(wp) wp->username + #define websGetRequestWritten(wp) wp->written + + #define websSetDefaultDir websSetDocuments + #define websSetDefaultPage websSetIndex + #define websSetRequestLpath websSetRequestFilename + #define websSetRequestWritten(wp, nbytes) if (1) { wp->written = nbytes; } else + #define websTimeoutCancel websCancelTimeout + #define websWriteDataNonBlock websWriteRaw + + #define ringqOpen bufCreate + #define ringqClose bufFree + #define ringqLen bufLen + #define ringqPutc bufPutc + #define ringqInsertc bufInsertc + #define ringqPutStr bufPutStr + #define ringqGetc bufGetc + #define ringqGrow bufGrow + #define ringqPutBlk bufPutBlk + #define ringqPutBlkMax bufRoom + #define ringqPutBlkAdj bufAdjustEnd + #define ringqGetBlk bufGetBlk + #define ringqGetBlkMax bufGetBlkMax + #define ringqGetBlkAdj bufAdjustSTart + #define ringqFlush bufFlush + #define ringqCompact bufCompact + #define ringqReset bufReset + #define ringqAddNull bufAddNull + + #define symCreate hashCreate + #define symClose hashFree + #define symLookup hashLookup + #define symEnter hashEnter + #define symDelete hashDelete + #define symWalk hashWalk + #define symFirst hashFirst + #define symNext hashNext + + typedef Webs *webs_t; + typedef Webs WebsRec; + typedef Webs websType; + typedef WebsBuf ringq_t; + typedef WebsError websErrorType; + typedef WebsProc WebsFormProc; + typedef int (*WebsLegacyHandlerProc)(Webs *wp, char *prefix, char *dir, int flags); + typedef SocketHandler socketHandler_t; + typedef SocketAccept socketAccept_t; + typedef WebsType vtype_t; + + typedef WebsHash sym_fd_t; + typedef WebsKey sym_t; + typedef WebsMime websMimeType; + typedef WebsSocket socket_t; + typedef WebsStat gstat_t; + typedef WebsValue value_t; + + PUBLIC int fmtValloc(char **s, int n, char *fmt, va_list arg); + PUBLIC int fmtAlloc(char **s, int n, char *fmt, ...); + PUBLIC void websFooter(Webs *wp); + PUBLIC void websHeader(Webs *wp); + PUBLIC int websPublish(char *prefix, char *path); + PUBLIC void websSetRequestFilename(Webs *wp, char *filename); + PUBLIC int websUrlHandlerDefine(char *prefix, char *dir, int arg, WebsLegacyHandlerProc handler, int flags); + +#if ME_ROM + typedef WebsRomIndex websRomIndexType; +#endif +#endif + +#if ME_CUSTOMIZE + #include "customize.h" +#endif + +#ifdef __cplusplus +} +#endif +#endif /* _h_GOAHEAD */ + +/* + @copy default + + Copyright (c) Embedthis Software. All Rights Reserved. + + This software is distributed under commercial and open source licenses. + You may use the Embedthis GoAhead open source license or you may acquire + a commercial license from Embedthis Software. You agree to be fully bound + by the terms of either license. Consult the LICENSE.md distributed with + this software for full details and other copyrights. + + Local variables: + tab-width: 4 + c-basic-offset: 4 + End: + vim: sw=4 ts=4 expandtab + + @end + */ diff --git a/inc/js.h b/inc/js.h new file mode 100644 index 0000000..2fe857d --- /dev/null +++ b/inc/js.h @@ -0,0 +1,348 @@ +/* + js.h -- JavaScript header + + Copyright (c) All Rights Reserved. See details at the end of the file. + */ + +#ifndef _h_JS +#define _h_JS 1 + +/********************************* Includes ***********************************/ + +#include "goahead.h" + +#if ME_GOAHEAD_JAVASCRIPT +/********************************** Defines ***********************************/ +/* + Constants + */ +#define JS_INC 110 /* Growth for tags/tokens */ +#define JS_SCRIPT_INC 1023 /* Growth for ej scripts */ +#define JS_OFFSET 1 /* hAlloc doesn't like 0 entries */ +#define JS_MAX_RECURSE 100 /* Sanity for maximum recursion */ + +/* + Javascript Lexical analyser tokens + */ +#define TOK_ERR -1 /* Any error */ +#define TOK_LPAREN 1 /* ( */ +#define TOK_RPAREN 2 /* ) */ +#define TOK_IF 3 /* if */ +#define TOK_ELSE 4 /* else */ +#define TOK_LBRACE 5 /* { */ +#define TOK_RBRACE 6 /* } */ +#define TOK_LOGICAL 7 /* ||, &&, ! */ +#define TOK_EXPR 8 /* +, -, /, % */ +#define TOK_SEMI 9 /* ; */ +#define TOK_LITERAL 10 /* literal string */ +#define TOK_FUNCTION 11 /* function name */ +#define TOK_NEWLINE 12 /* newline white space */ +#define TOK_ID 13 /* function name */ +#define TOK_EOF 14 /* End of script */ +#define TOK_COMMA 15 /* Comma */ +#define TOK_VAR 16 /* var */ +#define TOK_ASSIGNMENT 17 /* = */ +#define TOK_FOR 18 /* for */ +#define TOK_INC_DEC 19 /* ++, -- */ +#define TOK_RETURN 20 /* return */ + +/* + Expression operators + */ +#define EXPR_LESS 1 /* < */ +#define EXPR_LESSEQ 2 /* <= */ +#define EXPR_GREATER 3 /* > */ +#define EXPR_GREATEREQ 4 /* >= */ +#define EXPR_EQ 5 /* == */ +#define EXPR_NOTEQ 6 /* != */ +#define EXPR_PLUS 7 /* + */ +#define EXPR_MINUS 8 /* - */ +#define EXPR_DIV 9 /* / */ +#define EXPR_MOD 10 /* % */ +#define EXPR_LSHIFT 11 /* << */ +#define EXPR_RSHIFT 12 /* >> */ +#define EXPR_MUL 13 /* * */ +#define EXPR_ASSIGNMENT 14 /* = */ +#define EXPR_INC 15 /* ++ */ +#define EXPR_DEC 16 /* -- */ +#define EXPR_BOOL_COMP 17 /* ! */ +/* + Conditional operators + */ +#define COND_AND 1 /* && */ +#define COND_OR 2 /* || */ +#define COND_NOT 3 /* ! */ + +/* + States + */ +#define STATE_ERR -1 /* Error state */ +#define STATE_EOF 1 /* End of file */ +#define STATE_COND 2 /* Parsing a "(conditional)" stmt */ +#define STATE_COND_DONE 3 +#define STATE_RELEXP 4 /* Parsing a relational expr */ +#define STATE_RELEXP_DONE 5 +#define STATE_EXPR 6 /* Parsing an expression */ +#define STATE_EXPR_DONE 7 +#define STATE_STMT 8 /* Parsing General statement */ +#define STATE_STMT_DONE 9 +#define STATE_STMT_BLOCK_DONE 10 /* End of block "}" */ +#define STATE_ARG_LIST 11 /* Function arg list */ +#define STATE_ARG_LIST_DONE 12 +#define STATE_DEC_LIST 16 /* Declaration list */ +#define STATE_DEC_LIST_DONE 17 +#define STATE_DEC 18 +#define STATE_DEC_DONE 19 +#define STATE_RET 20 /* Return statement */ + +#define STATE_BEGIN STATE_STMT + +/* + Flags. Used in Js and as parameter to parse() + */ +#define FLAGS_EXE 0x1 /* Execute statements */ +#define FLAGS_VARIABLES 0x2 /* Allocated variables store */ +#define FLAGS_FUNCTIONS 0x4 /* Allocated function store */ + +/* + Function call structure + */ +typedef struct JsFun { + char *fname; /* Function name */ + char **args; /* Args for function (halloc) */ + int nArgs; /* Number of args */ +} JsFun; + +/* + Evaluation block structure + */ +typedef struct JsInput { + WebsBuf tokbuf; /* Current token */ + WebsBuf script; /* Input script for parsing */ + char *putBackToken; /* Putback token string */ + int putBackTokenId; /* Putback token ID */ + char *line; /* Current line */ + int lineLength; /* Current line length */ + int lineNumber; /* Parse line number */ + int lineColumn; /* Column in line */ +} JsInput; + + +/** + Javascript engine structure + @defgroup Js Js + */ +typedef struct Js { + JsInput *input; /* Input evaluation block */ + WebsHash functions; /* Symbol table for functions */ + WebsHash *variables; /* hAlloc list of variables */ + int variableMax; /* Number of entries */ + JsFun *func; /* Current function */ + char *result; /* Current expression result */ + char *error; /* Error message */ + char *token; /* Pointer to token string */ + int tid; /* Current token id */ + int jid; /* Halloc handle */ + int flags; /* Flags */ + void *userHandle; /* User defined handle */ +} Js; + + +/** + Javascript function procedure + @ingroup Js + */ +typedef int (*JsProc)(int jid, void *handle, int argc, char **argv); + +/******************************** Prototypes **********************************/ +/** + Utility routine to parse function arguments + @param argc Count of arguments in argv + @param argv Array of arguments + @param fmt Printf style format string + @return Count of the arguments parsed + @ingroup Js + */ +PUBLIC int jsArgs(int argc, char **argv, char *fmt, ...); + +/** + Close a javascript engine + @param jid Javascript ID allocated via jsOpenEngine + @ingroup Js + */ +PUBLIC void jsCloseEngine(int jid); + +/** + Emit a parse error + @param js Javascript engine object + @param fmt Error message format string + @ingroup Js + */ +PUBLIC void jsError(Js *js, char *fmt, ...); + +/** + Parse and evaluate a script. Return the last function return value. + @param jid Javascript ID allocated via jsOpenEngine + @param script Script to evaluate + @param emsg Pointer to a string to receive any error message + @param str String value to use as the result. Set to null for errors. + @ingroup Js + */ +PUBLIC char *jsEval(int jid, char *script, char **emsg); + +/** + Get the function result value + @param jid Javascript ID allocated via jsOpenEngine + @return Function return value string. Caller must not free. + @ingroup Js + */ +PUBLIC char *jsGetResult(int jid); + +/** + Get a variable value + @param jid Javascript ID allocated via jsOpenEngine + @param var Variable name + @param value Returned value. + @return If successful, a positive variable index, otherwise -1. This will be zero for global variables + and > 0 for local variables. + @ingroup Js + */ +PUBLIC int jsGetVar(int jid, char *var, char **value); + +/** + Open a new javascript engine + @param variables Hash table of variables + @param functions Hash table of functions + @ingroup Js + */ +PUBLIC int jsOpenEngine(WebsHash variables, WebsHash functions); + +/** + Set a local variable + @param jid Javascript ID allocated via jsOpenEngine + @param var Variable name + @param value Value to use + @ingroup Js + */ +PUBLIC void jsSetLocalVar(int jid, char *var, char *value); + +/** + Set a global variable + @param jid Javascript ID allocated via jsOpenEngine + @param var Variable name + @param value value to use + @ingroup Js + */ +PUBLIC void jsSetGlobalVar(int jid, char *var, char *value); + +/** + Set the function return result + @param jid Javascript ID allocated via jsOpenEngine + @param str String value to use as the result + @ingroup Js + */ +PUBLIC void jsSetResult(int jid, char *str); + +/** + Set a variable value in the top most variable frame + @param jid Javascript ID allocated via jsOpenEngine + @param var Variable name + @param value Value to set + @ingroup Js + */ +PUBLIC void jsSetVar(int jid, char *var, char *value); + +/** + Set a global function + @param jid Javascript ID allocated via jsOpenEngine + @param name Javascript function name + @param fn C function providing the implementation. + @ingroup Js + */ +PUBLIC int jsSetGlobalFunction(int jid, char *name, JsProc fn); + +/* + Internal API + */ +PUBLIC int jsCloseBlock(int jid, int vid); +PUBLIC char *jsEvalBlock(int jid, char *script, char **emsg); +PUBLIC WebsHash jsGetFunctionTable(int jid); +PUBLIC void *jsGetGlobalFunction(int jid, char *name); +PUBLIC int jsGetLineNumber(int jid); +PUBLIC void *jsGetUserHandle(int jid); +PUBLIC WebsHash jsGetVariableTable(int jid); +PUBLIC int jsLexOpen(Js *ep); +PUBLIC void jsLexClose(Js *ep); +PUBLIC int jsLexOpenScript(Js *ep, char *script); +PUBLIC void jsLexCloseScript(Js *ep); +PUBLIC void jsLexSaveInputState(Js *ep, JsInput *state); +PUBLIC void jsLexFreeInputState(Js *ep, JsInput *state); +PUBLIC void jsLexRestoreInputState(Js *ep, JsInput *state); +PUBLIC int jsLexGetToken(Js *ep, int state); +PUBLIC void jsLexPutbackToken(Js *ep, int tid, char *string); +PUBLIC int jsOpenBlock(int jid); +PUBLIC int jsRemoveGlobalFunction(int jid, char *name); +PUBLIC int jsSetGlobalFunctionDirect(WebsHash functions, char *name, JsProc fn); +PUBLIC void jsSetUserHandle(int jid, void *handle); + +#if ME_GOAHEAD_LEGACY + typedef Js ej_t; + typedef JsInput jsinput_t; + typedef JsFun jsfunc_t; + + #define ejOpenBlock jsOpenBlock + #define ejCloseBlock jsCloseBlock + #define ejEvalBlock jsEvalBlock + #define ejRemoveGlobalFunction jsRemoveGlobalFunction + #define ejGetGlobalFunction jsGetGlobalFunction + #define ejSetGlobalFunctionDirect jsSetGlobalFunctionDirect + #define ejError jsError + #define ejSetUserHandle jsSetUserHandle + #define ejGetUserHandle jsGetUserHandle + #define ejGetLineNumber jsGetLineNumber + #define ejGetResult jsGetResult + #define ejSetLocalVar jsSetLocalVar + #define ejSetGlobalVar jsSetGlobalVar + #define ejLexOpen jsLexOpen + #define ejLexClose jsLexClose + #define ejLexOpenScript jsLexOpenScript + #define ejLexCloseScript jsLexCloseScript + #define ejLexSaveInputState jsLexSaveInputState + #define ejLexFreeInputState jsLexFreeInputState + #define ejLexRestoreInputState jsLexRestoreInputState + #define ejLexGetToken jsLexGetToken + #define ejLexPutbackToken jsLexPutbackToken + #define ejGetVariableTable jsGetVariableTable + #define ejGetFunctionTable jsGetFunctionTable + #define ejArgs jsArgs + #define ejSetResult jsSetResult + #define ejOpenEngine jsOpenEngine + #define ejCloseEngine jsCloseEngine + #define ejSetGlobalFunction jsSetGlobalFunction + #define ejSetVar jsSetVar + #define ejGetVar jsGetVar + #define ejEval jsEval +#endif + +#endif /* ME_GOAHEAD_JAVASCRIPT */ +#endif /* _h_JS */ + +/* + @copy default + + Copyright (c) Embedthis Software. All Rights Reserved. + + This software is distributed under commercial and open source licenses. + You may use the Embedthis GoAhead open source license or you may acquire + a commercial license from Embedthis Software. You agree to be fully bound + by the terms of either license. Consult the LICENSE.md distributed with + this software for full details and other copyrights. + + Local variables: + tab-width: 4 + c-basic-offset: 4 + End: + vim: sw=4 ts=4 expandtab + + @end + */ diff --git a/inc/me.h b/inc/me.h new file mode 100644 index 0000000..9812def --- /dev/null +++ b/inc/me.h @@ -0,0 +1,390 @@ +/* + me.h -- MakeMe Configure Header for linux-x86-static + + This header is created by Me during configuration. To change settings, re-run + configure or define variables in your Makefile to override these default values. + */ + +/* Settings */ +#ifndef ME_AUTHOR + #define ME_AUTHOR "Embedthis Software" +#endif +#ifndef ME_CERTS_BITS + #define ME_CERTS_BITS 2048 +#endif +#ifndef ME_CERTS_DAYS + #define ME_CERTS_DAYS 3650 +#endif +#ifndef ME_CERTS_GENDH + #define ME_CERTS_GENDH 1 +#endif +#ifndef ME_COMPANY + #define ME_COMPANY "embedthis" +#endif +#ifndef ME_COMPATIBLE + #define ME_COMPATIBLE "3.4" +#endif +#ifndef ME_COMPILER_HAS_ATOMIC + #define ME_COMPILER_HAS_ATOMIC 0 +#endif +#ifndef ME_COMPILER_HAS_ATOMIC64 + #define ME_COMPILER_HAS_ATOMIC64 0 +#endif +#ifndef ME_COMPILER_HAS_DOUBLE_BRACES + #define ME_COMPILER_HAS_DOUBLE_BRACES 0 +#endif +#ifndef ME_COMPILER_HAS_DYN_LOAD + #define ME_COMPILER_HAS_DYN_LOAD 1 +#endif +#ifndef ME_COMPILER_HAS_LIB_EDIT + #define ME_COMPILER_HAS_LIB_EDIT 0 +#endif +#ifndef ME_COMPILER_HAS_LIB_RT + #define ME_COMPILER_HAS_LIB_RT 1 +#endif +#ifndef ME_COMPILER_HAS_MMU + #define ME_COMPILER_HAS_MMU 1 +#endif +#ifndef ME_COMPILER_HAS_MTUNE + #define ME_COMPILER_HAS_MTUNE 1 +#endif +#ifndef ME_COMPILER_HAS_PAM + #define ME_COMPILER_HAS_PAM 0 +#endif +#ifndef ME_COMPILER_HAS_STACK_PROTECTOR + #define ME_COMPILER_HAS_STACK_PROTECTOR 1 +#endif +#ifndef ME_COMPILER_HAS_SYNC + #define ME_COMPILER_HAS_SYNC 1 +#endif +#ifndef ME_COMPILER_HAS_SYNC64 + #define ME_COMPILER_HAS_SYNC64 1 +#endif +#ifndef ME_COMPILER_HAS_SYNC_CAS + #define ME_COMPILER_HAS_SYNC_CAS 0 +#endif +#ifndef ME_COMPILER_HAS_UNNAMED_UNIONS + #define ME_COMPILER_HAS_UNNAMED_UNIONS 1 +#endif +#ifndef ME_COMPILER_WARN64TO32 + #define ME_COMPILER_WARN64TO32 0 +#endif +#ifndef ME_COMPILER_WARN_UNUSED + #define ME_COMPILER_WARN_UNUSED 1 +#endif +#ifndef ME_DEBUG + #define ME_DEBUG 1 +#endif +#ifndef ME_DEPTH + #define ME_DEPTH 1 +#endif +#ifndef ME_DESCRIPTION + #define ME_DESCRIPTION "Embedthis GoAhead Embedded Web Server" +#endif +#ifndef ME_GOAHEAD_ACCESS_LOG + #define ME_GOAHEAD_ACCESS_LOG 0 +#endif +#ifndef ME_GOAHEAD_AUTH + #define ME_GOAHEAD_AUTH 1 +#endif +#ifndef ME_GOAHEAD_AUTH_STORE + #define ME_GOAHEAD_AUTH_STORE "file" +#endif +#ifndef ME_GOAHEAD_AUTO_LOGIN + #define ME_GOAHEAD_AUTO_LOGIN 0 +#endif +#ifndef ME_GOAHEAD_CGI + #define ME_GOAHEAD_CGI 1 +#endif +#ifndef ME_GOAHEAD_CGI_BIN + #define ME_GOAHEAD_CGI_BIN "cgi-bin" +#endif +#ifndef ME_GOAHEAD_CLIENT_CACHE + #define ME_GOAHEAD_CLIENT_CACHE "css,gif,ico,jpg,js,png" +#endif +#ifndef ME_GOAHEAD_CLIENT_CACHE_LIFESPAN + #define ME_GOAHEAD_CLIENT_CACHE_LIFESPAN 86400 +#endif +#ifndef ME_GOAHEAD_DIGEST + #define ME_GOAHEAD_DIGEST 1 +#endif +#ifndef ME_GOAHEAD_DOCUMENTS + #define ME_GOAHEAD_DOCUMENTS "web" +#endif +#ifndef ME_GOAHEAD_JAVASCRIPT + #define ME_GOAHEAD_JAVASCRIPT 1 +#endif +#ifndef ME_GOAHEAD_LEGACY + #define ME_GOAHEAD_LEGACY 0 +#endif +#ifndef ME_GOAHEAD_LIMIT_BUFFER + #define ME_GOAHEAD_LIMIT_BUFFER 1024 +#endif +#ifndef ME_GOAHEAD_LIMIT_FILENAME + #define ME_GOAHEAD_LIMIT_FILENAME 256 +#endif +#ifndef ME_GOAHEAD_LIMIT_FILES + #define ME_GOAHEAD_LIMIT_FILES 0 +#endif +#ifndef ME_GOAHEAD_LIMIT_HEADER + #define ME_GOAHEAD_LIMIT_HEADER 2048 +#endif +#ifndef ME_GOAHEAD_LIMIT_HEADERS + #define ME_GOAHEAD_LIMIT_HEADERS 4096 +#endif +#ifndef ME_GOAHEAD_LIMIT_NUM_HEADERS + #define ME_GOAHEAD_LIMIT_NUM_HEADERS 64 +#endif +#ifndef ME_GOAHEAD_LIMIT_PARSE_TIMEOUT + #define ME_GOAHEAD_LIMIT_PARSE_TIMEOUT 5 +#endif +#ifndef ME_GOAHEAD_LIMIT_PASSWORD + #define ME_GOAHEAD_LIMIT_PASSWORD 32 +#endif +#ifndef ME_GOAHEAD_LIMIT_POST + #define ME_GOAHEAD_LIMIT_POST 16384 +#endif +#ifndef ME_GOAHEAD_LIMIT_PUT + #define ME_GOAHEAD_LIMIT_PUT 204800000 +#endif +#ifndef ME_GOAHEAD_LIMIT_SESSION_COUNT + #define ME_GOAHEAD_LIMIT_SESSION_COUNT 512 +#endif +#ifndef ME_GOAHEAD_LIMIT_SESSION_LIFE + #define ME_GOAHEAD_LIMIT_SESSION_LIFE 1800 +#endif +#ifndef ME_GOAHEAD_LIMIT_STRING + #define ME_GOAHEAD_LIMIT_STRING 256 +#endif +#ifndef ME_GOAHEAD_LIMIT_TIMEOUT + #define ME_GOAHEAD_LIMIT_TIMEOUT 60 +#endif +#ifndef ME_GOAHEAD_LIMIT_UPLOAD + #define ME_GOAHEAD_LIMIT_UPLOAD 204800000 +#endif +#ifndef ME_GOAHEAD_LIMIT_URI + #define ME_GOAHEAD_LIMIT_URI 2048 +#endif +#ifndef ME_GOAHEAD_LISTEN + #define ME_GOAHEAD_LISTEN "http://*:80,https://*:443" +#endif +#ifndef ME_GOAHEAD_LOGFILE + #define ME_GOAHEAD_LOGFILE "stderr:0" +#endif +#ifndef ME_GOAHEAD_LOGGING + #define ME_GOAHEAD_LOGGING 1 +#endif +#ifndef ME_GOAHEAD_PUT_DIR + #define ME_GOAHEAD_PUT_DIR "." +#endif +#ifndef ME_GOAHEAD_REALM + #define ME_GOAHEAD_REALM "example.com" +#endif +#ifndef ME_GOAHEAD_REPLACE_MALLOC + #define ME_GOAHEAD_REPLACE_MALLOC 0 +#endif +#ifndef ME_GOAHEAD_SSL_AUTHORITY + #define ME_GOAHEAD_SSL_AUTHORITY "" +#endif +#ifndef ME_GOAHEAD_SSL_CACHE + #define ME_GOAHEAD_SSL_CACHE 512 +#endif +#ifndef ME_GOAHEAD_SSL_CERTIFICATE + #define ME_GOAHEAD_SSL_CERTIFICATE "self.crt" +#endif +#ifndef ME_GOAHEAD_SSL_CIPHERS + #define ME_GOAHEAD_SSL_CIPHERS "" +#endif +#ifndef ME_GOAHEAD_SSL_KEY + #define ME_GOAHEAD_SSL_KEY "self.key" +#endif +#ifndef ME_GOAHEAD_SSL_LOG_LEVEL + #define ME_GOAHEAD_SSL_LOG_LEVEL 5 +#endif +#ifndef ME_GOAHEAD_SSL_RENEGOTIATE + #define ME_GOAHEAD_SSL_RENEGOTIATE 1 +#endif +#ifndef ME_GOAHEAD_SSL_REVOKE + #define ME_GOAHEAD_SSL_REVOKE "" +#endif +#ifndef ME_GOAHEAD_SSL_TICKET + #define ME_GOAHEAD_SSL_TICKET 1 +#endif +#ifndef ME_GOAHEAD_SSL_TIMEOUT + #define ME_GOAHEAD_SSL_TIMEOUT 86400 +#endif +#ifndef ME_GOAHEAD_SSL_VERIFY_ISSUER + #define ME_GOAHEAD_SSL_VERIFY_ISSUER 0 +#endif +#ifndef ME_GOAHEAD_SSL_VERIFY_PEER + #define ME_GOAHEAD_SSL_VERIFY_PEER 0 +#endif +#ifndef ME_GOAHEAD_STEALTH + #define ME_GOAHEAD_STEALTH 1 +#endif +#ifndef ME_GOAHEAD_TRACING + #define ME_GOAHEAD_TRACING 1 +#endif +#ifndef ME_GOAHEAD_UPLOAD + #define ME_GOAHEAD_UPLOAD 1 +#endif +#ifndef ME_GOAHEAD_UPLOAD_DIR + #define ME_GOAHEAD_UPLOAD_DIR "/COMTRADE" +#endif +#ifndef ME_GOAHEAD_XFRAME_HEADER + #define ME_GOAHEAD_XFRAME_HEADER "SAMEORIGIN" +#endif +#ifndef ME_INTEGRATE + #define ME_INTEGRATE 1 +#endif +#ifndef ME_MANIFEST + #define ME_MANIFEST "installs/manifest.me" +#endif +#ifndef ME_MBEDTLS_COMPACT + #define ME_MBEDTLS_COMPACT 1 +#endif +#ifndef ME_NAME + #define ME_NAME "goahead" +#endif +#ifndef ME_PREFIXES + #define ME_PREFIXES "install-prefixes" +#endif +#ifndef ME_STATIC + #define ME_STATIC 1 +#endif +#ifndef ME_TITLE + #define ME_TITLE "Embedthis GoAhead" +#endif +#ifndef ME_VERSION + #define ME_VERSION "3.4.9" +#endif + +/* Prefixes */ +#ifndef ME_ROOT_PREFIX + #define ME_ROOT_PREFIX "/" +#endif +#ifndef ME_BASE_PREFIX + #define ME_BASE_PREFIX "/usr/local" +#endif +#ifndef ME_DATA_PREFIX + #define ME_DATA_PREFIX "/" +#endif +#ifndef ME_STATE_PREFIX + #define ME_STATE_PREFIX "/var" +#endif +#ifndef ME_APP_PREFIX + #define ME_APP_PREFIX "/usr/local/lib/goahead" +#endif +#ifndef ME_VAPP_PREFIX + #define ME_VAPP_PREFIX "/usr/local/lib/goahead/3.4.9" +#endif +#ifndef ME_BIN_PREFIX + #define ME_BIN_PREFIX "/usr/local/bin" +#endif +#ifndef ME_INC_PREFIX + #define ME_INC_PREFIX "/usr/local/include" +#endif +#ifndef ME_LIB_PREFIX + #define ME_LIB_PREFIX "/usr/local/lib" +#endif +#ifndef ME_MAN_PREFIX + #define ME_MAN_PREFIX "/usr/local/share/man" +#endif +#ifndef ME_SBIN_PREFIX + #define ME_SBIN_PREFIX "/usr/local/sbin" +#endif +#ifndef ME_ETC_PREFIX + #define ME_ETC_PREFIX "/etc/goahead" +#endif +#ifndef ME_WEB_PREFIX + #define ME_WEB_PREFIX "/var/www/goahead" +#endif +#ifndef ME_LOG_PREFIX + #define ME_LOG_PREFIX "/var/log/goahead" +#endif +#ifndef ME_SPOOL_PREFIX + #define ME_SPOOL_PREFIX "/var/spool/goahead" +#endif +#ifndef ME_CACHE_PREFIX + #define ME_CACHE_PREFIX "/var/spool/goahead/cache" +#endif +#ifndef ME_SRC_PREFIX + #define ME_SRC_PREFIX "goahead-3.4.9" +#endif + +/* Suffixes */ +#ifndef ME_EXE + #define ME_EXE "" +#endif +#ifndef ME_SHLIB + #define ME_SHLIB ".so" +#endif +#ifndef ME_SHOBJ + #define ME_SHOBJ ".so" +#endif +#ifndef ME_LIB + #define ME_LIB ".a" +#endif +#ifndef ME_OBJ + #define ME_OBJ ".o" +#endif + +/* Profile */ +#ifndef ME_CONFIG_CMD + #define ME_CONFIG_CMD "me -d -q -platform linux-x86-static -static -configure . -with openssl -gen make" +#endif +#ifndef ME_GOAHEAD_PRODUCT + #define ME_GOAHEAD_PRODUCT 1 +#endif +#ifndef ME_PROFILE + #define ME_PROFILE "static" +#endif +#ifndef ME_TUNE_SIZE + #define ME_TUNE_SIZE 1 +#endif + +/* Miscellaneous */ +#ifndef ME_MAJOR_VERSION + #define ME_MAJOR_VERSION 3 +#endif +#ifndef ME_MINOR_VERSION + #define ME_MINOR_VERSION 4 +#endif +#ifndef ME_PATCH_VERSION + #define ME_PATCH_VERSION 9 +#endif +#ifndef ME_VNUM + #define ME_VNUM 300040009 +#endif + +/* Components */ +#ifndef ME_COM_CC + #define ME_COM_CC 1 +#endif +#ifndef ME_COM_LIB + #define ME_COM_LIB 1 +#endif +#ifndef ME_COM_MATRIXSSL + #define ME_COM_MATRIXSSL 0 +#endif +#ifndef ME_COM_MBEDTLS + #define ME_COM_MBEDTLS 0 +#endif +#ifndef ME_COM_NANOSSL + #define ME_COM_NANOSSL 0 +#endif +#ifndef ME_COM_OPENSSL + #define ME_COM_OPENSSL 0 +#endif +#ifndef ME_COM_OSDEP + #define ME_COM_OSDEP 1 +#endif +#ifndef ME_COM_SSL + #define ME_COM_SSL 0 +#endif +#ifndef ME_COM_VXWORKS + #define ME_COM_VXWORKS 0 +#endif +#ifndef ME_COM_WINSDK + #define ME_COM_WINSDK 1 +#endif diff --git a/inc/osdep.h b/inc/osdep.h new file mode 100644 index 0000000..7342ccc --- /dev/null +++ b/inc/osdep.h @@ -0,0 +1,1397 @@ +/** + osdep.h -- Embedthis O/S abstraction for products using MakeMe. + */ + +#ifndef _h_OSDEP +#define _h_OSDEP 1 + +/********************************** Includes **********************************/ + +#include "me.h" + +/******************************* Default Features *****************************/ +/* + MakeMe defaults + */ +#ifndef ME_COM_SSL + #define ME_COM_SSL 0 /**< Build without SSL support */ +#endif +#ifndef ME_DEBUG + #define ME_DEBUG 0 /**< Default to a debug build */ +#endif +#ifndef ME_FLOAT + #define ME_FLOAT 1 /**< Build with floating point support */ +#endif +#ifndef ME_ROM + #define ME_ROM 0 /**< Build for execute from ROM */ +#endif + +/********************************* CPU Families *******************************/ +/* + CPU Architectures + */ +#define ME_CPU_UNKNOWN 0 +#define ME_CPU_ARM 1 /**< Arm */ +#define ME_CPU_ITANIUM 2 /**< Intel Itanium */ +#define ME_CPU_X86 3 /**< X86 */ +#define ME_CPU_X64 4 /**< AMD64 or EMT64 */ +#define ME_CPU_MIPS 5 /**< Mips */ +#define ME_CPU_PPC 6 /**< Power PC */ +#define ME_CPU_SPARC 7 /**< Sparc */ +#define ME_CPU_TIDSP 8 /**< TI DSP */ +#define ME_CPU_SH 9 /**< SuperH */ + +/* + Byte orderings + */ +#define ME_LITTLE_ENDIAN 1 /**< Little endian byte ordering */ +#define ME_BIG_ENDIAN 2 /**< Big endian byte ordering */ + +/* + Use compiler definitions to determine the CPU type. + The default endianness can be overridden by configure --endian big|little. + */ +#if defined(__alpha__) + #define ME_CPU "alpha" + #define ME_CPU_ARCH ME_CPU_ALPHA + #define CPU_ENDIAN ME_LITTLE_ENDIAN + +#elif defined(__arm__) + #define ME_CPU "arm" + #define ME_CPU_ARCH ME_CPU_ARM + #define CPU_ENDIAN ME_LITTLE_ENDIAN + +#elif defined(__x86_64__) || defined(_M_AMD64) + #define ME_CPU "x64" + #define ME_CPU_ARCH ME_CPU_X64 + #define CPU_ENDIAN ME_LITTLE_ENDIAN + +#elif defined(__i386__) || defined(__i486__) || defined(__i585__) || defined(__i686__) || defined(_M_IX86) + #define ME_CPU "x86" + #define ME_CPU_ARCH ME_CPU_X86 + #define CPU_ENDIAN ME_LITTLE_ENDIAN + +#elif defined(_M_IA64) + #define ME_CPU "ia64" + #define ME_CPU_ARCH ME_CPU_ITANIUM + #define CPU_ENDIAN ME_LITTLE_ENDIAN + +#elif defined(__mips__) || defined(__mips64) + #define ME_CPU "mips" + #define ME_CPU_ARCH ME_CPU_MIPS + #define CPU_ENDIAN ME_BIG_ENDIAN + +#elif defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__) || defined(__ppc) + #define ME_CPU "ppc" + #define ME_CPU_ARCH ME_CPU_PPC + #define CPU_ENDIAN ME_BIG_ENDIAN + +#elif defined(__sparc__) + #define ME_CPU "sparc" + #define ME_CPU_ARCH ME_CPU_SPARC + #define CPU_ENDIAN ME_BIG_ENDIAN + +#elif defined(_TMS320C6X) + #define TIDSP 1 + #define ME_CPU "tidsp" + #define ME_CPU_ARCH ME_CPU_SPARC + #define CPU_ENDIAN ME_LITTLE_ENDIAN + +#elif defined(__sh__) + #define ME_CPU "sh" + #define ME_CPU_ARCH ME_CPU_SH + #define CPU_ENDIAN ME_LITTLE_ENDIAN + +#else + #error "Cannot determine CPU type in osdep.h" +#endif + +/* + Set the default endian if me.h does not define it explicitly + */ +#ifndef ME_ENDIAN + #define ME_ENDIAN CPU_ENDIAN +#endif + +/* + Operating system defines. Use compiler standard defintions to sleuth. Works for all except VxWorks which does not + define any special symbol. NOTE: Support for SCOV Unix, LynxOS and UnixWare is deprecated. + */ +#if defined(__APPLE__) + #define ME_OS "macosx" + #define MACOSX 1 + #define ME_UNIX_LIKE 1 + #define ME_WIN_LIKE 0 + #define ME_BSD_LIKE 1 + #define HAS_USHORT 1 + #define HAS_UINT 1 + +#elif defined(__linux__) + #define ME_OS "linux" + #define LINUX 1 + #define ME_UNIX_LIKE 1 + #define ME_WIN_LIKE 0 + +#elif defined(__FreeBSD__) + #define ME_OS "freebsd" + #define FREEBSD 1 + #define ME_UNIX_LIKE 1 + #define ME_WIN_LIKE 0 + #define ME_BSD_LIKE 1 + +#elif defined(__OpenBSD__) + #define ME_OS "freebsd" + #define OPENBSD 1 + #define ME_UNIX_LIKE 1 + #define ME_WIN_LIKE 0 + #define ME_BSD_LIKE 1 + +#elif defined(_WIN32) + #define ME_OS "windows" + #define WINDOWS 1 + #define ME_UNIX_LIKE 0 + #define ME_WIN_LIKE 1 + +#elif defined(__OS2__) + #define ME_OS "os2" + #define OS2 0 + #define ME_UNIX_LIKE 0 + #define ME_WIN_LIKE 0 + +#elif defined(MSDOS) || defined(__DME__) + #define ME_OS "msdos" + #define WINDOWS 0 + #define ME_UNIX_LIKE 0 + #define ME_WIN_LIKE 0 + +#elif defined(__NETWARE_386__) + #define ME_OS "netware" + #define NETWARE 0 + #define ME_UNIX_LIKE 0 + #define ME_WIN_LIKE 0 + +#elif defined(__bsdi__) + #define ME_OS "bsdi" + #define BSDI 1 + #define ME_UNIX_LIKE 1 + #define ME_WIN_LIKE 0 + #define ME_BSD_LIKE 1 + +#elif defined(__NetBSD__) + #define ME_OS "netbsd" + #define NETBSD 1 + #define ME_UNIX_LIKE 1 + #define ME_WIN_LIKE 0 + #define ME_BSD_LIKE 1 + +#elif defined(__QNX__) + #define ME_OS "qnx" + #define QNX 0 + #define ME_UNIX_LIKE 0 + #define ME_WIN_LIKE 0 + +#elif defined(__hpux) + #define ME_OS "hpux" + #define HPUX 1 + #define ME_UNIX_LIKE 1 + #define ME_WIN_LIKE 0 + +#elif defined(_AIX) + #define ME_OS "aix" + #define AIX 1 + #define ME_UNIX_LIKE 1 + #define ME_WIN_LIKE 0 + +#elif defined(__CYGWIN__) + #define ME_OS "cygwin" + #define CYGWIN 1 + #define ME_UNIX_LIKE 1 + #define ME_WIN_LIKE 0 + +#elif defined(__VMS) + #define ME_OS "vms" + #define VMS 1 + #define ME_UNIX_LIKE 0 + #define ME_WIN_LIKE 0 + +#elif defined(VXWORKS) + /* VxWorks does not have a pre-defined symbol */ + #define ME_OS "vxworks" + #define ME_UNIX_LIKE 0 + #define ME_WIN_LIKE 0 + #define HAS_USHORT 1 + +#elif defined(ECOS) + /* ECOS may not have a pre-defined symbol */ + #define ME_OS "ecos" + #define ME_UNIX_LIKE 0 + #define ME_WIN_LIKE 0 + +#elif defined(TIDSP) + #define ME_OS "tidsp" + #define ME_UNIX_LIKE 0 + #define ME_WIN_LIKE 0 + #define HAS_INT32 1 + +#endif + +#if __WORDSIZE == 64 || __amd64 || __x86_64 || __x86_64__ || _WIN64 || __mips64 + #define ME_64 1 + #define ME_WORDSIZE 64 +#else + #define ME_64 0 + #define ME_WORDSIZE 32 +#endif + +/* + Unicode + */ +#ifndef ME_CHAR_LEN + #define ME_CHAR_LEN 1 +#endif +#if ME_CHAR_LEN == 4 + typedef int wchar; + #define UT(s) L ## s + #define UNICODE 1 +#elif ME_CHAR_LEN == 2 + typedef short wchar; + #define UT(s) L ## s + #define UNICODE 1 +#else + typedef char wchar; + #define UT(s) s +#endif + +#define ME_PLATFORM ME_OS "-" ME_CPU "-" ME_PROFILE + +/********************************* O/S Includes *******************************/ +/* + Out-of-order definitions and includes. Order really matters in this section. + */ +#if WINDOWS + #undef _CRT_SECURE_NO_DEPRECATE + #define _CRT_SECURE_NO_DEPRECATE 1 + #undef _CRT_SECURE_NO_WARNINGS + #define _CRT_SECURE_NO_WARNINGS 1 + #define _WINSOCK_DEPRECATED_NO_WARNINGS 1 + #ifndef _WIN32_WINNT + /* Target Windows 7 by default */ + #define _WIN32_WINNT 0x601 + #endif + /* + Work-around to allow the windows 7.* SDK to be used with VS 2012 + */ + #if _MSC_VER >= 1700 + #define SAL_SUPP_H + #define SPECSTRING_SUPP_H + #endif +#endif + +#if LINUX + /* + Use GNU extensions for: + RTLD_DEFAULT for dlsym() + */ + #define _GNU_SOURCE 1 + #if !ME_64 + #define _LARGEFILE64_SOURCE 1 + #ifdef __USE_FILE_OFFSET64 + #define _FILE_OFFSET_BITS 64 + #endif + #endif +#endif + +#if VXWORKS + #ifndef _VSB_CONFIG_FILE + #define _VSB_CONFIG_FILE "vsbConfig.h" + #endif + #include +#endif + +#if ME_WIN_LIKE + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #if ME_DEBUG + #include + #endif +#endif + +/* + Includes in alphabetic order + */ + #include +#if !ME_ROM +#if ME_WIN_LIKE + #include +#else + #include +#endif +#endif +#if ME_UNIX_LIKE + #include +#endif + #include + #include +#if ME_FLOAT + #include + #define __USE_ISOC99 1 + #include +#endif +#if ME_UNIX_LIKE + #include +#endif +#if ME_WIN_LIKE + #include +#endif +#if MACOSX || LINUX + #include +#endif + #include +#if ME_UNIX_LIKE || VXWORKS + #include + #include + #include + #include + #include + #include + #include +#endif +#if ME_UNIX_LIKE + #include + #include +#if !CYGWIN + #include +#endif +#endif +#if ME_BSD_LIKE + #include +#endif + #include + #include + #include +#if ME_UNIX_LIKE + #include +#endif + #include + #include + #include +#if ME_UNIX_LIKE + #include +#endif +#if !TIDSP + #include + #include +#endif +#if ME_UNIX_LIKE + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include +#endif + #include +#if !VXWORKS && !TIDSP + #include +#endif + +/* + Extra includes per O/S + */ +#if CYGWIN + #include "w32api/windows.h" + #include "sys/cygwin.h" +#endif +#if LINUX + #include + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + #include + #endif + #include + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + #include + #endif + #if !__UCLIBC__ + #include + #endif +#endif +#if MACOSX + #include + #include + #include + #include + #include + #include + #include + #include +#endif +#if VXWORKS + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #if _WRS_VXWORKS_MAJOR >= 6 + #include + #endif + #if _WRS_VXWORKS_MAJOR > 6 || (_WRS_VXWORKS_MAJOR == 6 && _WRS_VXWORKS_MINOR >= 8) + #include + #include + #endif +#endif + +#if TIDSP + #include + #include + #include + #include + #include +#endif + +/************************************** Types *********************************/ +/* + Standard types + */ +#ifndef HAS_BOOL + #ifndef __cplusplus + #if !MACOSX + #define HAS_BOOL 1 + /** + Boolean data type. + */ + typedef char bool; + #endif + #endif +#endif + +#ifndef HAS_UCHAR + #define HAS_UCHAR 1 + /** + Unsigned char data type. + */ + typedef unsigned char uchar; +#endif + +#ifndef HAS_SCHAR + #define HAS_SCHAR 1 + /** + Signed char data type. + */ + typedef signed char schar; +#endif + +#ifndef HAS_CCHAR + #define HAS_CCHAR 1 + /** + Constant char data type. + */ + typedef const char cchar; +#endif + +#ifndef HAS_CUCHAR + #define HAS_CUCHAR 1 + /** + Unsigned char data type. + */ + typedef const unsigned char cuchar; +#endif + +#ifndef HAS_USHORT + #define HAS_USHORT 1 + /** + Unsigned short data type. + */ + typedef unsigned short ushort; +#endif + +#ifndef HAS_CUSHORT + #define HAS_CUSHORT 1 + /** + Constant unsigned short data type. + */ + typedef const unsigned short cushort; +#endif + +#ifndef HAS_CVOID + #define HAS_CVOID 1 + /** + Constant void data type. + */ + typedef const void cvoid; +#endif + +#ifndef HAS_INT8 + #define HAS_INT8 1 + /** + Integer 8 bits data type. + */ + typedef char int8; +#endif + +#ifndef HAS_UINT8 + #define HAS_UINT8 1 + /** + Unsigned integer 8 bits data type. + */ + typedef unsigned char uint8; +#endif + +#ifndef HAS_INT16 + #define HAS_INT16 1 + /** + Integer 16 bits data type. + */ + typedef short int16; +#endif + +#ifndef HAS_UINT16 + #define HAS_UINT16 1 + /** + Unsigned integer 16 bits data type. + */ + typedef unsigned short uint16; +#endif + +#ifndef HAS_INT32 + #define HAS_INT32 1 + /** + Integer 32 bits data type. + */ + typedef int int32; +#endif + +#ifndef HAS_UINT32 + #define HAS_UINT32 1 + /** + Unsigned integer 32 bits data type. + */ + typedef unsigned int uint32; +#endif + +#ifndef HAS_UINT + #define HAS_UINT 1 + /** + Unsigned integer (machine dependent bit size) data type. + */ + typedef unsigned int uint; +#endif + +#ifndef HAS_ULONG + #define HAS_ULONG 1 + /** + Unsigned long (machine dependent bit size) data type. + */ + typedef unsigned long ulong; +#endif + +#ifndef HAS_CINT + #define HAS_CINT 1 + /** + Constant int data type. + */ + typedef const int cint; +#endif + +#ifndef HAS_SSIZE + #define HAS_SSIZE 1 + #if ME_UNIX_LIKE || VXWORKS || DOXYGEN + /** + Signed integer size field large enough to hold a pointer offset. + */ + typedef ssize_t ssize; + #elif TIDSP + typedef int ssize_t; + typedef ssize_t ssize; + #else + typedef SSIZE_T ssize; + #endif +#endif + +/* + Windows uses uint for write/read counts (Ugh!) + */ +#if ME_WIN_LIKE + typedef uint wsize; +#else + typedef ssize wsize; +#endif + +#ifndef HAS_INT64 + #if ME_UNIX_LIKE + __extension__ typedef long long int int64; + #elif VXWORKS || DOXYGEN + /** + Integer 64 bit data type. + */ + typedef long long int int64; + #elif ME_WIN_LIKE + typedef __int64 int64; + #else + typedef long long int int64; + #endif +#endif + +#ifndef HAS_UINT64 + #if ME_UNIX_LIKE + __extension__ typedef unsigned long long int uint64; + #elif VXWORKS || DOXYGEN + typedef unsigned long long int uint64; + #elif ME_WIN_LIKE + typedef unsigned __int64 uint64; + #else + typedef unsigned long long int uint64; + #endif +#endif + +/** + Signed file offset data type. Supports large files greater than 4GB in size on all systems. + */ +typedef int64 Offset; + +#if DOXYGEN + /** Size to hold the length of a socket address */ + typedef int Socklen; +#elif VXWORKS + typedef int Socklen; +#else + typedef socklen_t Socklen; +#endif + +#if DOXYGEN || ME_UNIX_LIKE || VXWORKS + /** Argument for sockets */ + typedef int Socket; + #ifndef SOCKET_ERROR + #define SOCKET_ERROR -1 + #endif + #define SOCKET_ERROR -1 + #ifndef INVALID_SOCKET + #define INVALID_SOCKET -1 + #endif +#elif ME_WIN_LIKE + typedef SOCKET Socket; +#elif TIDSP + typedef SOCKET Socket; + #define SOCKET_ERROR INVALID_SOCKET +#else + typedef int Socket; + #ifndef SOCKET_ERROR + #define SOCKET_ERROR -1 + #endif + #ifndef INVALID_SOCKET + #define INVALID_SOCKET -1 + #endif +#endif + +typedef int64 Time; + +/** + Elapsed time data type. Stores time in milliseconds from some arbitrary start epoch. + */ +typedef int64 Ticks; + +/** + Time/Ticks units per second (milliseconds) + */ +#define TPS 1000 + +/*********************************** Defines **********************************/ + +#ifndef BITSPERBYTE + #define BITSPERBYTE ((int) (8 * sizeof(char))) +#endif + +#ifndef BITS + #define BITS(type) ((int) (BITSPERBYTE * (int) sizeof(type))) +#endif + +#if ME_FLOAT + #ifndef MAXFLOAT + #if ME_WIN_LIKE + #define MAXFLOAT DBL_MAX + #else + #define MAXFLOAT FLT_MAX + #endif + #endif + #if VXWORKS + #undef isnan + #define isnan(n) ((n) != (n)) + #define isnanf(n) ((n) != (n)) + #define isinf(n) ((n) == (1.0 / 0.0) || (n) == (-1.0 / 0.0)) + #define isinff(n) ((n) == (1.0 / 0.0) || (n) == (-1.0 / 0.0)) + #endif + #if ME_WIN_LIKE + #define isNan(f) (_isnan(f)) + #elif VXWORKS || MACOSX || LINUX + #define isNan(f) (isnan(f)) + #else + #define isNan(f) (fpclassify(f) == FP_NAN) + #endif +#endif + +#if ME_WIN_LIKE + #define INT64(x) (x##i64) + #define UINT64(x) (x##Ui64) +#else + #define INT64(x) (x##LL) + #define UINT64(x) (x##ULL) +#endif + +#ifndef MAXINT +#if INT_MAX + #define MAXINT INT_MAX +#else + #define MAXINT 0x7fffffff +#endif +#endif + +#ifndef MAXUINT +#if UINT_MAX + #define MAXUINT UINT_MAX +#else + #define MAXUINT 0xffffffff +#endif +#endif + +#ifndef MAXINT64 + #define MAXINT64 INT64(0x7fffffffffffffff) +#endif +#ifndef MAXUINT64 + #define MAXUINT64 INT64(0xffffffffffffffff) +#endif + +#if SIZE_T_MAX + #define MAXSIZE SIZE_T_MAX +#elif ME_64 + #define MAXSIZE INT64(0xffffffffffffffff) +#else + #define MAXSIZE MAXINT +#endif + +#if SSIZE_T_MAX + #define MAXSSIZE SSIZE_T_MAX +#elif ME_64 + #define MAXSSIZE INT64(0x7fffffffffffffff) +#else + #define MAXSSIZE MAXINT +#endif + +#if OFF_T_MAX + #define MAXOFF OFF_T_MAX +#else + #define MAXOFF INT64(0x7fffffffffffffff) +#endif + +/* + Word size and conversions between integer and pointer. + */ +#if ME_64 + #define ITOP(i) ((void*) ((int64) i)) + #define PTOI(i) ((int) ((int64) i)) + #define LTOP(i) ((void*) ((int64) i)) + #define PTOL(i) ((int64) i) +#else + #define ITOP(i) ((void*) ((int) i)) + #define PTOI(i) ((int) i) + #define LTOP(i) ((void*) ((int) i)) + #define PTOL(i) ((int64) (int) i) +#endif + +#undef PUBLIC +#undef PUBLIC_DATA +#undef PRIVATE + +#if ME_WIN_LIKE + /* + Use PUBLIC on function declarations and definitions (*.c and *.h). + */ + #define PUBLIC __declspec(dllexport) + #define PUBLIC_DATA __declspec(dllexport) + #define PRIVATE static +#else + #define PUBLIC + #define PUBLIC_DATA extern + #define PRIVATE static +#endif + +#ifndef max + #define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif +#ifndef min + #define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef PRINTF_ATTRIBUTE + #if ((__GNUC__ >= 3) && !DOXYGEN) || MACOSX + /** + Use gcc attribute to check printf fns. a1 is the 1-based index of the parameter containing the format, + and a2 the index of the first argument. Note that some gcc 2.x versions don't handle this properly + */ + #define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) + #else + #define PRINTF_ATTRIBUTE(a1, a2) + #endif +#endif + +/* + Optimize expression evaluation code depending if the value is likely or not + */ +#undef likely +#undef unlikely +#if (__GNUC__ >= 3) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else + #define likely(x) (x) + #define unlikely(x) (x) +#endif + +#if !__UCLIBC__ && !CYGWIN && __USE_XOPEN2K + #define ME_COMPILER_HAS_SPINLOCK 1 +#endif + +#if ME_COMPILER_HAS_DOUBLE_BRACES + #define NULL_INIT {{0}} +#else + #define NULL_INIT {0} +#endif + +#ifdef __USE_FILE_OFFSET64 + #define ME_COMPILER_HAS_OFF64 1 +#else + #define ME_COMPILER_HAS_OFF64 0 +#endif + +#if ME_UNIX_LIKE + #define ME_COMPILER_HAS_FCNTL 1 +#endif + +#ifndef R_OK + #define R_OK 4 + #define W_OK 2 +#if ME_WIN_LIKE + #define X_OK R_OK +#else + #define X_OK 1 +#endif + #define F_OK 0 +#endif + +#if MACOSX + #define LD_LIBRARY_PATH "DYLD_LIBRARY_PATH" +#else + #define LD_LIBRARY_PATH "LD_LIBRARY_PATH" +#endif + +#if VXWORKS +/* + Old VxWorks can't do array[] + */ + #define ARRAY_FLEX 0 +#else + #define ARRAY_FLEX +#endif + +/* + Deprecated API warnings + */ +#if ((__GNUC__ >= 3) || MACOSX) && !VXWORKS + #define ME_DEPRECATED(MSG) __attribute__ ((deprecated(MSG))) +#else + #define ME_DEPRECATED(MSG) +#endif + +/********************************** Tunables *********************************/ +/* + These can be defined in main.bit settings (pascal case) to override. E.g. + + settings: { + maxPath: 4096 + } + */ +#ifndef ME_MAX_FNAME + #define ME_MAX_FNAME 256 /**< Reasonable filename size */ +#endif +#ifndef ME_MAX_PATH + #define ME_MAX_PATH 1024 /**< Reasonable filename size */ +#endif +#ifndef ME_MAX_BUFFER + #define ME_MAX_BUFFER 4096 /**< Reasonable size for buffers */ +#endif +#ifndef ME_MAX_ARGC + #define ME_MAX_ARGC 32 /**< Maximum number of command line args if using MAIN()*/ +#endif +#ifndef ME_DOUBLE_BUFFER + #define ME_DOUBLE_BUFFER (DBL_MANT_DIG - DBL_MIN_EXP + 4) +#endif +#ifndef ME_MAX_IP + #define ME_MAX_IP 1024 +#endif + + +#ifndef ME_STACK_SIZE +#if ME_COMPILER_HAS_MMU && !VXWORKS + /* + If the system supports virtual memory, then stack size should use system default. Only used pages will + actually consume memory + */ + #define ME_STACK_SIZE 0 /**< Default thread stack size (0 means use system default) */ +#else + /* + No MMU, so the stack size actually consumes memory. Set this as low as possible. + NOTE: php and ejs use stack heavily. + */ + #define ME_STACK_SIZE (128 * 1024) /**< Default thread stack size (0 means use system default) */ +#endif +#endif + +/*********************************** Fixups ***********************************/ + +#ifndef ME_INLINE + #if ME_WIN_LIKE + #define ME_INLINE __inline + #else + #define ME_INLINE inline + #endif +#endif + +#if ECOS + #define LIBKERN_INLINE /* to avoid kernel inline functions */ +#endif /* ECOS */ + +#if ME_UNIX_LIKE || VXWORKS || TIDSP + #define FILE_TEXT "" + #define FILE_BINARY "" +#endif + +#if !TIDSP + #define ME_COMPILER_HAS_MACRO_VARARGS 1 +#else + #define ME_COMPILER_HAS_MACRO_VARARGS 1 +#endif + +#if ME_UNIX_LIKE + #define closesocket(x) close(x) + #ifndef PTHREAD_MUTEX_RECURSIVE_NP + #define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE + #endif + #ifndef PTHREAD_MUTEX_RECURSIVE + #define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP + #endif +#endif + +#if !ME_WIN_LIKE && !CYGWIN + #ifndef O_BINARY + #define O_BINARY 0 + #endif + #ifndef O_TEXT + #define O_TEXT 0 + #endif +#endif + +#if !LINUX + #define __WALL 0 + #if !CYGWIN && !defined(MSG_NOSIGNAL) + #define MSG_NOSIGNAL 0 + #endif +#endif + +#if MACOSX + /* + Fix for MAC OS X - getenv + */ + #if !HAVE_DECL_ENVIRON + #ifdef __APPLE__ + #include + #define environ (*_NSGetEnviron()) + #else + extern char **environ; + #endif + #endif +#endif + +#if SOLARIS + #define INADDR_NONE ((in_addr_t) 0xffffffff) +#endif + +#if VXWORKS + #define getpid mprGetPid + #ifndef SHUT_RDWR + #define SHUT_RDWR 2 + #endif + #define HAVE_SOCKLEN_T + #if _DIAB_TOOL + #define inline __inline__ + #define MPR_INLINE __inline__ + #endif + #ifndef closesocket + #define closesocket(x) close(x) + #endif + #ifndef va_copy + #define va_copy(d, s) ((d) = (s)) + #endif + #ifndef strcasecmp + #define strcasecmp scaselesscmp + #endif + #ifndef strncasecmp + #define strncasecmp sncaselesscmp + #endif +#endif + +#if ME_WIN_LIKE + typedef int uid_t; + typedef void *handle; + typedef char *caddr_t; + typedef long pid_t; + typedef int gid_t; + typedef ushort mode_t; + typedef void *siginfo_t; + typedef int socklen_t; + + #define HAVE_SOCKLEN_T + #define MSG_NOSIGNAL 0 + #define FILE_BINARY "b" + #define FILE_TEXT "t" + + /* + Error codes + */ + #define EPERM 1 + #define ENOENT 2 + #define ESRCH 3 + #define EINTR 4 + #define EIO 5 + #define ENXIO 6 + #define E2BIG 7 + #define ENOEXEC 8 + #define EBADF 9 + #define ECHILD 10 + #define EAGAIN 11 + #define ENOMEM 12 + #define EACCES 13 + #define EFAULT 14 + #define EOSERR 15 + #define EBUSY 16 + #define EEXIST 17 + #define EXDEV 18 + #define ENODEV 19 + #define ENOTDIR 20 + #define EISDIR 21 + #define EINVAL 22 + #define ENFILE 23 + #define EMFILE 24 + #define ENOTTY 25 + #define EFBIG 27 + #define ENOSPC 28 + #define ESPIPE 29 + #define EROFS 30 + #define EMLINK 31 + #define EPIPE 32 + #define EDOM 33 + #define ERANGE 34 + + #ifndef EWOULDBLOCK + #define EWOULDBLOCK EAGAIN + #define EINPROGRESS 36 + #define EALREADY 37 + #define ENETDOWN 43 + #define ECONNRESET 44 + #define ECONNREFUSED 45 + #define EADDRNOTAVAIL 49 + #define EISCONN 56 + #define EADDRINUSE 46 + #define ENETUNREACH 51 + #define ECONNABORTED 53 + #endif + #ifndef ENOTCONN + #define ENOTCONN 126 + #endif + #ifndef EPROTO + #define EPROTO 134 + #endif + + #undef SHUT_RDWR + #define SHUT_RDWR 2 + + #define TIME_GENESIS UINT64(11644473600000000) + #ifndef va_copy + #define va_copy(d, s) ((d) = (s)) + #endif + + #if !WINCE + #define access _access + #define chdir _chdir + #define chmod _chmod + #define close _close + #define fileno _fileno + #define fstat _fstat + #define getcwd _getcwd + #define getpid _getpid + #define gettimezone _gettimezone + #define lseek _lseek + #define mkdir(a,b) _mkdir(a) + #define open _open + #define putenv _putenv + #define read _read + #define rmdir(a) _rmdir(a) + #define stat _stat + #define strdup _strdup + #define tempnam _tempnam + #define umask _umask + #define unlink _unlink + #define write _write + PUBLIC void sleep(int secs); + #endif + #define strcasecmp scaselesscmp + #define strncasecmp sncaselesscmp + #pragma comment( lib, "ws2_32.lib" ) +#endif /* WIN_LIKE */ + +#if WINCE + typedef void FILE; + typedef int off_t; + + #ifndef EOF + #define EOF -1 + #endif + #define O_RDONLY 0 + #define O_WRONLY 1 + #define O_RDWR 2 + #define O_NDELAY 0x4 + #define O_NONBLOCK 0x4 + #define O_APPEND 0x8 + #define O_CREAT 0x100 + #define O_TRUNC 0x200 + #define O_TEXT 0x400 + #define O_EXCL 0x800 + #define O_BINARY 0x1000 + /* + stat flags + */ + #define S_IFMT 0170000 + #define S_IFDIR 0040000 + #define S_IFCHR 0020000 /* character special */ + #define S_IFIFO 0010000 + #define S_IFREG 0100000 + #define S_IREAD 0000400 + #define S_IWRITE 0000200 + #define S_IEXEC 0000100 + + #ifndef S_ISDIR + #define S_ISDIR(X) (((X) & S_IFMT) == S_IFDIR) + #endif + #ifndef S_ISREG + #define S_ISREG(X) (((X) & S_IFMT) == S_IFREG) + #endif + + #define STARTF_USESHOWWINDOW 0 + #define STARTF_USESTDHANDLES 0 + + #define BUFSIZ ME_MAX_BUFFER + #define PATHSIZE ME_MAX_PATH + #define gethostbyname2(a,b) gethostbyname(a) + #pragma comment( lib, "ws2.lib" ) +#endif /* WINCE */ + +#if TIDSP + #define EINTR 4 + #define EAGAIN 11 + #define INADDR_NONE 0xFFFFFFFF + #define PATHSIZE ME_MAX_PATH + #define NBBY 8 + #define hostent _hostent + #define NFDBITS ((int) (sizeof(fd_mask) * NBBY)) + typedef long fd_mask; + typedef int Socklen; + struct sockaddr_storage { char pad[1024]; }; +#endif /* TIDSP */ + +/*********************************** Externs **********************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +#if LINUX + extern int pthread_mutexattr_gettype (__const pthread_mutexattr_t *__restrict __attr, int *__restrict __kind) __THROW; + extern int pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind) __THROW; + extern char **environ; +#endif + +#if VXWORKS + #if _WRS_VXWORKS_MAJOR < 6 || (_WRS_VXWORKS_MAJOR == 6 && _WRS_VXWORKS_MINOR < 9) + PUBLIC int gettimeofday(struct timeval *tv, struct timezone *tz); + #endif + PUBLIC char *strdup(const char *); + PUBLIC int sysClkRateGet(); + + #if _WRS_VXWORKS_MAJOR < 6 + #define NI_MAXHOST 128 + extern STATUS access(cchar *path, int mode); + typedef int socklen_t; + struct sockaddr_storage { + char pad[1024]; + }; + #else + /* + This may or may not be necessary - let us know dev@embedthis.com if your system needs this (and why). + */ + #if _DIAB_TOOL + #if ME_CPU_ARCH == ME_CPU_PPC + #define __va_copy(dest, src) memcpy((dest), (src), sizeof(va_list)) + #endif + #endif + #define HAVE_SOCKLEN_T + #endif +#endif /* VXWORKS */ + +#if ME_WIN_LIKE + struct timezone { + int tz_minuteswest; /* minutes W of Greenwich */ + int tz_dsttime; /* type of dst correction */ + }; + PUBLIC int getuid(void); + PUBLIC int geteuid(void); + PUBLIC int gettimeofday(struct timeval *tv, struct timezone *tz); + PUBLIC long lrand48(void); + PUBLIC long nap(long); + PUBLIC void srand48(long); + PUBLIC long ulimit(int, ...); +#endif + +#if WINCE + struct stat { + int st_dev; + int st_ino; + ushort st_mode; + short st_nlink; + short st_uid; + short st_gid; + int st_rdev; + long st_size; + time_t st_atime; + time_t st_mtime; + time_t st_ctime; + }; + extern int access(cchar *filename, int flags); + extern int chdir(cchar dirname); + extern int chmod(cchar *path, int mode); + extern int close(int handle); + extern void exit(int status); + extern long _get_osfhandle(int handle); + extern char *getcwd(char* buffer, int maxlen); + extern char *getenv(cchar *charstuff); + extern pid_t getpid(); + extern long lseek(int handle, long offset, int origin); + extern int mkdir(cchar *dir, int mode); + extern time_t mktime(struct tm *pt); + extern int _open_osfhandle(int *handle, int flags); + extern uint open(cchar *file, int mode,...); + extern int read(int handle, void *buffer, uint count); + extern int rename(cchar *from, cchar *to); + extern int rmdir(cchar dir); + extern uint sleep(uint secs); + extern int stat(cchar *path, struct stat *stat); + extern char *strdup(char *s); + extern int write(int handle, cvoid *buffer, uint count); + extern int umask(int mode); + extern int unlink(cchar *path); + extern int errno; + + #undef CreateFile + #define CreateFile CreateFileA + WINBASEAPI HANDLE WINAPI CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile); + + #undef CreateProcess + #define CreateProcess CreateProcessA + + #undef FindFirstFile + #define FindFirstFile FindFirstFileA + WINBASEAPI HANDLE WINAPI FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData); + + #undef FindNextFile + #define FindNextFile FindNextFileA + WINBASEAPI BOOL WINAPI FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData); + + #undef GetModuleFileName + #define GetModuleFileName GetModuleFileNameA + WINBASEAPI DWORD WINAPI GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize); + + #undef GetModuleHandle + #define GetModuleHandle GetModuleHandleA + WINBASEAPI HMODULE WINAPI GetModuleHandleA(LPCSTR lpModuleName); + + #undef GetProcAddress + #define GetProcAddress GetProcAddressA + + #undef GetFileAttributes + #define GetFileAttributes GetFileAttributesA + extern DWORD GetFileAttributesA(cchar *path); + + extern void GetSystemTimeAsFileTime(FILETIME *ft); + + #undef LoadLibrary + #define LoadLibrary LoadLibraryA + HINSTANCE WINAPI LoadLibraryA(LPCSTR lpLibFileName); + + #define WSAGetLastError GetLastError + + #define _get_timezone getTimezone + extern int getTimezone(int *secs); + + extern struct tm *localtime_r(const time_t *when, struct tm *tp); + extern struct tm *gmtime_r(const time_t *t, struct tm *tp); +#endif /* WINCE */ + +#ifdef __cplusplus +} +#endif + +#endif /* _h_OSDEP */ + +/* + @copy default + + Copyright (c) Embedthis Software. All Rights Reserved. + + This software is distributed under commercial and open source licenses. + You may use the Embedthis Open Source license or you may acquire a + commercial license from Embedthis Software. You agree to be fully bound + by the terms of either license. Consult the LICENSE.md distributed with + this software for full details and other copyrights. + + Local variables: + tab-width: 4 + c-basic-offset: 4 + End: + vim: sw=4 ts=4 expandtab + + @end + */ diff --git a/scl_srvr/TEMPLATE.icd b/scl_srvr/TEMPLATE.icd new file mode 100644 index 0000000..058aec1 --- /dev/null +++ b/scl_srvr/TEMPLATE.icd @@ -0,0 +1,881 @@ + + +
+ + + +
+ + + +
+

172.16.3.10

+

255.255.0.0

+

172.16.3.1

+

00 00 00 01

+

00 01

+

00 01

+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + on + + + status-only + + + + + on + + + + + ZPEPC MODEL:2008 + + + + + ZPEPC MODEL:2008 + + + + + + + Ok + + + + + 0 + + + + + 0 + + + + + ZPEPC MODEL:2008 + + + + + ZPEPC MODEL:2008 + + + + + + + on + + + status-only + + + + + on + + + + + Ok + + + + + ZPEPC MODEL:2008 + + + + + 绝缘液体温度(Mpa) + + + + + 氢气含量 + + + + + 氢气含量 + + + ZPEPC MODEL:2008 + + + + + 甲烷含量(ul/l) + + + ZPEPC MODEL:2008 + + + + + 乙烯含量(ul/l) + + + ZPEPC MODEL:2008 + + + + + 乙烷含量(ul/l) + + + ZPEPC MODEL:2008 + + + + + 乙炔含量(ul/l) + + + ZPEPC MODEL:2008 + + + + + 总烃含量(ul/l) + + + ZPEPC MODEL:2008 + + + + + 采样时间 + + + ZPEPC MODEL:2008 + + + + + 二氧化碳含量(ul/l) + + + ZPEPC MODEL:2008 + + + + + 微水含量(ul/l) + + + ZPEPC MODEL:2008 + + + + + 载气压力(Mpa) + + + ZPEPC MODEL:2008 + + + + + 异常的气瓶号 + + + ZPEPC MODEL:2008 + + + + + 监测装置通讯状态 + + + ZPEPC MODEL:2008 + + + + + 监测装置运行状态 + + + ZPEPC MODEL:2008 + + + + + 载气欠压告警 + + + + + 载气低压告警 + + + ZPEPC MODEL:2008 + + + + + 实际气瓶供气状态异常 + + + ZPEPC MODEL:2008 + + + + + 采集间隔(min) + + + ZPEPC MODEL:2008 + + + + + 立即开始工作 + + + ZPEPC MODEL:2008 + + + + + 次采集时间(min) + + + ZPEPC MODEL:2008 + + + + + 立即重载(Mpa) + + + ZPEPC MODEL:2008 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pulse + persistent + + + status-only + direct-with-normal-security + sbo-with-normal-security + direct-with-enhanced-security + sbo-with-enhanced-security + + + operate-once + operate-many + + + not-supported + bay-control + station-control + remote-control + automatic-bay + automatic-station + automatic-remote + maintenance + process + + + on + blocked + test + test/blocked + off + + + Ok + Warning + Alarm + + + on + blocked + test + test/blocked + off + + + dimensionless + m + kg + s + A + K + mol + cd + deg + rad + sr + Gy + q + °C + Sv + F + C + S + H + V + ohm + J + N + Hz + lx + Lm + Wb + T + W + Pa + + + m/s + m/s² + m³/s + m/m³ + M + kg/m³ + m²/s + W/m K + J/K + ppm + 1/s + rad/s + VA + Watts + VAr + phi + cos(phi) + Vs + + As + + A²t + VAh + Wh + VArh + V/Hz + + + y + z + a + f + p + n + µ + m + c + d + + da + h + k + M + G + T + P + E + Z + Y + + + intermediate + off + on + bad + + +
diff --git a/scl_srvr/datamap.cfg b/scl_srvr/datamap.cfg new file mode 100644 index 0000000..5c1eb2c --- /dev/null +++ b/scl_srvr/datamap.cfg @@ -0,0 +1,438 @@ +TIED10MONT LLN0$ST$Mod$stVal "string" type=Byte +TIED10MONT LLN0$ST$Mod$q "string" type=BVstring13 +TIED10MONT LLN0$ST$Mod$t "string" type=Utctime +TIED10MONT LLN0$ST$Beh$q "string" type=BVstring13 +TIED10MONT LLN0$ST$Beh$t "string" type=Utctime +TIED10MONT LLN0$ST$Health$stVal "string" type=Byte +TIED10MONT LLN0$ST$Health$q "string" type=BVstring13 +TIED10MONT LLN0$ST$Health$t "string" type=Utctime +TIED10MONT LLN0$CF$Mod$ctlModel "string" type=Byte +TIED10MONT LLN0$CF$SenNum$minVal "string" type=Long +TIED10MONT LLN0$CF$SenNum$maxVal "string" type=Long +TIED10MONT LLN0$CF$SenNum$stepSize "string" type=Ulong +TIED10MONT LLN0$DC$NamPlt$vendor "string" type=Vstring255 +TIED10MONT LLN0$DC$NamPlt$swRev "string" type=Vstring255 +TIED10MONT LLN0$DC$NamPlt$d "string" type=Vstring255 +TIED10MONT LLN0$DC$NamPlt$dU "string" type=UTF8Vstring255 +TIED10MONT LLN0$DC$NamPlt$configRev "string" type=Vstring255 +TIED10MONT LLN0$DC$SenNum$dU "string" type=UTF8Vstring255 +TIED10MONT LLN0$SP$SenNum$setVal "string" type=Long +TIED10MONT LLN0$EX$NamPlt$ldNs "string" type=Vstring255 +TIED10MONT LLN0$EX$SenNum$dataNs "string" type=Vstring255 +TIED10MONT LPHD1$ST$PhyHealth$stVal "string" type=Byte +TIED10MONT LPHD1$ST$PhyHealth$q "string" type=BVstring13 +TIED10MONT LPHD1$ST$PhyHealth$t "string" type=Utctime +TIED10MONT LPHD1$ST$OutOv$stVal "string" type=Bool +TIED10MONT LPHD1$ST$OutOv$q "string" type=BVstring13 +TIED10MONT LPHD1$ST$OutOv$t "string" type=Utctime +TIED10MONT LPHD1$ST$Proxy$stVal "string" type=Bool +TIED10MONT LPHD1$ST$Proxy$q "string" type=BVstring13 +TIED10MONT LPHD1$ST$Proxy$t "string" type=Utctime +TIED10MONT LPHD1$CF$SntpAddr$minVal "string" type=Long +TIED10MONT LPHD1$CF$SntpAddr$maxVal "string" type=Long +TIED10MONT LPHD1$CF$SntpAddr$stepSize "string" type=Ulong +TIED10MONT LPHD1$CF$TimeZone$minVal "string" type=Long +TIED10MONT LPHD1$CF$TimeZone$maxVal "string" type=Long +TIED10MONT LPHD1$CF$TimeZone$stepSize "string" type=Ulong +TIED10MONT LPHD1$DC$PhyNam$vendor "string" type=Vstring255 +TIED10MONT LPHD1$DC$PhyNam$hwRev "string" type=Vstring255 +TIED10MONT LPHD1$DC$PhyNam$swRev "string" type=Vstring255 +TIED10MONT LPHD1$DC$PhyNam$serNum "string" type=Vstring255 +TIED10MONT LPHD1$DC$PhyNam$model "string" type=Vstring255 +TIED10MONT LPHD1$DC$PhyNam$location "string" type=Vstring255 +TIED10MONT LPHD1$DC$OutOv$dU "string" type=UTF8Vstring255 +TIED10MONT LPHD1$DC$Proxy$dU "string" type=UTF8Vstring255 +TIED10MONT LPHD1$DC$SntpAddr$dU "string" type=UTF8Vstring255 +TIED10MONT LPHD1$DC$TimeZone$dU "string" type=UTF8Vstring255 +TIED10MONT LPHD1$SP$SntpAddr$setVal "string" type=Long +TIED10MONT LPHD1$SP$TimeZone$setVal "string" type=Long +TIED10MONT LPHD1$SV$OutOv$subEna "string" type=Bool +TIED10MONT LPHD1$SV$OutOv$subVal "string" type=Bool +TIED10MONT LPHD1$SV$OutOv$subQ "string" type=BVstring13 +TIED10MONT LPHD1$SV$OutOv$subID "string" type=Vstring64 +TIED10MONT LPHD1$SV$Proxy$subEna "string" type=Bool +TIED10MONT LPHD1$SV$Proxy$subVal "string" type=Bool +TIED10MONT LPHD1$SV$Proxy$subQ "string" type=BVstring13 +TIED10MONT LPHD1$SV$Proxy$subID "string" type=Vstring64 +TIED10MONT LPHD1$EX$SntpAddr$dataNs "string" type=Vstring255 +TIED10MONT LPHD1$EX$TimeZone$dataNs "string" type=Vstring255 +TIED10MONT SIML01$MX$Tmp$mag$f "0.0.10.0" type=Float +TIED10MONT SIML01$MX$Tmp$q "0.0.10.1" type=BVstring13 +TIED10MONT SIML01$MX$Tmp$t "0.0.10.2" type=Utctime +TIED10MONT SIML01$MX$H2$mag$f "0.0.0.0" type=Float +TIED10MONT SIML01$MX$H2$q "0.0.0.1" type=BVstring13 +TIED10MONT SIML01$MX$H2$t "0.0.0.2" type=Utctime +TIED10MONT SIML01$MX$CO$mag$f "0.0.1.0" type=Float +TIED10MONT SIML01$MX$CO$q "0.0.1.1" type=BVstring13 +TIED10MONT SIML01$MX$CO$t "0.0.1.2" type=Utctime +TIED10MONT SIML01$MX$CH4$mag$f "0.0.2.0" type=Float +TIED10MONT SIML01$MX$CH4$q "0.0.2.1" type=BVstring13 +TIED10MONT SIML01$MX$CH4$t "0.0.2.2" type=Utctime +TIED10MONT SIML01$MX$C2H4$mag$f "0.0.3.0" type=Float +TIED10MONT SIML01$MX$C2H4$q "0.0.3.1" type=BVstring13 +TIED10MONT SIML01$MX$C2H4$t "0.0.3.2" type=Utctime +TIED10MONT SIML01$MX$C2H6$mag$f "0.0.4.0" type=Float +TIED10MONT SIML01$MX$C2H6$q "0.0.4.1" type=BVstring13 +TIED10MONT SIML01$MX$C2H6$t "0.0.4.2" type=Utctime +TIED10MONT SIML01$MX$C2H2$mag$f "0.0.5.0" type=Float +TIED10MONT SIML01$MX$C2H2$q "0.0.5.1" type=BVstring13 +TIED10MONT SIML01$MX$C2H2$t "0.0.5.2" type=Utctime +TIED10MONT SIML01$MX$TotHyd$mag$f "0.0.6.0" type=Float +TIED10MONT SIML01$MX$TotHyd$q "0.0.6.1" type=BVstring13 +TIED10MONT SIML01$MX$TotHyd$t "0.0.6.2" type=Utctime +TIED10MONT SIML01$MX$SmpTm$mag$i "0.0.7.0" type=Long +TIED10MONT SIML01$MX$SmpTm$q "0.0.7.1" type=BVstring13 +TIED10MONT SIML01$MX$SmpTm$t "0.0.7.2" type=Utctime +TIED10MONT SIML01$MX$CO2$mag$f "0.0.8.0" type=Float +TIED10MONT SIML01$MX$CO2$q "0.0.8.1" type=BVstring13 +TIED10MONT SIML01$MX$CO2$t "0.0.8.2" type=Utctime +TIED10MONT SIML01$MX$MicrWat$mag$f "0.0.9.0" type=Float +TIED10MONT SIML01$MX$MicrWat$q "0.0.9.1" type=BVstring13 +TIED10MONT SIML01$MX$MicrWat$t "0.0.9.2" type=Utctime +TIED10MONT SIML01$MX$GasPres$mag$f "0.0.11.0" type=Float +TIED10MONT SIML01$MX$GasPres$q "0.0.11.1" type=BVstring13 +TIED10MONT SIML01$MX$GasPres$t "0.0.11.2" type=Utctime +TIED10MONT SIML01$MX$GasBot$mag$i "0.0.12.0" type=Long +TIED10MONT SIML01$MX$GasBot$q "0.0.12.1" type=BVstring13 +TIED10MONT SIML01$MX$GasBot$t "0.0.12.2" type=Utctime +TIED10MONT SIML01$ST$Mod$stVal "string" type=Byte +TIED10MONT SIML01$ST$Mod$q "string" type=BVstring13 +TIED10MONT SIML01$ST$Mod$t "string" type=Utctime +TIED10MONT SIML01$ST$Beh$q "string" type=BVstring13 +TIED10MONT SIML01$ST$Beh$t "string" type=Utctime +TIED10MONT SIML01$ST$Health$stVal "string" type=Byte +TIED10MONT SIML01$ST$Health$q "string" type=BVstring13 +TIED10MONT SIML01$ST$Health$t "string" type=Utctime +TIED10MONT SIML01$ST$InsAlm$stVal "string" type=Bool +TIED10MONT SIML01$ST$InsAlm$q "string" type=BVstring13 +TIED10MONT SIML01$ST$InsAlm$t "string" type=Utctime +TIED10MONT SIML01$ST$MoDevConf$stVal "0.0.13.0" type=Bool +TIED10MONT SIML01$ST$MoDevConf$q "0.0.13.1" type=BVstring13 +TIED10MONT SIML01$ST$MoDevConf$t "0.0.13.2" type=Utctime +TIED10MONT SIML01$ST$SupDevRun$stVal "0.0.14.0" type=Bool +TIED10MONT SIML01$ST$SupDevRun$q "0.0.14.1" type=BVstring13 +TIED10MONT SIML01$ST$SupDevRun$t "0.0.14.2" type=Utctime +TIED10MONT SIML01$ST$GasUnPresAlm$stVal "0.0.15.0" type=Bool +TIED10MONT SIML01$ST$GasUnPresAlm$q "0.0.15.1" type=BVstring13 +TIED10MONT SIML01$ST$GasUnPresAlm$t "0.0.15.2" type=Utctime +TIED10MONT SIML01$ST$GasLowPresAlm$stVal "0.0.16.0" type=Bool +TIED10MONT SIML01$ST$GasLowPresAlm$q "0.0.16.1" type=BVstring13 +TIED10MONT SIML01$ST$GasLowPresAlm$t "0.0.16.2" type=Utctime +TIED10MONT SIML01$ST$ActCyGasSta$stVal "0.0.17.0" type=Bool +TIED10MONT SIML01$ST$ActCyGasSta$q "0.0.17.1" type=BVstring13 +TIED10MONT SIML01$ST$ActCyGasSta$t "0.0.17.2" type=Utctime +TIED10MONT SIML01$CF$Mod$ctlModel "string" type=Byte +TIED10MONT SIML01$CF$Tmp$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$Tmp$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$Tmp$db "string" type=Ulong +TIED10MONT SIML01$CF$Tmp$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$Tmp$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$Tmp$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$Tmp$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$Tmp$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$Tmp$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$Tmp$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$Tmp$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$Tmp$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$Tmp$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$H2$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$H2$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$H2$db "string" type=Ulong +TIED10MONT SIML01$CF$H2$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$H2$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$H2$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$H2$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$H2$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$H2$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$H2$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$H2$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$H2$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$H2$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$CO$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$CO$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$CO$db "string" type=Ulong +TIED10MONT SIML01$CF$CO$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$CO$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$CO$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$CO$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$CO$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$CO$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$CO$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$CO$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$CO$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$CO$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$CH4$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$CH4$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$CH4$db "string" type=Ulong +TIED10MONT SIML01$CF$CH4$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$CH4$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$CH4$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$CH4$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$CH4$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$CH4$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$CH4$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$CH4$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$CH4$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$CH4$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$C2H4$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$C2H4$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$C2H4$db "string" type=Ulong +TIED10MONT SIML01$CF$C2H4$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$C2H4$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$C2H4$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$C2H4$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H4$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H4$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H4$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H4$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$C2H4$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$C2H4$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$C2H6$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$C2H6$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$C2H6$db "string" type=Ulong +TIED10MONT SIML01$CF$C2H6$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$C2H6$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$C2H6$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$C2H6$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H6$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H6$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H6$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H6$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$C2H6$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$C2H6$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$C2H2$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$C2H2$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$C2H2$db "string" type=Ulong +TIED10MONT SIML01$CF$C2H2$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$C2H2$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$C2H2$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$C2H2$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H2$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H2$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H2$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H2$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$C2H2$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$C2H2$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$TotHyd$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$TotHyd$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$TotHyd$db "string" type=Ulong +TIED10MONT SIML01$CF$TotHyd$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$TotHyd$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$TotHyd$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$TotHyd$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$TotHyd$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$TotHyd$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$TotHyd$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$TotHyd$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$TotHyd$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$TotHyd$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$SmpTm$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$SmpTm$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$SmpTm$db "string" type=Ulong +TIED10MONT SIML01$CF$SmpTm$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$SmpTm$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$SmpTm$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$SmpTm$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$SmpTm$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$SmpTm$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$SmpTm$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$SmpTm$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$SmpTm$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$SmpTm$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$CO2$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$CO2$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$CO2$db "string" type=Ulong +TIED10MONT SIML01$CF$CO2$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$CO2$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$CO2$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$CO2$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$CO2$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$CO2$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$CO2$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$CO2$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$CO2$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$CO2$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$MicrWat$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$MicrWat$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$MicrWat$db "string" type=Ulong +TIED10MONT SIML01$CF$MicrWat$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$MicrWat$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$MicrWat$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$MicrWat$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$MicrWat$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$MicrWat$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$MicrWat$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$MicrWat$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$MicrWat$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$MicrWat$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$GasPres$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$GasPres$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$GasPres$db "string" type=Ulong +TIED10MONT SIML01$CF$GasPres$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$GasPres$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$GasPres$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$GasPres$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$GasPres$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$GasPres$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$GasPres$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$GasPres$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$GasPres$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$GasPres$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$GasBot$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$GasBot$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$GasBot$db "string" type=Ulong +TIED10MONT SIML01$CF$GasBot$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$GasBot$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$GasBot$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$GasBot$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$GasBot$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$GasBot$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$GasBot$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$GasBot$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$GasBot$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$GasBot$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$SamInteC$minVal "string" type=Long +TIED10MONT SIML01$CF$SamInteC$maxVal "string" type=Long +TIED10MONT SIML01$CF$SamInteC$stepSize "string" type=Ulong +TIED10MONT SIML01$CF$StartWork$minVal "string" type=Long +TIED10MONT SIML01$CF$StartWork$maxVal "string" type=Long +TIED10MONT SIML01$CF$StartWork$stepSize "string" type=Ulong +TIED10MONT SIML01$CF$NextWorkTime$minVal "string" type=Long +TIED10MONT SIML01$CF$NextWorkTime$maxVal "string" type=Long +TIED10MONT SIML01$CF$NextWorkTime$stepSize "string" type=Ulong +TIED10MONT SIML01$CF$ReStart$minVal "string" type=Long +TIED10MONT SIML01$CF$ReStart$maxVal "string" type=Long +TIED10MONT SIML01$CF$ReStart$stepSize "string" type=Ulong +TIED10MONT SIML01$DC$NamPlt$vendor "string" type=Vstring255 +TIED10MONT SIML01$DC$NamPlt$swRev "string" type=Vstring255 +TIED10MONT SIML01$DC$NamPlt$d "string" type=Vstring255 +TIED10MONT SIML01$DC$NamPlt$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$NamPlt$configRev "string" type=Vstring255 +TIED10MONT SIML01$DC$Tmp$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$H2$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$CO$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$CH4$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$C2H4$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$C2H6$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$C2H2$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$TotHyd$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$SmpTm$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$CO2$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$MicrWat$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$GasPres$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$GasBot$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$InsAlm$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$MoDevConf$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$SupDevRun$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$GasUnPresAlm$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$GasLowPresAlm$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$ActCyGasSta$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$SamInteC$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$StartWork$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$NextWorkTime$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$ReStart$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$SG$SamInteC$setVal "string" type=Long +TIED10MONT SIML01$SG$StartWork$setVal "string" type=Long +TIED10MONT SIML01$SG$NextWorkTime$setVal "string" type=Long +TIED10MONT SIML01$SG$ReStart$setVal "string" type=Long +TIED10MONT SIML01$SV$Tmp$subEna "string" type=Bool +TIED10MONT SIML01$SV$Tmp$subMag$f "string" type=Float +TIED10MONT SIML01$SV$Tmp$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$Tmp$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$H2$subEna "string" type=Bool +TIED10MONT SIML01$SV$H2$subMag$f "string" type=Float +TIED10MONT SIML01$SV$H2$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$H2$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$CO$subEna "string" type=Bool +TIED10MONT SIML01$SV$CO$subMag$f "string" type=Float +TIED10MONT SIML01$SV$CO$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$CO$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$CH4$subEna "string" type=Bool +TIED10MONT SIML01$SV$CH4$subMag$f "string" type=Float +TIED10MONT SIML01$SV$CH4$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$CH4$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$C2H4$subEna "string" type=Bool +TIED10MONT SIML01$SV$C2H4$subMag$f "string" type=Float +TIED10MONT SIML01$SV$C2H4$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$C2H4$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$C2H6$subEna "string" type=Bool +TIED10MONT SIML01$SV$C2H6$subMag$f "string" type=Float +TIED10MONT SIML01$SV$C2H6$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$C2H6$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$C2H2$subEna "string" type=Bool +TIED10MONT SIML01$SV$C2H2$subMag$f "string" type=Float +TIED10MONT SIML01$SV$C2H2$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$C2H2$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$TotHyd$subEna "string" type=Bool +TIED10MONT SIML01$SV$TotHyd$subMag$f "string" type=Float +TIED10MONT SIML01$SV$TotHyd$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$TotHyd$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$SmpTm$subEna "string" type=Bool +TIED10MONT SIML01$SV$SmpTm$subMag$i "string" type=Long +TIED10MONT SIML01$SV$SmpTm$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$SmpTm$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$CO2$subEna "string" type=Bool +TIED10MONT SIML01$SV$CO2$subMag$f "string" type=Float +TIED10MONT SIML01$SV$CO2$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$CO2$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$MicrWat$subEna "string" type=Bool +TIED10MONT SIML01$SV$MicrWat$subMag$f "string" type=Float +TIED10MONT SIML01$SV$MicrWat$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$MicrWat$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$GasPres$subEna "string" type=Bool +TIED10MONT SIML01$SV$GasPres$subMag$f "string" type=Float +TIED10MONT SIML01$SV$GasPres$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$GasPres$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$GasBot$subEna "string" type=Bool +TIED10MONT SIML01$SV$GasBot$subMag$i "string" type=Long +TIED10MONT SIML01$SV$GasBot$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$GasBot$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$InsAlm$subEna "string" type=Bool +TIED10MONT SIML01$SV$InsAlm$subVal "string" type=Bool +TIED10MONT SIML01$SV$InsAlm$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$InsAlm$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$MoDevConf$subEna "string" type=Bool +TIED10MONT SIML01$SV$MoDevConf$subVal "string" type=Bool +TIED10MONT SIML01$SV$MoDevConf$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$MoDevConf$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$SupDevRun$subEna "string" type=Bool +TIED10MONT SIML01$SV$SupDevRun$subVal "string" type=Bool +TIED10MONT SIML01$SV$SupDevRun$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$SupDevRun$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$GasUnPresAlm$subEna "string" type=Bool +TIED10MONT SIML01$SV$GasUnPresAlm$subVal "string" type=Bool +TIED10MONT SIML01$SV$GasUnPresAlm$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$GasUnPresAlm$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$GasLowPresAlm$subEna "string" type=Bool +TIED10MONT SIML01$SV$GasLowPresAlm$subVal "string" type=Bool +TIED10MONT SIML01$SV$GasLowPresAlm$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$GasLowPresAlm$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$ActCyGasSta$subEna "string" type=Bool +TIED10MONT SIML01$SV$ActCyGasSta$subVal "string" type=Bool +TIED10MONT SIML01$SV$ActCyGasSta$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$ActCyGasSta$subID "string" type=Vstring64 +TIED10MONT SIML01$SE$SamInteC$setVal "string" type=Long +TIED10MONT SIML01$SE$StartWork$setVal "string" type=Long +TIED10MONT SIML01$SE$NextWorkTime$setVal "string" type=Long +TIED10MONT SIML01$SE$ReStart$setVal "string" type=Long +TIED10MONT SIML01$EX$NamPlt$ldNs "string" type=Vstring255 +TIED10MONT SIML01$EX$CO$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$CH4$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$C2H4$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$C2H6$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$C2H2$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$TotHyd$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$SmpTm$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$CO2$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$MicrWat$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$GasPres$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$GasBot$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$MoDevConf$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$SupDevRun$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$GasUnPresAlm$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$GasLowPresAlm$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$ActCyGasSta$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$SamInteC$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$StartWork$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$NextWorkTime$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$ReStart$dataNs "string" type=Vstring255 diff --git a/scl_srvr/datamapout.cfg b/scl_srvr/datamapout.cfg new file mode 100644 index 0000000..5c1eb2c --- /dev/null +++ b/scl_srvr/datamapout.cfg @@ -0,0 +1,438 @@ +TIED10MONT LLN0$ST$Mod$stVal "string" type=Byte +TIED10MONT LLN0$ST$Mod$q "string" type=BVstring13 +TIED10MONT LLN0$ST$Mod$t "string" type=Utctime +TIED10MONT LLN0$ST$Beh$q "string" type=BVstring13 +TIED10MONT LLN0$ST$Beh$t "string" type=Utctime +TIED10MONT LLN0$ST$Health$stVal "string" type=Byte +TIED10MONT LLN0$ST$Health$q "string" type=BVstring13 +TIED10MONT LLN0$ST$Health$t "string" type=Utctime +TIED10MONT LLN0$CF$Mod$ctlModel "string" type=Byte +TIED10MONT LLN0$CF$SenNum$minVal "string" type=Long +TIED10MONT LLN0$CF$SenNum$maxVal "string" type=Long +TIED10MONT LLN0$CF$SenNum$stepSize "string" type=Ulong +TIED10MONT LLN0$DC$NamPlt$vendor "string" type=Vstring255 +TIED10MONT LLN0$DC$NamPlt$swRev "string" type=Vstring255 +TIED10MONT LLN0$DC$NamPlt$d "string" type=Vstring255 +TIED10MONT LLN0$DC$NamPlt$dU "string" type=UTF8Vstring255 +TIED10MONT LLN0$DC$NamPlt$configRev "string" type=Vstring255 +TIED10MONT LLN0$DC$SenNum$dU "string" type=UTF8Vstring255 +TIED10MONT LLN0$SP$SenNum$setVal "string" type=Long +TIED10MONT LLN0$EX$NamPlt$ldNs "string" type=Vstring255 +TIED10MONT LLN0$EX$SenNum$dataNs "string" type=Vstring255 +TIED10MONT LPHD1$ST$PhyHealth$stVal "string" type=Byte +TIED10MONT LPHD1$ST$PhyHealth$q "string" type=BVstring13 +TIED10MONT LPHD1$ST$PhyHealth$t "string" type=Utctime +TIED10MONT LPHD1$ST$OutOv$stVal "string" type=Bool +TIED10MONT LPHD1$ST$OutOv$q "string" type=BVstring13 +TIED10MONT LPHD1$ST$OutOv$t "string" type=Utctime +TIED10MONT LPHD1$ST$Proxy$stVal "string" type=Bool +TIED10MONT LPHD1$ST$Proxy$q "string" type=BVstring13 +TIED10MONT LPHD1$ST$Proxy$t "string" type=Utctime +TIED10MONT LPHD1$CF$SntpAddr$minVal "string" type=Long +TIED10MONT LPHD1$CF$SntpAddr$maxVal "string" type=Long +TIED10MONT LPHD1$CF$SntpAddr$stepSize "string" type=Ulong +TIED10MONT LPHD1$CF$TimeZone$minVal "string" type=Long +TIED10MONT LPHD1$CF$TimeZone$maxVal "string" type=Long +TIED10MONT LPHD1$CF$TimeZone$stepSize "string" type=Ulong +TIED10MONT LPHD1$DC$PhyNam$vendor "string" type=Vstring255 +TIED10MONT LPHD1$DC$PhyNam$hwRev "string" type=Vstring255 +TIED10MONT LPHD1$DC$PhyNam$swRev "string" type=Vstring255 +TIED10MONT LPHD1$DC$PhyNam$serNum "string" type=Vstring255 +TIED10MONT LPHD1$DC$PhyNam$model "string" type=Vstring255 +TIED10MONT LPHD1$DC$PhyNam$location "string" type=Vstring255 +TIED10MONT LPHD1$DC$OutOv$dU "string" type=UTF8Vstring255 +TIED10MONT LPHD1$DC$Proxy$dU "string" type=UTF8Vstring255 +TIED10MONT LPHD1$DC$SntpAddr$dU "string" type=UTF8Vstring255 +TIED10MONT LPHD1$DC$TimeZone$dU "string" type=UTF8Vstring255 +TIED10MONT LPHD1$SP$SntpAddr$setVal "string" type=Long +TIED10MONT LPHD1$SP$TimeZone$setVal "string" type=Long +TIED10MONT LPHD1$SV$OutOv$subEna "string" type=Bool +TIED10MONT LPHD1$SV$OutOv$subVal "string" type=Bool +TIED10MONT LPHD1$SV$OutOv$subQ "string" type=BVstring13 +TIED10MONT LPHD1$SV$OutOv$subID "string" type=Vstring64 +TIED10MONT LPHD1$SV$Proxy$subEna "string" type=Bool +TIED10MONT LPHD1$SV$Proxy$subVal "string" type=Bool +TIED10MONT LPHD1$SV$Proxy$subQ "string" type=BVstring13 +TIED10MONT LPHD1$SV$Proxy$subID "string" type=Vstring64 +TIED10MONT LPHD1$EX$SntpAddr$dataNs "string" type=Vstring255 +TIED10MONT LPHD1$EX$TimeZone$dataNs "string" type=Vstring255 +TIED10MONT SIML01$MX$Tmp$mag$f "0.0.10.0" type=Float +TIED10MONT SIML01$MX$Tmp$q "0.0.10.1" type=BVstring13 +TIED10MONT SIML01$MX$Tmp$t "0.0.10.2" type=Utctime +TIED10MONT SIML01$MX$H2$mag$f "0.0.0.0" type=Float +TIED10MONT SIML01$MX$H2$q "0.0.0.1" type=BVstring13 +TIED10MONT SIML01$MX$H2$t "0.0.0.2" type=Utctime +TIED10MONT SIML01$MX$CO$mag$f "0.0.1.0" type=Float +TIED10MONT SIML01$MX$CO$q "0.0.1.1" type=BVstring13 +TIED10MONT SIML01$MX$CO$t "0.0.1.2" type=Utctime +TIED10MONT SIML01$MX$CH4$mag$f "0.0.2.0" type=Float +TIED10MONT SIML01$MX$CH4$q "0.0.2.1" type=BVstring13 +TIED10MONT SIML01$MX$CH4$t "0.0.2.2" type=Utctime +TIED10MONT SIML01$MX$C2H4$mag$f "0.0.3.0" type=Float +TIED10MONT SIML01$MX$C2H4$q "0.0.3.1" type=BVstring13 +TIED10MONT SIML01$MX$C2H4$t "0.0.3.2" type=Utctime +TIED10MONT SIML01$MX$C2H6$mag$f "0.0.4.0" type=Float +TIED10MONT SIML01$MX$C2H6$q "0.0.4.1" type=BVstring13 +TIED10MONT SIML01$MX$C2H6$t "0.0.4.2" type=Utctime +TIED10MONT SIML01$MX$C2H2$mag$f "0.0.5.0" type=Float +TIED10MONT SIML01$MX$C2H2$q "0.0.5.1" type=BVstring13 +TIED10MONT SIML01$MX$C2H2$t "0.0.5.2" type=Utctime +TIED10MONT SIML01$MX$TotHyd$mag$f "0.0.6.0" type=Float +TIED10MONT SIML01$MX$TotHyd$q "0.0.6.1" type=BVstring13 +TIED10MONT SIML01$MX$TotHyd$t "0.0.6.2" type=Utctime +TIED10MONT SIML01$MX$SmpTm$mag$i "0.0.7.0" type=Long +TIED10MONT SIML01$MX$SmpTm$q "0.0.7.1" type=BVstring13 +TIED10MONT SIML01$MX$SmpTm$t "0.0.7.2" type=Utctime +TIED10MONT SIML01$MX$CO2$mag$f "0.0.8.0" type=Float +TIED10MONT SIML01$MX$CO2$q "0.0.8.1" type=BVstring13 +TIED10MONT SIML01$MX$CO2$t "0.0.8.2" type=Utctime +TIED10MONT SIML01$MX$MicrWat$mag$f "0.0.9.0" type=Float +TIED10MONT SIML01$MX$MicrWat$q "0.0.9.1" type=BVstring13 +TIED10MONT SIML01$MX$MicrWat$t "0.0.9.2" type=Utctime +TIED10MONT SIML01$MX$GasPres$mag$f "0.0.11.0" type=Float +TIED10MONT SIML01$MX$GasPres$q "0.0.11.1" type=BVstring13 +TIED10MONT SIML01$MX$GasPres$t "0.0.11.2" type=Utctime +TIED10MONT SIML01$MX$GasBot$mag$i "0.0.12.0" type=Long +TIED10MONT SIML01$MX$GasBot$q "0.0.12.1" type=BVstring13 +TIED10MONT SIML01$MX$GasBot$t "0.0.12.2" type=Utctime +TIED10MONT SIML01$ST$Mod$stVal "string" type=Byte +TIED10MONT SIML01$ST$Mod$q "string" type=BVstring13 +TIED10MONT SIML01$ST$Mod$t "string" type=Utctime +TIED10MONT SIML01$ST$Beh$q "string" type=BVstring13 +TIED10MONT SIML01$ST$Beh$t "string" type=Utctime +TIED10MONT SIML01$ST$Health$stVal "string" type=Byte +TIED10MONT SIML01$ST$Health$q "string" type=BVstring13 +TIED10MONT SIML01$ST$Health$t "string" type=Utctime +TIED10MONT SIML01$ST$InsAlm$stVal "string" type=Bool +TIED10MONT SIML01$ST$InsAlm$q "string" type=BVstring13 +TIED10MONT SIML01$ST$InsAlm$t "string" type=Utctime +TIED10MONT SIML01$ST$MoDevConf$stVal "0.0.13.0" type=Bool +TIED10MONT SIML01$ST$MoDevConf$q "0.0.13.1" type=BVstring13 +TIED10MONT SIML01$ST$MoDevConf$t "0.0.13.2" type=Utctime +TIED10MONT SIML01$ST$SupDevRun$stVal "0.0.14.0" type=Bool +TIED10MONT SIML01$ST$SupDevRun$q "0.0.14.1" type=BVstring13 +TIED10MONT SIML01$ST$SupDevRun$t "0.0.14.2" type=Utctime +TIED10MONT SIML01$ST$GasUnPresAlm$stVal "0.0.15.0" type=Bool +TIED10MONT SIML01$ST$GasUnPresAlm$q "0.0.15.1" type=BVstring13 +TIED10MONT SIML01$ST$GasUnPresAlm$t "0.0.15.2" type=Utctime +TIED10MONT SIML01$ST$GasLowPresAlm$stVal "0.0.16.0" type=Bool +TIED10MONT SIML01$ST$GasLowPresAlm$q "0.0.16.1" type=BVstring13 +TIED10MONT SIML01$ST$GasLowPresAlm$t "0.0.16.2" type=Utctime +TIED10MONT SIML01$ST$ActCyGasSta$stVal "0.0.17.0" type=Bool +TIED10MONT SIML01$ST$ActCyGasSta$q "0.0.17.1" type=BVstring13 +TIED10MONT SIML01$ST$ActCyGasSta$t "0.0.17.2" type=Utctime +TIED10MONT SIML01$CF$Mod$ctlModel "string" type=Byte +TIED10MONT SIML01$CF$Tmp$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$Tmp$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$Tmp$db "string" type=Ulong +TIED10MONT SIML01$CF$Tmp$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$Tmp$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$Tmp$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$Tmp$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$Tmp$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$Tmp$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$Tmp$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$Tmp$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$Tmp$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$Tmp$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$H2$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$H2$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$H2$db "string" type=Ulong +TIED10MONT SIML01$CF$H2$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$H2$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$H2$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$H2$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$H2$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$H2$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$H2$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$H2$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$H2$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$H2$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$CO$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$CO$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$CO$db "string" type=Ulong +TIED10MONT SIML01$CF$CO$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$CO$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$CO$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$CO$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$CO$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$CO$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$CO$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$CO$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$CO$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$CO$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$CH4$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$CH4$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$CH4$db "string" type=Ulong +TIED10MONT SIML01$CF$CH4$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$CH4$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$CH4$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$CH4$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$CH4$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$CH4$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$CH4$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$CH4$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$CH4$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$CH4$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$C2H4$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$C2H4$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$C2H4$db "string" type=Ulong +TIED10MONT SIML01$CF$C2H4$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$C2H4$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$C2H4$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$C2H4$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H4$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H4$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H4$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H4$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$C2H4$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$C2H4$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$C2H6$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$C2H6$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$C2H6$db "string" type=Ulong +TIED10MONT SIML01$CF$C2H6$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$C2H6$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$C2H6$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$C2H6$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H6$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H6$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H6$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H6$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$C2H6$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$C2H6$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$C2H2$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$C2H2$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$C2H2$db "string" type=Ulong +TIED10MONT SIML01$CF$C2H2$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$C2H2$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$C2H2$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$C2H2$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H2$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H2$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H2$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$C2H2$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$C2H2$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$C2H2$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$TotHyd$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$TotHyd$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$TotHyd$db "string" type=Ulong +TIED10MONT SIML01$CF$TotHyd$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$TotHyd$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$TotHyd$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$TotHyd$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$TotHyd$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$TotHyd$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$TotHyd$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$TotHyd$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$TotHyd$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$TotHyd$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$SmpTm$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$SmpTm$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$SmpTm$db "string" type=Ulong +TIED10MONT SIML01$CF$SmpTm$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$SmpTm$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$SmpTm$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$SmpTm$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$SmpTm$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$SmpTm$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$SmpTm$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$SmpTm$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$SmpTm$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$SmpTm$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$CO2$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$CO2$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$CO2$db "string" type=Ulong +TIED10MONT SIML01$CF$CO2$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$CO2$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$CO2$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$CO2$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$CO2$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$CO2$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$CO2$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$CO2$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$CO2$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$CO2$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$MicrWat$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$MicrWat$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$MicrWat$db "string" type=Ulong +TIED10MONT SIML01$CF$MicrWat$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$MicrWat$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$MicrWat$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$MicrWat$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$MicrWat$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$MicrWat$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$MicrWat$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$MicrWat$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$MicrWat$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$MicrWat$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$GasPres$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$GasPres$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$GasPres$db "string" type=Ulong +TIED10MONT SIML01$CF$GasPres$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$GasPres$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$GasPres$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$GasPres$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$GasPres$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$GasPres$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$GasPres$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$GasPres$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$GasPres$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$GasPres$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$GasBot$units$SIUnit "string" type=Byte +TIED10MONT SIML01$CF$GasBot$units$multiplier "string" type=Byte +TIED10MONT SIML01$CF$GasBot$db "string" type=Ulong +TIED10MONT SIML01$CF$GasBot$zeroDb "string" type=Ulong +TIED10MONT SIML01$CF$GasBot$sVC$scaleFactor "string" type=Float +TIED10MONT SIML01$CF$GasBot$sVC$offset "string" type=Float +TIED10MONT SIML01$CF$GasBot$rangeC$hhLim$f "string" type=Float +TIED10MONT SIML01$CF$GasBot$rangeC$hLim$f "string" type=Float +TIED10MONT SIML01$CF$GasBot$rangeC$lLim$f "string" type=Float +TIED10MONT SIML01$CF$GasBot$rangeC$llLim$f "string" type=Float +TIED10MONT SIML01$CF$GasBot$rangeC$min$f "string" type=Float +TIED10MONT SIML01$CF$GasBot$rangeC$max$f "string" type=Float +TIED10MONT SIML01$CF$GasBot$smpRate "string" type=Ulong +TIED10MONT SIML01$CF$SamInteC$minVal "string" type=Long +TIED10MONT SIML01$CF$SamInteC$maxVal "string" type=Long +TIED10MONT SIML01$CF$SamInteC$stepSize "string" type=Ulong +TIED10MONT SIML01$CF$StartWork$minVal "string" type=Long +TIED10MONT SIML01$CF$StartWork$maxVal "string" type=Long +TIED10MONT SIML01$CF$StartWork$stepSize "string" type=Ulong +TIED10MONT SIML01$CF$NextWorkTime$minVal "string" type=Long +TIED10MONT SIML01$CF$NextWorkTime$maxVal "string" type=Long +TIED10MONT SIML01$CF$NextWorkTime$stepSize "string" type=Ulong +TIED10MONT SIML01$CF$ReStart$minVal "string" type=Long +TIED10MONT SIML01$CF$ReStart$maxVal "string" type=Long +TIED10MONT SIML01$CF$ReStart$stepSize "string" type=Ulong +TIED10MONT SIML01$DC$NamPlt$vendor "string" type=Vstring255 +TIED10MONT SIML01$DC$NamPlt$swRev "string" type=Vstring255 +TIED10MONT SIML01$DC$NamPlt$d "string" type=Vstring255 +TIED10MONT SIML01$DC$NamPlt$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$NamPlt$configRev "string" type=Vstring255 +TIED10MONT SIML01$DC$Tmp$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$H2$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$CO$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$CH4$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$C2H4$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$C2H6$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$C2H2$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$TotHyd$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$SmpTm$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$CO2$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$MicrWat$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$GasPres$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$GasBot$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$InsAlm$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$MoDevConf$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$SupDevRun$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$GasUnPresAlm$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$GasLowPresAlm$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$ActCyGasSta$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$SamInteC$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$StartWork$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$NextWorkTime$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$DC$ReStart$dU "string" type=UTF8Vstring255 +TIED10MONT SIML01$SG$SamInteC$setVal "string" type=Long +TIED10MONT SIML01$SG$StartWork$setVal "string" type=Long +TIED10MONT SIML01$SG$NextWorkTime$setVal "string" type=Long +TIED10MONT SIML01$SG$ReStart$setVal "string" type=Long +TIED10MONT SIML01$SV$Tmp$subEna "string" type=Bool +TIED10MONT SIML01$SV$Tmp$subMag$f "string" type=Float +TIED10MONT SIML01$SV$Tmp$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$Tmp$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$H2$subEna "string" type=Bool +TIED10MONT SIML01$SV$H2$subMag$f "string" type=Float +TIED10MONT SIML01$SV$H2$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$H2$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$CO$subEna "string" type=Bool +TIED10MONT SIML01$SV$CO$subMag$f "string" type=Float +TIED10MONT SIML01$SV$CO$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$CO$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$CH4$subEna "string" type=Bool +TIED10MONT SIML01$SV$CH4$subMag$f "string" type=Float +TIED10MONT SIML01$SV$CH4$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$CH4$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$C2H4$subEna "string" type=Bool +TIED10MONT SIML01$SV$C2H4$subMag$f "string" type=Float +TIED10MONT SIML01$SV$C2H4$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$C2H4$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$C2H6$subEna "string" type=Bool +TIED10MONT SIML01$SV$C2H6$subMag$f "string" type=Float +TIED10MONT SIML01$SV$C2H6$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$C2H6$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$C2H2$subEna "string" type=Bool +TIED10MONT SIML01$SV$C2H2$subMag$f "string" type=Float +TIED10MONT SIML01$SV$C2H2$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$C2H2$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$TotHyd$subEna "string" type=Bool +TIED10MONT SIML01$SV$TotHyd$subMag$f "string" type=Float +TIED10MONT SIML01$SV$TotHyd$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$TotHyd$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$SmpTm$subEna "string" type=Bool +TIED10MONT SIML01$SV$SmpTm$subMag$i "string" type=Long +TIED10MONT SIML01$SV$SmpTm$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$SmpTm$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$CO2$subEna "string" type=Bool +TIED10MONT SIML01$SV$CO2$subMag$f "string" type=Float +TIED10MONT SIML01$SV$CO2$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$CO2$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$MicrWat$subEna "string" type=Bool +TIED10MONT SIML01$SV$MicrWat$subMag$f "string" type=Float +TIED10MONT SIML01$SV$MicrWat$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$MicrWat$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$GasPres$subEna "string" type=Bool +TIED10MONT SIML01$SV$GasPres$subMag$f "string" type=Float +TIED10MONT SIML01$SV$GasPres$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$GasPres$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$GasBot$subEna "string" type=Bool +TIED10MONT SIML01$SV$GasBot$subMag$i "string" type=Long +TIED10MONT SIML01$SV$GasBot$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$GasBot$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$InsAlm$subEna "string" type=Bool +TIED10MONT SIML01$SV$InsAlm$subVal "string" type=Bool +TIED10MONT SIML01$SV$InsAlm$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$InsAlm$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$MoDevConf$subEna "string" type=Bool +TIED10MONT SIML01$SV$MoDevConf$subVal "string" type=Bool +TIED10MONT SIML01$SV$MoDevConf$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$MoDevConf$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$SupDevRun$subEna "string" type=Bool +TIED10MONT SIML01$SV$SupDevRun$subVal "string" type=Bool +TIED10MONT SIML01$SV$SupDevRun$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$SupDevRun$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$GasUnPresAlm$subEna "string" type=Bool +TIED10MONT SIML01$SV$GasUnPresAlm$subVal "string" type=Bool +TIED10MONT SIML01$SV$GasUnPresAlm$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$GasUnPresAlm$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$GasLowPresAlm$subEna "string" type=Bool +TIED10MONT SIML01$SV$GasLowPresAlm$subVal "string" type=Bool +TIED10MONT SIML01$SV$GasLowPresAlm$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$GasLowPresAlm$subID "string" type=Vstring64 +TIED10MONT SIML01$SV$ActCyGasSta$subEna "string" type=Bool +TIED10MONT SIML01$SV$ActCyGasSta$subVal "string" type=Bool +TIED10MONT SIML01$SV$ActCyGasSta$subQ "string" type=BVstring13 +TIED10MONT SIML01$SV$ActCyGasSta$subID "string" type=Vstring64 +TIED10MONT SIML01$SE$SamInteC$setVal "string" type=Long +TIED10MONT SIML01$SE$StartWork$setVal "string" type=Long +TIED10MONT SIML01$SE$NextWorkTime$setVal "string" type=Long +TIED10MONT SIML01$SE$ReStart$setVal "string" type=Long +TIED10MONT SIML01$EX$NamPlt$ldNs "string" type=Vstring255 +TIED10MONT SIML01$EX$CO$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$CH4$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$C2H4$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$C2H6$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$C2H2$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$TotHyd$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$SmpTm$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$CO2$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$MicrWat$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$GasPres$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$GasBot$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$MoDevConf$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$SupDevRun$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$GasUnPresAlm$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$GasLowPresAlm$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$ActCyGasSta$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$SamInteC$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$StartWork$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$NextWorkTime$dataNs "string" type=Vstring255 +TIED10MONT SIML01$EX$ReStart$dataNs "string" type=Vstring255 diff --git a/scl_srvr/lap_out.xml b/scl_srvr/lap_out.xml new file mode 100644 index 0000000..5d6dda3 --- /dev/null +++ b/scl_srvr/lap_out.xml @@ -0,0 +1,2 @@ + + diff --git a/scl_srvr/leafmap.xml b/scl_srvr/leafmap.xml new file mode 100644 index 0000000..baa016a --- /dev/null +++ b/scl_srvr/leafmap.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scl_srvr/logcfg.xml b/scl_srvr/logcfg.xml new file mode 100644 index 0000000..c62830f --- /dev/null +++ b/scl_srvr/logcfg.xml @@ -0,0 +1,192 @@ + + + + + + Off + + + On + mms.log + 1000000 + Off + Off + + + MMS-LITE-80X-001 SCL_SRVR + 10 + Off + 55200 + 1 + 1 + On + 55146 + 127.0.0.1 + 500 + On + On + 2 + 10 + + + + + + On + Off + + + Off + Off + + + On + Off + Off + Off + On + Off + Off + Off + + + On + Off + + + On + Off + Off + + + On + Off + Off + Off + Off + Off + Off + Off + + + On + Off + Off + Off + Off + + + Off + Off + Off + Off + Off + Off + Off + Off + Off + Off + + + Off + Off + + + On + Off + Off + Off + Off + + + On + Off + Off + Off + Off + + + + On + Off + Off + Off + + + Off + Off + + + Off + Off + Off + Off + + + + diff --git a/scl_srvr/osicfg.xml b/scl_srvr/osicfg.xml new file mode 100644 index 0000000..be8081c --- /dev/null +++ b/scl_srvr/osicfg.xml @@ -0,0 +1,307 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 120000 + 0 + 12 + + + + 12 + 1 + 120 + 5 + 49 00 01 53 49 53 43 21 00 01 + + + + + 1024 + 4 + 4 + 16 + 10 + 120 + 10 + 2 + 2 + + + 1024 + 50 + + + + + + local1 + 1 3 9999 33 + 33 + 00 00 00 01 + 00 01 + 00 01 + TCP + + + + local1cl + 1 3 9999 33 + 33 + 00 00 00 02 + 00 01 + 00 01 + TCP + + + + + + remote1 + 1 3 9999 23 + 23 + 00 00 00 01 + 00 01 + 00 01 + 127.0.0.1 + + + + + + diff --git a/scl_srvr/startup.cfg b/scl_srvr/startup.cfg new file mode 100644 index 0000000..0513c98 --- /dev/null +++ b/scl_srvr/startup.cfg @@ -0,0 +1,7 @@ +SCLFileName TEMPLATE.icd +IEDName TIED10 +AccessPointName S1 +ReportScanRate 2.0 +BRCBBufferSize 32768 +LogScanRateSeconds 2.0 +LogMaxEntries 1000 diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..008cd88 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,288 @@ +# Generic Makefile by tmb +# Program name +PROGRAM = app + +#PLAT = x86 +PLAT = arm + +#VER = debug +VER = release + +TYPE = bin +#TYPE = so + +##========================================================================== +PROGRAM := $(strip $(PROGRAM)) +PLAY := $(strip $(TYPE)) +VER := $(strip $(VER)) + +MY_CFLAGS = -fmessage-length=0 + +ifeq ($(PLAT),x86) +MY_LIBS = -lpthread -L../lib -lrt -ldl -lscl_shm -lm -lgo +else +MY_LIBS = -L../lib -lpthread -lrt -ldl -lscl_shm -lm -lgo +endif + +# The pre-processor options used by the cpp (man cpp for more). +#CPPFLAGS = -DHAVE_CONFIG_H -Wall -Wextra -Wno-invalid-offsetof +CPPFLAGS = -Wall -Wextra + +# The options used in linking as well as in any direct use of ld. +ifeq ($(TYPE),so) +LDFLAGS = -shared -fPIC +else +LDFLAGS = +endif + +# The directories in which source files reside. +# If not specified, only the current directory will be serached. +SRCDIRS = + +## Implicit Section: change the following only when necessary. +##========================================================================== + +# The source file types (headers excluded). +# .c indicates C source files, and others C++ ones. +SRCEXTS = .c .C .cc .cpp .CPP .c++ .cxx .cp + +# The header file types. +HDREXTS = .h .H .hh .hpp .HPP .h++ .hxx .hp + +# The pre-processor and compiler options. +# Users can override those variables from the command line. +ifeq ($(VER),debug) +ifeq ($(TYPE),so) +CFLAGS = -ggdb -pipe -O0 -fPIC -I. -I../inc +CXXFLAGS= -ggdb -pipe -O0 -fPIC -I. -I../inc +else +CFLAGS = -ggdb -pipe -O0 -I. -I../inc +CXXFLAGS= -ggdb -pipe -O0 -I. -I../inc +endif +else +ifeq ($(TYPE),so) +CFLAGS = -O2 -pipe -fPIC -I. -I../inc +CXXFLAGS= -O2 -pipe -fPIC -I. -I../inc +else +CFLAGS = -O2 -pipe -I. -I../inc +CXXFLAGS= -O2 -pipe -I. -I../inc +endif +endif + +# The C program compiler. +ifeq ($(PLAT),x86) +CC = gcc +else +CC = arm-linux-gnueabihf-gcc +endif + +# The C++ program compiler. +ifeq ($(PLAT),x86) +CXX = g++ +else +CXX = arm-linux-gnueabihf-g++ +endif + +# Un-comment the following line to compile C programs as C++ ones. +#CC = $(CXX) + +ifeq ($(PLAT),x86) +STRIP = strip +else +STRIP = arm-none-linux-gnueabi-strip +endif + +# The command used to delete file. +#RM = rm -f + +ETAGS = etags +ETAGSFLAGS = + +CTAGS = ctags +CTAGSFLAGS = + +## Stable Section: usually no need to be changed. +##========================================================================== +SHELL = /bin/sh +EMPTY = +SPACE = $(EMPTY) $(EMPTY) +ifeq ($(PROGRAM),) + CUR_PATH_NAMES = $(subst /,$(SPACE),$(subst $(SPACE),_,$(CURDIR))) + PROGRAM = $(word $(words $(CUR_PATH_NAMES)),$(CUR_PATH_NAMES)) + ifeq ($(PROGRAM),) + PROGRAM = a.out + endif +endif +ifeq ($(SRCDIRS),) + SRCDIRS = . +endif +SOURCES = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(SRCEXTS)))) +HEADERS = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(HDREXTS)))) +SRC_CXX = $(filter-out %.c,$(SOURCES)) +OBJS = $(addsuffix .o, $(basename $(SOURCES))) +DEPS = $(OBJS:.o=.d) + +## Define some useful variables. +#DEP_OPT = $(shell if `$(CC) --version | grep "GCC"`; then echo "-MM -MP"; else echo "-M"; fi ) +DEP_OPT = -M +DEPEND = $(CC) $(DEP_OPT) $(MY_CFLAGS) $(CFLAGS) $(CPPFLAGS) +DEPEND.d = $(subst -g ,,$(DEPEND)) +COMPILE.c = $(CC) $(MY_CFLAGS) $(CFLAGS) $(CPPFLAGS) -c +COMPILE.cxx = $(CXX) $(MY_CFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c +LINK.c = $(CC) $(MY_CFLAGS) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) +LINK.cxx = $(CXX) $(MY_CFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) + +.PHONY: all objs tags ctags clean distclean help show objclean + +# Delete the default suffixes +.SUFFIXES: + +all: $(PROGRAM) + +# Rules for creating dependency files (.d). +#------------------------------------------ + +%.d:%.c + @echo -n $(dir $<) > $@ + @$(DEPEND.d) $< >> $@ + +%.d:%.C + @echo -n $(dir $<) > $@ + @$(DEPEND.d) $< >> $@ + +%.d:%.cc + @echo -n $(dir $<) > $@ + @$(DEPEND.d) $< >> $@ + +%.d:%.cpp + @echo -n $(dir $<) > $@ + @$(DEPEND.d) $< >> $@ + +%.d:%.CPP + @echo -n $(dir $<) > $@ + @$(DEPEND.d) $< >> $@ + +%.d:%.c++ + @echo -n $(dir $<) > $@ + @$(DEPEND.d) $< >> $@ + +%.d:%.cp + @echo -n $(dir $<) > $@ + @$(DEPEND.d) $< >> $@ + +%.d:%.cxx + @echo -n $(dir $<) > $@ + @$(DEPEND.d) $< >> $@ + +# Rules for generating object files (.o). +#---------------------------------------- +objs:$(OBJS) + +%.o:%.c + @$(COMPILE.c) $< -o $@ + @echo "[M] $@" + +%.o:%.C + @$(COMPILE.cxx) $< -o $@ + @echo "[M] $@" + +%.o:%.cc + @$(COMPILE.cxx) $< -o $@ + @echo "[M] $@" + +%.o:%.cpp + @$(COMPILE.cxx) $< -o $@ + @echo "[M] $@" + +%.o:%.CPP + $(COMPILE.cxx) $< -o $@ + +%.o:%.c++ + $(COMPILE.cxx) $< -o $@ + +%.o:%.cp + $(COMPILE.cxx) $< -o $@ + +%.o:%.cxx + @$(COMPILE.cxx) $< -o $@ + @echo "[M] $@" + +# Rules for generating the tags. +#------------------------------------- +tags: $(HEADERS) $(SOURCES) + $(ETAGS) $(ETAGSFLAGS) $(HEADERS) $(SOURCES) + +ctags: $(HEADERS) $(SOURCES) + $(CTAGS) $(CTAGSFLAGS) $(HEADERS) $(SOURCES) + +# Rules for generating the executable. +#------------------------------------- +$(PROGRAM):$(OBJS) +ifeq ($(SRC_CXX),) + @$(LINK.c) $(OBJS) $(MY_LIBS) -o $@ + @echo "[L] $@" + @$(STRIP) $(PROGRAM) + @echo "[S] $(PROGRAM)" + @$(RM) $(DEPS) + @echo "*** version:$(VER)-$(PLAT): Build $@ Finished ***" +else + @$(LINK.cxx) $(OBJS) $(MY_LIBS) -o $@ + @echo "[L] $@" + @$(STRIP) $(PROGRAM) + @echo "[S] $(PROGRAM)" + @$(RM) $(DEPS) + @echo "*** version:$(VER)-$(PLAT): Build $@ Finished ***" +endif + +ifndef NODEP +ifneq ($(DEPS),) + sinclude $(DEPS) +endif +endif + +clean: + $(RM) $(OBJS) $(PROGRAM) $(DEPS) + +distclean: clean + $(RM) $(DEPS) TAGS + +objclean: + $(RM) $(OBJ) $(DEPS) + +# Show help. +help: + @echo 'Generic Makefile for C/C++ Programs version' + @echo + @echo 'Usage: make [TARGET]' + @echo 'TARGETS:' + @echo ' all (=make) compile and link.' + @echo ' NODEP=yes make without generating dependencies.' + @echo ' objs compile only (no linking).' + @echo ' tags create tags for Emacs editor.' + @echo ' ctags create ctags for VI editor.' + @echo ' clean clean objects and the executable file.' + @echo ' distclean clean objects, the executable and dependencies.' + @echo ' show show variables (for debug use only).' + @echo ' help print this message.' + @echo + @$(RM) $(DEPS) + +# Show variables (for debug use only.) +show: + @echo 'PROGRAM :' $(PROGRAM) + @echo 'PLAT :' $(PLAT) + @echo 'TYPE :' $(TYPE) + @echo 'SRCDIRS :' $(SRCDIRS) + @echo 'HEADERS :' $(HEADERS) + @echo 'SOURCES :' $(SOURCES) + @echo 'SRC_CXX :' $(SRC_CXX) + @echo 'OBJS :' $(OBJS) + @echo 'DEPS :' $(DEPS) + @echo 'DEPEND :' $(DEPEND) + @echo 'COMPILE.c :' $(COMPILE.c) + @echo 'COMPILE.cxx :' $(COMPILE.cxx) + @echo 'link.c :' $(LINK.c) + @echo 'link.cxx :' $(LINK.cxx) + + +############################# End of the Makefile ################################ diff --git a/src/PID_AutoTune.c b/src/PID_AutoTune.c new file mode 100644 index 0000000..7e48624 --- /dev/null +++ b/src/PID_AutoTune.c @@ -0,0 +1,237 @@ +#include "PID_AutoTune.h" +#include + +unsigned long PID_ATune_millis() +{ + return 0; +} + +void PID_ATune_Cancel(PID_ATune *pid_atune) +{ + pid_atune->running = TUNE_FALSE; +} + + +void PID_ATune_GetKp(PID_ATune *pid_atune,float *Kp) +{ + if(Kp!=NULL) + *Kp=(pid_atune->controlType==1?0.6*(pid_atune->Ku):0.4*(pid_atune->Ku)); +} + + +void PID_ATune_GetKi(PID_ATune *pid_atune,float *Ki) +{ + if(Ki!=NULL) + *Ki=(pid_atune->controlType==1?1.2*(pid_atune->Ku)/(pid_atune->Pu):0.48*(pid_atune->Ku)/(pid_atune->Pu)); // Ki = Kc/Ti +} + + + +void PID_ATune_GetKd(PID_ATune *pid_atune,float *Kd) +{ + if(Kd!=NULL) + *Kd=(pid_atune->controlType==1?0.075*(pid_atune->Ku)*(pid_atune->Pu):0); //Kd = Kc * Td +} + +void PID_ATune_SetOutputStep(PID_ATune *pid_atune,float *Step) +{ + if(Step!=NULL) + pid_atune->oStep = *Step; +} + +void PID_ATune_GetOutputStep(PID_ATune *pid_atune,float *Step) +{ + if(Step!=NULL) + *Step=pid_atune->oStep; +} + +void PID_ATune_SetControlType(PID_ATune *pid_atune,int Type) //0=PI, 1=PID +{ + pid_atune->controlType = Type; +} + +int PID_ATune_GetControlType(PID_ATune *pid_atune) +{ + return pid_atune->controlType; +} + +void PID_ATune_SetNoiseBand(PID_ATune *pid_atune,float *Band) +{ + if(Band!=NULL) + pid_atune->noiseBand = *Band; +} + +void PID_ATune_GetNoiseBand(PID_ATune *pid_atune,float *noiseBand) +{ + if(noiseBand!=NULL) + *noiseBand=pid_atune->noiseBand; +} + + +void PID_ATune_SetLookbackSec(PID_ATune *pid_atune,int value) +{ + if(value<1) + value = 1; + + if(value<25) + { + pid_atune->nLookBack = value*4; + pid_atune->sampleTime = 250; + } + else + { + pid_atune->nLookBack = value/4; + if((pid_atune->nLookBack)>=(MAX_INPUTS-1)) + pid_atune->nLookBack=(MAX_INPUTS-2); + pid_atune->sampleTime = 4; + } +} + + +int PID_ATune_GetLookbackSec(PID_ATune *pid_atune) +{ + return (pid_atune->nLookBack)*(pid_atune->sampleTime);//1000; +} + +void PID_ATune_FinishUp(PID_ATune *pid_atune) +{ + *(pid_atune->output) = pid_atune->outputStart; + pid_atune->Ku = 4*(2*(pid_atune->oStep))/(((pid_atune->absMax)-(pid_atune->absMin))*3.14159); + pid_atune->Pu = (float)((pid_atune->peak1)-(pid_atune->peak2)); +} + + +void PID_ATune_Init(PID_ATune *pid_atune,float *Input,unsigned short *Output) +{ + pid_atune->input = Input; + pid_atune->output = Output; + + pid_atune->controlType =TYPE_PID; + pid_atune->noiseBand = NOISE_BAND; + pid_atune->running = TUNE_FALSE; + pid_atune->oStep = OSTEP; + PID_ATune_SetLookbackSec(pid_atune,LOOK_BACK_TIME); + pid_atune->lastTime = 0; +} + + +int PID_ATune_Runtime(PID_ATune *pid_atune,unsigned long time_tick) +{ + unsigned long now; + float refVal; + int i; + float val; + float avgSeparation; + + pid_atune->justevaled=TUNE_FALSE; + if((pid_atune->peakCount)>(MAX_PEAKS-1)&&(pid_atune->running)) + { + pid_atune->running = TUNE_FALSE; + PID_ATune_FinishUp(pid_atune); + return 1; + } + + now = time_tick; + + pid_atune->lastTime = now; + + + + refVal = *(pid_atune->input); + + pid_atune->justevaled=TUNE_TURE; + + if(!(pid_atune->running)) + { + pid_atune->peakType = 0; + pid_atune->peakCount=0; + pid_atune->justchanged=TUNE_FALSE; + pid_atune->absMax=refVal; + pid_atune->absMin=refVal; + pid_atune->setpoint = refVal; + pid_atune->running = TUNE_TURE; + pid_atune->outputStart = *(pid_atune->output); + *(pid_atune->output) = (pid_atune->outputStart)+(pid_atune->oStep); + } + else + { + if(refVal>(pid_atune->absMax)) + pid_atune->absMax=refVal; + if(refVal<(pid_atune->absMin)) + pid_atune->absMin=refVal; + } + + + if(refVal>((pid_atune->setpoint)+(pid_atune->noiseBand))) + *(pid_atune->output) = (pid_atune->outputStart)-(pid_atune->oStep); + else if (refVal<((pid_atune->setpoint)-(pid_atune->noiseBand))) + *(pid_atune->output) = (pid_atune->outputStart)+(pid_atune->oStep); + + + + pid_atune->isMax=TUNE_TURE; + pid_atune->isMin=TUNE_TURE; + + for(i=((pid_atune->nLookBack)-1);i>=0;i--) + { + val = pid_atune->lastInputs[i]; + if(pid_atune->isMax) + pid_atune->isMax = (refVal>val); + if(pid_atune->isMin) + pid_atune->isMin = (refVallastInputs[i+1]=pid_atune->lastInputs[i]; + } + pid_atune->lastInputs[0] = refVal; + + + + if((pid_atune->nLookBack)<9) + { + return 0; + } + + + if((pid_atune->isMax)) + { + if((pid_atune->peakType)==0) + pid_atune->peakType=1; + if((pid_atune->peakType)==-1) + { + pid_atune->peakType = 1; + pid_atune->justchanged=TUNE_TURE; + (pid_atune->peak2) = (pid_atune->peak1); + } + pid_atune->peak1 = now; + pid_atune->peaks[(pid_atune->peakCount)]=refVal; + + } + else if((pid_atune->isMin)) + { + if((pid_atune->peakType)==0) + pid_atune->peakType=-1; + if((pid_atune->peakType)==1) + { + pid_atune->peakType=-1; + pid_atune->peakCount++; + pid_atune->justchanged=TUNE_TURE; + } + + if((pid_atune->peakCount)peaks[(pid_atune->peakCount)] = refVal;// + } + + + if((pid_atune->justchanged)&&(pid_atune->peakCount>2)) + { + avgSeparation = (abs(pid_atune->peaks[(pid_atune->peakCount)-1]-(pid_atune->peaks[(pid_atune->peakCount)-2]))+abs(pid_atune->peaks[(pid_atune->peakCount)-2]-(pid_atune->peaks[(pid_atune->peakCount)-3])))/2; + + if(avgSeparation<0.05*((pid_atune->absMax)-(pid_atune->absMin))) + { + PID_ATune_FinishUp(pid_atune); + pid_atune->running= TUNE_FALSE; + return 1; + } + } + pid_atune->justchanged=TUNE_FALSE; + return 0; +} \ No newline at end of file diff --git a/src/PID_AutoTune.h b/src/PID_AutoTune.h new file mode 100644 index 0000000..9c1ab1c --- /dev/null +++ b/src/PID_AutoTune.h @@ -0,0 +1,52 @@ +#ifndef _PID_AUTOTUNE_H +#define _PID_AUTOTUNE_H + + +#define TYPE_PID 1 +#define TYPE_PI 0 + + +#ifndef TUNE_TURE +#define TUNE_TURE 1 +#endif + +#ifndef TUNE_FALSE +#define TUNE_FALSE 0 +#endif + +#define MAX_PEAKS 10 +#define MAX_INPUTS 128 +#define NOISE_BAND 0.01 +#define OSTEP 8 +#define LOOK_BACK_TIME 256 //单位为秒 +#define SAMPLE_TIME 4 + +typedef struct +{ +int isMax,isMin; +float *input; +unsigned short *output; +float setpoint; +float noiseBand; +int controlType; +int running; +unsigned int peak1,peak2,lastTime; +int sampleTime; +int nLookBack; +int peakType; +float lastInputs[MAX_INPUTS]; +float peaks[MAX_PEAKS]; +int peakCount; +int justchanged; +int justevaled; +float absMax,absMin; +unsigned short oStep; +unsigned short outputStart; +float Ku,Pu; +unsigned int start_time; +}PID_ATune; + +#endif + + + diff --git a/src/S71ntpdate b/src/S71ntpdate new file mode 100644 index 0000000..ec09247 --- /dev/null +++ b/src/S71ntpdate @@ -0,0 +1,23 @@ +#! /bin/sh + +ntpdate=/usr/sbin/ntpdate + +test -x "$ntpdate" || exit 0 + +case "$1" in + start) + echo -n "Starting ntpdate daemon" + start-stop-daemon --start --background --exec $ntpdate + echo "." + ;; + stop) + echo -n "Stopping ntpdate daemon" + start-stop-daemon --stop --name ntpdate + echo "." + ;; + *) + echo "Usage: /etc/init.d/ntpdate {start|stop}" + exit 1 +esac + +exit 0 diff --git a/src/S81srvrd b/src/S81srvrd new file mode 100644 index 0000000..37928b9 --- /dev/null +++ b/src/S81srvrd @@ -0,0 +1,23 @@ +#! /bin/sh + +srvrd=/usr/sbin/scl_srvr_ld + +test -x "$srvrd" || exit 0 + +case "$1" in + start) + echo -n "Starting srvrd daemon" + start-stop-daemon --start --background --exec $srvrd -- -d /scl_srvr + echo "." + ;; + stop) + echo -n "Stopping srvrd daemon" + start-stop-daemon --stop --name scl_srvr_ld + echo "." + ;; + *) + echo "Usage: /etc/init.d/S80srvrd {start|stop}" + exit 1 +esac + +exit 0 diff --git a/src/S90app b/src/S90app new file mode 100644 index 0000000..37d328e --- /dev/null +++ b/src/S90app @@ -0,0 +1,23 @@ +#! /bin/sh + +usr_app_d=/usr_app/app + +test -x "$usr_app_d" || exit 0 + +case "$1" in + start) + echo -n "Starting user appliction daemon" + start-stop-daemon --start --background --exec $usr_app_d + echo "." + ;; + stop) + echo -n "Stopping user appliction daemon" + start-stop-daemon --stop --name app + echo "." + ;; + *) + echo "Usage: /etc/init.d/S90app {start|stop}" + exit 1 +esac + +exit 0 diff --git a/src/S91fileprocess b/src/S91fileprocess new file mode 100644 index 0000000..5dcced4 --- /dev/null +++ b/src/S91fileprocess @@ -0,0 +1,23 @@ +#! /bin/sh + +fileprocess=/usr/sbin/fileprocess + +test -x "$fileprocess" || exit 0 + +case "$1" in + start) + echo -n "Starting fileprocess daemon" + start-stop-daemon --start --background --exec $fileprocess + echo "." + ;; + stop) + echo -n "Stopping fileprocess daemon" + start-stop-daemon --stop --name fileprocess + echo "." + ;; + *) + echo "Usage: /etc/init.d/S91fileprocess {start|stop}" + exit 1 +esac + +exit 0 diff --git a/src/analysis.c b/src/analysis.c new file mode 100644 index 0000000..ce17f5c --- /dev/null +++ b/src/analysis.c @@ -0,0 +1,2493 @@ +#include "common.h" +#include "ysp_debug.h" +#include "msq.h" +#include +#include +#include +#include "thread.h" +#include "analysis.h" + +#define DEBUG_ANALYSIS + +#define REDUCE_BIT 3 // +#define SUM_NUM 8 //ÿĿ +#define MOVE_NUM 8 //ƶĵ +#define JUDGE_NUM 8 //ÿжϵĵ + +#define MAX_JUDGE_NUM 32 //жϵ +#define MIN_JUDGE_NUM 7 //Сжϵ + +#define MIN_AMP 4 //С +#define MIN_LEN 12 //Сʱ + +#define BACK_SUM_NUM 20 +/* +˳˵: +ΪH2,CO,CH4,C2H4,C2H6,C2H2 +ǰ㹫ʽΪ: +S=A*K=K*h*tr +A=߼ֵ +h=(ߵֵ-׼ֵ) +tr=ʱ() +K=궨ϵ + +㹫ʽΪ: +S=A*K=K*1.064*h*(y/2)=1.064*K*h*h/4 +A=1.064*h*(y/2)=1.064*h*h/4 +y/2= +h==ߵ- +y/2=h/2 +߶ʽ +H'=Kx(H-С߶)*tr+Ũֵ +HΪĸ߶ + +//ʽ: +S'=Kx(S-С)+Ũֵ +KxΪK1-K12еһϵ,SΪԭʼݼ +KxͨSСλòKxļ +СΪkx_fac4,KxΪkx_fac1,ŨֵΪkx_fac2 +*/ + +#define MIN_SLOPE 1 +#define ANALYSIS_MESSAGE_SIZE 1024 +#define ANALYSIS_MAX_MESSAGE 8 +#define ANALYSIS_MQ_PRIO 30 +#define ANALYSIS_MQ "/analysis_mq" + +#define MAX_DATA_LEN 5000 + +mqd_t analysis_mq;// +char analysis_buf[ANALYSIS_MESSAGE_SIZE]; + +int slope_data[MAX_DATA_LEN]; + +int filter_data[MAX_DATA_LEN]; + +int raw_data_buf[MAX_DATA_LEN]; + +/* +1.бʼ㶥 +2.һδҵ,ֵ +3.ǰδҳ,趨IJ +*/ + +//͵ۼӺ +int cal_int_sum(int *buf,int len) +{ + int sum=0; + int i; + if(buf==NULL) + return 0; + for(i=0;i>fac); + } +} + + + +//ֵ,ֵλ +int find_max_val(int *buf,int len,int *val) +{ + int i; + int max_val,max_pos; + max_val=buf[0]; + max_pos=0; + + for(i=0;imax_val) + { + max_val=buf[i]; + max_pos=i; + } + } + if(val!=NULL) + *val=max_val; + return max_pos; +} +//time():974943297 +//time()->localtime()->mktime():974943297 +int find_max_val_ex(int *buf,int len,int *val) +{ + int i; + int max_val,max_pos; + + max_val=buf[0]; + max_pos=0; + for(i=0;i=max_val) + { + max_val=buf[i]; + max_pos=i; + } + } + if(val!=NULL) + *val=max_val; + return max_pos; +} + +//ref_val᷵һֵ +void process_data(int *raw_data,int len,int *ref_val) +{ + static float proc_data[MAX_DATA_LEN]; + float start_val,end_val,delt_y; + float offs; + int i; + + + for(i=0;i0) + //{ + for(i=0;i=0;i-=(BACK_SUM_NUM/2)) + { + curr=cal_int_sum(&buf[i],BACK_SUM_NUM); + if(curr<=(top_end_val+2)) + { + top_end_val=curr; + top_end_pos=i+(BACK_SUM_NUM/2); + } + else + { + //printf("i=%d top_end_pos=%d\n",i,top_end_pos); + break; + } + } + max_pos=find_max_val(buf,top_end_pos,NULL); + //printf("max_pos=%d\n",max_pos); + return max_pos; +}*/ + + +//ۼӺ,λ,sum_numΪۼӵĵ, +int find_max_sum(int *buf,int len,int sum_num,int delt) +{ + int i,result; + int curr_sum,max_sum; + + max_sum=cal_int_sum(buf,sum_num); + result=0; + for(i=sum_num;imax_sum) + { + max_sum=curr_sum; + result=i; + } + } + result+=find_max_val(&buf[result],sum_num,NULL); + return result; +} + + +/* +//С +int find_min_sum(int *buf,int len,int sum_num,int delt) +{ + int i,result; + int curr_sum,min_sum; + + min_sum=cal_int_sum(&buf[len-1],sum_num); + result=len-1; + for(i=len-sum_num-1;i>0;i-=sum_num) + { + curr_sum=cal_int_sum(&buf[i-sum_num],sum_num); + if(curr_sum(pre_sum+delt)) + { + //printf("arrived 1\n"); + if((cal_int_sum(&buf[i+sum_num],sum_num)+delt)=contine_cnt) + { + *ret=(i+(forward_cnt/2)); + return 0; + } + } + return -2; +} + +//,(i㵽i+per_widthƽֵ) +//(i+tot_widthi+tot_width+per_widthƽֵ) +//Ƚ,Ƚ3,ÿȽһƶmov_width +int FindLeftPosEx(int *buf,int len,int tot_width,int per_width,int mov_width,int min_slope) +{ + int i,n,result; + int avr_val1[3],avr_val2[3]; + result=-1; + if(len<=(tot_width+4*mov_width+per_width)) + return -1; + for(n=0;n<(len-tot_width-4*mov_width-per_width);n++) + { + for(i=0;i<(sizeof(avr_val1)/sizeof(int));i++) + { + avr_val1[i]=cal_int_avr(&buf[n+i*mov_width],per_width); + avr_val2[i]=cal_int_avr(&buf[n+i*mov_width+tot_width],per_width); + } + if(avr_val1[2]gas_cal_fac[i].position.start; + //㶥λ + //end_pos=para_ptr->gas_cal_fac[i].position.peak+para_ptr->gas_cal_fac[i].position.width; + end_pos=para_ptr->gas_cal_fac[i].position.end; + + //printf("start_pos=%d\n",start_pos); + + while(start_poscal_int_sum(&buf[start_pos+SUM_NUM],SUM_NUM)) + { + start_pos+=2; + } + else + { + break; + } + } + + + if((start_pos+5+8)gas_cal_fac[i].gradient.lYmin; + //,5,1͵8 + if(FindLeftPos(data_stream,end_pos-start_pos,5,8,min_slope,&str_pos)==0) + { + FindMaxPos(data_stream+str_pos,end_pos-start_pos-str_pos,NULL,NULL,&peak_pos); + left_pos=start_pos+str_pos; + top_pos=left_pos+peak_pos; + //if(top_pos>(left_pos+MIN_LEN)) + //{ + left_val=*(buf+left_pos); + top_val=*(buf+top_pos); + // if((left_val+MIN_AMP)(start_pos+MIN_LEN)) + { + if(cal_int_sum(&buf[end_pos-(SUM_NUM/2)],SUM_NUM)>cal_int_sum(&buf[end_pos-SUM_NUM],SUM_NUM)) + { + end_pos-=2; + mov_tick++; + } + else + { + LOG_DEBUG(TRACE_DEBUG,"find pos%d in 2st\n",i); + if(mov_tick>10) + { + left_pos=end_pos; + ret|=(1<gas_cal_fac[i].position.start; + top_pos=para_ptr->gas_cal_fac[i].position.peak; + } + else + { + left_pos=start_pos; + top_pos=left_pos; + } + } + if(pos_data!=NULL) + { + pos_data->position[i].start=left_pos; + pos_data->position[i].peak=top_pos; + } + } + return ret; +} + +int find_key_pos2(int *buf,int len,YSP_PARA *para_ptr,FIND_POS_DATA *pos_data) +{ + int ret=0; + int i; + int *curr_ptr; + int min_slope;//Сݶ + int start_pos,end_pos;//趨ʼλúͽλ + int pos_start,pos_peak;//ҵͶλ + int start_val,peak_val;//ҵֵͶֵ + for(i=INDEX_H2;i<=INDEX_C2H2;i++) + { + start_pos=para_ptr->gas_cal_fac[i].position.start; + end_pos=para_ptr->gas_cal_fac[i].position.end; + min_slope=(int)para_ptr->gas_cal_fac[i].gradient.lYmin; + while(start_poscal_int_sum(&buf[start_pos+(SUM_NUM/2)],SUM_NUM)) + { + start_pos+=2; + } + else + { + break; + } + } + if(start_pos0) + { + //ҵ + //Ҷ + FindMaxPos(curr_ptr+pos_start,end_pos-start_pos-pos_start,¶_ptr->gas_cal_fac[i].gradient,NULL,&pos_peak); + pos_start+=start_pos; + pos_peak+=pos_start; + if(pos_peak>(pos_start+MIN_LEN))//жͶĿ + { + start_val=*(buf+pos_start); + peak_val=*(buf+pos_peak); + if((start_val+MIN_AMP)position[i].start=pos_start; + pos_data->position[i].peak=pos_peak; + } + } + + return ret; +} + + +// +int find_left_pos_ex(int *buf,int len,int sum_num,int delt) +{ + int i,result; + int start_sum,curr_sum; + + start_sum=cal_int_sum(&buf[len-sum_num-1],sum_num);//ұߵĵ + + result=len-sum_num-1; + + for(i=len-sum_num-1;i>0;i-=sum_num) + { + curr_sum=cal_int_sum(&buf[i-sum_num],sum_num); // + if((curr_sum+delt)>start_sum) + { + if((cal_int_sum(&buf[i-2*sum_num],sum_num)+delt)>=cal_int_sum(&buf[i-sum_num],sum_num)) + { + if((cal_int_sum(&buf[i-3*sum_num],sum_num)+delt)>=cal_int_sum(&buf[i-2*sum_num],sum_num)) + { + if((cal_int_sum(&buf[i-4*sum_num],sum_num)+delt)>=cal_int_sum(&buf[i-3*sum_num],sum_num)) + { + //if((cal_int_sum(&buf[i-5*sum_num],sum_num)+delt)>cal_int_sum(&buf[i-4*sum_num],sum_num)) + // { + result=len-i; + break; + // } + } + } + } + } + start_sum=curr_sum; + } + return result; +} + + + +int find_key_pos(int *buf,int len,YSP_PARA *para_ptr,FIND_POS_DATA *pos_data) +{ + int i,n,*data_stream; + int start_pos,end_pos; + int left_pos,top_pos,right_pos; + int ret=0; + int top_val,left_val; + int top_flg=0,left_flg=0; + +// #ifdef DEBUG_ANALYSIS + int str_pos,peak_pos; + //#endif + for(i=INDEX_H2;i<=INDEX_C2H2;i++) + { + //1.Ҷ + //㶥ʼλ + start_pos=para_ptr->gas_cal_fac[i].position.start; + //㶥λ + //end_pos=para_ptr->gas_cal_fac[i].position.peak+para_ptr->gas_cal_fac[i].position.width; + end_pos=para_ptr->gas_cal_fac[i].position.end; + + //printf("start_pos=%d\n",start_pos); + + while(start_poscal_int_sum(&buf[start_pos+SUM_NUM],SUM_NUM)) + { + start_pos+=2; + } + else + { + break; + } + } + + data_stream=buf+start_pos;// + //ȡλ + //if(i==INDEX_C2H4) + if(find_top_pos(data_stream,end_pos-start_pos,&(para_ptr->gas_cal_fac[i].gradient),&str_pos,&peak_pos)>0) + { + //top_val=data_stream[peak_pos]; + top_pos=peak_pos+start_pos;// + + top_val=top_pos-para_ptr->gas_cal_fac[i].position.width; + + data_stream=buf+top_val; + + top_pos=top_val+find_max_val(data_stream,para_ptr->gas_cal_fac[i].position.width+8,NULL); + top_val=buf[top_pos]; + top_flg|=(1<gas_cal_fac[i].position.peak-(para_ptr->gas_cal_fac[i].position.width/2); + end_pos=start_pos+para_ptr->gas_cal_fac[i].position.width; + + data_stream=buf+start_pos;// + top_pos=find_max_val(data_stream,end_pos-start_pos,NULL);//Ҷ + top_val=data_stream[top_pos]; + if(top_pos!=0) + { + if((top_val-data_stream[0])>MIN_AMP)//˴Ҫ + { + //ҵֵ + top_pos+=start_pos; + top_flg|=(1<gas_cal_fac[i].position.start; + //printf("top=%d sta=%d 2\n",top_val,data_stream[0]); + } + } + else + { + //δȷǷҵֵ,,ҪҲǷ½ + if(cal_int_avr(data_stream,4)>cal_int_avr(&data_stream[4],4)) + { + if(cal_int_avr(&data_stream[4],4)>cal_int_avr(&data_stream[8],4)) + { + if(cal_int_avr(&data_stream[8],4)>cal_int_avr(&data_stream[12],4)) + { + //ҵ˶ + top_pos+=start_pos; + top_flg|=(1<gas_cal_fac[i].position.start; + } + } + else + { + //δҵ + top_pos=para_ptr->gas_cal_fac[i].position.start; + } + } + else + { //δҵ + top_pos=para_ptr->gas_cal_fac[i].position.start; + } + } + } + + if(i==INDEX_CO||i==INDEX_CH4) + { + if((top_flg&(1<gas_cal_fac[i].position.peak; + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"warning:can not find top pos,use default peak_pos=%d index=%d\n",top_pos,i); + } + } + + //2. + if((top_flg&(1<gas_cal_fac[i].position.start;//ȡʼ± + data_stream=buf+start_pos;//ƫƵַ + end_pos=top_pos;//λΪ + if(find_left_pos(data_stream,end_pos-start_pos,SUM_NUM,(int)para_ptr->gas_cal_fac[i].gradient.lYmin,&left_pos)==0) + { + //ҵ + left_val=data_stream[left_pos]; + left_pos+=start_pos; + left_flg|=(1<=top_pos)) + { + LOG_DEBUG(ANALYSIS_EEROR_DEBUG,"error:left_val=%d top_val=%d index=%d\n",left_val,top_val,i); + ret&=(~(1<position[i].start=left_pos; + pos_data->position[i].peak=top_pos; + } + return ret; +} + + +/* +int find_left_start(int *buf,int len,GRADIENT_TYPE_DEF *para_ptr,int *str,int *peak) +{ + int i,n; + int area[JUDGE_NUM]; + int k[JUDGE_NUM]; + int avr[JUDGE_NUM]; + int str_pos=0; + int peak_pos=0; + int tmp; + int find_flg=0; + + for(n=0;n=k[n+1]) + { + break; + } + } + //printf("\n"); + //Ҳpara_ptr->lYmin; + if(n>=(JUDGE_NUM-2)) + { + if((k[0]>=0)&&k[1]>0&&k[2]>0&&k[3]>0&&k[4]>0) + { + //ҵ + if(find_flg==0) + { + str_pos=i-JUDGE_NUM*MOVE_NUM; + //printf("str_pos=%d ",str_pos); + find_flg=1; + if(str!=NULL) + *str=str_pos; + } + } + } + + //Ҷ + if(find_flg!=0) + { + for(n=(JUDGE_NUM-1);n>=0;n--) + { + if(k[n]>=0) + { + break; + } + } + if(n<1) + { + //ҵ + tmp=i-((JUDGE_NUM-n)*MOVE_NUM); + if(peak_pos==0) + { + peak_pos=tmp; + if(peak!=NULL) + *peak=peak_pos; + //printf("top_pos=%d\n",peak_pos); + } + } + } + // + for(n=0;n<(JUDGE_NUM-1);n++) + { + area[n]=area[n+1]; + k[n]=k[n+1]; + avr[n]=avr[n+1]; + } + area[n]=cal_int_sum(&buf[i],SUM_NUM);//ƶһ + avr[n]=area[n]/SUM_NUM;//ƽֵƶһ + //k[n]=avr[n]-avr[n-1];//ƽֵбƶһ + k[n]=area[n]-area[n-1];//ƽֵбƶһ + } +}*/ + +int find_top_pos(int *buf,int len,GRADIENT_TYPE_DEF *para_ptr,int *str,int *peak) +{ + int i,n; + int area[JUDGE_NUM]; + int k[JUDGE_NUM]; + int avr[JUDGE_NUM]; + int find_pos[JUDGE_NUM]; + //int find_val[JUDGE_NUM]; + int str_pos=0; + int peak_pos=0; + int left_flg,right_flg; + int tmp; + int find_num=0; + int pre_k=0,curr_k=0; + + //жJUDGE_NUM,ÿΪSUM_NUMƽ + for(n=0;n=(JUDGE_NUM/2)) + { //ҰݶȫС + + + //ݶСĵ + left_flg=0; + for(n=0;n<(JUDGE_NUM/2);n++) + { + if(k[n]>0) + left_flg++; + } + + + if(left_flg>=(JUDGE_NUM/2))//ݶȫ + { + //ҵ + find_pos[find_num]=i-((JUDGE_NUM+1)*MOVE_NUM/2); + curr_k=0; + for(tmp=0;tmp<(JUDGE_NUM/2);tmp++) + { + curr_k+=k[tmp];//ۼk + //printf("k%d=%d ",tmp,k[tmp]); + } + //printf("\n"); + find_num++; + if(curr_k>pre_k)//ҵ͵ + { + if(peak!=NULL) + { + *peak=i-((JUDGE_NUM+1)*MOVE_NUM/2); + } + pre_k=curr_k; + } + if(find_num>=JUDGE_NUM) + break; + } + } + } + + // + for(n=0;n<(JUDGE_NUM-1);n++) + { + area[n]=area[n+1]; + k[n]=k[n+1]; + avr[n]=avr[n+1]; + } + area[n]=cal_int_sum(&buf[i],SUM_NUM);//ƶһ + avr[n]=area[n]/SUM_NUM;//ƽֵƶһ + k[n]=avr[n]-avr[n-1];//ƽֵбƶһ + } + return find_num; +} + + +int find_top_pos_ex(int *buf,int len,GRADIENT_TYPE_DEF *para_ptr,int *str,int *peak,int tot_width,int per_width,int mov_width) +{ + int i,n; + int area[MAX_JUDGE_NUM]; + int k[MAX_JUDGE_NUM]; + int avr[MAX_JUDGE_NUM]; + int find_pos[MAX_JUDGE_NUM]; + //int find_val[JUDGE_NUM]; + int str_pos=0; + int peak_pos=0; + int left_flg,right_flg; + int tmp; + int find_num=0; + int pre_k=0,curr_k=0; + + int tot_judge_num; + + tot_judge_num=(tot_width-((per_width+1)/2))/mov_width; + if(tot_judge_numMAX_JUDGE_NUM) + { + tot_judge_num=MAX_JUDGE_NUM; + } + //жJUDGE_NUM,ÿΪSUM_NUMƽ + for(n=0;n=(tot_judge_num/2)) + { //ҰݶȫС + //ݶСĵ + left_flg=0; + for(n=0;n<(tot_judge_num/2);n++) + { + if(k[n]>0) + left_flg++; + } + + + if(left_flg>=(tot_judge_num/2))//ݶȫ + { + //ҵ + find_pos[find_num]=i-((tot_judge_num+1)*mov_width/2); + curr_k=0; + for(tmp=0;tmp<(tot_judge_num/2);tmp++) + { + curr_k+=k[tmp];//ۼk + //printf("k%d=%d ",tmp,k[tmp]); + } + //printf("\n"); + find_num++; + if(curr_k>pre_k)//ҵ͵ + { + if(peak!=NULL) + { + *peak=i-((tot_judge_num+1)*mov_width/2); + } + pre_k=curr_k; + } + if(find_num>=tot_judge_num) + break; + } + } + } + + // + for(n=0;n<(tot_judge_num-1);n++) + { + area[n]=area[n+1]; + k[n]=k[n+1]; + avr[n]=avr[n+1]; + } + area[n]=cal_int_sum(&buf[i],per_width);//ƶһ + avr[n]=area[n]/per_width;//ƽֵƶһ + k[n]=avr[n]-avr[n-1];//ƽֵбƶһ + } + return find_num; +} + +/* +int find_key_pos_ex(int *buf,int len,YSP_PARA *para_ptr,FIND_POS_DATA *pos_data) +{ + int i,n,*data_stream; + int start_pos,end_pos; + int left_pos,top_pos,right_pos; + int ret=0; + int top_val,left_val; + + for(i=INDEX_H2;i<=INDEX_C2H2;i++) + { + //1.Ҷ + //㶥ʼλ + start_pos=para_ptr->gas_cal_fac[i].position.start; + //㶥λ + end_pos=para_ptr->gas_cal_fac[i].position.end; + + while(start_poscal_int_sum(&buf[start_pos+SUM_NUM],SUM_NUM)) + { + start_pos+=4; + } + else + { + break; + } + } + //ȡλ + data_stream=buf+start_pos;// + top_pos=find_max_val(data_stream,end_pos-start_pos,NULL);//Ҷ + top_val=data_stream[top_pos]; + if(top_pos!=0) + { + //ҵֵ + top_pos+=start_pos; + } + else + { + //δȷǷҵֵ,,ҪҲǷ½ + top_pos+=start_pos; + } + + //2. + start_pos=para_ptr->gas_cal_fac[i].position.start;//ȡʼ± + data_stream=buf+start_pos;//ƫƵַ + end_pos=top_pos-(para_ptr->gas_cal_fac[i].position.width);//λΪ + + left_pos=find_left_pos(data_stream,end_pos-start_pos,SUM_NUM,(int)para_ptr->gas_cal_fac[i].gradient.lYmin); + //left_pos=find_left_pos_ex(data_stream,end_pos-start_pos,SUM_NUM,(int)para_ptr->gas_cal_fac[i].gradient.lYmin); + left_val=data_stream[left_pos]; + left_pos+=start_pos; + + if(top_val<=left_val) + { + LOG_DEBUG(ANALYSIS_EEROR_DEBUG,"error:left_val=%d top_val=%d index=%d\n",left_val,top_val,i); + } + pos_data->position[i].start=left_pos; + pos_data->position[i].peak=top_pos; + ret|=(1<data[i-1]&&data[i]>data[i+1]) + { + data[i]=(data[i-1]+data[i+1])/2; + } + } + } +} + +void avr_filter(int *data,unsigned int len,unsigned int smooth_num,int *out) +{ + unsigned int i,n; + int num; + num=smooth_num/2; + for(i=0;i<(len-smooth_num);i++) + { + out[i+num]=cal_int_avr(&data[i],smooth_num); + } + for(n=0;ncorrect_fac.k[i].fac[3];//С + max=gas_cal_fac->correct_fac.k[i].fac[4];// + if(((*raw_data)<=max)&&((*raw_data)>min)) + { + if(index_out!=NULL) + { + *index_out=i; + } + return &(gas_cal_fac->correct_fac.k[i]); + } + } + return NULL; +} + + +// +int cal_h(int *raw_data,int str_pos,int peak_pos,float *out_data,int *base_data) +{ + int h,base_val; + if(raw_data==NULL||out_data==NULL) + return -1; + + if(base_data!=NULL) + { + base_val=(*base_data); + } + else + { + base_val=raw_data[str_pos-1]; + } + h=raw_data[peak_pos]-base_val; + if(h<0) + h=0; + //printf("max=%d base=%d h=%d peak_pos=%d\n",raw_data[peak_pos],base_val,h,peak_pos); + //out=h*tr + //*out_data=((float)h*(peak_pos-str_pos+1)*(my_para_data.mach_run_para.sample_rate))/1000; + *out_data=(float)h;//((float)h*(peak_pos)*(my_para_data.mach_run_para.sample_rate))/100000; + return 0; +} + +int correct_h(float *raw_h,float *out_h,GAS_CAL_PARA *gas_cal_fac) +{ + float h=0; + int k_index=0; + FACTOR_TYPE *fac_ptr; + + if(gas_cal_fac==NULL||raw_h==NULL||out_h==NULL) + return -1; + //raw_hҴһKֵ,ȻʹøKֵ + if((fac_ptr=find_right_fac(raw_h,gas_cal_fac,&k_index))!=NULL) + { + //fac[0]=Kx + //fac[1]=Ũֵ + //fac[3]=С + h=(fac_ptr->fac[0])*((*raw_h)-(fac_ptr->fac[3]))+(fac_ptr->fac[1]); + if(out_h!=NULL) + { + *out_h=h; + } + return k_index; + } + return -2; +} + +// +int cal_area(int *raw_data,int str_pos,int peak_pos,float *out_area) +{ + float area=0; + int tmp=0; + int i; + int base_data; + if(raw_data==NULL||out_area==NULL) + return -1; + base_data=raw_data[str_pos];//ֵ + for(i=str_pos;ifac[0])*((*raw_area)-(fac_ptr->fac[3]))+(fac_ptr->fac[1]); + if(out_area!=NULL) + { + *out_area=area; + } + return k_index; + } + return -2; +} + + +int save_dumy_file(const char *file,long offs,int *ptr,unsigned int len) +{ + FILE *fp; + unsigned int i; + fp=fopen(file,"w"); + if(fp==NULL) + { + LOG_DEBUG(ERROR_DEBUG,"Creat file %s failed when savefile\r\n",file); + return -1; + } + if(offs!=0) + { + fseek(fp,offs,SEEK_SET); + } + for(i=0;iMAX_DATA_LEN) + len=MAX_DATA_LEN; + smooth_data(raw_data,len,1); //˲ȥ + + /* + avr_filter(raw_data,len,SUM_NUM,filter_data); + + ref_val=cal_int_avr(&filter_data[para_ptr->gas_cal_fac[INDEX_CH4].position.end],16); + for(i=para_ptr->gas_cal_fac[INDEX_CH4].position.end;igas_cal_fac[INDEX_C2H4].position.start;i++) + { + filter_data[i]=ref_val; + } + for(i=INDEX_C2H4;i<=INDEX_C2H2;i++) + { + printf("ref_val=%d start=%d start1=%d\n",ref_val,filter_data[para_ptr->gas_cal_fac[i].position.start],filter_data[para_ptr->gas_cal_fac[i].position.start-1]); + process_data(&filter_data[para_ptr->gas_cal_fac[i].position.start],(para_ptr->gas_cal_fac[i].position.end)-(para_ptr->gas_cal_fac[i].position.start)+1,&ref_val); + if(i!=INDEX_C2H2) + { + for(n=para_ptr->gas_cal_fac[i].position.end;ngas_cal_fac[i+1].position.start;n++) + { + filter_data[n]=filter_data[n-1]; + } + } + else + { + for(n=para_ptr->gas_cal_fac[i].position.end;ngas_cal_fac[i].position.end-1]; + } + */ + + //ref_val=cal_int_avr(&raw_data[para_ptr->gas_cal_fac[INDEX_CH4].position.end],16); + //ref_val=&raw_data[para_ptr->gas_cal_fac[INDEX_C2H4].position.start]; + //for(i=para_ptr->gas_cal_fac[INDEX_CH4].position.end;igas_cal_fac[INDEX_C2H4].position.start;i++) + //{ + // raw_data[i]=ref_val; + // } + ref_val=raw_data[para_ptr->gas_cal_fac[INDEX_C2H4].position.start]; + for(i=INDEX_C2H4;i<=INDEX_C2H2;i++) + { + segment_len=(para_ptr->gas_cal_fac[i].position.end)-(para_ptr->gas_cal_fac[i].position.start)+1; + + //ƽƶ(ֵ-ref_val) + process_data(&raw_data[para_ptr->gas_cal_fac[i].position.start],segment_len,&ref_val); + //ref_val洢һֵ + if(i!=INDEX_C2H2) + { + for(n=para_ptr->gas_cal_fac[i].position.end;ngas_cal_fac[i+1].position.start;n++) + { + raw_data[n]=raw_data[n-1]; + } + } + else + {//ƽһ + for(n=para_ptr->gas_cal_fac[i].position.end;nfind_mask=find_mask; + for(i=INDEX_H2;i<=INDEX_C2H2;i++) + { + str_pos[i]=pos_data->position[i].start; + peak_pos[i]=pos_data->position[i].peak; + ana_rlt->pos_info[i].start=str_pos[i]; + ana_rlt->pos_info[i].peak=peak_pos[i]; + } + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"find_mask=%d,now start cal ysp data\n",find_mask); + + // + if((find_mask&(1<area[INDEX_H2]=tmp; + k_index=correct_h(&tmp,&ana_rlt->result.H2ppm,¶_ptr->gas_cal_fac[INDEX_H2]); + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"H2_corect=%f k_index=%d kx=%f min_area=%f min_ppm=%f\n",ana_rlt->result.H2ppm,k_index,para_ptr->gas_cal_fac[INDEX_H2].correct_fac.k[k_index].fac[0],para_ptr->gas_cal_fac[INDEX_H2].correct_fac.k[k_index].fac[3],para_ptr->gas_cal_fac[INDEX_H2].correct_fac.k[k_index].fac[1]); + } + else + { + //cal_h(raw_data,str_pos[INDEX_H2],peak_pos[INDEX_H2],&tmp,NULL); + tmp=0; + ana_rlt->area[INDEX_H2]=tmp; + ana_rlt->result.H2ppm=0; + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"H2_start=%d H2_peak=%d H2_amp=%f\n",str_pos[INDEX_H2],peak_pos[INDEX_H2],tmp); + } + + //һ̼ʹͬһ + if((find_mask&(1<area[INDEX_CO]=tmp; + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"CO_start=%d CO_peak=%d CO_amp=%f\n",str_pos[INDEX_CO],peak_pos[INDEX_CO],tmp); + k_index=correct_h(&tmp,&ana_rlt->result.COppm,¶_ptr->gas_cal_fac[INDEX_CO]); + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"CO_corect=%f k_index=%d kx=%f min_area=%f min_ppm=%f\n",ana_rlt->result.COppm,k_index,para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[0],para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[3],para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[1]); + } + else + { + /* + tmp=0; + ana_rlt->area[INDEX_CO]=tmp; + ana_rlt->result.COppm=0; + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"CO_start=%d CO_peak=%d CO_amp=%f\n",str_pos[INDEX_CO],peak_pos[INDEX_CO],tmp); + */ + base_val=raw_data[str_pos[INDEX_H2]-1]; + cal_h(raw_data,para_ptr->gas_cal_fac[INDEX_CO].position.start,para_ptr->gas_cal_fac[INDEX_CO].position.peak,&tmp,&base_val); + ana_rlt->area[INDEX_CO]=tmp; + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"use dfault postion para:CO_start=%d CO_peak=%d CO_amp=%f\n",para_ptr->gas_cal_fac[INDEX_CO].position.start,para_ptr->gas_cal_fac[INDEX_CO].position.peak,tmp); + k_index=correct_h(&tmp,&ana_rlt->result.COppm,¶_ptr->gas_cal_fac[INDEX_CO]); + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"CO_corect=%f k_index=%d kx=%f min_area=%f min_ppm=%f\n",ana_rlt->result.COppm,k_index,para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[0],para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[3],para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[1]); + } + + if((find_mask&(1<area[INDEX_CH4]=tmp; + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"CH4_start=%d CH4_peak=%d CH4_amp=%f\n",str_pos[INDEX_CH4],peak_pos[INDEX_CH4],tmp); + k_index=correct_h(&tmp,&ana_rlt->result.CH4ppm,¶_ptr->gas_cal_fac[INDEX_CH4]); + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"CH4_corect=%f k_index=%d kx=%f min_area=%f min_ppm=%f\n",ana_rlt->result.CH4ppm,k_index,para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[0],para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[3],para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[1]); + } + else + { + tmp=0; + ana_rlt->area[INDEX_CH4]=tmp; + ana_rlt->result.CH4ppm=0; + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"CH4_start=%d CH4_peak=%d CH4_amp=%f\n",str_pos[INDEX_CH4],peak_pos[INDEX_CH4],tmp); + } + + if((find_mask&(1<area[INDEX_C2H4]=tmp; + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H4_start=%d C2H4_peak=%d C2H4_amp=%f\n",str_pos[INDEX_C2H4],peak_pos[INDEX_C2H4],tmp); + k_index=correct_area(&tmp,&ana_rlt->result.C2H4ppm,¶_ptr->gas_cal_fac[INDEX_C2H4]); + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H4_corect=%f k_index=%d kx=%f min_area=%f min_ppm=%f\n",ana_rlt->result.C2H4ppm,k_index,para_ptr->gas_cal_fac[INDEX_C2H4].correct_fac.k[k_index].fac[0],para_ptr->gas_cal_fac[INDEX_C2H4].correct_fac.k[k_index].fac[3],para_ptr->gas_cal_fac[INDEX_C2H4].correct_fac.k[k_index].fac[1]); + } + else + { + tmp=0; + ana_rlt->area[INDEX_C2H4]=tmp; + ana_rlt->result.C2H4ppm=0; + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H4_start=%d C2H4_peak=%d C2H4_amp=%f\n",str_pos[INDEX_C2H4],peak_pos[INDEX_C2H4],tmp); + } + + if((find_mask&(1<area[INDEX_C2H6]=tmp; + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H6_start=%d C2H6_peak=%d C2H6_amp=%f\n",str_pos[INDEX_C2H6],peak_pos[INDEX_C2H6],tmp); + k_index=correct_area(&tmp,&ana_rlt->result.C2H6ppm,¶_ptr->gas_cal_fac[INDEX_C2H6]); + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H6_corect=%f k_index=%d kx=%f min_area=%f min_ppm=%f\n",ana_rlt->result.C2H6ppm,k_index,para_ptr->gas_cal_fac[INDEX_C2H6].correct_fac.k[k_index].fac[0],para_ptr->gas_cal_fac[INDEX_C2H6].correct_fac.k[k_index].fac[3],para_ptr->gas_cal_fac[INDEX_C2H6].correct_fac.k[k_index].fac[1]); + } + else + { + tmp=0; + ana_rlt->area[INDEX_C2H6]=tmp; + ana_rlt->result.C2H6ppm=0; + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H6_start=%d C2H6_peak=%d C2H6_amp=%f\n",str_pos[INDEX_C2H6],peak_pos[INDEX_C2H6],tmp); + } + + //ԭʼtmp + if((find_mask&(1<area[INDEX_C2H2]=tmp; + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H2_start=%d C2H2_peak=%d C2H2_amp=%f\n",str_pos[INDEX_C2H2],peak_pos[INDEX_C2H2],tmp); + //tmp&out_data->C2H2ppm + k_index=correct_area(&tmp,&ana_rlt->result.C2H2ppm,¶_ptr->gas_cal_fac[INDEX_C2H2]); + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H2_corect=%f k_index=%d kx=%f min_area=%f min_ppm=%f\n",ana_rlt->result.C2H2ppm,k_index,para_ptr->gas_cal_fac[INDEX_C2H2].correct_fac.k[k_index].fac[0],para_ptr->gas_cal_fac[INDEX_C2H2].correct_fac.k[k_index].fac[3],para_ptr->gas_cal_fac[INDEX_C2H2].correct_fac.k[k_index].fac[1]); + } + else + { + tmp=0; + ana_rlt->area[INDEX_C2H2]=tmp; + ana_rlt->result.C2H2ppm=0; + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H2_start=%d C2H2_peak=%d C2H2_amp=%f\n",str_pos[INDEX_C2H2],peak_pos[INDEX_C2H2],tmp); + } + ana_rlt->result.TotHyd=(ana_rlt->result.CH4ppm)+(ana_rlt->result.C2H4ppm)+(ana_rlt->result.C2H6ppm)+(ana_rlt->result.C2H2ppm); + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"h2=%fppm co=%fppm ch4=%fppm\n",ana_rlt->result.H2ppm,ana_rlt->result.COppm,ana_rlt->result.CH4ppm); + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"c2h4=%fppm c2h6=%fppm c2h2=%fppm\n",ana_rlt->result.C2H4ppm,ana_rlt->result.C2H6ppm,ana_rlt->result.C2H2ppm); + //if(co2_is_ok) + // { + ana_rlt->result.CO2ppm=last_co2_ppm; + // } +// else + // { + // ana_rlt->result.CO2ppm=0; + // } + ret=0; + return ret; +} +/* +int analysis_co2(unsigned short *buf,unsigned int buf_len,float *result) +{ + int i; + int max_pos=0; + int start_pos=0; + unsigned short max=0; + unsigned int sum=0; + int find_flg=0; + int large_cnt=0; + int less_cnt=0; + float ppm; + // + for(i=0;i<(buf_len-5);i++) + { + if(buf[i]max) + { //ߵ + max=buf[i]; + max_pos=i; + large_cnt++; + less_cnt=0; + } + if(buf[i]=4) + { + if(large_cnt>=4) + { + find_flg=2; + break; + } + } + } + } + if(find_flg==2) + { + sum=0; + for(i=start_pos;i<=max_pos;i++) + { + sum+=(buf[i]-buf[start_pos]); + } + ppm=(float)2*sum; + LOG_DEBUG(TRACE_DEBUG,"co2_start_pos=%d co2_peak_pos=%d co2_area=%f\n",start_pos,max_pos,ppm); + if(correct_area(&ppm,&ppm,&my_para_data.co2_cal_fac)==0) + { + if(result!=NULL) + *result=ppm; + LOG_DEBUG(TRACE_DEBUG,"co2_ppm=%f\n",ppm); + return 0; + } + else + { + LOG_DEBUG(ERROR_DEBUG,"can't find co2 cal fac\n"); + if(result!=NULL) + *result=0; + return -3; + } + } + else + { + LOG_DEBUG(ERROR_DEBUG,"can't find co2 peak pos\n"); + if(result!=NULL) + *result=0; + return -1; + } + } + else + { + LOG_DEBUG(ERROR_DEBUG,"can't find co2 start pos\n"); + if(result!=NULL) + *result=0; + } + return -2; +}*/ +int analysis_co2(unsigned short *buf,unsigned int buf_len,float *result) +{ + int i; + int max_pos=0; + int start_pos=0; + unsigned short max=0; + unsigned int sum=0; + int find_flg=0; + int large_cnt=0; + int less_cnt=0; + float ppm; + // + for(i=0;i<(buf_len-5);i++) + { + if(buf[i](buf[i+2]-buf[i])) + { + start_pos=i; + find_flg=1; + break; + } + } + } + } + } + + if(find_flg) + { + //ߵ + max=buf[start_pos]; + large_cnt=0; + for(i=(start_pos+1);imax) + { //ߵ + max=buf[i]; + max_pos=i; + large_cnt++; + less_cnt=0; + } + else if(buf[i]<=max) + { + less_cnt++; + if(less_cnt>=2) + { + if(large_cnt>=2) + { + find_flg=2; + break; + } + } + } + } + if(find_flg==2) + { + sum=0; + for(i=start_pos;i<=max_pos;i++) + { + sum+=(buf[i]-buf[start_pos]); + } + ppm=(float)2*sum; + LOG_DEBUG(TRACE_DEBUG,"co2_start_pos=%d co2_peak_pos=%d co2_area=%f\n",start_pos,max_pos,ppm); + if(correct_area(&ppm,&ppm,&my_para_data.co2_cal_fac)==0) + { + if(result!=NULL) + *result=ppm; + LOG_DEBUG(TRACE_DEBUG,"co2_ppm=%f\n",ppm); + return 0; + } + else + { + LOG_DEBUG(ERROR_DEBUG,"can't find co2 cal fac\n"); + if(result!=NULL) + *result=0; + return -3; + } + } + else + { + LOG_DEBUG(ERROR_DEBUG,"can't find co2 peak pos\n"); + if(result!=NULL) + { + ppm=(float)buf[buf_len/2]; + if(correct_area(&ppm,&ppm,&my_para_data.co2_cal_fac)==0) + { + *result=ppm; + } + else + { + *result=0; + } + } + + return -1; + } + } + else + { + LOG_DEBUG(ERROR_DEBUG,"can't find co2 start pos\n"); + if(result!=NULL) + { + ppm=(float)buf[buf_len/2]; + if(correct_area(&ppm,&ppm,&my_para_data.co2_cal_fac)==0) + { + *result=ppm; + } + else + { + *result=0; + } + } + } + return -2; +} + +/* +//csvļȡ +int read_float_csv(const char *fname,float *buf,int len) +{ + FILE *stream; + int i; + stream=fopen(fname,"r"); + if(stream==NULL) + return -1; + for(i=0;i0) + tmp_len=len; + else + tmp_len=para_ptr->mach_run_para.sample_len; + if((act_len=read_int_raw(file_name,raw_data_buf,tmp_len))<=0)//ȡ + { + LOG_DEBUG(ERROR_DEBUG,"read_int_raw failed\n"); + return -1; + } + ana_rlt->result.SmpTm=time(NULL); + //out_data->SmpTm=time(NULL); + return analysis_data(raw_data_buf,act_len,para_ptr,ana_rlt);// +} + + +/* +//󲨹,k=0,ұk>0,ճһk<0,ұk>0 +//ۺk<=0,ұk>0,Ϊб +int lfind_slope_trough(float *data,unsigned int len,unsigned int *pos,unsigned int pos_num) +{ + unsigned int i; + unsigned int find_pos; + unsigned int find_index=0; + for(i=0;i<(len-6);i++) + { + if(data[i]<=0&&data[i+1]<=0&&data[i+2]<=0) //<=0 + { + if(data[i+3]>0&&data[i+4]>0&&data[i+5]>=0)//ұ0 + { + find_pos=i+2; + pos[find_index++]=find_pos; + if(find_index>=pos_num) + break; + } + } + } + return find_index; +} + + + +//ҲͶ +int find_increase_start(float *data,int len,int judge_num,int *str_pos,int *endpos) +{ + int i; + int meet_lcnt=0,meet_rcnt=0; + int start_pos=-1,end_pos=-1; + for(i=0;iMIN_SLOPE)// + { + meet_rcnt=0; + meet_lcnt++; + if(meet_lcnt>=judge_num) + { + if((-1)==start_pos) + { + start_pos=i-judge_num;// + *str_pos=start_pos; + } + } + } + else + { + meet_lcnt=0; + if(data[i]<=0)// + meet_rcnt++; + if((-1)!=start_pos) + { + if(meet_rcnt>=judge_num) + { + if((-1)==end_pos) + { + end_pos=i-judge_num;//֮½,жΪ + *endpos=end_pos; + return 0; + } + } + } + } + } + return -1; +} + + +//Ҳҹȵ,Ӷ㿪ʼ +//,kС0,;ճʱk<0,ͻȻ0 +//k<-MIN_SLOPE,ұk>=0; +int find_decrease_start(float *data,int len,int judge_num,int *str_pos,int *endpos) +{ + int i; + int meet_lcnt=0,meet_rcnt=0; + int start_pos=-1,end_pos=-1; + for(i=0;i=judge_num) + { + if((-1)==start_pos) + { + start_pos=i-judge_num;// + *str_pos=start_pos; + } + } + } + else + { + meet_lcnt=0; + if(data[i]<=0) + meet_rcnt++; + if((-1)!=start_pos) + { + if(meet_rcnt>=judge_num) + { + if((-1)==end_pos) + { + end_pos=i-judge_num;//յ + *endpos=end_pos; + return 0; + } + } + } + } + } + return -1; +}*/ + + + +/* +//жϲǷ,ͨ岨Ƿճж,Ϊб +int data_distinguish_type(float *data,unsigned int len,unsigned int judge_num) +{ + int i; + int last_slope=0,curr_slope=0; + for(i=0;iMIN_SLOPE&&data[i+1]>MIN_SLOPE) + { + if(data[i+2]>MIN_SLOPE&&data[i+3]>MIN_SLOPE) + { + curr_slope=1; + if(curr_slope!=last_slope) + { + // + } + } + } + } +} + + + + +//Ҳ߽ +//>0,ұСڵ0,Ϊб +int find_peak_lboundary(float *data,unsigned int len,unsigned int *pos) +{ + unsigned int i; + for(i=3;i<(len-1);i++) + { + if((data[i]<=0)&&data[i-1]>0&&data[i-2]>0&&data[i-3]>0) + { + if(data[i+1]<=0) + { + if(pos!=NULL) + *pos=i; + return i; + } + } + } + return -1; +} + +//Ҳұ߽ +//>=0,ұ<0,Ϊб +int find_peak_rboundary(float *data,unsigned int len,unsigned int *pos) +{ + unsigned int i; + for(i=3;i<(len-1);i++) + { + if((data[i]<0)&&data[i-1]>=0&&data[i-2]>=0&&data[i-3]>=0) + { + if(data[i+1]<0) + { + if(pos!=NULL) + *pos=i; + return i; + } + } + } + return -1; +}*/ + + + + + +//Ҳ,k<0,ұk=0,ճһk<0,ұk>0 +//ۺk<0,ұk>=0 +int rfind_slope_trough(float *data,unsigned int len,unsigned int *pos,unsigned int pos_num,unsigned int *lpos) +{ + unsigned int i; + unsigned int find_pos; + unsigned int find_index=0; + for(i=0;i<(len-6);i++) + { + if(data[i]<0&&data[i+1]<0&&data[i+2]<0) //<=0 + { + if(data[i+3]>=0&&data[i+4]>=0&&data[i+5]>=0)//ұ0 + { + find_pos=i+2; + if(lpos!=NULL) + { + if(find_pos<=lpos[find_index]) + continue; + } + pos[find_index++]=find_pos; + if(find_index>=pos_num) + break; + } + } + } + return find_index; +} + +/* +int find_key_points(float *raw_data,unsigned int len,void *key_points) +{ + unsigned int lrough_pos[6]; //󲨹 + unsigned int rrough_pos[6]; //Ҳ + unsigned int peak_pos[6]; // + + smooth_data(raw_data,len,1); //˲ȥ + cal_slope(raw_data,slope_data,len);//б + //lfind_slope_trough(slope_data,len,lrough_pos,6);//󲨹 + //rfind_slope_trough(slope_data,len,rrough_pos,6);//Ҳ + //ҵλú趨IJȽ, + //ڲҵλмҲ + return 0; +}*/ + +int save_last_result(ANALY_RESULT *pri_data) +{ + FILE *fp; + if(pri_data==NULL) + return -1; + fp=fopen("last.dat","w"); + if(fp==NULL) + return -2; + if(fwrite((const void *)pri_data,sizeof(ANALY_RESULT),1,fp)!=1) + { + fclose(fp); + return -3; + } + fclose(fp); + return 0; +} + +int load_last_result(ANALY_RESULT *pri_data) +{ + FILE *fp; + if(pri_data==NULL) + return -1; + fp=fopen("last.dat","r"); + if(fp==NULL) + return -2; + if(fread((void *)pri_data,sizeof(ANALY_RESULT),1,fp)!=1) + { + fclose(fp); + return -3; + } + fclose(fp); + return 0; +} + +/*,,,*/ +int save_analysis_file(char *file_name,int len,YSP_PARA *para_ptr,FIND_POS_DATA *pos_data,YSP_PRI_DATA *out_data) +{ + FILE *fp; + unsigned int i; + char *p; + char file[64]; + + if(file_name==NULL||para_ptr==NULL||pos_data==NULL||out_data==NULL) + return -1; + sprintf(file,"%s",file_name); + i=strlen(file); + if(i<3) + return -2; + //滻β׺ + sprintf(&file[i-3],"dat"); + fp=fopen(file,"w"); + if(fp==NULL) + { + LOG_DEBUG(ERROR_DEBUG,"Creat file %s failed when save_analysis_file\n",file); + return -1; + } + if(fwrite((const void *)para_ptr->mach_run_para.version,16,1,fp)!=1) + {//汾 + fclose(fp); + LOG_DEBUG(ERROR_DEBUG,"save version failed when save_analysis_file %s\n",file); + return -2; + } + if(fwrite((const void *)para_ptr->mach_run_para.station,64,1,fp)!=1) + { + //վ + fclose(fp); + LOG_DEBUG(ERROR_DEBUG,"save station failed when save_analysis_file %s\n",file); + return -3; + } + if(fwrite((const void *)para_ptr->mach_run_para.device,64,1,fp)!=1) + { + //豸 + fclose(fp); + LOG_DEBUG(ERROR_DEBUG,"save device failed when save_analysis_file %s\n",file); + return -4; + } + if(fwrite((const void *)&last_sample_time,4,1,fp)!=1) + {// + fclose(fp); + LOG_DEBUG(ERROR_DEBUG,"save sample date failed when save_analysis_file %s\n",file); + return -5; + } + if(fwrite((const void *)¶_ptr->mach_run_para.sample_len,4,1,fp)!=1) + {// + fclose(fp); + LOG_DEBUG(ERROR_DEBUG,"save sample_len failed when save_analysis_file %s\n",file); + return -6; + } + if(fwrite((const void *)¶_ptr->mach_run_para.sample_rate,4,1,fp)!=1) + {// + fclose(fp); + LOG_DEBUG(ERROR_DEBUG,"save sample_rate failed when save_analysis_file %s\n",file); + return -7; + } + for(i=0;i<6;i++) + { + if(fwrite((const void *)¶_ptr->gas_cal_fac[i],sizeof(GAS_CAL_PARA),1,fp)!=1) + {//ϵ + fclose(fp); + LOG_DEBUG(ERROR_DEBUG,"save cal fac failed when save_analysis_file %s\n",file); + return (-8-i); + } + } + if(fwrite((const void *)pos_data,sizeof(FIND_POS_DATA),1,fp)!=1) + {//ҵĹؼ + fclose(fp); + LOG_DEBUG(ERROR_DEBUG,"save pos data failed when save_analysis_file %s\n",file); + return -14; + } + if(fwrite((const void *)out_data,sizeof(YSP_PRI_DATA),1,fp)!=1) + {//Ľ + fclose(fp); + LOG_DEBUG(ERROR_DEBUG,"save result data failed when save_analysis_file %s\n",file); + return -14; + } +/* if(fwrite((const void *)out_data,sizeof(YSP_PRI_DATA),1,fp)!=1) + {//Ľ + fclose(fp); + LOG_DEBUG(ERROR_DEBUG,"save result data failed when save_analysis_file %s\n",file); + return -14; + }*/ + if(fseek(fp,RSV_SPACE_SIZE,SEEK_CUR)!=0) + { //ռ + fclose(fp); + LOG_DEBUG(ERROR_DEBUG,"fseek failed when save_analysis_file %s\n",file); + return -15; + } + if(fwrite((const void *)raw_data_buf,(para_ptr->mach_run_para.sample_len)*4,1,fp)!=1) + {// + fclose(fp); + LOG_DEBUG(ERROR_DEBUG,"save sample data failed when save_analysis_file %s\n",file); + return -16; + } + fclose(fp); + return 0; +} + +//߳,Լ߳ +void *analysis_routine(void *arg) +{ + YSP_PRI_DATA ysp_pri_data; + FIND_POS_DATA ysp_ana_pos; + ANALY_RESULT latest_ana_rlt; + float delt; + int i; + if((analysis_mq=create_mq(ANALYSIS_MQ,ANALYSIS_MAX_MESSAGE,ANALYSIS_MESSAGE_SIZE))<0) + { + LOG_DEBUG(ERROR_DEBUG,"create analysis message queue failed\n"); + exit(1); + } + if(load_last_result(&ana_result)==0) + { + send_ysp_msg(&ana_result.result); + } + else + { + LOG_DEBUG(ERROR_DEBUG,"load last history data failed\n"); + } + while(1) + { + if(recv_mq_wait(analysis_mq,(void *)analysis_buf,sizeof(analysis_buf),60000000)>0) + { + if(analysis_file(analysis_buf,my_para_data.mach_run_para.sample_len,&my_para_data,&ana_result)==0) + { + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"analysis %s sucessful\n",analysis_buf); + if((my_para_data.mach_run_para.run_mode)==0) + {//ģʽ²,ģʽ² + if(read_his_entry(&latest_ana_rlt)==0) + { + // + if(ana_result.result.H2ppm0.2)//ʴ-20% + { + LOG_DEBUG(TRACE_DEBUG,"lastH2=%f currH2=%f delt=%f correc to %f\n",latest_ana_rlt.result.H2ppm,ana_result.result.H2ppm,delt,latest_ana_rlt.result.H2ppm*0.9); + ana_result.result.H2ppm=latest_ana_rlt.result.H2ppm*0.9; + } + } + else if(latest_ana_rlt.result.H2ppm>=(1.0))//ϴβֵ1ppm + { + //αϴδ + delt=(ana_result.result.H2ppm-latest_ana_rlt.result.H2ppm)/latest_ana_rlt.result.H2ppm; + if(delt>0.4)//ʴ40% + { + LOG_DEBUG(TRACE_DEBUG,"lastH2=%f currH2=%f delt=%f correc to %f\n",latest_ana_rlt.result.H2ppm,ana_result.result.H2ppm,delt,latest_ana_rlt.result.H2ppm*1.2); + ana_result.result.H2ppm=latest_ana_rlt.result.H2ppm*1.2; + } + } + if(ana_result.result.COppm0.2)//ʴ-20% + { + LOG_DEBUG(TRACE_DEBUG,"lastCO=%f currCO=%f delt=%f correc to %f\n",latest_ana_rlt.result.COppm,ana_result.result.COppm,delt,latest_ana_rlt.result.COppm*0.9); + ana_result.result.COppm=latest_ana_rlt.result.COppm*0.9; + } + } + else if(latest_ana_rlt.result.COppm>=(1.0))//ϴβֵ1ppm + { + //αϴδ + delt=(ana_result.result.COppm-latest_ana_rlt.result.COppm)/latest_ana_rlt.result.COppm; + if(delt>0.4)//ʴ40% + { + LOG_DEBUG(TRACE_DEBUG,"lastCO=%f currCO=%f delt=%f correc to %f\n",latest_ana_rlt.result.COppm,ana_result.result.COppm,delt,latest_ana_rlt.result.COppm*1.2); + ana_result.result.COppm=latest_ana_rlt.result.COppm*1.2; + } + } + if(ana_result.result.CH4ppm0.2)//ʴ-20% + { + LOG_DEBUG(TRACE_DEBUG,"lastCH4=%f currCH4=%f delt=%f correc to %f\n",latest_ana_rlt.result.CH4ppm,ana_result.result.CH4ppm,delt,latest_ana_rlt.result.CH4ppm*0.9); + ana_result.result.CH4ppm=latest_ana_rlt.result.CH4ppm*0.9; + } + } + else if(latest_ana_rlt.result.CH4ppm>=(1.0))//ϴβֵ1ppm + { + //αϴδ + delt=(ana_result.result.CH4ppm-latest_ana_rlt.result.CH4ppm)/latest_ana_rlt.result.CH4ppm; + if(delt>0.4)//ʴ40% + { + LOG_DEBUG(TRACE_DEBUG,"lastCH4=%f currCH4=%f delt=%f correc to %f\n",latest_ana_rlt.result.CH4ppm,ana_result.result.CH4ppm,delt,latest_ana_rlt.result.CH4ppm*1.2); + ana_result.result.CH4ppm=latest_ana_rlt.result.CH4ppm*1.2; + } + } + if(ana_result.result.C2H4ppm0.2)//ʴ-20% + { + LOG_DEBUG(TRACE_DEBUG,"lastC2H4=%f currC2H4=%f delt=%f correc to %f\n",latest_ana_rlt.result.C2H4ppm,ana_result.result.C2H4ppm,delt,latest_ana_rlt.result.C2H4ppm*0.9); + ana_result.result.C2H4ppm=latest_ana_rlt.result.C2H4ppm*0.9; + } + } + else if(latest_ana_rlt.result.C2H4ppm>=(1.0))//ϴβֵ1ppm + { + //αϴδ + delt=(ana_result.result.C2H4ppm-latest_ana_rlt.result.C2H4ppm)/latest_ana_rlt.result.C2H4ppm; + if(delt>0.4)//ʴ40% + { + LOG_DEBUG(TRACE_DEBUG,"lastC2H4=%f currC2H4=%f delt=%f correc to %f\n",latest_ana_rlt.result.C2H4ppm,ana_result.result.C2H4ppm,delt,latest_ana_rlt.result.C2H4ppm*1.2); + ana_result.result.C2H4ppm=latest_ana_rlt.result.C2H4ppm*1.2; + } + } + if(ana_result.result.C2H6ppm0.2)//ʴ-20% + { + LOG_DEBUG(TRACE_DEBUG,"lastC2H6=%f currC2H6=%f delt=%f correc to %f\n",latest_ana_rlt.result.C2H6ppm,ana_result.result.C2H6ppm,delt,latest_ana_rlt.result.C2H6ppm*0.9); + ana_result.result.C2H6ppm=latest_ana_rlt.result.C2H6ppm*0.9; + } + } + else if(latest_ana_rlt.result.C2H6ppm>=(1.0))//ϴβֵ1ppm + { + //αϴδ + delt=(ana_result.result.C2H6ppm-latest_ana_rlt.result.C2H6ppm)/latest_ana_rlt.result.C2H6ppm; + if(delt>0.4)//ʴ40% + { + LOG_DEBUG(TRACE_DEBUG,"lastC2H6=%f currC2H6=%f delt=%f correc to %f\n",latest_ana_rlt.result.C2H6ppm,ana_result.result.C2H6ppm,delt,latest_ana_rlt.result.C2H6ppm*1.2); + ana_result.result.C2H6ppm=latest_ana_rlt.result.C2H6ppm*1.2; + } + } + if(ana_result.result.C2H2ppm0.2)//ʴ-20% + { + LOG_DEBUG(TRACE_DEBUG,"lastC2H2=%f currC2H2=%f delt=%f correc to %f\n",latest_ana_rlt.result.C2H2ppm,ana_result.result.C2H2ppm,delt,latest_ana_rlt.result.C2H2ppm*0.9); + ana_result.result.C2H2ppm=latest_ana_rlt.result.C2H2ppm*0.9; + } + } + else if(latest_ana_rlt.result.C2H2ppm>=(1.0))//ϴβֵ1ppm + { + //αϴδ + delt=(ana_result.result.C2H2ppm-latest_ana_rlt.result.C2H2ppm)/latest_ana_rlt.result.C2H2ppm; + if(delt>0.4)//ʴ40% + { + LOG_DEBUG(TRACE_DEBUG,"lastC2H2=%f currC2H2=%f delt=%f correc to %f\n",latest_ana_rlt.result.C2H2ppm,ana_result.result.C2H2ppm,delt,latest_ana_rlt.result.C2H2ppm*1.2); + ana_result.result.C2H2ppm=latest_ana_rlt.result.C2H2ppm*1.2; + } + } + if(my_para_data.mach_run_para.co2_pos!=0) + { + if(ana_result.result.CO2ppm0.2)//ʴ-20% + { + LOG_DEBUG(TRACE_DEBUG,"lastCO2=%f currCO2=%f delt=%f correc to %f\n",latest_ana_rlt.result.CO2ppm,ana_result.result.CO2ppm,delt,latest_ana_rlt.result.CO2ppm*0.9); + ana_result.result.CO2ppm=latest_ana_rlt.result.CO2ppm*0.9; + } + } + else if(latest_ana_rlt.result.CO2ppm>=(1.0))//ϴβֵ1ppm + { + //αϴδ + delt=(ana_result.result.CO2ppm-latest_ana_rlt.result.CO2ppm)/latest_ana_rlt.result.CO2ppm; + if(delt>0.4)//ʴ40% + { + LOG_DEBUG(TRACE_DEBUG,"lastCO2=%f currCO2=%f delt=%f correc to %f\n",latest_ana_rlt.result.CO2ppm,ana_result.result.CO2ppm,delt,latest_ana_rlt.result.CO2ppm*1.2); + ana_result.result.CO2ppm=latest_ana_rlt.result.CO2ppm*1.2; + } + } + } + else + { + ana_result.result.CO2ppm=0; + } + } + } + memcpy(&ysp_pri_data,&ana_result.result,sizeof(YSP_PRI_DATA)); + ysp_pri_data.TotHyd=ysp_pri_data.CH4ppm+ysp_pri_data.C2H2ppm+ysp_pri_data.C2H4ppm+ysp_pri_data.C2H6ppm; + ana_result.result.TotHyd=ysp_pri_data.TotHyd; + add_his_entry(&ana_result);//ӽݿ + if(save_last_result(&ana_result)!=0) + { + LOG_DEBUG(ERROR_DEBUG,"save last data failed\n"); + } + + send_ysp_msg(&ysp_pri_data); + for(i=0;i<6;i++) + { + ysp_ana_pos.position[i].start=ana_result.pos_info[i].start; + ysp_ana_pos.position[i].peak=ana_result.pos_info[i].peak; + } + + if(save_analysis_file(analysis_buf,MAX_DATA_LEN,&my_para_data,&ysp_ana_pos,&ysp_pri_data)==0) + { + LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"save analysis file %s sucessful\n",analysis_buf); + } + else + { + LOG_DEBUG(ERROR_DEBUG,"save_analysis_file %s failed\n",analysis_buf); + } + } + else + { + LOG_DEBUG(ERROR_DEBUG,"analysis %s failed\n",analysis_buf); + } + } + else + { + //LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"analysis is running\n"); + } + } + return ((void *)0); +} + +int analysis_init(void) +{ + pthread_t analysis_thread; + if((analysis_thread=task_create(analysis_routine,NULL,0,0))==-1) + { + LOG_DEBUG(ERROR_DEBUG,"create analysis_routine failed\n"); + return 1; + } + return 0; +} + + + \ No newline at end of file diff --git a/src/analysis.h b/src/analysis.h new file mode 100644 index 0000000..69a3b0f --- /dev/null +++ b/src/analysis.h @@ -0,0 +1,11 @@ +#ifndef _ANALYSIS_H +#define _ANALYSIS_H + +#define RSV_SPACE_SIZE 344 + +extern int send_analysis_req(char *file_name,int len); +extern int analysis_init(void); + +#endif + + diff --git a/src/app使能开关.rar b/src/app使能开关.rar new file mode 100644 index 0000000000000000000000000000000000000000..72e60563f3ec582c1b6fc541e4e7220a5d3e1f1f GIT binary patch literal 340603 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

#ZHTsO${x2&8cG_2a@fR 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

    60i1X1^8P04*g=Wxjq+pY^w%H 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

    ; z@g?q9`@2a^IXSG7Wq#+~J!AEoozWoolp5_}<5nl_(IZCea{<|wFHK zSByiY2jhv&(nYadNaffbKCtmar?VZzA*6%n|3*~cPeih--~KTUUrRlP;G#Qs=VmIh6xbS6w591?_k0z70wa-jIm#xB$d zecUi{Ads@9AugP(x^+(Sr6jQ1y+jG-^61seoYSp83Dr)mjpLt@;zbJ29Le3D#K#Jm z4K74!5^2af?C+?M>u?vax(&5J@b0L1PZ*e)TvY4Uj%>RUCJw{3ObOwFbmx(K&~Tt1 zaB?2k`?spxRNoFrFX-9LycFc zm6$P29WuTahIT()lhQ1kR@MgI4~sg84S&2aTK6@4V{MLiqoaI8iI87jED$cx!`DEM zJcJ33`F268!X)j)kdNbd$j@^^r!-WuKJXJ91}Ce^qGaU(eOz(0oJDcZQq~bM!ked1@!MwLmQh!D2{| z$m|E@t|QHIu0|UFz-Dag+xz{UlyaX!B&I2cXz0}5i3WgBM`Q{?p-iW8@Te7Ko(JPWgM5pJ zJmtwwO2(UEZrbrx#g??H^kPv#(+QCM%DWyF+C4tw!kT}6@XqpUx5EIM>JuX@J<>(Y z7JrdS&5Z-7QMdCqIE`}oN`z@x+eoZ&8Y*It2CQ=buN>p_IUX|R3)1sl#)18XANgo}$;{ZOEezI1WMqjGTZHR@iEDnqos5|BYW`XocIg0-FSFqgyj&0={j&ZGGEapM}Fj7H1Fh1}S zdWhZ9Mhg#zsdHIOk)n24BU@u&^Ux8ijIst@8k3MTX~vEf0-R3A4)+nrm1Iyq%mMug zNOQJN_vW*U_g!XAWoQ@N#ti5x&hV3UOae%NJ&rWG<@z8vt3=|5+6m2r{Wp*cp(0bY zT#hwzer7hVf4PE4P2u`z&5<>2DUh5_&kfn2Eb8q(O_)nk@nlo(= zBl`=gVe=Gdvcdhzcz1-;;3oEfAA=L6YZc}P6(OpS;T zNZX5{vrg?vA_lTQs=4#J_kgj$f3PNe7u^#=)UNGXfYM2#i9J35ebwQO(W>PMr6kC9 zz0R1}rTx~XJU<~eF<7;EglR_K(AB38?GG{{+@6rLFOp3vw)qV;Riz})riIcG0beif zK?$v?FjX~9Tq&Cgw9dd1F=rRP&n=;uFI|{CT=c;fvvUoD%qDLyTyK2>TTQ`-;Fy;H zYg}`kg^jyQwC?*|P8VkFIs=wyoZSEDPEw#QqU}rj3M=x7O<$J?sWlzgY59X*itIG; zgISBP(^wkeuG54fF?iuUGA+H*HhVS5!@jSpN-3~*u6M;P8#ODspnWJG!j;&j(jgOP ziN=^CCXIWZdx&+_hG#58l10}wtapy8#1*kQo9edTisd9;L^+_O0gyFaJIu03oAHo@ z!b}k5&$RJE5lrfOz;uv1Mx5L&BR;GQ`P;IhQ7pMC3(+M}k3N|6H^90jJ$zI}-GkhX zqN9;o^rzzlQ!|>3nDvNj(%mQ|Ylz9}gt|&dO@jIjQ4{!>k-WLLu@zrPyK8$&P(E1b zphvtK+&nS|yA@=cJKqVCH~et&%@L2sBnA5|Pv=4hqdEtjtwfnU147@&l!1AkQd9_8=rO&tw(%lXebryleX=t?Zrg>DmgeTK~yqfX#{oM|&`0 zYr`Ow(o=9rtGuAcpKLjR@Lz=_!#2$1nNRk z3Z^~k#9<6|KxBynOfVdzBYJZ|MF*fiSk%eyFBLQij99ycOyd?&4e1(mX=86taJtta znVQ$R@RXDg{$vE!U74J~9@62^#qZ>DffDoYuHK18;q#&jy-53y&V}ujGcvQYD++5A zuJG9!LRgLovO$}3NRx@jAS@{q(n3c}2RtNwg5l89NH)qmGwz^rn;!YwD3%guOB2j= zfN}OwE<{8LXUkc2Dk5WN5u;qG@b+dCwDm6zEsuLHBv6qVbTcXW%u>d196kz+DpMH9 z^OK(B`MQXcp7_D!O^jr7O|Zmrqi81@rHh(Y3X7M9G@*9KdrI)F2~Ep)0~(PO40JT$ zYGx_$NzUYfjBn2kAjO3rLuV7z+#}L9P*NBsYz)fe-FuxM47glK#x!a;V5>x?Zo=o7 z7sV-uc7ZK{{?bRMbBHGEic7#B6~)b$9TIf@)$UZ4VXJH zUML)MB%92UuLKT=9*7la6WQkd>bR-c1MB0p3xCTf8gWEcTh~1S%_)*N)xpQnKa%^` zywqaO@?Ay)Mxv6yZdR8Gkvt_B3ut-Rlr0#BCh$nA=s;Ojt+Qql5cLa~QBf4ab0}Y3 z(WdJ>2%UHKhgLI#{t0xsilFbzQ$Apu|ythx>$;Qqe3(jGT zNZgz*iYS3!6<_k22;l~2Tgxro0an_|_F8DC2y70ghI40^LbCnM%MF0H_Q7AiNZde)guk{Eiamp)x-jiu?rhWaAjaF$&;`x>#6Gb^3Q$AlBu+(f6MXJh2ta&bPRugwh^p8JwQ|i^%p0^dox}mi@R$bE6&;Gm49x(OwYGx zrm^kG_G1ci`jZ$ltw@eWus}>hHm@@^1UCAWCrOhpg_rPS0ns@(u2tUr2xdj9ty$U1 z!7Kv?eaV(}K>03%s6y=#Re=7GM|I>wK0D9W3&98R!*0MQ$i7}EKW+5Q25oOU;8Fng zptJx)vzo!om8pB3-OItj>3eb*4HhM;N zb~;NMx0+1W5jK7Eu&d#85B!2OE2KO^T_|;(;A9hDT$|_pgCN%WrR2k|bT`fe^%}aX z+tt?9$F}E<80r#;8e>3tM4i4+F0m57NK5uK`8*;5#|JFKAXZTblt}n#fk&gxith#z zpyY5R*Wb4Wa&^|1sShoZGz|# zY@-2oD$f92`Jo;R-TC3;4_iBVSG}Fo2HVB#2E3(sY)sQ?{~zeH_U(^gKU>2K zp4W9zg;q&%3D)OMhc?s&NsWsBo7DwYeDVqaD9+$)_=v4zp)b23DZE?Ccif-->i58S zvRCvY-*Yh;1q9u-5E!oFx<8E7}JEgzzu(gdga0`?$#(QjnX~|2f<*?Hb%M zADNF!l&H-rwI)AeUdqI3QbzWb2GBnZs{3xI=kncXGNXII+dDUVS=%$x$ImKn_Iw3? zXJG1ewoW=dRWSW(9>?K;GXq}t{Jq7;fOg1E$Sf%Fd(+?is73}Pre7ly;5=k5xu`Ob z{*m80pIgtE_J<^HTX*vi255*oIUV?Q#}~~;Apcwy9%$|Eiu=S)^+Olad|A~BXF3cr z=ogBxGN7aY;(0?;q}10!Sm^rk98JyuT<7xnh= z=lMs~{)T5eVQ}s5jrUKhw!$4>rbJc6*z!apu1SgYC+=QyGp{Mvu{ZBfk?Fn^6r=ez zP|jk)fJ*5xJJM9zzU$fHCp(zH&l2!2)312SfsCdfGxguq0MAb)QD(z~K;4ol){SVcI6e`Zkg~P47AF@g?VZNmfNQnS4Z3%pNjVwXR_rr%Vpi{MZ z*FUicw;sOdDukMc1kh$Vp*%Z5AHw^sfKPpMEDiA3gz9c&1DczbD1G!3i&8<1^p6<{ zcCM(85Y2o_}0>v2ELBSp6D^+I04u61%?7+jZ^%XyRnWE zUNasx%kzO)(ypCnOFmhDDo-S^%@RC|ggg1?kTGtqG__5KhP%ZeWNHkuV75SMfJwDI zZbtW_(o(jxkU;qsHo_~r=o__44LiwL9(Y-o({rR>QYx%UEn;`0zK;7wfw4dYW8u@| zF@2sH2)}b9FoalYkw#yv#_YTM&qX<90dwzpx4VWo%Ea4`3#3rO)zaie3IkhYZTmKj zR0moI+l=r(lAM&=0Ag>TQpc&EAx;ZfJ*9cui;0w+_eda410t&?`Tsqu9>8=Bu9NA3La7DH39&dJ#UBX>HFlMh!oNw9aKeK-O8>b05ygaErh`}NVVV!xHEy(|OoW-NPRkd``I z^1rt#5W@~s)s4Rx-Mc}iB{H7#{jj55!9R`gEUGN~Yv9jHb@b*hE|klpz^iGM9PBew zrA)%h+s#ExwkQ_)*i@J!)I52Rk3uy?o&|I8L#@*<(?H#onFZMHHfthcG!Gz@oekDy&8Q#4Rm+^3tQ%)d;@cdQ|1l8v+^94~z}{R5$9%-UivD zoE#E0wzLQxqwmj4gU8hKHod4WfrRL`cUH3?`)TfQJwB*UX=-}~EN#$U7I@RQrYcK3 zyL&JxC6lP9Ow!E>W(o@j5EAjw^RX#GV!iJ<@6110skp|oT?x`OgehK4>D+FM`j>Y^ za`NjWi^h#2<#(wU02^xin@OE!#(2^pCXt-1EnHus4M&4?<;b4uXwm{?$iu20Hy;6LH)eiDSk;I%+|#v#9VvcSPa<(&|CJb$}m4UaSB3AQexkS{s0~Op!mqm z<0}L08n+iH=)lXGDiTZfQ<>J!p=xB9)=&NtWAVBUGJ*ArR}hh+S(0+5NJw{{j9i_} zv^eylPQVV}m#U(4KjoL zxMs1&Ionk?Cpic{$BMu3nJzTH@GTp!%h-x%l4XG~n31-zij8#aCBu~ok`GKW#=@es z-0V;e_#by7B#7gd%t*9mlDj_at;PMu!BAt4LHhRwQ?Vng0(!}VbO#~|9)%V;nYd}) z6En!Ydl?eeOu`A`p9#P!rz{~t##Na;(z=`Tpar1R!%h2tZJNaN*S^z*OH&*VOJ+J< zN4tFnwAN-}PQqM6*~f+dfxvHk#5MASgk8f}(OAdbt+~MB!uJx<)1TC9?8g-b3r8fM z48xFx`zGm54mk0-cokJCX)92l!LEs!rE4v0;o2NlIjU20VE__~;l zPOVWG3h9xwvURCopqm>KTAdCiSwhPZ6J)?CVf!thT{%$DSfBj*}H!nIVc5n%I5120~Ga7^$5*!YpXzs*=R0;{-`rD-q6%+~V&O zz+0Et(vHXNicRd*T6mS=+bp^(^WTzQVzK?fB}&gKD-)EzLtvNuLcF%g-AP<4@^8ep z=Md2Ts`u~@DuQ6XgbXY1gZGf$R@A-(o#tb6QdP|Gt&c_7RLMIM+6GH~1|~~SLW%BB z(Ngu#Yj(`GRPrrk%GfNHPwUkbc{H`Pib2f%@;lNVWb|$T;y-!@LrtugPpX_Rk{IB1 zWEP-Ki3R551T0LzJ27QdjBSv`%4tL_O!9Wf#OgR^r(qM87xS1wE?_u!k~o%X#!BDc ztCKb=34@^zjWjx-pxw?P5Dvd3bHoSYm!0HPy+Q@Y4NKA<^8`{a#x^beA+ND?cu3nm zn7FL1?jnY4s6XL!yusQ8q4Jk?we;q}`2Ykb8pm!EqX+m@I?6&XJRv{;n`9cqvl~ts zAqA;OHlB)YEYbx4JV~g$#~=-m?gyXTiU)QkA7R?BGP!1ipPMLDw$#`wyW7kinFveXU1(~O7_Hh!{&C% z#k7di_JVvcc=H%P7b)ARi`FLc-1l5#6wXF*de~SewGDW#!}Xrz?5TrI>$YS<);tC- zAAtB6xZ`^+SXJnN#}Y6}KUkUc`G_mH4SdIJ&Qy_t)@)MP%r)>G{d{uo16E2Plgx1L z%l-o#+?|jr975LwT2H{2bhPyh->fMhla>C{&yi-VDIW(2L&D2=ezJ0 zK$DRQ*QW)ecicu7xkLf__&|27Jbi%IvAIb5dKBhLs)|)zcIR7pSxs2W%X5k%0*zTE zOtwz5G|bLM5WfbMF~YQQbKIL6Y#39UxnCIsZ~}H<)`yLdYs7^s7+dW)u+tGa_fDx% z>+3lIWfuYA5x3TL_4O|GgI_h#i9HKdX(^2T?-rn#79~P?or-$QA};rCo)}Yc0Uluy zE3HRgyy`aBU2=wWvQ~=gT{DcbR(164QGF|-%Z}?1A@MlwjFFXHWcsaL0YN*fWvv|= z8R*^{T|k&P5lq{_!yxjF&Lnwmc{b@JXAZ7bVz8x2BUCzQXoco!c$GjCvtb9emWH`j zFKK(3#~m%SD}4tBB=2Q+kuFr|I0ViTa;$3;7sxB0Ht9RdbJSZNTeMK* zEJ=EBP9X?@^@KZ~6q7zCl`%33iXa^*)$SvK%-meayxJvizI-A%@9vkA;i>X+N19`g zk~n$i?zsDLrT5V)9UHE!_E@GUjr}fNQl4puLtib={#vL{W%MM8mh*<*+`O#Ce)o4# zxH+ui9k`;j#V`%RSvK@4GH(>xA19GGg&pf~@lH)>X%FmlqcYa*jzK%(^ipQl?>G@@ z7f-7%*>zE4W+)eC%ON^Us}u;;p5)r7i!y0V`>4A6M1~BJ8S>p;DBQ8{kdm6fR>?H_ zhApaWWIlre9Q5BfviuxniG#H8Y>XZ~KTU?TCHPtx7g#*eL?O1c04>>>Yb9SOga z2$Af&C5(k&Ga$#bGcFK$?$1{qo%VTr=eN6z?8# zxQ%dkrg!^2XQ%l}0H)1TKUx)a{5d62vAp0Xs|N?RY@;D&LBo*OadM&)PK;^HPriuP zbA(EF>A5V06_q)tI<~L5%!^3Ux}+@G66d>ClEaV}USX()A~FWb1bnwND51$cQdtw% z-F+sA#pBJ2&yrt|ZLWMzP2ZW)A#WaCaK!Ri-*5c}mcUx{h-GHHrz(eHkj^A)LWR{x znlqr)dm>`${K##C_Vu+5)T&G|%)ahp~Vp9k=||AhXy&MOT)Cs;Z9 z!DK3N)hofwFO=vFHDRb7T0&JaiCvSAMKDtfg-~CV=7WrjWF=cEv_5e1NzD#R6HGCO zZ5+X9M0=gG#t`J=SSIbxuJz;F^Qr=kIs>w|P;S+%^!yHCb&P#B4i4vrGYqq0`lL~2 zG(M7z;q4;a)Gj;h6jp@2*E7)(jYzg!f8SJLyFawE)XJzU=)zxoUa)S z-pO4-RP+HJmDy**&f|j>cNZ{vdEqQU{tzRb9Aa`Kr}_q3{RA4J?-MQrZm!Iu5uD{V};TU z2~TV|JSNety^42c;#POskG_es!7=_1* znj~EYN)0VQos!RrjmsFiu@q}gveT$Dhv$zq%OZzYOPX-&55gqsfb1yOa7j;0=$<61 z$O>bc{WmHKcH<2yVKceC!neRMMwggd6hQFlJ6KVrp>@ndc;I~COrT_tPAEI321t`* z%5x!W4Kn`0j)~is+9t>rN-u)euUY?19&t zJhJW%4kG8dIOP_*_z`S@O#!Viuj40E6vVk>XOI--sYL?Coz!s;S^%Nv)(hq~vvIQ1 z02kvAsx!l>Ssf$74R_*1ZzKnZL8)0nQoJl8WOi?^+ zRZaJgdOWiNv=5#&kYGQhpYYB zsD|_5op3H~=~f4*wOqo*FFehv)*nCpkqhMy@yy`NWKpQ*m8?^*I#!kBReRIOC^}n$ zYyF%g6V?I$*NF`qbqy-hSjd*xh?v!;$e6hZb`GXV6nr`vY78}Ev`-2EFt%tsIk}qV zsd4^Y5*uSXvnSCQ+!2GJj=y3vvB31)Lune~+8b`T#arh_TbD_|bffbZY@;+oBLOWF zpPa%8Yb>7UC?&Vyy@V-gnFtZtlSilKb!I^Ra@QS$EP$3QudPiTDy@0%^^xGFuP(rx z#_0^)Hmu@+(9lA}@)Y-Hl7v1~)(n3r6m}&Sz<)DMF(a!wYwDaVDTn8u9U%lvB2rIP z45w3=vS6W(sE;|tl?H%t?V&)KG-5TuGLx$q(Ecya4vT`yE#g`y>Y(iHVQBMy3z(Hj`Ye-lMW3Y@e`Meb z;3O^)Tn?g@(z)Rz%eSKu1O>QboVj{bl@e4DBtiPT ziE{@tO4a!AVe^#=6U)ztj=x!;DG3QS0-8De?r8X{7!V4|puYBXMJzDQL?o$E$(+5E z48K&I#bb?bSQ}5?VwCN2>=sR{8I%223dY1oX&rk-({PO^s=-@uMB*|n25E^utRlf2 zw7UYFlc@yk`)P1+g;*)J8-_PdeoNEDwg9?Er483jz<z&(l}eAgu~99VN0#F!&ySe+fENqzq9Q`;s_a5aK2 zV|N8zYUMO7t;`2n%)k$;L{hXr%9sny3D$$jUhj<4uE^O`7mOF@TTLuRtP=M;dxLs4 z(t*}y1GD!=zabWC2~ws+ROGW01yMnx83&^hR}@7ZN|*`O-i2B+6|oJMo;YUWNm)4d zJyDRQ*VO?${n+!k=>AoA-@$So&-dIdGxSI{g}-Yk_goKecubp1w^XJ;90}e@wcAM} zuxYS)4PLsSA#f}hf-K`EGj1C9w~WQYSoc{}uVXPt%$#F!O@&?k5-zD)6L7Tb4o7H4 zw@@hG=hekH^9)^!FxP!nZU4g|v1Af%m7z&5uE8Fd!yqIb<0}fH%qTaC3@kU6j2j4% zRTI!*w5Bl{7xW(BDoF^8y}&NuDux;2ibkZyPBKKRjMVzxK0#pir>RyNDMB2NUZ_ne z&{zEB%qugkc4xxZi9p6Mmy_QSg0PiRjN(ta zOe9LuTt^*3`~_+XOjkGX>x_in5(!%LFm{bS=u1FVa@w}N;EjtHHNRqS2Q0ixu{>hY zVcF9c%GTKhr_I2;z0bRhSI$9(wxo5He1%%NpAueCjRPqfNs3b@KaR$@GJqavKC%Ih z*#+FP4K?Q?oLbQ_u*wRPXnC$kj~x=>>eF2-s(TVvz&P!sj@uk9;V$rRcQLihkv^w* zE~p{u|KS+4jdehIj8IG?G}0thjvqaJSyFqK*l8j}#MRdWDyxm>QGIF05*}h!hBd^T zYK>i7810a0AQ%5cTJHfFFx^>G`P~1$8cBL}`$LA9`Y4Mo94liJJVh9>p{cd`u7S#fTT1B(N=HhjZbWjWyRgIt}_RUB1Q*PSqMCI4FUk#6COMDtKADyJ+o zg~xV`714_Yl}R)ZCnQ{^q##<4*O6B#LO*(!Om*E-o6&i&DTN(@#aSl16~T(EYImGU zoW&YZCCfa@D1+a<@176(mU_e<8UmAAI(20-(rXH=%h;a2BXO!qDX|o?zjl>EfF74% zv~E=R2NDU-togcC*wppc`d-UH8; zYeQPhM&hhKYQnljRXgDeSmQ3vrRwssA{dI5_?6wVK=8)6*8sn)Nfj0@P@U&gpoBV* zB@)%cvJXfEcwm+E{Rpk_Dwouj^D0+~zj3dR5ZfR!wnJuR? zlMwcbj}nD#NRkA>R)D@`*QRs*@Y*k_is_>&Lds{Wq{{?sf%?Zp4Mb;jp*t{tz_@o` zHss-x!|ciyAnu2@_iDRW4lmgFfoINVPMG-nMU164qwB2RaSz^O{g zMT+bx1y%PGLLV5&3I*);gbK6TVMr>(l8#tpr?qe_Af)CWQk;QYiG#(xn##0L1FWbR z*i)OSSC}d2MXFwyaB=3`Zl^aB7tuUY^}gU~;)Uw0@o~%SLcJX2)1T>fps2$prm*B> zMI@+3tca-BLOy23=SY{&Y-F|cEN=u}5=vMW0=$*Hw9)ZQ{Oawa!l1v+^yONkn65*>GS`z8-?S6j2xcaL; zV$;tDB+y=BU)LPa{w7u8oEo&0)!+Tc77^*jENJ0nrn(){PdFS{i3*DZ+_yZUG>MSm z<9Oyqg6oqr*Xwa#6sRV%84<*<5UI_;U&Uu1%JBQV7Nqtv&MwKaHdsiA+}bkLMJIZo z?44j|vK(MA<`?F53?;&*pnu^R-GkdY!MBu&X$u%J)`2BhnL3}IoDFPR9+5fz6sF{2 z5s0M{Iuja@<8O&1KB{hPN?FoY!OEc)oW}< zsw$f`b+*z9EAaJ1v8yW+sG;P3=SLCjU?po%tJ#2{WP3bqw?Y=o)Yo*OsRt*JEaup^tU5Z{ObuR{QJc;-*U zts01@w|g-6N+ZS9j;z6a*%t<2%+%{xejd9%_gU%rYD^}v-W-V%u?caUg!=s=`m-7u za{Uk)7rO%PSI|lC#--Z|H1Y)wuCy{7=lj%KES+E9!4E~@voE_QbkC@HbOdV^Zzebl z4+i!^#wzjVrq%fI^J_eDMu66gS4>)jVi2*?!{$BD?=fz%gYihlvpSv7J74|5@Jd8K z31FBy5?FI&YM?gwFyxt0zHTA&%IB^)CHF}cYxSL2n1zEi#x_~=<|F^a|>zMR)vftJ>2QvJ7A+dMf8ujTdPQjZ3I+rHqe&+|&gWT&_ioF2L z)@76k{{h9ke4Ul2GEf~aT=SvY*e68*Se_A}n(YW?Qq~|K`7jfUrI7fC))a5d2=m}i z@AkoD4B(&xA`k36iU>724|0|{0t$9k$3*cNbjjRs^nbLqPR6o!r2Cyh{q#cYwBjFz z(7saWKOf9<_c*j^_|2U1PSS8JKLC`Z{~DIyQT@rH@s`AFW&88Sm|TzIs$4=>q92kCw|WbPdjZ&{sl|u1)Xc1(63d zY4YJaNi(ea(}g~h^XjtMa2S-9@aG{jj4Hmq5I#T5oQ!)eZs*sDyR#gEZi;)w8jvwu z59FFt^(Me{XSJ?ojbB72n~F$bM9oK>QZH7Snhs?&I? zos2_ZoN2}BT*l3cj6QZ_=4?FlbV5Bjxu%fJyfQ0 z`jl-5z}coDGJcFDPn7 z$F)1S)=xS8j>;J~R)NV*FJw@*$RGX!nWG_6Aa~suo95E0i%FVmO-qM>UTF_A2kQ}Y zdDHMK*DiOrg?>RR))wtEXFAK6)=n5dSPr~9)`!D|O9KD+4mdmM1LjyCjt0yz@W_IJ zAMolW{D&9`8+eq8W=EnM$#l9Zwkv|^h*S`AK#s2jdmF=wlvaVv7a)xxIGCuuOP^PY zmhp)Ux>A<@s`4EkWL#%b0)B%yd9)LJkIW(5v>GJC0N|adYIxwrs@15U7UfOXn?Fxj zb71M2`xTN$h!&Mz#Ql z^-ND?a-7cOS`%=ip9gmgOMl0$=d;IFw8WwUQWBfR-AJIXqG#Im3dnUlXFjNnLHy7= zjGxO|8-RFPfd}8d?Jb9{?}B!3IpzIUC2$oh7w!_Y&K;s%a(Im)|8uVt(yiOSdd9ezSp>T{-S=3f7(l=SGAXcL`|^IlXja!PCv)(F={* zQDXqN`?z#vdBklZ{k}V$)#llj-I4tF7muu>q!rsaROvAGJ)(Cnc_WCzFs8&2T}E91 z^|t3-D#9#E%h)1UNU^lIVE;^{JL4Q6w{!*Do+azVuR(d;KzqXB6-xC3%^p<)d*#QB z&NmVk&YEopeeSGofcNGdGAc`ionk{`rKdhCdL5}Y2@7NBf-;XmG#vPN>n-jSkOWJp z(_-2uczZM=+R;Sk{fs7)D9qR??#P{{Fx07MqMe1XKl%+xQxvf*KyDm62Egsj*y~1& z{6u72GX#;W^Z)fPNaW$d=`f{JdB+;Dj_C2I^Qc+g;I{b(1z04Rle2srOXC4JnUy?< zn!PdZik2_96EqG<>9xtES|okh3Rz%h!o997No2a5o;Y+bCixD2>5K3O)(R#zKvg*X zcj-q70?}6wKGkBD1=`uNz7J4q7*MCse5gqLpr`5rdPDN5m4tYk1zwoJX3l1ApAO9g zx}XLqLRNJ**UQpBB2NI#Y}{v4Cm8l(0`>JKKn?56(szs&`*&}0LQAJqn~#~YXTakN zra0hFWbyS#r16OmW(MZ(_javCZj^AK(t^xC&RWxv?-(ae4v4GemAZ5Dl78284L=xV z6kVzZV)%h>!yj5P*BZy{vtK37lHGF!Lve?cIP;P!ZYx8zh5$~mxpRqlky9>IcT5~f zpG{@}^~MWzP59$)==FB)WGXc2|hnTBtp*b7Cm8 z7vs;u-qsJAuvQeiU@tEe9@SYXJvT;hZISJBr%Bntr~C~cs0fM&pgGM;`}n~SiXPCe z&mfl_{{1(w_%x}gatayNtOxn;5&c4!<93%4@|P)&hKLl3&j^%E&vJZiMh+(Vw^6eL z)uo)+cc{-KF>a$+e^bmL|0*@@tqHdWRdi#^%cEO~NRjU)&$Yu22JbE!JU<<%6mI?c z96TOHEYx5fLf`DlVBz*k=-G`Fq%yH!j}0CB-thAy3UY45?b0xn>zTc&16I!hvH{;1 zR;5lkK1?3^uWSvONu#V5lePArzX+9Hqrmvl#iY9R;UxopXsPPO*+hanP?o^|6U7?y z%0Rm?l~bX5cZ}m5G{G`yGrsT{VGtP+Gc*;q8Xr$Q>d;eC>LBm87%8)((H}a~mg~sv z@bw*-6>-mOH`5r+V2AW7JMk}0!K1)4kB%3N8zCn~i&lxb8Ew#@x@s0a=NU&1 z4LSjp0~nTWNV#t1lnL-Yx3AD$IgWJ_xu(!`$j0rgsi^zZ3D~7F-{R!;i-oR6@jAbu zN0+$zXb4lI7qvG<(MhPW{e`=EgD2^WhcK$6UtK8*rVdIS6m`b3^#! zs*f#n2E!9u4QBXYH{?0(IHhq{#D0ELTQ(HN8w(IjIJJO%U~EAXsnS>5u_H$v$#nyq zHw9uRbPp~K@&U2)nsjloS2l6CBVd!zgHd0rhvKj?wU%c*Hu0#gzxzUY;vKANRb$A{_`x?1k?! zCFX|^C$Lz*u3Y}m#WAlDf}zL>)&h#_V?$62XTvjTfqY$^l?SZO6X!vnbctQT7}@*L=Gjl?ml zZIC|}cEkwt#Ored+5EBd3JWq`=0*i|V@%(P*Kw7^p%HHY9TCxk?9xlVSp5!@L@soO zgV^Ao1Tt#(7Kbg+V4^b_VYEcDZpPL#lIrmG zYp{qK zwu+(mFEJO3r#pvf(Cka8)E2Pzb-ZjUu#|!G37=B!ISld7lX^o6Jg53NPYF3hVmyN) zoglx_7{UrKa=VBleJ`k3fwj!ci{h3RS#V40gNX7*17!$M0r~0YzH@t+Q;MZY@*m}? zIZ6ElmiD2y6{zaj-&EkzqHor5KsWQv9T->1YbJzh>R@s-ZOPO6$3+1vDzsxcZVPoI zAkm#skTTMx&HQM`cTD`A+{I;&)#=U1+mlm=)R#V%ujJFvT;P|GMkO@M<)@W5=PS>g z#yh@`Rlu$R(T~sDOV9p4OofZmNt1niUSA%$^X*YCs&lS1gp12~=ZJJkLrUUR(}Vdz zd}tD%cn{+RLfh7^!0!J3JHySJX}zhL-UvTj7pP@F6d$MxJ*hQmLETN*0@eflsXKLm zv^UMv-{J+X2jl|pjN|ITs+{h@Y(duo?hM1y16?`y!Fkj{dSw8NiY~fu?gH5Z(SqyV z;{n92-4U5Kz}N!KG$lRIKAA(sx%#6ICT}K+J;UTjKno6Lsu{4kpj^}6kRG;g6ZQNL z`FsYKA%To){7*{anv+}@KRH33L;I`)5qG}i%z6oIS@{lm?iuUWo_)IG4ft-mQkI8O z3Guvaa>u=5*w!vxmrJJ?n?qo_2V@zCYMpP`4Y3A4f{7OasZ5=L&XvRKX41$9DafJ^UJN0SSVh48NoHv0VKtDVt zzz(e_0Gt{0rFOX-_QFlPnuz>CHK2Py43_e|tx}=HU91|9wiI%mx!|;T7IdDR97*gA^AK4}m$*TJxGnc|a zMbxADo)`DxELLPkfZ9;mW@p$rbECaXdkbT9yD~N4Z5fv8F$-f74fujs=mPRi>|-rM zstK$~oy|LqxK*l$C!I+8);nGt?*eO)d~1>3M(yrmW#45924?Ayh=&KAa~vXT6y-O0HejMhI6#b1t`v_13?2IbFhcm%k6 z&&P62skUhZ<&J$nUQFBq_ZG)!U3teixV$U6Kkp_8b)zIIX&~qST?>h7%-rj#;7u^T={wuy{G1S?bOv zvn~;~yGw}~vvuvdlUhoq*tblr@!ZI9MXfJ+U@D%;&y^bWo!nO%IU7Md)f8?umo94} z`2whnyx30FDh#G{mgcr)ieeEwbM69>Y1KHJ8N`np>hH@b@Tdpo&?YxP{UFTMAa!>6 zA_ra=h9-bnGhbM8#%gnK8%2-OR4LK^6^ZQ1wh=s!s^;T&p9;(XaL_Hs#*lSmqGaN^ zvb#^UGIF-P$>*@CJNmmHeNFZF_w;%IV91XTFMZf-wr6_b&r&&{|JTfA`N@qre2&Tw zEgl(w^1TE-mlZnZYt7o*(EV^NCMXZ^a_}?Ytbm^PidefaTug6f%j z1o$=lw%pkMuinULUdNCO@+w>p#Kyv90m-tjpe zertu=#1+Gy=IB@QlSQ=y^Rjy*3u1RZU_lymRIaH0zdchw1T`Q8GY%Kqr#(T06O-VQ+O_Gf ziZ`4$z9k!VvyczTyfXy(1j$68VM6s6&WTh=KwE}CLS?>k^8NErPZtiJI4=)IuG(n-@D|vs5rf%PwNGJtIQ%6!*t!)Vy`(yoc2@ z>InQhch%Umh_mhkvIU$1a302U=gYJMep7^m0gS+|I1vG1PvJEPJXj_}c0K|9_|e;4B#qSF&8D*h zwV8BBXf#!-7dun~$tlek^Nf94<1YQsI(NE!xRCK@QmU)4Es~zj8?j}}z%Iiti$i=r zb96FO_>_~h;uo6f@?cGV)vR3ud&0x#CGY0}_8#m(>_F}w>VfKj?H=o%=U$Zh{|+Zq zhuU#8sF2)lGAhERrv|x0R;smvvX%!>8&{W0a1D-Md~dBh<%Kc)YbP``uXR(F0QXg{Tp6)5UykR& z;u#YGi)u=~csj?WeizV!!4%{P>bUnp-@fh2$>M=?{zFujjP)q zIR!rC)z1&$!mikxnWh_@H3`+j`MU8CC3yf_V9(k}YUfUMcX^mwjY_>#U4fjVwi$q( zG6b{k1Mxve0X1PbdundL%k2U8klNYP=I@dK^yv5B@ZD2p4a(II4`Jk%r&B8$o7Xs- z(bGdNek6&OC0Y}l*dP1i1!2IB#v*q^TsdiTi9-N+yP}wB4h@N_=;+Nf44=RGdAPzN zdrauaEHe-zjxs@f;!bsiA|fG}=;HU2OX!<|YKsbbf;I#ma#9HV}p7S7;WJEG$w>e{}l!(pB%?zdoyvGO1$}*(}*X-iMKUT%WmE zL{jyBM{}%mFL43>2VksFl(eJc*sK7uRE#QY@3461KLA}aN|w@uLuxLFxH$0fKS~F1 zNdbq^YP$BM(`XvdKDAyJdhEDGr7g8chreE$NkVENDoX7ZYgd&VbqV zuo17Wj+*P+iGw7^DxZ%s;+%jkrO#GdH4z#hFTCSo1|a(`!ZpDB0S(qiqAR}Qn!h3}X?7??v1N*s zN~)n699j0)n=WYUA{$DIlH~JgUtN4>3}vhQMRv^8gPApT(0SP`J?yj>xS<5+xDReJ&w+PXA{%eHo2e%sTa0cH)XoG}F02K0<5QI^TlnKb(36?qJK_`ns z!YLmo0Irec_}nAPBmKpr?hzJ=qvtQ*$;BZ1s=P11!06krDT83=xFRy1&(VmYZRYZ{ z1gVZGA!1jKNgAX)r#>*olim1VF+@HkWbOsZc5ij<+besnEvI7W4QV4~i?1m{Zj6&N zaIMK7p6a8s%+*l0O;%>y-FkPWvxFV}>NvzFDP0-Sv{pX-Atpx=u6>~FpKA!gdG%x( zW@=S|b#NEXG{1W8DYTCz8kk|LzYT4vSGUk^Wu>Xq3MqGF*I=7mI9 z%*qE>xKBWo@6WpEn z*7Bbqa=WGuGqR>c|Fl~|ljONbrbt$@HxtKORVzsX=!`PO6k7bq0AWPy^+{)Z;+b5a}|P6hcTxwxnTx~Qp7*7(9!!73c2)( zUa@oE4+NIYxw35vh*`{An76QSgv#%S>TJ_aY;0z>8B=y)EMr5n52~$LwDeZ{<1*|f zio*xD&G5+E-%&-4oL<8S^5Q~*nju81SkbqHpS0gOsg~YMj!-DUFZG!5f!@0>PK9@HIATxXV zuNT9FN|Cx*<-76e>e-d65HFg=tH%6>4n6|r8AqZ}_ZO*jF9;vMtZ!GA(@dDTD+a-; zru#vvPj70YP;<(LG2q(Awktg^AHKbd%^_Jj$4HlRYoRb2gG%zQVugN}fk|Umh@qIi z1GV|3`o6WjWheJotH*d5a6t#vgVzPC#N``L7E1lfUj3E&&xi0hm7dY^^IwzcS^ z+>sOd3*oq{W{F1857iL^Xwe+8B6_CwYkh|ERDd379s%S}^7nOc551R0-v@wMf@TH> zQ5n}46(0kCT2<}?H~sMRr+IlmSJi@nnFY|e^mRWIe)B*cwn2H;{RKwtzv9$~uB0zE z-d3aDag|ygx{$uHy1fU);f8=cbs>FYjr!kd#dN58>O%9){T)xZ<2ODYx}c}?=JK*M zndSfVK$Ss#dw=RL9UuL2GO6{^H=LCLte+2EP+wHv$(8t=YqSCDt4FWRKkqly)CaBc zMyOm(t=+iV^9UNotnVn41p27k)95}X{OjV4@&miXTuGWe4p7hhA6AZX1G@bw;?zj! z`m>HZ3EyGA{zHMiDnRW4XNyrOsMI*$_zfukL~?$A>mX!Z6Mww7`?u)P_9Y{rPe3^f z*}2>AUGw`*>*_zdk1=XKw5kc7aqdt2E%&;VeQ8kUb;tYAdky$Oi2mxr=v(}npMk$h zjwAa@t&}c55X=|&M<0IDs3jAAEhg>0gfSo5R6X{bM@sw7K6HJT&#i9if8ue*q(|0^ zp>M#Q_M7(_lznMb8#d#_r1unqS6i?NjY|5s)Y2P)!^{6}rKdFnT7KIWl(CW)y zQSLX?L#}S5Ie?OAPK6j6raz}Zk5l2?fH%o1e^NM-Tk$ymP{Zv^=x)V0{hOWlkrasa z%mYc-yyN%kcWype^n6pXGm2UNiM@?NJ}F0DxyGK8-*LI9N5v_c>YRI39>a}#)O=F6 zZ5wxBe96>&QlH93|N1o<<0Fs0sn7YuaOM#3=^uEdOWk{X)E3-)a<9BnsvlV6{Yv~T z?CKHmN~k?khg6=skJ+h5#VVfX8}`F;9?ACb7i2VZF-V+YJ%aOdzY~0%Ig|8}mx9dA z>42%vi;pi;yKm4#nNLV20pL7p4M<=zLD(<<^#8o$TRx9kkd|W1@#&))LGHB^@i_8P z&Om*VnT+F)W>?y8qR=Df4t+dKiF*Gl=WJPH5!2Uvx|HLio)Z{X+=^QlgK zv(+Bck3Uk6npOE8`ql9`%2Yn{hj-+#++45zarUV?`gxMOw-OZ}@((f&yZA@9&?D%o zPO=|nci(YAphwLrS?k-_&if8G)2R8SOXv^r#}6+Ge*0oPdKMFLeT%2-ey=Ym#s2t` zjUCQEogjVf|5G3T$(t&?eAh6K;ZyviUL%YPDmrbh`8$|7;^P_eX}0?eDRAV zDKF~4>2Ole>kK8i*f+<>5~N0<(z!*p!$k<*hu+v%vC%3W`{ERx;~O97X)9JQgAx?M z6kR9U#+UA+RO<`B0voO)ShBNJVMMAx)7Y{uIH-$DNVlD4ZK^&STw!!1g=q{W%@<^0 zAv=c`HH;id7*utJjCzj|%*13$RgF-t6(KEq$4&LnaU&uTph>%l$qybH#&Z+blW3e;nC2y=IiAs)i&oV z_HOIBAI;r+f7xucZ?nh9EnWKu_BNRQEg|~Y8>bCy?Y(~b{L$MiS(4oBZ{D8&*M!%B zq6wk`tR+|?jLCsUYrxS2(E(Nx ztPih?MpXeuYrxS2(E(NxtyG&0KUF2UggE{T2vaBQaqd5RbRSFKgctM z&Vrq<^qu$(z_!?n=$;F(>nSK+KnVF|$o=3BTvcuE=AzytP(BOMBKxcDA`yNRFCFe;7OE`M$>)%C5!NHn6T3 z)1Hvrzuf$me*CJUwq4j!LS{K+J`unOQ= zHV@ob8yC*BLLLMw<#5}Y{#z)oFt4ZkUr9=7eaT9Un@Ez{IiOYnqCe2Jc<@KX^ShC^ zoY6ylmX0~C3a+w?CAp#*pFbIHRdVi|a<7)kU$Tyw#@CcoT%9_ys}u1jbitfN@tNG> z7%X9*wS(Ls`xq+yl6AmZA_3Jw+|hddkKq@iGCE8O^6Q1e96w6)|4tUaCNE;2Vqxk4 z(Tt~j(0R4X57Ny(LvxI6-%@!XGu7>>dk7cu1;H)3FLStQbwn1M7#%b%f)6Z^+?ixw z=@cS+jP2(Ze}m4dZ@$*o$IOj)tBzlN?&rfE}zQFYeBCx($!AZ-5x?MyrH$l z43imgoAv+P8udGRow@D*VoU3x%Gr{_avqBYPp~t@y|AZio$%+kZQbsDH=< z#eXs2=>uIg`uMoL5~;#(4~ImQ*tKO6`Cr@o!c1IKbUFC+7j@GsK-9B$g#a^_ai(ZlWTt0TH^@InWn<-5A?0DtyzcEN`?3bq~?-ox3o@hIwe8%KTrBSrlEk)bh>ZiYxV z!+>xySCvO=AtBPqP_W25@UC-1dd?>5gj@yVWbdGogl--dEuaqq&1D>q1IWh6aqnm2 zx0mn1-1+=voiv+>?mOGNUNV5vMeRPndA|_qKW=Nc0YCOIQ#!q--`+!h<~B(__@rM=f9)z zUln}*!*l=iNYR0wA%WRUkRmG0X{3@u*{(S-;-k{FX`w?j0SyhJyi%6w$)dzBE{rsC z&RfM9(t(h57eD|bT!PS5l}0Eq1T`Q5WFr#))Rv#(P&ph+zfnA0+ zSMB3857%FX+}`C%O4fZJLH1YK=xIM&Yi52au2dAbP+bq@_ggN}tO;z${)PCpFL)l5@}t zoyva~DmKJB4-UVNBz^j0YtXV+F3v9(U**USphENu=Rz8dB>r(=G@q3r9Kjt&m>FJ- zakYNvG#&a$_=&`kq>}KcuO|NdXqe;8tX^tgW8|@Q<~!DB{)uGJxCxiwPNrJxGOkd} zC*5|uhthy@e;X>r$N#B5$Bf%M&E2JQqy0e`U~xJDY`yv9In!Stz$9~;%iw-(Uy%g; z;F)`BIYUk1K0gH6&Pm_+%m=9thXb+bz;+u9o#W(uGn`KRzSm^oiT~pxL6H@Nj zACzT!?t2HHxdm~MB~h&9!FS$a8B~Yqd+&`OWCe$bm2$BxJVdYU#Rt^3UK=&>GZ z4#jwKu;!_7^1O~SKdw8TU4z`N-L_{T^%aEID*G%t5sSdIX#dh=uRRN2z$71{!yR{g zB?BU87Ar}{fWN*QJVOh}vh9)K4#ZjXtl21E<SIlE}o*bSIN-R{7P zYiW5+#!dH)2lqd}4VpLny**{}RzCpIFd=J!hqge;cd1dw4!_65szQ4vBBEytu`X5n+WW7S8nOOS$c`b}B zi=l@)Z?fK0fY!rHy>o`9y4fQ|2Gb)GVTnP7A9MNtjR15-V}3m`vdX68BC*-?rJITC zK`;Yc(_>T&u>eb)J^Xs3qB;Q7cRe*{ErGy;Y5VK2aXfeiB!Nhx)`-<1KoX`m7@Ln#o@7PglM#h@{<9qI35oEooPb<0qA(pdJ2;Cmj5c#u)CKK=J#eD^i}8cqK9u0hUZZ3F!?ygfY^z zAt$F+$k3!b1qHPVXaFXKEiCdhZIY@Sg*z_MV2vXUTDo)u$xR#VBK{!0)i!pKRkMoP zB|LnT(}a|i(Y(n`8+??sTaZk&TY#x(w;<5~^-4XGOz3PTb2KJ$He{19_5hgILb%g# zjWRUfYGZLsZV8O)s`{f$9D*WNn??m3S@1}_&?cjcMq!eTHssC%T4@BbjhqfZX;YkZ z57a@Tb{55mLfK&~M(0AFg554Mcx=5G{oZVc;xmEadgg|iQg+5HPoH$N;5;j-N^wwq zx{w6aS1__m(hJ=E<41bPI{7o zOCHh%V8vk|6dlqTauGZV^VFs@%MI}%UsqTdS0Y|9bdjVHD-^9A)r+b+4-30JLRNh; zcYJ;skKC|4wt1pxnTK;yrqOa}?J}XYfN8>7HicZNWm}n`0}aW5X}f4B0F^^+GDF)0 zuKIp#0CzXC&6E2lu8CPZpJh4?u>Pm+U7Rk~! zC?wU|NkhX!geGqS5%YGV#%NL(hoOCbBiNGpkIbG<^eW935K!w{#ScIfduo7c)Tf}S z9pR;r^Xn-nsMj^soHQK+FHJnUsBVT(MGi$Nqsgm>x&_r&1$aoa6}#j84Gxz zR2RXkbCVhy2;l0@F+});g{y&IL_H2k%1v8PLCm!==i9d>IVmGMD3*3dCoyWv%B7i_ zol7a3m&?xO$7$gynrK*QDWqUaMWY2XoG8<7L`3SP($#7ZiI=BWJ5JVF zmbhglCjg&BC8JR-%{G>Gh=f7n9vjE@;{$N?=Mh_x6!O!sa+w>Xog%qSrgfZ5?>ic9 zQKlv_%?8DhZmyg{mWy!>GptC{aBx0auR%LJwCog{!g_Zplc4Sbx)GPARYf~U4K8+H zEh(3sk;_fuM`~2S%oERs8w9gch8`_krC2bLzkaqOFKjgGS*gUcl9O{1GE#%1$)IMs zA+UtGnHh}3R3Up9VdCj<8X<8lSsdb!vx>Ro>J&W7tAwQnWOd*8KaOajn+JWHGchS7 zaf(YTIW?AUj#VsBrD9q7w5PTClv_ZQJT!kLiDz^niiScVrsU0MWe*#KT0Bcj6s19b zvJKGKWdn$*sHCcEnyLysLneoYr#OsB?#WJqQa=rbE(DDq;QS@Q>afiKPe8E0NsG+b znY1%*X8haz^Ij>OgDebx{7n*?j&2}1$*^;#D>FodzOjR|VC~G{8T6UUV?z9nAWdOR zkTPt>F-FF!jbxQnP|{IUtU=%CX7JmA-)2&te%Qspw57@_k)sEzVJC~~9snL>_oFfC zSY9&vD;XDz#{~XPrjnUN?OL@l=H(`)ex``lN^dabGIhz;Q;KUZ9+l%Z9wq_-Qo(y^ z+#rQigUMM3FuR;8psA+{#M~#5TDF;$q6_|M)6$2DSpj--LBZXLlB5vUaH2~eSy zN*V>~kdTRFs3`4-X>}0!D&1$PTi|UuI$bSx$J**L4yP1=@in;rY5gs3*T@%95OsK{ zt8w2WMe5gWwYA#)(7KF={xNZGNEYOZ?-xhO@-_9lJr#blNz_DN^N>bc>QAk?uJ!$a z9pmcpQ4BAy-RY~nKQ^~};#TSPRo*76kGs7QvM>wE2aom@c^h5x}oxls=! z9mcTJcL*%2jLo2~ResWYTz%JyE2u5WTy+qboG(_H+mzdJcN&m>c8;8+&{dn#eeHF+ zuNJpQ-`z3?3RhE#iNgQFa_*=)kR5R{+~IOujX$l(+j_Oz3rlh6R_?#*yI1Gd>Ajvu zx8hdmcU*n$`;p)8auDq%eWZswjR3BZKsvjLby1BUugTYXWEFLUxL?*y2mniSL!C;2 zc#)!w^$I1`3KPL%J)`|KX6}k^E2|b5qkn8szm_Q98Vz~c?EmnZL|dHzS2OCQM= zZ{>?Ot!7E!(sz}WzJ8$fwOy|EYjoSVSd3a|tVsr~$?!CTjV6_CCV(NwB7PsQTccG{ zvAO*SG~@~Usyz;Yu+nWhkJ}ZbMLt|i2a~Sb@_dbKDrVTlfxUAlE@u58@C<>Ky(U6p z)LD|aRWuHKUGOvZ7A7Ji7a0)5x+mLxZ`-Nl`dPS)Yc>`7y(}#{+pcIHxoO~RpGIz4 zBDcQqYxlcQuk>6-Ix_2-k337pj$RZ%X+CRo&1%(oynXJd+g(L{Cr5s%ZN*1VIwdQM zi=lAqI|P)j9iJxh?05N^~hwnT5L&>dcM;Xg3S z-mupDds^+b-n(U4UF>Qcu31HADAP5wC3KTO7uAZ&18!*~Yt`2|>T@@Wp>wm2M*CUF z^EEZwPcf~23!ql3cq?g>s4bS8od2|!EG5f)XgiRa#KCDb! zjk>rnAUw@lt*;+(;Bohx6ft_O+juum7n+r0>NpP*o9`R*BlP5k15R5`T3E5_CWm~H zlHtQna@E#OZfh?(IXl8k%#7wqTQbg{zK(@2`f-_fC9} zrIQ5_G(DA}?3Ij2bB#8W8x?9=KuGICr?o<)m8*M9oUolgZVqhYpxwqv&X{fzaI!UCrIM5z%${ za(y4SkZ|ckJBtSdkVA(wTOVwL9tPuqM8=*02M3~c!+aqhenqa0%|is`U;=V!qtQd! zQ)*n4jKG6rJs2=|uqGmlTn@AJiU_dNXDP{9ifr9FdZsGGBdju(5vr6a=q*$0f@D>s z(a{ko)e;&B4onpqK)$&ThU$g^w&Y-C{LO`))aK*ZyZpG=tRqRptd z)@3AsaxfUQHJplw7zW{xMKETMC!(VnIJmfh&}5#8#;_5gNuwh{G81SgL+N`xMrV_Z zg~~kn5F?OU!UJCA19v>CnRM`VUSeFKrX{^otBFIJG2)J>v&fZD44!haN*U+KbBZye zX+W1tNFJ0Jt|%d#s4;@TV5l^Q8FuQA1)K`Yhi#QIda&9~S^{`|U)mFr^$TifXlW=Z z0_(z7!BGz02X^p6A376d8_|)CoJ7PzVO!n%OF?a7*4>5esIom1kWopVCId8pNlH$- z;geK61dJ;s2(_jO0@eWDO5q0C8-#F*3C#L-(dx*;Mq?9D{kksvIwPiOudUK(?egw= z8Pl+C`!|_6v+3b46Ct**I1D30mj)(Lub{LHDJneWkM6D!K{X$j zM;`#uE-|^9nYuXh80Dg+WlwcI|DcQN1WSq>VTb>ytsu{Xzt>?|^)uoPmF-S3bx|+` zo}f3Ikk~ZR0%t&^HeR#VmN6`)P)Sr#V+n{lGy~{^9@u_2CM}^{u09?g6(1cD3^;2^ z5-u!vyM{{uN%gF39y1<@<^9Ra4dm8SA$i&n?U*I@$P+v{7H>qQaq*~Jq0$-=$jEHw zPYoU}o~VwMB3C-3`{R~yL= zn{8D3r9iF}uA{1R1h%1aw>aw;IHCGQDga6EX59ACry;_1s>xBq)Z~zdh_=Yowp5!G zpz&*vJ}8?B#K;rFe#|mi6$%F65|e?<7BQGn_t za&*24@$tr?m%Ck}*jD)aMvN6Pt82oyA&Q8l#)*UM{ zYzv=Bx{RpS;Q4y}Z?Rpv)*r8*I2zrbjg&&;P>$*c8t9PlHZ}eKrh>vgnNNMMBO|0! zK|HW~hte#FBx7x_jEG9jt{vHEMDcWXmP;)sJ(rZ3wI=5!=cMFkWKvs*Mqk^SPf_t% z*t|VR8=)+Tip|rkH^=|kw6GTlnwdx~7Z*-X6c`MtRu1&X%f_XoX(p^CCN{%+;4uQKp(D%)@ea9yNp2$@nNwGC|lX|J#H(;n+e-m48KtFL60?M5cYoBCU-B58DMx{0h>uJ#(2|h8gAIreG#`9 zHwb7=9MYtyC)G^?q2jp<`_RLvNR|>j)sdxk>3GMA#uWQTJ?Tx!LLO?s3}>l2WdQL& zJdsfbu-S3^A>x6!K`d**gh`(h1_mq8=tP@xSm=T{@|qlZw5N`Egg^y}mYF z1?tDhG=@+3V-p>a1k(i%&4u3R22~#OmpLqh?EQ0-myGG^{OUmy5;NyH5}MpZdeazp zE-daCZf40)SmH7XSyPP6S~iV3qN2_69(NXRfRqvE+pN50x{5>;F()nJCF7nqgb^xk zevbGKbbHfB4xrC{Pq?kv3HF_|5&Dm(OGaG)pW(PDGSeHet{m&}x@;g%x{umrQQRv{e2v<34(q80e>OGNMxR zyu4w$iGs^~dL0Y5VR4ru0Ey|Sh?90Aj$P&Pr`4F#b~$6ncgk~{N;wB>`f=Sp%kem6 z%ZHaX`t?oRI$pa)fa23eBEhlW3FN?oU9O2QaY;}@VEgWEz#?0>+6AE$nA$<7O(~fN1-fy5b5&_!-bW0|C1AMK#|I12tYh|Z3OAi7HURvW?pA0afqD* zg!Dm^{PD6B!@kiJ_&Q%H9&`5g1OTU;e98`!WBHkY3?7FSQrm?E(S?j|MMOH&XS{uO z4BVzKFb-?DJ5pUnO4v}5<8dc7d_}F>u>L#{4rY`@+%-Wyc>vfwUmlls;!L{yy6W1R z0L>WxzhUqqKj;_$2#D!;4AKk-VLCy0OS5jDQVQD2CqTOA3uKC7ar?Lc5Bqiii~pd2 z03iVXziptTU+5qJ2u{K{4AKm*E0AszBom~WC5iwx!NMQ~Knb9Z90m>P zfU|KKq?`z_O@e^I+HOK%EZjyZM+3B+guq$2j8e`d0un+UN{Dw{Q8ERSINDh@V<T;5a1; zTN<)~I_E4`XA40o4Q1lwq#6e9p-CX6+Us1i_=#_Xl#e1eaHmFGyaA2C>MjP`=Kx4? zMCX@w&Khrz?wh!Dj*;M0<4Rq_HahfnxQm2JIv;&DiE*K>-#0es@E4G*ZOEC%o4VfS z;u*kw;0>_K$6umkX6Zxs5maT-rg7H_Y3A|v;UIa^4vn@>z*BK1I%AW&fIw=ct#Yu; z)>h$2JKU1;BkDIl7V&o*gEsJ2UBTVFRmkA=c2)5j=0zwfHD7Ju?x5piuQcn*=cukGl8wZaf36RB5Vz|jfAG`-H z&aspS;3yY=A(2Y8RY)n?T@HmQByvXc`;wkK7$ms{@h9qNXhR@luV{E!T=J?$b&ABq zVn&+{qw(5RTBV~laYLIK#$+~}ZR5s=cu9pXTcu~yt+$vw0G_Jt<&so|w)u4~=wU7& z4$ESKTOw(Q?P4(lQ}!HV-6Hk@*%oMC6flTmw!|`dRW)a3GG&sg9KbJ#hahsz_6J`-@1A?a#8zq~fAjye6mnnA-02Z;%U6K%L~1bfcn4ZI|9-gZvC zW3>9iAr_$#3)PAz7)|6O`*iR}+BA$&2>b&ALS2Uq#gBfnfOwG42qY&P=||9qE%USF zUH8rjEQ(T&@&XBjW20?D-a>MQ=Pr&d(r+0;C_bA!^-8Sx^t6a`P;H$xAS83&awLJ* zxyL_!tddA?y%Hfe+{p>ceZ-OoZ@?m;xZiptmA?&C6m+eMrbUiz^W?zDVx?La`8a{FwE1V-Cwrw7et_R;pSXBPu#@m>?zFXmC8oJi z2WFNt@o~AObM9Z%G)@vc1vo?Jj@}>`d`F+O+h%}SpQ}SdI6)-UtewF7wt2Ah$Telt zYAW6d8R8wGE_#P`>0;g}?H2F{cL)`AXs3k}37mwdWv8Jfp)$~!bN(JnteN=_2WF`; zu4s74>HXfo;6Ui)BgPXaRV;~HEB?343O)E#b z21F!$fSkhOQSu0G7ZQLXEA)9B)eDJ7>{=$Y7WDS``uzU@lI?fAUT;u0zOwm!>tLYo z*Zc+t1%twM&hzNUA3IE4I9gu63)o?yF!+YKV!w1YFBuOJ5}GP5GB+C?j*rLWGC3~B zK|K8cWb9E<(svZJ)b$FL_bV2zsn2KXs`MSFYuk47+1rkPy3qH1=X+V-e-8geqta<~ z+J6I4snu%y9cP8%_?q7r#@8?L{EsJJ<#~GzkD2D|wtjd0dHYX8`1(GVr?vGq-mk6e z?fs8u+T3n;TfOG@+uv{f&v)M7aDSKc_y4C0`tbe_?eOtFFOTH;esAyd@p#|k==y)p z`ue`Vv+e(UdfMv#M<LdS=Di!UljyTQ!Grb~ z!vXMiq0IcpZPT%R%&Dj5cXkE@xEHpYd?-H)FnrzP;=3NuMO#+N5r74V1#Su{4ro_l zsm%P5$L!Ps-(L^m^!N|OKOY_|86Av?h_r}~I9^6Pez<{fPaqXzmiCURvbYm$$Jhs0TwS>6WRh3%RVRQ$tftOnX)u^8t5(KH0`hKc}3F2rLkJ zER3ytHGB_Uuqj<9vyIJrC+Hmc#v{dVlECD!e*-@=Ii_>W=@{o=9q@Li(PQASkggl%a+U(Gf(j;o*`}_5v z`by6|oV^<;SEKx!r7=lU*$WqI&I>FVDsJ;Pp)Slus}=EqRxJ9_L3YEx;#VjsMv#d8 z^dSCai3}<$@ULRfMnQ@4qW_&UL)>ILtab|;F3?Ia0pz{zd$muSr@Z1Rh1rX&&MHb5 z_WPWcGIZm&g~zNG7|a;6J&b^_xe-SRv<;hm2EM+(T2`H?{tXlfaU(RlK9&sb0ruE; zM^XNs#x-GwHdB7KY2t zoJofG^^=h&a_A20%2sux0GO4OoSYnKhI5;el$)Jp8ab(Rvh!0dADCiHG}WmtIk}9+ zUSBd!>^qUQ=H`RCcIO$xMNT!btp@;2wLVA?>rAv1jZ-gsOX`0BeN8PZ1=5m(8HL0*n2~5)wuy)%t z7I2nc79z=mMdU3reH0k4;rW9Lso{l*7BEo)j1*|G;>ij`QbLpz$TzIWSYmit(J2)m zsl`$)0ILP27OYFfuos%e^M&V`=!ocj)L*c= z0_cj&PlZ4g0#p%LQlUzTDk!XRSt6tg$`vqIW>#pf*s1cUN~9@KOG?lcp)0>DMpl%q zVOr9>g0>}X3iQo)rEm)VrEtpm3i-&-xl@r?j!yI;kG}Py8hM?0mA0;`Noo z;u1p7%1ThbRm-f!_fzSx-DJmkke|EcR`-33ghJ;(CtwrFbKT(SeiN@9c|4xE5B^MQ z9gJZE{ZRzqteKKR#G7cD6JxH6fx@BicJ9*CL0dF);-wa7Sy-W9VI}h7>?F!7n zptRuVEmzuUqk0D@Z%@ z1{2I6H^bOfUvp}L=h>WHjL(^RGJu&AYKFTd)T9~vR2X7`D>feO0YVN8oGD;EH3m@T z@+_be#}tGs47U%55QK4lt)tnoQ>{e1url_jFr|qeiHSn$HLI!=EGCTy5BQPE$py!U z5zl{mFc`Y1fo9?W7lIWGJxQ1!S;W7GIRgaz7*?TDJ|(=qL|-1`px+9?J`STb0k->2 zAJZBSlX5+dp}D-IsHhET!o@`RS%cr5pu1q~2iN!aC}Mgn6luz`F?w`-nkoDIHw+ET z1x)MFyx1FgMtl^8-1p)bs4j%KNkg3od((+XdSuoIli;a>>Qn3#rV z2w04SvDh&L=RPQXsI2l@wU@ub&%3aG^0xxY z4?d4zTa%X8eB#(W=JWx6&q`L$`^0)a=&s%W;l${}-~AiJNHoV~dYlK^vBhTpjFtkp zAc$|Re%|Hp-{pNAzUAuAHRwU8YaA(7-Ud?ewNiC|sJtq^WZ&bxlNZVTp@pF2fwNbn z#qxSjof5wfgE#qD75&McuyfZ8%@_ zEDWq27xv1`cLJ4_fd3dWzhb@RzklmEm&UQE(}&C+Sr$L%x!C)>KI372+=gxUj>`or zRcYUguJD@?>U(ZV7e&XEiQ6$;oLrNZV!5XLE{p8W`$o3_EFXl{hH!X z%K)Cne0vbyynI)Mc~7uTlbR%-u}~c1_x~I>!`y|+NrPA+qQ?XhT_@WCfA(?k0{1E- zzv|aLJ|`BU0-IY*z_KWy{tJKe;<#&0qBpTI{=7E1{83@+AY_@722PpUnMPvcD-6_` zuQO<7+|Bu%GdQMk%;lM2V3(Rdn%_)HWGRsbM;Rt$>52?iW`xZVn!^{Fu`|*$Zf5Y# z0h}{9rg6;s%;p$}^l-x|lmDZcTinwIqv)Mfnd)@wLmJ#FM5F9AHlTHzaLE#%s`^GE z>H2BsNd=0P2a?!QkEHT&uySBoB>GHCxAcGzH~;?=Uo$xVO({IIInDSdkeac`&ufaSKBI_8BXaKA-1m{w6jp_Z13K>S=<@DP3%~5^##XtpNuOMguiF!G( zV89(u;AD{6!D|sgwu&JbWe9&_J>8HfmI-^h0Q*y0!VuNB6b#9Ni8ri5T`LD>Z9SUp zjiJnN&Tl9X{bx6$YwtCIHmn%X;|JOQ7q%21XoU5Mpbl?{BwqX^3hM+vv;@!cteyBJ z;F#9T<_y}w8+=)*{#4ED5f9EB}$41@#)GMO`87lizxVP?_O%sV*pW)c(50KIb#uGek;-np|sAE?NqDi zJB#H@I)r*N6`=X5uMO8Lk)TgH5lALT zi-ewJ1JJ&=uD$On`J#KIH@UO;j^uiA-esF!PuW5=n?;f@#|8nS` zKaH8Ow7?7KuJFDgJb3h8{Akq#gW-d~y#aJ9_%heO&%1XGe^vxww{nApjsA`0aQn*B zjN(Y-*nSA4tRM6qw%2bDH{Uh0ErZ8;Vx$(jgR@;4Yv$=Z+<#^z++8A%S*==40DePb zSR32EH}*-rk`x!`dO3jJ;+c=D+HU(&Jz;4857ZqvGl-m^1=+VZe(|E@#Y zvoE*lZSdTu>nE%)D#rX!{M(mwce!^W%^_K z_o1qPGyvV%g&u@+@py|FlZIPqrM}79sF|d-^cSU&p_aXYncKp_B z9*>`~`t67BMRmB(^m*^^PvGuzL?~Zx050oCg6;W*73%#$JAO~z=%If@|E!Z5-dg@$ zY|pGFA6$n5KTdIF1IlP%L@Ym8GZA@&bAzBo!&?Q{c6^8rbWBL zD}XOX7v6*O72uper|^33vImwf6}Rjc@k(X^>{)BKIKFn9hayY=-_%c>!CwCo8DJ}> zHtxs%scetL&pO|@PW(i13CkK+z9Y4Ku*V!ofr%0!wgQA#vD0$~tg8Ah!OEm0*UjHB2V*CbgHOK4u%*v5?!xxOnSzPg77g)*I z*uZyPeB0MP$A@QNSj0WV^nboMsUyBMs7!q2m^ddwB*z~LUeJ3Lb`_`sj+-kWQ z=#t%8YbmeTKD&#;)@hisZEv!&CPdkGLU`~Q8v^MgfJKo{EUSh&6y-QLNM#=MgC_h4 zgF9>@S@en_h!kVY?0;P&h2kM|a+GKM-tGAxNu$%48f>aGeRA-p1-=24a# zv5-iIR#*O?2&&pX*Fkz?=0H$pKfA!Qbf@sAq9O8|)$s{oJlJi?j9bf}`P1oEcTjAM zy}8M@?3Y_j zPf>xvC!g!oKR@T{ps$p;s&-n@p1~%HKVnRCw5!#$YPlIqq_n?fm6*#OPTh^cN_K_6 zDbRUWdI}|AG`up(m}7{d|H+3)qC6t`CXR9d>j*HKW~Quy`{Y$ zNr9)yY9uXx^`XG{7wwZt{{SM{F~$hoI6lX-25`TFfZnxRk@fwbYV`f41CYDr`IrBy zuqW7`s3V9jQzPoZ{!6xAt*=*UIup0!aD(98p#R*j6X{>q0WYwh4`8MBtLk&uAN3R6 zUznH>)`SwD^`Y8&ACpo4i)kRe+lh9skX%dj9kbvP(JSy4)vx$lHElxpu3&QKSPfWa z?mr;d#`5DQSJJQR@5|IFz?$NKn!pp##zWcMo!MvVjxII~WY?$QjB^+VoCF=AfHMu; zczz=erThk|Uk)v{10RP3zn{=wvJL>(at?Sb6OIqNhBJM?UukTY% zzC5S!tp2Sl-obaAKKK(~0|{vQ{5)Hd_`TeE;pZ8z#GT$J2{Ll=nIQxT^*LOX&=?5QwNZYkUzHb6@KV#qoa(@r? zb$AY^bTcLGiru|;rSFAm;tGc^HY5KB)^v5V2D7HlTwRe{kn1&jLhg$=!xh_>Vj%qz z&DjDixmkkqg8kx~Xj1b`ix)H_L`3>V?Mw(K5oB%zJTwk~y0ZO|e-iNQnN>w+%Dsyw zL~Utb$X`)iptHqJ3TR$)u-;_W(WMg(jnIwVI9bN5Qo+|T$19%EC4M4B11?_tA6;Gx ztrmzK!Qd6{l`LPlM5uqAiCTgqf6QJ`Xw~qI%x`WfpyRRMV-@Wt*5R4AZC_T-t94!*{8 zvHn99>y?o&J}q%y7`)LYEo;=-W{qXI(Y}GZX^U$J&lH5F=s{g}#aIi~EA*SiZ2nSgVEl3Xn&cJr^)v5L_~^WyP22 zkwtKxwSwA*Shch(jx7mTvQvK8ym4#=<%qK4g;j0IdE)Yc(mid8-92ytY+AG>;>Ffn zjA8QPskS!47S`VkuJ}J|5=!@qkSpXDTwcs9QTz&o2>DX!h06+sGFFtSpbKkm1Y82R zBvvJZR!pt1r84<;v6XBbsd8f274sA}ipdCQnt^HVN}FGCHhHE0QlHDf7R1q&vURu zm%s^tG<|WSeoe%zNfy}Ln^ancSE^R5tzbR7u0auAR?J7i3MSf(ROztv9!36yXd5f@r3+Jx91R+)i@vr z?gy+8Ahf3^2NEEt?wa}#TNZJSDyUdeGZ`RNaN+4Okp?I-fW;z^0$m6}rxdSMBW&jy z9;M5T01sup7c#|GWUw9N7{2gB$C%g=)<DngwO6{>t^ap;5}M1 z>?dXw-jF%P3rbZ0YD@MC#e*R7%JK^Qiu=Na;Dz&)$JuN-|BNElvK8Rx5-aIQk<){gq!Cy$faTwxwFdt-qo}L$!RhcL7LHNjxwWtnk=MW^! zUZ8iIH*hrgQ5a57F#WEOofhZl~@H10_-lOVfeUk^XJDAU3 zWIM^yq&_PoIuT=03`?L3V&0|OS#?w`hM5;YXyDwk+Y8Zt8ftHCru8thNbqlTZ5zRN z|L^^~ht_xs9-dT(WOv1-Yl9cs0dwD?x?IcYz&>*!ZMquLEuuA1pCM~L0j#{#RbwA%D7 z8tvEATSP^@X?ddH)A?L)LrFE?_b?+})~kmU<<#ANjn>+VCNnd=)5>!!Zn`zN`KO4^feN1xtn`-$ttUc2e&5_fPj@ie+CLrC}kx=0?d#+S!9VyQn-A7^YLL|5&)qD8xDkt09c3~2@L=2 zI0u+S5KzY$hB*uv;S6{L286)>09ZgQG98iO{RtKW$?BRPu$(Q#ijD*%1PK5_KmfcX zfB+7$Cw58z9Z@2KQ3S=IC_OKYSO6Tb36U+V)&U@qBBS9TpdMk~2=K2EP=FQ5D2_Tr zi4u^O3!(#AUe`OfJ?ZN#vhb6-`N()}D;Vl+jvcB0UK?md@vu;Z>SdZYVBL;!hH-;- zEyN)RL?RH%Hzhcr`Ak+Gs3U&E#a7EuVL(#B1F0G9bi9K})|4EKB8pA&fT&jsiep4k?WUiX!EOlwoC-Sz)Olh>IHy1d7VyA+bPV zsA908sA34PP(W-%SXLq+h={P!jZ7*_EGV&IQ9}e+ii|cQD#aoNA{L4nNZ2Y6s4$|W zRDn_`2qjY%#Gt^o<5DuPDzGYG*wF~k6oo*Dpj3jO)H0|520=jocF9kF*Yo4p01wCS z=jYV-{QP`-4GWEzg@~yoyPb11o+dU}3|_aAET+N^qFkI_;CbSe+U6 zbB@IN^f!z)Yh;GG-%iCFX9rEaL@eSylRRA%&iC{77gGviC z5jKB)c%C+J?heuB2#;TWxQn^DQe4^IJni5*+~Egh*PLFwdOU2|IwN}C*-6%7o`z!V-Y zcX1L9v$3Svad<-H>L`Vv5;FiB;&(yOq>a!wNGNWBpkO`=cV;XZm;lY(8JW4bklU5Qk6x@E>cxWR8Fc?qa_&HbquOfLg(Pj zuJ{iO@Eq~J_WOedlBu~>DnR!Kd)vNWhi}WCH_qQ%N~w(h5qE!b`S&jV<=@r!_b;5j z{e16uGoyD!Zq;w`#`*ERDBq_W_9J~b->n}^Qg z=-=v%{+Ql`Z$>xg#`&?l$lswG^kaT(Z}LX18|Oy+xZj-{@}p3V*p00kY;8E%ak>$* zqj*uiOmD`GiyCxpJZtFRA~sBHNZe@Hal6>r@w1~!jns|PjpN4gV@ZwwUH7rR{(bin zHx4%$&$_ z_M8v-a>YRr`KA4n=f2lJ!MqY{+x_MX>v{19N3Jk`X6OYQJGP)cONyc#4M}!jTxN8m zC(^X1L_T=#XLNG1WaLWO{Ch3P=gQ~fWo2da00f^4HzOM#I~$vkidl5>I97w<_uMQl z9~+Ow;&I`53({DEy9~b1K6F3^v@!bbG)7*4oA}$72Rbh%VI9^>*glrq2R_?iGJUkCQ}Kfp@Rgyk7>0>ij$>9)N#hB9I>sNIz@iWO(gNqzpXRQu3@Cus5yZ z3jl9anxITISUhBSHg@Cy2Fi?9sNDUq=yn6bo!!A4Pj`QtK4`QQO|)j-7LjSWntOE1 zKzepE!_nE=PD?nUTTyHc4Q1w+h=qI6cpnj0!Al>wB}1F*Biqwsky4hl@_-!}^p)3K zxbk-Y$OJzTQoA}^ovkFUz*S2_ zt2)k#g2j;7sj7Qfv@9j{hM?7J2$Z8DxcKjZZ^i8a*3=E9g+1wQOY37-pQ%_jM%}Np z!@joiwV*Nk+e~(w=^_IRSxp|pK_9gT!DNL;xnX2Bg$XDsRYY(X@Y%at9*wpIlOjE% zcJi%4+u9R@{a0GpHhG3E{UKW+2)5-dIrkTl8e8r#}jEzId`cps8Nc#c5ilo7l?$>gSyx6X0zzeHYE$z!fdrL zyjgjUz*Y~Gl?{u{m^2FtOoblmPZ?^&gCwZ5-!}NyRY{sY8Ns=FjP_)!zP*+#Y;-}e z(H#|LheUi3ppvH2Dhl0V>Fq1Y_i$qgV%?HzQY?8TKHJ1l_u?hM<&aqB{=e?zEx?z*R+9Rt-YQ8%uCiX~w ztxOgQ9Xpcm$Z6;84x=TY)F}q!sm0z;!v;dha73Z)0W$jp8w-SO-8O!V^JW`5ngH!%X ztx-P~_E7=U{f-CC-XdC}g$|?$Kol}CT3S{!NMlQ{m})F7u9mUjxf@4rB#W*X%0Dt1 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 JJ$nE^2LQN{)1&|Z literal 0 HcmV?d00001 diff --git a/src/common.c b/src/common.c new file mode 100644 index 0000000..6cf9e5a --- /dev/null +++ b/src/common.c @@ -0,0 +1,87 @@ +#include "common.h" +#include + +YSP_IEC_DATA ysp_glb_data; + +OUTPUT_TYPE_DEF my_output_data; +INPUT_TYPE_DEF my_input_data; +SAMPLE_INPUT_TYPE my_sample_data; + +YSP_PARA my_para_data; +unsigned int last_sample_time; +ANALY_RESULT ana_result; + +pthread_mutex_t my_output_mutex; +pthread_mutex_t my_input_mutex; +static int mutex_inited=0; + +float last_co2_ppm=0; +int co2_is_ok=0; + +int comunication_flg=0; + +PID_ATune HeatAutoTuner; +AUTO_TUNE_RECORD HeatTuneRecord; + +int ctrl_fd=-1; //ư崮 +int sample_fd=-1;//ɼ崮 + + +void mutex_init(void) +{ + if(!mutex_inited) + { + if(pthread_mutex_init(&my_output_mutex,NULL)!=0) + { + printf("init output mutex failed\r\n"); + return; + } + if(pthread_mutex_init(&my_input_mutex,NULL)!=0) + { + printf("init input mutex failed\r\n"); + return; + } + mutex_inited++; + } +} + +void lock_input_data(void) +{ + pthread_mutex_lock(&my_input_mutex); +} + +void unlock_input_data(void) +{ + pthread_mutex_unlock(&my_input_mutex); +} + +void lock_output_data(void) +{ + pthread_mutex_lock(&my_output_mutex); +} + +void unlock_output_data(void) +{ + pthread_mutex_unlock(&my_output_mutex); +} + +unsigned char cal_sum(unsigned char *buf,unsigned int len) +{ + unsigned char sum=0; + unsigned int i; + for(i=0;i +#include +#include "scl_shm.h" +#include "PID_AutoTune.h" + +#define WEB_DIR "/var/www/web" + +//#define STOP_SAMPLE_COOL +//#define YSP_DEBUG + +/* +#ifdef YSP_DEBUG +#define ysp_log((x)) printf(x) +#else +#define ysp_log(x) +#endif */ + +#define CTRL_SERIAL_DEV "/dev/ttyO4" +//#define CTRL_SERIAL_DEV "/dev/ttyUSB0" +#define CTRL_SERIAL_SPEED 115200 + +#define SAMPLE_SERIAL_DEV "/dev/ttyO2" +#define SAMPLE_SERIAL_SPEED 115200 + + +#define CTRL_TX_MQ "/ctrl_tx_mq" +#define CTRL_TX_MAX_MESSAGE 16 +#define CTRL_TX_MESSAGE_SIZE 1024 +#define CTRL_MQ_PRIO 31 + +#define OFF 0 +#define ON 1 + +#define INDEX_H2 0 +#define INDEX_CO 1 +#define INDEX_CH4 2 +#define INDEX_C2H4 3 +#define INDEX_C2H6 4 +#define INDEX_C2H2 5 + +#define CO2_SAMPLE_LEN 50 +#define CO2_BACK_NUM 150 + +//继电器定义 +#define RLY_OIL 14 //油泵 +#define RLY_YV4 3 //油缸退(I5反馈) +#define RLY_YV5 4 //油缸进(I4反馈) +#define RLY_YV6 5//气缸退(I7反馈) +#define RLY_YV7 6 //气缸进(I6反馈) +#define RLY_YV8 7 +#define RLY_YV9 8 +#define RLY_YV10 19 //清洗阀(进载气清洗) +#define RLY_YV11 10 //气缸进油阀(脱气) +#define RLY_YV12 11 //进气到集气缸阀 +#define RLY_YV13 12 //出油阀 +#define RLY_YV14 13 //清洗排空阀 + +//注意新RLY_A板V2版本将YV15-YV16移动到7,8了 +//#define RLY_YV15 14 //样气进气缸阀 +//#define RLY_YV16 15//进油阀 +#define RLY_YV15 7 //样气进气缸阀 +#define RLY_YV16 8//进油阀 + +#define RLY_YV17 16//样气压力平衡气阀 +#define RLY_YV18 17//吹扫阀 +#define RLY_YV19 18//定量阀(6通阀) +//#define RLY_YV20 19//传感器平衡阀 +#define RLY_YV21 20//CO2传感器检测阀 + +#define RLY_KA1 14 //抽油电机 +//#define RLY_KA2 22 //传感器加热开关 +#define RLY_KA3 23 //柜子风扇 + + +#define RLY_KA4 24 //采样单元风扇 +#define RLY_KA5 25 //采样电源控制信号 +#define RLY_KA6 26 //冷井风扇输出 +#define RLY_KA7 27 //冷井电源控制信号 +#define RLY_SENSOR 29 //传感器加热控制 + +#define RLY_FAN 30 //采样单元排热风扇 +#define RLY_PUMP 31 //气泵启停控制(220v,550w) + +#define RLY_KA8 21 //排水阀 + + +#define STA_I4 0//油缸进到位指示 +#define STA_I5 1//油缸退到位指示 +#define STA_I6 2//气缸进到位指示 +#define STA_I7 3//气缸退到位指示 + +//注意新RLY_A板V2版本将I8-I9移动到6,7了 +//#define STA_I8 4//油位液位开关(定量传感器) +//#define STA_I9 5//集气缸进油检测开关 + +#define STA_I8 6//油位液位开关(定量传感器) +#define STA_I9 7//集气缸进油检测开关 + + + +#define PRES_PA1 0 //载气压力检测通道 +#define PRES_GAS_PUMP 1 //气缸压力 + +#define START_PRES 0.25 //Mpa +#define STOP_PRES 0.51 //Mpa + +#define TEMP_SPZ 0 //色谱柱温度通道 +#define TEMP_LJ 2 //冷井温度通道 +#define TEMP_SAM 3 //采样单元温度通道 +#define TEMP_ENV 1 //环境温度(柜内温度) +#define TEMP_OUTSIDE 4 //室外温度 + + +#define PID_SPZ 0 //色谱柱PID通道 +#define PID_LJ 2 //冷井PID通道,输出对应A3 +#define PID_SAMPLE 3 //采样单元PID通道号,输出对应A2 + + +#define PID_EN 1 +#define PID_DIS 0 + + +#define I7_WAIT_CNT 12 +#define I7_WAIT_MAX 24 +#define I6_WAIT_CNT 12 +#define I6_WAIT_MAX 24 + +#define I4_WAIT_CNT 8 +#define I4_WAIT_MAX 24 +#define I5_WAIT_CNT 8 +#define I5_WAIT_MAX 24 + + +#define GAS_CLEAN_MAX_STEP 17 //气路清洗最大步骤 +#define GAS_CLEAN_MAX_TIME 600 //气路清洗最长时间 +#define CLEAN_AIR_REPEAT_CNT 3 //空气清洗次数 +#define CLEAN_CARRIER_REPEAT_CNT 6 //载气清洗次数 +#define GAS_MAKE_REPEAT_CNT 2 //制气重复次数 + +#define YV10_ON_TIME 12 //进载气时间6秒 +#define MOTOR_RUN_TIME (3*60*2) //抽油电机运行3分钟 +#define GAS_ADMISSION_TIME 8 //进油气时间4秒 +#define GAS_MAKE_TIME (4*60*2) //油气制作时间4分钟 + + +//状态定义 +#define MODE_IDLE 0 +#define SIX_SAMPLE 1 //6组分采样 +#define DEMARCATE 2 //标定 +#define REMOVE_GAS 3 //脱气 +#define GAS_FAULT_PROCESS 4 //脱气故障处理 +#define PUMP_OIL_PROCESS 5 + +//命令定义 +#define ENTER_IDLE 0 +#define START_SIX_SAMPLE 1 +#define START_DEMARCATE 2 +#define START_RM_GAS 3 +#define START_FAULT_PROCESS 4 +#define START_OIL_PROCESS 5 +#define STOP_SAMPLE 6 + + +#define NORMAL_PRES 0.103 //Mpa +#define DELT_PRES 0.005 +#define SPZ_TEMP_DELT 0.01 + + + +//低字节序品质定义,由于是低字节序,mmslite会将高低字节倒过来 +#define GOOD 0x0000 +#define INVALID 0x0040 +#define QUESTIONABLE 0x00C0 + +#define OVERFLOWED 0x0020 +#define OUTOFRANGE 0x0010 +#define BADREFERENCE 0x0008 +#define OSCILLATORY 0x0004 +#define FAILURED 0x0002 +#define OLDDATA 0x0001 +#define INCONSISTENT 0x8000 +#define INACCURATE 0x4000 + +#define SUBSTITUTED 0x2000 +#define TEST 0x1000 + +typedef struct{ +int auto_turn; +float tune_input; +unsigned short tune_output; +}AUTO_TUNE_RECORD; + +typedef struct{ +int step; +int dly_cnt; +int repeat_cnt; +}CLEAN_STAT; + +typedef struct{ +int cmd;//命令 +int src;//发送者 +}ACTION_MSG_TYPE;//动作消息定义 + +typedef struct{ +unsigned int t; +unsigned int stNum; +unsigned int sqNum; +unsigned char dataSet; +unsigned char numDatEntries; +unsigned short next_time; +}COM_HEADER; + + + +typedef struct{ +float Kp; +float Ki; +float Kd; +}PID_TYPE_DEF; + +typedef struct{ +unsigned int relay_ctrl; //继电器控制 +unsigned char pid_en[4]; //PID使能0-1加热,2-3制冷,0关闭,非零开启 +float temperature[4];//0-1加热,2-3制冷 +float volt_output[2];//0-5V输出控制 +PID_TYPE_DEF pid_para[3]; //PID参数,通道0色谱柱,通道1冷井,输出到A3,通道2是采样室,输出到A2 +unsigned short man_output[4];//ch0=色谱柱 ch1=保留 ch2=冷井 ch3=采样单元 +}OUTPUT_TYPE_DEF;//输出数据结构定义 + + +typedef struct{ +PID_TYPE_DEF heat_pid[2]; +PID_TYPE_DEF cool_pid[2]; +}OUTPUT_PARA_DEF;//PID参数定义 + + +typedef struct{ +//input +float PresVolt[5]; //pres +float temperature[5];// +unsigned int io_input; //io输入 + +//output +unsigned int relay_state; //继电器输出 +unsigned short pwm_out[2]; //pwm输出 +unsigned short vi_out[4]; //模拟量输出 +unsigned char pid_en[4]; //pid控制通道工作状态 +unsigned int work_state; //工作状态 +float temp;//油温 +float humidity;//湿度 +float water;//微水 +unsigned short com_flg; //微水传感器通讯状态,0=OK,1=FAILED +}INPUT_TYPE_DEF; //输入数据结构 + + + +typedef struct{ +unsigned int data_flg; +int ref_out; +int sen_in; +int amp_in; +float temperature; +float humidity; +unsigned int co2_ppm; +unsigned int co2_len; +}SAMPLE_INPUT_TYPE; + + +typedef struct{ +float a; +float b; +}PRES_FAC_TYPE; + + +typedef struct +{ +char version[16]; +char station[64]; +char device[64]; +unsigned int start_hour; //采样开始时刻 +unsigned int start_minute; //采样开始分钟 +unsigned int start_interval;//采样间隔 +PRES_FAC_TYPE pres_fac[8]; //8组压力计算系数 +float volt_output[2];//0-5V输出控制 +float temperature[4];//0-1加热,2-3制冷 +unsigned char pid_en[4]; //4路PID使能信号 +PID_TYPE_DEF pid_type_def[4];//4路pid参数 +unsigned int sample_len; //采集长度1-5000 +unsigned int sample_rate; //采样率,单位为毫秒,取值范围为1-1000 +unsigned int sample_offs; //采样偏置设置0-4095,对应0-3.3v +unsigned int sample_cool_en; // +unsigned int co2_pos; +unsigned int h2o_en; +unsigned int auto_gas_en;//自动造气体 +unsigned int run_mode; //运行模式 +unsigned int upload_time; //上传时间间隔 +}MACHINE_RUN_PARA;//机器参数定义 + + + +typedef struct{ +int start;//起始位置 +int peak;//峰顶位置 +int end;//结束位置 +int width; //峰宽 +}KEY_POS_TYPE;//查找到的位置定义 + +typedef struct +{ + KEY_POS_TYPE position[6]; +}FIND_POS_DATA; + + +typedef struct{ +COM_HEADER header; +}COM_FRAME; + +typedef struct{ +int start;//起始位置 +int peak;//峰顶位置 +int end;//结束位置 +int width; //峰宽 +}POSSIBLE_POS_TYPE;//可能的位置定义 + +typedef struct{ +float lYmin;//左梯度 +float lXmax; +float rYmin; +float rXmax; +}GRADIENT_TYPE_DEF;//梯度定义 + +typedef struct +{ +float fac[6]; //依次为K值,柱修正系数,脱气率修正系数,最小面积,最大面积,离线/在线计算偏差基值 +}FACTOR_TYPE; + +typedef struct +{ +FACTOR_TYPE k[12]; //12级修正系数 +}CORRECTION_FACTOR_TYPE; + + +typedef struct{ +POSSIBLE_POS_TYPE position; //可能的位置定义 +GRADIENT_TYPE_DEF gradient; //梯度定义 +CORRECTION_FACTOR_TYPE correct_fac;//修正系数定义 +}GAS_CAL_PARA;//气体浓度计算参数 + + + +typedef struct{ +MACHINE_RUN_PARA mach_run_para; //机器运行参数 +GAS_CAL_PARA gas_cal_fac[6]; //气体浓度计算系数,依次为H2,CO,CH4,C2H4,C2H6,C2H2 +GAS_CAL_PARA co2_cal_fac;//CO2计算参数 +}YSP_PARA;//油色谱参数定义 + + + + +/* +typedef struct +{ + float v; + int q; + unsigned int t; +} MV; + +typedef struct +{ + int v; + int q; + unsigned int t; +} MV_I; + +typedef struct +{ + char v; + int q; + unsigned int t; +}SPS; + +typedef union{ +MV f; +MV_I i; +SPS stVal; +}SCL_VAL;*/ + +typedef struct +{ +unsigned int secs; // Number of seconds since January 1, 1970 +unsigned int fraction; // Fraction of a second +unsigned int qflags; // Quality flags, 8 least-significant bits only +}Timestamp; + + +typedef struct +{ +float H2ppm; +float COppm; +float CH4ppm; +float C2H2ppm; +float C2H4ppm; +float C2H6ppm; +float TotHyd; +int SmpTm; //采样时间 +float CO2ppm;// +float Mst; //微水 +float temp; //油温 +}YSP_PRI_DATA;//油色谱原始数据 + + +typedef struct +{ +int start; +int peak; +}POS_INFO; + +typedef struct +{ +YSP_PRI_DATA result; +int find_mask; +POS_INFO pos_info[6];//找到的位置 +float area[6];//计算出的面积 +float spzTemp1;//采样前色谱柱温度 +float spzTemp2;//采样后色谱柱温度 +float samTemp1;//采样前采样室温度 +float samTemp2;//采样后采样室温度 +float pres;//采样后载气压力 +}ANALY_RESULT; + + +typedef struct +{ +USR_MV H2ppm; //氢气含量0 +USR_MV COppm; //一氧化碳含量1 +USR_MV CH4ppm; //甲烷含量2 +USR_MV C2H4ppm; //乙烯含量3 +USR_MV C2H6ppm; //乙烷含量4 +USR_MV C2H2ppm; //乙炔含量5 +USR_MV TotHyd; //总烃含量6 +USR_MV SmpTm; //采样时间(mv_i)7 +USR_MV CO2ppm; //二氧化碳含量8 +USR_MV Mst; //微水含量9 +USR_MV Tmp; //绝缘液体温度10 +USR_MV GasPres; //载气压力11 +USR_MV GasBot; //异常的气瓶号(ins)12 +USR_MV MoDevConf; //IED与监测设备通讯异常(sps)13 +USR_MV SupDevRun; //监测设备运行异常(sps)14 +USR_MV GasUnPresAlm; //载气欠压告警(sps)15 +USR_MV GasLowPresAlm;//载气低压告警(sps)16 +USR_MV ActCyGasSta; //实际气瓶供气状态异常(sps)17 +}YSP_IEC_DATA; //油色谱IEC 61850数据 + +extern ANALY_RESULT ana_result; +extern float last_co2_ppm; +extern int co2_is_ok; +extern OUTPUT_TYPE_DEF my_output_data; +extern INPUT_TYPE_DEF my_input_data; +extern SAMPLE_INPUT_TYPE my_sample_data; +extern YSP_PARA my_para_data; +extern unsigned int last_sample_time; +extern int comunication_flg; +extern PID_ATune HeatAutoTuner; +extern AUTO_TUNE_RECORD HeatTuneRecord; +extern unsigned int curr_state; +extern YSP_IEC_DATA ysp_glb_data; +extern void mutex_init(void); +extern void lock_input_data(void); +extern void unlock_input_data(void); +extern void lock_output_data(void); +extern void unlock_output_data(void); + +extern unsigned char cal_sum(unsigned char *buf,unsigned int len); +extern int chk_sum(unsigned char *buf,unsigned int len,unsigned char sum); + +#endif + + diff --git a/src/ctrl_process.c b/src/ctrl_process.c new file mode 100644 index 0000000..96fa4a9 --- /dev/null +++ b/src/ctrl_process.c @@ -0,0 +1,650 @@ +/* + * ctrl_process.c + * + * Created on: May 4, 2015 + * Author: root + */ +#include "common.h" +#include +#include "thread.h" +#include +#include "msq.h" +#include "serial.h" +#include "ysp_debug.h" +#include + +#define MAX_SEND_TIME_CURVE 5 +#define MAX_SAVE_TEMP 256 + +mqd_t ctrl_tx_mq;// + +extern int ctrl_fd;//控制信号发送串口句柄 + +COM_HEADER ctrl_tx_header; +COM_HEADER ctrl_rx_header; + +OUTPUT_TYPE_DEF ctrl_tx_data; + +unsigned char ctrl_tx_buf[128];//串口发送缓冲区 +unsigned char ctrl_rx_buf[128];// + +unsigned char ctrl_tx_mq_buf[CTRL_TX_MESSAGE_SIZE];//消息队列接收缓冲区 + +static const unsigned int timeout_curve[MAX_SEND_TIME_CURVE]={ +200000,300000,500000,1000000,2000000 +};//发送间隔 + + +float latest_spz_temp[MAX_SAVE_TEMP]; +unsigned char spz_save_index=0; +/* +static const char *relay_name[]={ +"LJ_FAN", +"SAMPLE_FAN", +"YV6", +"YV4", +"no_use", +"no_use", +"YV7", +"YV14", +"YV13", +"YV10", +"YV11", +"YV12", +"no", +"no", +"no", +"YV16", +"YV17", +"YV18", +"YV19", +"YV20", +"YV21", +"NO", +"NO", +"NO", +"NO", +"NO", +"NO", +"NO", +"NO", +"NO", +"NO", +};*/ + + +void arm_var_f32(float *pSrc,unsigned int blockSize,float *pResult) +{ + float sum = (float) 0.0; + float meanOfSquares, mean, in, squareOfMean; + unsigned int blkCnt; + float *pIn; + pIn = pSrc; + blkCnt = blockSize>>2u; + while(blkCnt>0u) + { + in = *pSrc++; + sum += in * in; + in = *pSrc++; + sum += in * in; + in = *pSrc++; + sum += in * in; + in = *pSrc++; + sum += in * in; + blkCnt--; + } + blkCnt = blockSize % 0x4u; + + while(blkCnt>0u) + { + in = *pSrc++; + sum += in * in; + blkCnt--; + } + meanOfSquares = sum/((float) blockSize-1.0f); + + sum = 0.0f; + + + blkCnt = blockSize>>2u; + + pSrc = pIn; + + while(blkCnt>0u) + { + sum += *pSrc++; + sum += *pSrc++; + sum += *pSrc++; + sum += *pSrc++; + blkCnt--; + } + + blkCnt = blockSize%0x4u; + + while(blkCnt>0u) + { + sum += *pSrc++; + blkCnt--; + } + mean = sum/(float)blockSize; + + squareOfMean = (mean * mean) *(((float)blockSize)/((float)blockSize-1.0f)); + *pResult = meanOfSquares - squareOfMean; +} + +void save_spz_temp(float *temp) +{ + latest_spz_temp[spz_save_index++]=*temp; +} + +int get_spz_stable(float *delt) +{ + lock_input_data(); + arm_var_f32(latest_spz_temp,sizeof(latest_spz_temp)/sizeof(float),delt); + unlock_input_data(); + /*if(*delt>8); + ctrl_tx_buf[4]=0x01;//cmd + memcpy(&ctrl_tx_buf[5],head,sizeof(COM_HEADER));//拷贝信息头 + memcpy(&ctrl_tx_buf[5+sizeof(COM_HEADER)],data,data_length);//拷贝数据 + ctrl_tx_buf[5+data_bytes]=cal_sum(ctrl_tx_buf,5+data_bytes); + ctrl_tx_buf[6+data_bytes]=0x55; + set_gpio_output(0,1); + ret=SerialWrite(dev_fd,ctrl_tx_buf,7+data_bytes); + //usleep(10000); + set_gpio_output(0,0); + return ret; +} + + +//控制数据重发 +int ctrl_data_retrans(void) +{ + static mqd_t ctrl_tx_slave_mq=(mqd_t)-1; + unsigned char dumy_msg[16]; + if(ctrl_tx_slave_mq==-1) + { + if((ctrl_tx_slave_mq= open_mq(CTRL_TX_MQ))==((mqd_t)-1)) + return -1; + } + if(mq_send(ctrl_tx_slave_mq,(const char *)dumy_msg,sizeof(dumy_msg),CTRL_MQ_PRIO)==-1) + return -2; + + return 0; +} + +void show_hex(unsigned char *buf,unsigned int len) +{ + unsigned int i; + for(i=0;i=5) + return -1; + if((my_input_data.work_state&(1<=5) + return -1; + //if((my_input_data.work_state&(1<31) + return; + lock_output_data(); + tmp=my_output_data.relay_ctrl; + if(val!=OFF)//=ON + { + tmp|=pos; + } + else//=OFF + { + tmp&=(~pos); + } + if(tmp!=my_output_data.relay_ctrl) + { + my_output_data.relay_ctrl=tmp; + retrans_flg=1; + } + unlock_output_data(); + if(retrans_flg) + { + //printf("relay=%x %x %x %x\n",my_output_data.relay_ctrl[0],my_output_data.relay_ctrl[1],my_output_data.relay_ctrl[2],my_output_data.relay_ctrl[3]); + if(mode) + ctrl_data_retrans(); + } + //show_hex(my_output_data.relay_ctrl,8); +} + +void relay_set_all(unsigned int val,unsigned int mode) +{ + unsigned int tmp; + int retrans_flg=0; + + lock_output_data(); + tmp=my_output_data.relay_ctrl; + + if(tmp!=val) + { + my_output_data.relay_ctrl=val; + retrans_flg=1; + } + unlock_output_data(); + if(retrans_flg) + { + if(mode) + ctrl_data_retrans(); + } +} + +unsigned int relay_get(unsigned int i,unsigned char *val) +{ + unsigned int pos=(1<0) + { + //清空消息队列? + ++ctrl_tx_header.stNum; + if(ctrl_tx_header.stNum==0) + ++ctrl_tx_header.stNum; //skip over 0 + ctrl_tx_header.sqNum = 0; //reset sqNum to 0 on each state change + send_index=0; + //show_time("tx"); + //printf("state change:stNum=%d sqNum=%d\r\n",ctrl_tx_header.stNum,ctrl_tx_header.sqNum); + //LOG_DEBUG(COMUNICATION_TRACE_DEBUG,"state change:stNum=%d sqNum=%d\n",ctrl_tx_header.stNum,ctrl_tx_header.sqNum); + usleep(10000); + } + else + { + if(send_index<(MAX_SEND_TIME_CURVE-1)) + { + send_index++; + } + ++ctrl_tx_header.sqNum; + //printf("stNum=%d sqNum=%d\n",ctrl_tx_head.stNum,ctrl_tx_head.sqNum); + } + //发送数据 + lock_output_data(); + memcpy(&my_output_data.pid_para[0],&my_para_data.mach_run_para.pid_type_def[PID_SPZ],sizeof(PID_TYPE_DEF)); + memcpy(&my_output_data.pid_para[1],&my_para_data.mach_run_para.pid_type_def[PID_LJ],sizeof(PID_TYPE_DEF)); + memcpy(&my_output_data.pid_para[2],&my_para_data.mach_run_para.pid_type_def[PID_SAMPLE],sizeof(PID_TYPE_DEF)); + my_output_data.temperature[TEMP_SPZ]=my_para_data.mach_run_para.temperature[TEMP_SPZ]; + my_output_data.temperature[TEMP_LJ]=my_para_data.mach_run_para.temperature[TEMP_LJ]; + my_output_data.temperature[TEMP_SAM]=my_para_data.mach_run_para.temperature[TEMP_SAM]; + //memcpy(my_output_data.pid_en,my_para_data.mach_run_para.pid_en,sizeof(my_output_data.pid_en)); + my_output_data.man_output[0]=(unsigned short)my_para_data.mach_run_para.volt_output[0]; + my_output_data.man_output[2]=0; + my_output_data.man_output[3]=0; + unlock_output_data(); + if(send_ctrl_frame(ctrl_fd,&ctrl_tx_header,&my_output_data,sizeof(my_output_data))<(sizeof(my_output_data)+7)) + { + LOG_DEBUG(COMUNICATION_EEROR_DEBUG,"send data failed\n"); + } + } +} + + +int process_message(unsigned char *msg_buf,unsigned int msg_length) +{ + static unsigned int spz_index=0; + //unsigned int i=0; + unsigned int length; + COM_HEADER received_header; + if(msg_length<(7+sizeof(COM_HEADER))) + return -1; + if(msg_buf[0]!=0xAA) + return -2; + if(msg_buf[msg_length-1]!=0x55) + return -3; + length=(unsigned int)256*msg_buf[3]+msg_buf[2]; + if(length!=(msg_length-7)) + return -4; + if(chk_sum(msg_buf,msg_length-2,msg_buf[msg_length-2])!=0) + return -5; + memcpy(&received_header,msg_buf+5,sizeof(COM_HEADER)); + if(received_header.stNum!=ctrl_rx_header.stNum) + { + //数据有变化 + //printf("state change stNum=%d sqNum=%d\n",received_header.stNum,received_header.sqNum); + } + else if(received_header.sqNum!=(ctrl_rx_header.sqNum+1)) + { + //丢帧了 + printf("lost frame old_sq=%d new_sq=%d\n",ctrl_rx_header.sqNum,received_header.sqNum); + } + memcpy(&ctrl_rx_header,&received_header,sizeof(COM_HEADER)); + //获取信号量 + lock_input_data(); + //拷贝数据到全局缓冲 + memcpy(&my_input_data,&msg_buf[5+sizeof(COM_HEADER)],sizeof(my_input_data)); + //保存最近的色谱柱温度,用于分析温度是否稳定 + spz_index++; + if((spz_index&3)==0) + { + save_spz_temp(&my_input_data.temperature[TEMP_SPZ]); + } + //printf("temp=%f %f %f %f pres=%f %f\n",my_input_data.temperature[0],my_input_data.temperature[1],my_input_data.temperature[2],my_input_data.temperature[3],my_input_data.PresVolt[6],my_input_data.Current[0]); + //释放信号量 + unlock_input_data(); + //printf("io_input=0x%2x 0x%2x\n",my_input_data.io_input[0],my_input_data.io_input[1]); + return 0; +} + + +//接收控制MCU发送的信息,并存入共享内存 +void ctrl_rx_routine(void *arg) +{ + + int curr_length,last_length,rx_length; + int recv_error_tick=0; + pthread_t ctrl_tx_thread; + + rx_length=0; //本次接收的字节长度 + last_length=0;//上一次接收的字节长度 + //打开全局设备 + if((ctrl_fd=SerialOpen(CTRL_SERIAL_DEV,CTRL_SERIAL_SPEED))==-1) + { + LOG_DEBUG(COMUNICATION_EEROR_DEBUG,"open ctrl serial device failed\n"); + pthread_exit(1); + } + if((ctrl_tx_thread=task_create(ctrl_tx_routine,NULL,0,0))==-1) + { + LOG_DEBUG(COMUNICATION_EEROR_DEBUG,"create ctrl_tx_routine failed\n"); + close(ctrl_fd); + pthread_exit(2); + } + my_input_data.com_flg=1; + while(1) + { + usleep(30000);//wait 30ms + curr_length=read(ctrl_fd,ctrl_rx_buf+rx_length,sizeof(ctrl_rx_buf)-rx_length); + if(curr_length>0) + { + //存入缓冲区 + rx_length+=curr_length; + last_length=curr_length; + if(rx_length>=sizeof(ctrl_rx_buf)) + { + //printf("code1=%d rx_length=%d\n",process_message(ctrl_rx_buf,rx_length),rx_length);//处理消息 + if(process_message(ctrl_rx_buf,rx_length)==0) + { + if(recv_error_tick>200) + { + LOG_DEBUG(ERROR_DEBUG,"ctrl mcu recovery\n"); + } + recv_error_tick=0; + if(comunication_flg==0) + { + ysp_glb_data.MoDevConf.v.stVal=0; + ysp_glb_data.MoDevConf.q=0; + ysp_glb_data.MoDevConf.t.secs=(unsigned int)time(NULL); + } + comunication_flg=1; + } + rx_length=0; + memset(ctrl_rx_buf,0,sizeof(ctrl_rx_buf)); + } + } + else + { + if(last_length>0) + { + //printf("code2=%d rx_length=%d\n",process_message(ctrl_rx_buf,rx_length),rx_length);//处理消息 + if(process_message(ctrl_rx_buf,rx_length)==0) + { + if(recv_error_tick>200) + { + LOG_DEBUG(ERROR_DEBUG,"ctrl mcu recovery\n"); + } + recv_error_tick=0; + if(comunication_flg==0) + { + ysp_glb_data.MoDevConf.v.stVal=0; + ysp_glb_data.MoDevConf.q=0; + ysp_glb_data.MoDevConf.t.secs=time(NULL); + } + comunication_flg=1; + } + memset(ctrl_rx_buf,0,sizeof(ctrl_rx_buf)); + } + else + { + //出错处理 + recv_error_tick++; + if(recv_error_tick>256) + { + comunication_flg=0; + if(recv_error_tick==257) + { + ysp_glb_data.MoDevConf.v.stVal=1; + ysp_glb_data.MoDevConf.q=0; + ysp_glb_data.MoDevConf.t.secs=(unsigned int)time(NULL); + LOG_DEBUG(ERROR_DEBUG,"ctrl mcu lost\n"); + } + } + } + last_length=0; + rx_length=0; + } + } + //wait ctrl_tx_thread exit + close(ctrl_fd); +} + +int ctrl_init(void) +{ + pthread_t ctrl_rx_thread; + if((ctrl_rx_thread=task_create(ctrl_rx_routine,NULL,0,0))==-1) + { + LOG_DEBUG(COMUNICATION_EEROR_DEBUG,"create ctrl_tx_routine failed\n"); + return 1; + } + return 0; +} + + diff --git a/src/ctrl_process.h b/src/ctrl_process.h new file mode 100644 index 0000000..72ad503 --- /dev/null +++ b/src/ctrl_process.h @@ -0,0 +1,39 @@ +#ifndef _CTRL_PROCESS_H +#define _CTRL_PROCESS_H + + +extern int get_spz_stable(float *delt); + +extern int ctrl_data_retrans(void); + +extern unsigned int io_get(unsigned int i); + +/*extern void get_curr(unsigned int ch,float *fval);*/ + +extern int get_pres_vol(unsigned int ch,float *fval); + +extern int get_temperature(unsigned int ch,float *fval); +extern int get_presure(unsigned int ch,float *fval); + +//extern void CurrCnvToPres(float *raw_data,float *fval); + +//extern void CurrCnvToPresEx(unsigned int ch,float *fval); + +extern void VoltCnvToPres(float *fval); + +extern int VoltCnvToPresEx(unsigned int ch,float *fval); + +extern void relay_clr(unsigned int mask); + +extern void set_pid_ch(unsigned int ch,unsigned int en_dis,unsigned int mode); + +extern void set_pid_temp(unsigned int ch,float *temp,unsigned int mode); + +extern void relay_set(unsigned int i,unsigned char val,unsigned int mode); +extern unsigned int relay_get(unsigned int i,unsigned char *val); +extern int ctrl_init(void); + + +#endif + + diff --git a/src/database.c b/src/database.c new file mode 100644 index 0000000..c7e5c2c --- /dev/null +++ b/src/database.c @@ -0,0 +1,283 @@ +#include "sqlite3.h" +#include +#include +#include +#include "common.h" + +#define MY_DATABASE "ysp.db" + +#define CREATE_TBL_CMD "CREATE TABLE IF NOT EXISTS his_tbl(H2 FLOAT,CO FLOAT,\ +CH4 FLOAT,C2H4 FLOAT,C2H6 FLOAT,C2H2 FLOAT,TotHyd FLOAT,SmpTm INTEGER,CO2 FLOAT,\ +H2O FLOAT,OilTmp FLOAT,findmask INTEGER,H2_s INTEGER,H2_p INTEGER,\ +CO_s INTEGER,CO_p INTEGER,CH4_s INTEGER,CH4_p INTEGER,C2H4_s INTEGER,C2H4_p INTEGER,\ +C2H6_s INTEGER,C2H6_p INTEGER,C2H2_s INTEGER,C2H2_p INTEGER,\ +H2_A FLOAT,CO_A FLOAT,CH4_A FLOAT,C2H4_A FLOAT,C2H6_A FLOAT,C2H2_A FLOAT,\ +spzT_s FLOAT,spzT_e FLOAT,samT_s FLOAT,samT_e FLOAT,pres FLOAT,logTime TIMESTAMP)" + + +//ȡݿ +//SQLITE_OPEN_READONLY, +sqlite3 *db_get(int flags) +{ + sqlite3 *db; + int rc; + sqlite3_initialize(); + if((rc=sqlite3_open_v2(MY_DATABASE,&db,flags,NULL))!=SQLITE_OK) + { + if((rc=sqlite3_open_v2(MY_DATABASE,&db,flags,NULL))!=SQLITE_OK) + { + printf("failed to open db\n"); + sqlite3_shutdown(); + return NULL; + } + } + return db; +} + +//رݿ +void db_close(sqlite3 *db,sqlite3_stmt *stmt) +{ + if(stmt) + sqlite3_finalize(stmt); + if(db) + sqlite3_close(db); + sqlite3_shutdown(); +} + + +//ݿִsqlѯ +sqlite3_stmt *db_query(sqlite3 *db,const char *sqlcmd) +{ + int rc; + sqlite3_stmt *stmt; + if((rc=sqlite3_prepare_v2(db,sqlcmd,strlen(sqlcmd),&stmt,NULL))!=SQLITE_OK) + { + printf("failed to prepare:%s\n",sqlite3_errmsg(db)); + db_close(db,stmt); + return NULL; + } + return stmt; +} + + + +int all_table_init(void) +{ + sqlite3 *db; + sqlite3_stmt *stmt; + char sqlcmd[1024]; + int rc; + + if((db=db_get(SQLITE_OPEN_READWRITE))==NULL) + return -1; + strcpy(sqlcmd,CREATE_TBL_CMD); + if((stmt=db_query(db,sqlcmd))==NULL) + return -2; + rc = sqlite3_step(stmt); + if(rc!=SQLITE_DONE) + { + printf("all_table_init failed to step:%s\r\n",sqlite3_errmsg(db)); + db_close(db,stmt); + return -3; + } + db_close(db,stmt); + return 0; +} + + +int log_entry_add(char *str,int len) +{ + sqlite3 *db; + sqlite3_stmt *stmt; + char sqlcmd[256]; + int rc; + + if((str==NULL)) + return -1; + + if((db=db_get(SQLITE_OPEN_READWRITE))==NULL) + return -2; + + //sprintf(sqlcmd,"INSERT INTO log_tbl VALUES(?,datetime())"); + sprintf(sqlcmd,"INSERT OR REPLACE INTO log_tbl VALUES(?,datetime())"); + if((stmt=db_query(db,sqlcmd))==NULL) + return -3; + + if(len!=0) + sqlite3_bind_text(stmt,1,str,len,NULL); + else + sqlite3_bind_text(stmt,1,str,strlen(str),NULL); + + rc = sqlite3_step(stmt); + if(rc!=SQLITE_DONE) + { + printf("log_entry_add failed to step:%s\r\n",sqlite3_errmsg(db)); + db_close(db,stmt); + return -4; + } + db_close(db,stmt); + return 0; +} + +int his_entry_add(ANALY_RESULT *str) +{ + sqlite3 *db; + sqlite3_stmt *stmt; + char sqlcmd[256]; + int rc; + + if((str==NULL)) + return -1; + + if((db=db_get(SQLITE_OPEN_READWRITE))==NULL) + return -2; + + sprintf(sqlcmd,"INSERT OR REPLACE INTO his_tbl VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,datetime())"); + if((stmt=db_query(db,sqlcmd))==NULL) + return -3; + sqlite3_bind_double(stmt,1,(double)str->result.H2ppm); + sqlite3_bind_double(stmt,2,(double)str->result.COppm); + sqlite3_bind_double(stmt,3,(double)str->result.CH4ppm); + sqlite3_bind_double(stmt,4,(double)str->result.C2H4ppm); + sqlite3_bind_double(stmt,5,(double)str->result.C2H6ppm); + sqlite3_bind_double(stmt,6,(double)str->result.C2H2ppm); + sqlite3_bind_double(stmt,7,(double)str->result.TotHyd); + sqlite3_bind_int(stmt,8,str->result.SmpTm); + sqlite3_bind_double(stmt,9,(double)str->result.CO2ppm); + sqlite3_bind_double(stmt,10,(double)str->result.Mst); + sqlite3_bind_double(stmt,11,(double)str->result.temp); + sqlite3_bind_int(stmt,12,str->find_mask); + sqlite3_bind_int(stmt,13,str->pos_info[0].start); + sqlite3_bind_int(stmt,14,str->pos_info[0].peak); + sqlite3_bind_int(stmt,15,str->pos_info[1].start); + sqlite3_bind_int(stmt,16,str->pos_info[1].peak); + sqlite3_bind_int(stmt,17,str->pos_info[2].start); + sqlite3_bind_int(stmt,18,str->pos_info[2].peak); + sqlite3_bind_int(stmt,19,str->pos_info[3].start); + sqlite3_bind_int(stmt,20,str->pos_info[3].peak); + sqlite3_bind_int(stmt,21,str->pos_info[4].start); + sqlite3_bind_int(stmt,22,str->pos_info[4].peak); + sqlite3_bind_int(stmt,23,str->pos_info[5].start); + sqlite3_bind_int(stmt,24,str->pos_info[5].peak); + sqlite3_bind_double(stmt,25,(double)str->area[0]); + sqlite3_bind_double(stmt,26,(double)str->area[1]); + sqlite3_bind_double(stmt,27,(double)str->area[2]); + sqlite3_bind_double(stmt,28,(double)str->area[3]); + sqlite3_bind_double(stmt,29,(double)str->area[4]); + sqlite3_bind_double(stmt,30,(double)str->area[5]); + sqlite3_bind_double(stmt,31,(double)str->spzTemp1); + sqlite3_bind_double(stmt,32,(double)str->spzTemp2); + sqlite3_bind_double(stmt,33,(double)str->samTemp1); + sqlite3_bind_double(stmt,34,(double)str->samTemp2); + sqlite3_bind_double(stmt,35,(double)str->pres); + rc = sqlite3_step(stmt); + if(rc!=SQLITE_DONE) + { + printf("his_entry_add failed to step:%s\r\n",sqlite3_errmsg(db)); + db_close(db,stmt); + return -4; + } + db_close(db,stmt); + return 0; +} + +int his_entry_read(ANALY_RESULT *str) +{ + sqlite3 *db; + sqlite3_stmt *stmt; + char sqlcmd[256]; + int rc; + + if((str==NULL)) + return -1; + + if((db=db_get(SQLITE_OPEN_READONLY))==NULL) + return -2; + + sprintf(sqlcmd,"SELECT * FROM his_tbl order by SmpTm desc limit 1 offset 0"); + if((stmt=db_query(db,sqlcmd))==NULL) + return -3; + rc = sqlite3_step(stmt); + if(rc==SQLITE_ROW) + { + str->result.H2ppm=(float)sqlite3_column_double(stmt,0); + str->result.COppm=(float)sqlite3_column_double(stmt,1); + str->result.CH4ppm=(float)sqlite3_column_double(stmt,2); + str->result.C2H4ppm=(float)sqlite3_column_double(stmt,3); + str->result.C2H6ppm=(float)sqlite3_column_double(stmt,4); + str->result.C2H2ppm=(float)sqlite3_column_double(stmt,5); + str->result.TotHyd=(float)sqlite3_column_double(stmt,6); + str->result.SmpTm=sqlite3_column_int(stmt,7); + str->result.CO2ppm=(float)sqlite3_column_double(stmt,8); + str->result.Mst=(float)sqlite3_column_double(stmt,9); + str->result.temp=(float)sqlite3_column_double(stmt,10); + str->find_mask=sqlite3_column_int(stmt,11); + str->pos_info[0].start=sqlite3_column_int(stmt,12); + str->pos_info[0].peak=sqlite3_column_int(stmt,13); + str->pos_info[1].start=sqlite3_column_int(stmt,14); + str->pos_info[1].peak=sqlite3_column_int(stmt,15); + str->pos_info[2].start=sqlite3_column_int(stmt,16); + str->pos_info[2].peak=sqlite3_column_int(stmt,17); + str->pos_info[3].start=sqlite3_column_int(stmt,18); + str->pos_info[3].peak=sqlite3_column_int(stmt,19); + str->pos_info[4].start=sqlite3_column_int(stmt,20); + str->pos_info[4].peak=sqlite3_column_int(stmt,21); + str->pos_info[5].start=sqlite3_column_int(stmt,22); + str->pos_info[5].peak=sqlite3_column_int(stmt,23); + str->area[0]=(float)sqlite3_column_double(stmt,24); + str->area[1]=(float)sqlite3_column_double(stmt,25); + str->area[2]=(float)sqlite3_column_double(stmt,26); + str->area[3]=(float)sqlite3_column_double(stmt,27); + str->area[4]=(float)sqlite3_column_double(stmt,28); + str->area[5]=(float)sqlite3_column_double(stmt,29); + str->spzTemp1=(float)sqlite3_column_double(stmt,30); + str->spzTemp2=(float)sqlite3_column_double(stmt,31); + str->samTemp1=(float)sqlite3_column_double(stmt,32); + str->samTemp2=(float)sqlite3_column_double(stmt,33); + str->pres=(float)sqlite3_column_double(stmt,34); + db_close(db,stmt); + return 0; + } + db_close(db,stmt); + return -4; +} +/* +char *database_format_time(time_t t) +{ +static char time_str_arr[32]; +//sprintf(time_str_arr,"%02d"); +strftime(char *ptr,size_t maxsize,const char *format,const struct tm *timeptr ); +}*/ +/* +תַ +SELECT datetime(1377168853,'unixepoch','localtime'); +ַת +SELECT strftime('%s','now'); +*/ +int data_entry_remove(char *tb_name,time_t rsv_time) +{ + sqlite3 *db; + sqlite3_stmt *stmt; + char sqlcmd[256]; + int rc; + + if((tb_name==NULL)) + return -1; + + if((db=db_get(SQLITE_OPEN_READWRITE))==NULL) + return -2; + + sprintf(sqlcmd,"DELETE FROM %s where logTime + + +sqlite3 *db_get(int flags); +sqlite3_stmt *db_query(sqlite3 *db,const char *sqlcmd); +void db_close(sqlite3 *db,sqlite3_stmt *stmt); + +int log_entry_add(char *str,int len); + +#endif + + diff --git a/src/database/main.c b/src/database/main.c new file mode 100644 index 0000000..f3db7dc --- /dev/null +++ b/src/database/main.c @@ -0,0 +1,1704 @@ +/* + * main.c + * + * Created on: Apr 15, 2015 + * Author: root + */ + +#include +#include +#include +#include +#include +#include +#include "ysp_debug.h" +#include "msq.h" +#include "main.h" +#include "common.h" +#include "para.h" + +typedef struct +{ +int heat_flg; //传感器加热标志 +int csf_flg; //吹扫阀开启标志 +int smp_flg; //采样室温度控制标志 +}PRE_ACTION_STATE; + +extern int sample_fd; +CLEAN_STAT gas_clean_stat; +CLEAN_STAT gas_make_stat; +CLEAN_STAT demarcate_stat; +PRE_ACTION_STATE my_action_state; + +unsigned int relay_close_tick[61]; +unsigned int relay_open_tick[61]; + +unsigned char main_rx_buf[MAIN_MESSAGE_SIZE]; + +mqd_t main_mq=(mqd_t)(-1); +static int doIt=1; + +unsigned int curr_state=0; + +const float sample_temp_table[]={ +0,0,0,0,0,0,0,0,0,0,0,0,1.9,2.8,3.7,4.7,5.6,6.5,7.4,8.4,9.3,10.2,11.0,12.0,12.9,13.9,14.8,15.7,16.6,17.5 +}; + +//根据室温计算采样单元需要设定的温度 +void get_sample_temp(float *evn_temp,float *sample_temp) +{ + int temp; + temp=(int)(*evn_temp); + if(temp11) + { + *sample_temp=sample_temp_table[temp]; + } + else + { + *sample_temp=sample_temp_table[12]; + } +} + +void relay_dly_close_set(unsigned int rly_num,unsigned int dly_sec) +{ + if(rly_num>=60) + return; + relay_close_tick[rly_num]=2*dly_sec; +} + +void relay_dly_open_set(unsigned int rly_num,unsigned int dly_sec) +{ + if(rly_num>=60) + return; + relay_open_tick[rly_num]=2*dly_sec; +} + + +void relay_dly_process(void) +{ + static unsigned int relay_tick=0; + int i; + relay_tick++; + if((relay_tick&1)==0) + { + for(i=0;i<(sizeof(relay_close_tick)/sizeof(int));i++) + { + if(relay_open_tick[i]>0) + { + relay_open_tick[i]--; + if(relay_open_tick[i]==0) + { + if(i<60) + { + relay_set(i,ON,0); + } + else + { + if(start_sample_heat(0,1)!=0) + { + if(start_sample_heat(0,1)!=0) + { + if(start_sample_heat(0,1)!=0) + { + printf("start sensor heat failed\n"); + } + } + } + } + } + } + + if(relay_close_tick[i]>0) + { + relay_close_tick[i]--; + if(relay_close_tick[i]==0) + { + if(i<60) + { + relay_set(i,OFF,0); + } + else + { + if(start_sample_heat(0,0)!=0) + { + if(start_sample_heat(0,0)!=0) + { + if(start_sample_heat(0,0)!=0) + { + printf("stop sensor heat failed\n"); + } + } + } + } + } + } + } + } +} + +void ctrlCfun (int i) +{ + doIt = 0; +} + +void show_time(char *s) +{ + struct timeval now; + gettimeofday(&now,NULL); + printf("sec=%d.%d\n",now.tv_sec,now.tv_usec/1000); +} + +int SendActionMsg(ACTION_MSG_TYPE *msg) +{ + static mqd_t slave_main_mq=(mqd_t)-1; + unsigned char dumy_msg[16]; + if(slave_main_mq==-1) + { + if((slave_main_mq= open_mq(MAIN_MESSAGE_MQ))==((mqd_t)-1)) + return -1; + } + if(mq_send(slave_main_mq,(const char *)msg,sizeof(ACTION_MSG_TYPE),MAIN_MESSAGE_PRIO)==-1) + return -2; + + return 0; +} + +int SendActionReq(int cmd,int src) +{ + ACTION_MSG_TYPE msg; + msg.cmd=cmd; + msg.src=src; + if(SendActionMsg(&msg)==0) + return 0; + return 1; +} + +int main_message_process(ACTION_MSG_TYPE *msg) +{ + switch(curr_state) + { + case SIX_SAMPLE: + if(msg->cmd==STOP_SAMPLE) + { + memset(&gas_clean_stat,0,sizeof(gas_clean_stat)); + memset(&gas_make_stat,0,sizeof(gas_make_stat)); + set_pid_ch(PID_LJ,PID_DIS,0); + set_pid_ch(PID_SAMPLE,PID_DIS,0); + memset(&my_action_state,0,sizeof(&my_action_state)); + relay_dly_close_set(RLY_SENSOR,4);//延时关传感器加热 + relay_clr(); + curr_state=MODE_IDLE; + } + break; + case CO2_SAMPLE: + break; + case DEMARCATE: + break; + default: + if(msg->cmd==START_SIX_SAMPLE) + { + memset(&gas_clean_stat,0,sizeof(gas_clean_stat)); + memset(&gas_make_stat,0,sizeof(gas_make_stat)); + gas_clean_stat.step=1; + gas_make_stat.step=1; + //gas_make_stat.step=29; + curr_state=SIX_SAMPLE; + //relay_set(RLY_YV18,ON,0);//开吹扫阀 + printf("start six sample\n"); + relay_set(RLY_YV20,ON,1);//开YV20 + printf("YV20 ON\n"); + } + else if(msg->cmd==START_DEMARCATE) + { + curr_state=DEMARCATE; + } + break; + } + return 0; +} + +void stop_gas_clean(int reason) +{ + SendActionReq(STOP_SAMPLE,reason); + printf("clean gas failed\n"); +} + +void stop_gas_make(int reason) +{ + SendActionReq(STOP_SAMPLE,reason); + printf("make gas failed\n"); +} + +int gas_clean(void) +{ + switch(gas_clean_stat.step) + { + case 1://检查I6 + if(io_get(STA_I6)==ON) + { + gas_clean_stat.dly_cnt=0; + gas_clean_stat.repeat_cnt=0; + gas_clean_stat.step++; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:I6 is in right position\n",gas_clean_stat.step); + } + else + { + LOG_DEBUG(ERROR_DEBUG,"clean_step=%d:I6 is not in right pos\n",gas_clean_stat.step); + stop_gas_clean(gas_clean_stat.step); + return gas_clean_stat.step; + } + break; + case 2://开YV14 + relay_set(RLY_YV14,ON,1); + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV14 ON\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + case 3://开YV6 + if(gas_clean_stat.dly_cnt==0) + { + relay_set(RLY_YV7,OFF,0); + relay_set(RLY_YV6,ON,1); + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV6 ON YV7 OFF\n",gas_clean_stat.step); + gas_clean_stat.dly_cnt++; + } + else + { + //等待I7到位 + if(gas_clean_stat.dly_cnt>I7_WAIT_CNT) + { + if(io_get(STA_I7)==ON) + { + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:I7 is arrived in right position\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + } + else + { + if(gas_clean_stat.dly_cnt>I7_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"gas_step=%d:wait I7 ON timeout\n",gas_clean_stat.step); + stop_gas_clean(gas_clean_stat.step); + gas_clean_stat.dly_cnt=0; + gas_clean_stat.step=0; + return gas_clean_stat.step; + } + } + } + gas_clean_stat.dly_cnt++; + } + break; + case 4://开YV7 + if(gas_clean_stat.dly_cnt==0) + { + relay_set(RLY_YV6,OFF,0); + relay_set(RLY_YV7,ON,1); + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV7 ON YV6 OFF\n",gas_clean_stat.step); + gas_clean_stat.dly_cnt++; + } + else + { + //等待I6到位 + if(gas_clean_stat.dly_cnt>I6_WAIT_CNT) + { + if(io_get(STA_I6)==ON) + { + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:I6 is arrived in right position\n",gas_clean_stat.step); + gas_clean_stat.step++; + + break; + } + else + { + if(gas_clean_stat.dly_cnt>I6_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"gas_step=%d:wait I6 arrived in right position timeout\n",gas_clean_stat.step); + stop_gas_clean(gas_clean_stat.step); + gas_clean_stat.dly_cnt=0; + gas_clean_stat.step=0; + return gas_clean_stat.step; + } + } + } + gas_clean_stat.dly_cnt++; + } + break; + case 5://重复3-4 + gas_clean_stat.dly_cnt=0; + gas_clean_stat.repeat_cnt++; + LOG_DEBUG(ACTION_DEBUG,"%dst gas clean completed,curr_step=%d\n",gas_clean_stat.repeat_cnt,gas_clean_stat.step); + if(gas_clean_stat.repeat_cnt>=CLEAN_AIR_REPEAT_CNT) + { + gas_clean_stat.repeat_cnt=0; + gas_clean_stat.step++; + } + else + { + gas_clean_stat.step=3; + } + break; + case 6://关YV14 + relay_set(RLY_YV14,OFF,1); + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV14 OFF\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + case 7://开YV15 + relay_set(RLY_YV15,ON,1); + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV15 ON\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + case 8://开YV6 + if(gas_clean_stat.dly_cnt==0) + { + relay_set(RLY_YV7,OFF,0); + relay_set(RLY_YV6,ON,1); + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV6 ON YV7 OFF\n",gas_clean_stat.step); + gas_clean_stat.dly_cnt++; + } + else + { + //等待I7到位 + if(gas_clean_stat.dly_cnt>I7_WAIT_CNT) + { + if(io_get(STA_I7)==ON) + { + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:I7 have arrived in right position\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + } + else + { + if(gas_clean_stat.dly_cnt>I7_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"gas_step=%d:wait I7 arrvied in right position timeout\n",gas_clean_stat.step); + stop_gas_clean(gas_clean_stat.step); + gas_clean_stat.dly_cnt=0; + gas_clean_stat.step=0; + return gas_clean_stat.step; + } + } + } + gas_clean_stat.dly_cnt++; + } + break; + case 9://关YV15 + relay_set(RLY_YV15,OFF,1); + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV15 OFF\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + case 10://开YV10,延时6秒 + if(gas_clean_stat.dly_cnt==0) + { + relay_set(RLY_YV10,ON,1); + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV10 ON,Start delay 6s\n",gas_clean_stat.step); + gas_clean_stat.dly_cnt++; + } + else + { + //延时6秒 + if(gas_clean_stat.dly_cnt>YV10_ON_TIME) + { + gas_clean_stat.dly_cnt=0; + gas_clean_stat.step++; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:Delay 6s is completed\n",gas_clean_stat.step); + } + else + { + gas_clean_stat.dly_cnt++; + } + } + break; + case 11://关YV10 + relay_set(RLY_YV10,OFF,1); + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV10 OFF\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + case 12://开YV14 + relay_set(RLY_YV14,ON,1); + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV14 ON\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + case 13://开YV7 + if(gas_clean_stat.dly_cnt==0) + { + relay_set(RLY_YV6,OFF,0); + relay_set(RLY_YV7,ON,1); + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV7 ON YV6 OFF\n",gas_clean_stat.step); + gas_clean_stat.dly_cnt++; + } + else + { + //等待I6到位 + if(gas_clean_stat.dly_cnt>I6_WAIT_CNT) + { + if(io_get(STA_I6)==ON) + { + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:I6 have arrived in right position\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + } + else + { + if(gas_clean_stat.dly_cnt>I6_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"gas_step=%d:wait I6 arrived in right position timeout\n",gas_clean_stat.step); + stop_gas_clean(gas_clean_stat.step); + gas_clean_stat.dly_cnt=0; + gas_clean_stat.step=0; + return gas_clean_stat.step; + } + } + } + gas_clean_stat.dly_cnt++; + } + break; + case 14://关YV14 + relay_set(RLY_YV14,OFF,1); + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV14 OFF\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + case 15://重复7-14 + gas_clean_stat.dly_cnt=0; + gas_clean_stat.repeat_cnt++; + LOG_DEBUG(ACTION_DEBUG,"%dst gas clean completed,curr_step=%d\n",gas_clean_stat.repeat_cnt,gas_clean_stat.step); + if(gas_clean_stat.repeat_cnt>=CLEAN_CARRIER_REPEAT_CNT) + { + gas_clean_stat.repeat_cnt=0; + gas_clean_stat.step++; + } + else + { + gas_clean_stat.step=7; + } + break; + case 16://开YV6 + if(gas_clean_stat.dly_cnt==0) + { + relay_set(RLY_YV7,OFF,0); + relay_set(RLY_YV6,ON,1); + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV6 ON YV7 OFF\n",gas_clean_stat.step); + gas_clean_stat.dly_cnt++; + } + else + { + //等待I7到位 + if(gas_clean_stat.dly_cnt>I7_WAIT_CNT) + { + if(io_get(STA_I7)==ON) + { + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:I7 have arrived in right position\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + } + else + { + if(gas_clean_stat.dly_cnt>I7_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"gas_step=%d:wait I7 arrived in right position timeout\n",gas_clean_stat.step); + stop_gas_clean(gas_clean_stat.step); + gas_clean_stat.dly_cnt=0; + gas_clean_stat.step=0; + return gas_clean_stat.step; + } + } + } + gas_clean_stat.dly_cnt++; + } + break; + case 17://启动冷井工作 + relay_set(RLY_KA6,ON,0);//开冷井风扇 + set_pid_ch(PID_LJ,PID_EN,1);//开冷井控制 + gas_clean_stat.dly_cnt=0; + gas_clean_stat.repeat_cnt=0; + gas_clean_stat.step++; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:gas clean have completed,KA6 ON and start LJ cold\n",gas_clean_stat.step); + break; + case 18: + break; + default: + break; + } + return 0; +} + + +int gas_make(void) +{ + float fval; + unsigned int sample_data_length=0; + + if(io_get(STA_I9)==ON) + { + usleep(500000); + if(io_get(STA_I9)==ON) + { + LOG_DEBUG(ERROR_DEBUG,"gas_make_step=%d gas_clean_step=%d:I9 is not in right position,exit\n",gas_make_stat.step,gas_clean_stat.step); + gas_clean_stat.step=0; + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + } + + if(gas_clean()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"gas clean failed\n"); + return gas_make_stat.step; + } + switch(gas_make_stat.step) + { + case 1://打开电机 + if(io_get(STA_I4)!=ON) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:I4 is not in right position,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + if(io_get(STA_I8)==OFF) + { + usleep(500000); + if(io_get(STA_I8)==OFF) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:I8 is not in right position,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + } + relay_set(RLY_YV16,ON,0); + relay_set(RLY_YV13,ON,0); + relay_set(RLY_KA1,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV16 ON,YV13 ON,KA1 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + break; + case 2://延时3分钟 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>=MOTOR_RUN_TIME) + { + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 3 minutes completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 3://关电机 + relay_set(RLY_KA1,OFF,0); + relay_set(RLY_YV16,OFF,0); + relay_set(RLY_YV13,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:KA1 OFF,YV16 OFF,YV13 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + break; + case 4: + if(io_get(STA_I8)==OFF) + { + usleep(500000); + if(io_get(STA_I8)==OFF) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:I8 is not in right position,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + } + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + break; + case 5://延时2秒,等待气路清洗完成, + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>=4) + { + if(gas_clean_stat.step>GAS_CLEAN_MAX_STEP) + { + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 2 minutes completed\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + } + else + { + if(gas_make_stat.dly_cnt>GAS_CLEAN_MAX_TIME) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:gas clean timeout,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + } + } + break; + case 6://开YV4 + if(gas_make_stat.dly_cnt==0) + { + relay_set(RLY_YV5,OFF,0); + relay_set(RLY_YV4,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV4 ON,YV5 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt++; + } + else + { + //等待I5到位 + if(gas_make_stat.dly_cnt>I5_WAIT_CNT) + { + if(io_get(STA_I5)==ON) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:I5 have arrived in right position\n",gas_make_stat.step); + gas_make_stat.step++; + break; + } + else + { + if(gas_make_stat.dly_cnt>I5_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:wait I5 arrived ON timeout,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step=0; + return gas_make_stat.step; + } + } + } + gas_make_stat.dly_cnt++; + } + break; + case 7://开YV11 + relay_set(RLY_YV11,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV11 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 8://开YV12 + relay_set(RLY_YV12,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV12 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 9://延时2分钟,制气时间 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>GAS_MAKE_TIME) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 2 minutes completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 10://关YV4,对应STM32上清洗油路第28步 + relay_set(RLY_YV4,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV4 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 11://开YV15 + relay_set(RLY_YV15,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV15 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 12://延时5秒,进气时间,admission + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>GAS_ADMISSION_TIME) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 5s completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 13://关YV15 + relay_set(RLY_YV15,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV15 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 14://关YV12 + relay_set(RLY_YV12,OFF,0); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV12 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 15://重复6-14 + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt++; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:%dst make gas completed\n",gas_make_stat.step,gas_make_stat.repeat_cnt); + if(gas_make_stat.repeat_cnt>=GAS_MAKE_REPEAT_CNT)//制气重复次数 + { + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + } + else + { + gas_make_stat.step=6; + } + break; + case 16://开YV5,延时1秒 + if(gas_make_stat.dly_cnt==0) + { + relay_set(RLY_YV5,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV5 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt++; + } + else + { + if(gas_make_stat.dly_cnt>=3) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 1s completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + else + { + gas_make_stat.dly_cnt++; + } + } + break; + case 17://关YV11 + relay_set(RLY_YV11,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV11 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 18://关YV5 + relay_set(RLY_YV5,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV5 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 19://等待冷井温度<-25 + get_temperature(TEMP_LJ,&fval); + if(fval>(-25)) + { + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>600)//5分钟未到达设置的温度 + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:wait lj temperature arrived -25 timeout %f,exit\n",gas_make_stat.step,fval); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + if((gas_make_stat.dly_cnt%16)==0) + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:leng jin temp is %f\n",gas_make_stat.step,fval); + break; + } + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:leng jin temp is %f\n",gas_make_stat.step,fval); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 20://开YV7,关YV6 + relay_set(RLY_YV6,OFF,0); + relay_set(RLY_YV7,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV7 ON,YV6 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 21://等待3分钟 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>120)//到达1分钟? + { + if(gas_make_stat.dly_cnt==121) + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:1 minutes arrived\n",gas_make_stat.step); + //查PA1,大于常压就开YV17,等于常压就关闭YV17 + CurrCnvToPresEx(0,&fval); + if(fval>DELT_PRES) + { + relay_set(RLY_YV17,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV17 ON,pres=%fMpa\n",gas_make_stat.step,fval); + } + else if(fabs(fval-DELT_PRES)<0.001) + { + relay_set(RLY_YV17,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV17 OFF,pres=%fMpa\n",gas_make_stat.step,fval); + } + if((gas_make_stat.dly_cnt%8)==0) + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:Pres=%fMpa\n",gas_make_stat.step,fval); + if(gas_make_stat.dly_cnt>360)//3分钟到? + { + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 3 minutes completed\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + } + } + break; + case 22://等待冷井温度<-28 + get_temperature(TEMP_LJ,&fval); + if(fval>(-28)) + { + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>600)//5分钟未到达设置的温度 + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:wait lj temperature arrived -28 timeout %f,exit\n",gas_make_stat.step,fval); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + if((gas_make_stat.dly_cnt%16)==0) + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:leng jin wendu is %f\n",gas_make_stat.step,fval); + break; + } + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:leng jin wen du is %f\n",gas_make_stat.step,fval); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 23://开YV19 + relay_set(RLY_YV20,ON,0);//和YV19一起开,和YV18一起关 + relay_set(RLY_YV19,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV20 ON,YV19 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 24://延时18秒 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>36) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 18s completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 25://关YV19 + relay_set(RLY_YV19,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV19 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 26://关冷井风扇和制冷,关采样单元风扇以及制冷输出,电柜顶上的风扇也关闭 + set_pid_ch(PID_LJ,PID_DIS,0); + relay_set(RLY_KA6,OFF,0);//冷井风扇 + + set_pid_ch(PID_SAMPLE,PID_DIS,0); + relay_set(RLY_KA4,OFF,0);//采样单元风扇 + + relay_set(RLY_KA3,OFF,1);//柜子风扇 + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:KA6 OFF,LengJin Ctrl disable,KA4 OFF,Sample room ctrl disable,KA3 OFF\n",gas_make_stat.step); + //关伴热带,目前未定义tmb + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 27://延时3秒 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>6) + { + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 3s completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 28://检查色谱柱温度 + if(get_spz_stable(&fval)==0) + { + //printf("spz wendu delt=%f is stable\n",fval); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:spz wendu delt=%f is stable\n",gas_make_stat.step,fval); + get_temperature(TEMP_SPZ,&fval); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:spz wendu is %f\n",gas_make_stat.step,fval); + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + } + else + { + gas_make_stat.repeat_cnt=0; + gas_make_stat.dly_cnt++; + if((gas_make_stat.dly_cnt%8)==0) + { + get_temperature(TEMP_SPZ,&fval); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:spz wendu is %f\n",gas_make_stat.step,fval); + } + if(gas_make_stat.dly_cnt>600)//5分钟内未达到,退出采样 + { + get_temperature(TEMP_SPZ,&fval); + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:chromatographic temperature is not stable for 5 minutes %f,exit\n",gas_make_stat.step,fval); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + } + /*if(fabs(fval-60)<=0.2) + { + gas_make_stat.repeat_cnt++; + if(gas_make_stat.repeat_cnt>120)//连续稳定1分钟,即可认为稳定 + { + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + } + } + else + { + gas_make_stat.repeat_cnt=0; + gas_make_stat.dly_cnt++; + if((gas_make_stat.dly_cnt%8)==0) + printf("spz wendu is %f\n",fval); + if(gas_make_stat.dly_cnt>600)//5分钟内未达到,退出采样 + { + printf("spz wendu %f is not statble,exit\n",fval); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + } */ + break; + case 29://启动采样 + get_temperature(TEMP_SAM,&fval); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:sample room temp is %f,sample_len=%d sample_intval=%dms\n",gas_make_stat.step,fval,my_para_data.mach_run_para.sample_len,my_para_data.mach_run_para.sample_rate); + if(start_sample_data(0,my_para_data.mach_run_para.sample_len,my_para_data.mach_run_para.sample_rate)==0) + { + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + } + else + { + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>8) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:start data sample failed,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:WARNING:start data sample failed,Try again\n",gas_make_stat.step); + } + break; + case 30: + if(query_sample_data((unsigned char *)&sample_data_length,sizeof(sample_data_length))==0) + { + if(sample_data_length>0) + { + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:sample data length is %d\n",gas_make_stat.step,sample_data_length); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + } + else + { + gas_make_stat.dly_cnt++; + } + } + else + { + gas_make_stat.dly_cnt++; + } + + if(gas_make_stat.dly_cnt>20*60*2) //大于20分钟 + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:wait data sample complete timeout,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + break; + case 31://读取数据 + if(read_sample_data(2*my_para_data.mach_run_para.sample_len)==0) + { + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:read sample data complete\n",gas_make_stat.step); + if(save_sample_data(2*my_para_data.mach_run_para.sample_len)!=0) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:WARNING:save data to file failed\n",gas_make_stat.step); + } + else + { + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:save sample data success\n",gas_make_stat.step); + } + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + } + else + { + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>4) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:read sample data failed,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:WARNING:read sample data failed,Try again\n",gas_make_stat.step); + } + break; + case 32://完成采样 + if(clear_sample_data()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:WARNING:clear sample data failed\n",gas_make_stat.step); + if(clear_sample_data()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:WARNING:clear sample data failed\n",gas_make_stat.step); + if(clear_sample_data()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:WARNING:clear sample data failed\n",gas_make_stat.step); + } + } + } + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:All action have completed\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + + relay_dly_close_set(RLY_YV18,10*60*2);//延时10分钟关吹扫阀 + relay_dly_close_set(RLY_YV20,10*60*2);//延时10分钟关YV20 + relay_dly_close_set(RLY_SENSOR,10*60*2);//延时10分钟关传感器加热 + break; +//此处开始新添加的 + case 33: + if(gas_make_stat.dly_cnt==0) + { + relay_set(RLY_YV5,OFF,0); + relay_set(RLY_YV4,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV4 ON,YV5 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt++; + } + else + { + //等待I5到位 + if(gas_make_stat.dly_cnt>I5_WAIT_CNT) + { + if(io_get(STA_I5)==ON) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:I5 have arrived in right position\n",gas_make_stat.step); + gas_make_stat.step++; + break; + } + else + { + if(gas_make_stat.dly_cnt>I5_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:wait I5 arrived ON timeout,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step=0; + return gas_make_stat.step; + } + } + } + gas_make_stat.dly_cnt++; + } + break; + case 34: + relay_set(RLY_YV11,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV11 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 35: + relay_set(RLY_YV12,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV12 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 36://等待5秒 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>GAS_ADMISSION_TIME) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 5s completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 37: + relay_set(RLY_YV12,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV12 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 38://等待5秒 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>GAS_ADMISSION_TIME) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 5s completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 39://开YV5,关YV4,等待到位 + if(gas_make_stat.dly_cnt==0) + { + relay_set(RLY_YV13,ON,0); + relay_set(RLY_YV5,ON,0); + relay_set(RLY_YV4,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV5 ON,YV4 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt++; + } + else + { + //等待I4到位 + if(gas_make_stat.dly_cnt>I4_WAIT_CNT) + { + if(io_get(STA_I4)==ON) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:I4 have arrived in right position\n",gas_make_stat.step); + gas_make_stat.step++; + break; + } + else + { + if(gas_make_stat.dly_cnt>32) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:wait I4 arrived ON timeout,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step=0; + return gas_make_stat.step; + } + } + } + gas_make_stat.dly_cnt++; + } + break; + case 40://关YV11 + relay_set(RLY_YV13,OFF,0); + relay_set(RLY_YV5,OFF,0); + relay_set(RLY_YV11,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV11 OFF,YV5 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; +//此处开始新添加的结束 + case 41://延时10分钟 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>10*60*2) + { + if(start_sample_heat(0,0)!=0)//停止感器加热 + { + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:stop sensor heat failed\n",gas_make_stat.step); + } + relay_set(RLY_YV18,OFF,0);// + relay_set(RLY_YV20,OFF,1);// + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV18 OFF,YV20 OFF\n",gas_make_stat.step); + curr_state=MODE_IDLE; + memset(&my_action_state,0,sizeof(&my_action_state)); + } + break; + default: + break; + } + return 0; +} +/* +开YV4,等待到位 +开YV11, +开YV12 +等待5秒 +关YV12 +等待4秒 +关YV4,开关到位后关YV11 +*/ +int demarcate_process(void) +{ + float fval; + unsigned int sample_data_length=0; + switch(demarcate_stat.step) + { + case 1: + if(start_sample_heat(0,1)==0)//开传感器加热 + { + relay_set(RLY_YV18,ON,0);// + relay_set(RLY_YV20,ON,1);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:Sensor heat started,YV18 ON,YV20 ON,start delay 15 minutes\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + else + { + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>4) + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:start sensor heating failed,exit\n",demarcate_stat.step); + curr_state=MODE_IDLE; + return demarcate_stat.step; + } + } + break; + case 2://延时15分钟 + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>(15*60*2)) + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:delay 15 minutes completed\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + break; + case 3: + relay_set(RLY_KA6,OFF,0);//关冷井风扇 + relay_set(RLY_KA4,OFF,0);//关采样单元风扇 + relay_set(RLY_KA3,OFF,0);//关柜子风扇 + set_pid_ch(PID_SAMPLE,PID_DIS,0);//关采样室温度控制电源 + set_pid_ch(PID_LJ,PID_DIS,1);//关冷井温度控制电源 + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:KA6 OFF,KA4 OFF,KA3 OFF,Sample room cold disable,lj cold disable\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + break; + case 4://开YV14,延时3秒,关YV14 + if(demarcate_stat.dly_cnt==0) + { + relay_set(RLY_YV14,ON,1);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV14 ON\n",demarcate_stat.step); + } + else + { + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>6) + { + relay_set(RLY_YV14,OFF,1);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV14 OFF\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + } + break; + case 5://开YV10 + relay_set(RLY_YV10,ON,0);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV10 ON\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + break; + case 6://延时6秒 + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>12) + { + demarcate_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:delay 6s completed\n",demarcate_stat.step); + demarcate_stat.step++; + } + break; + case 7://关YV10 + relay_set(RLY_YV10,OFF,0);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV10 OFF\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + break; + case 8://检测压力,DLY 3 SECOND + demarcate_stat.dly_cnt++; + CurrCnvToPresEx(0,&fval); + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:Pres=%fMpa\n",demarcate_stat.step,fval); + if(fval>DELT_PRES) + { + relay_set(RLY_YV17,ON,1); + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV17 ON\n",demarcate_stat.step); + } + else if(fabs(fval-DELT_PRES)<0.001) + { + relay_set(RLY_YV17,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV17 OFF\n",demarcate_stat.step); + } + if(demarcate_stat.dly_cnt>6) + { + relay_set(RLY_YV17,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:delay 3s completed,YV17 OFF\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + break; + case 9://重复4-8两次 + demarcate_stat.repeat_cnt++; + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:repeat %st completed\n",demarcate_stat.step,demarcate_stat.repeat_cnt); + if(demarcate_stat.repeat_cnt>=2) + { + demarcate_stat.dly_cnt=0; + demarcate_stat.repeat_cnt=0; + demarcate_stat.step++; + } + else + { + demarcate_stat.dly_cnt=0; + demarcate_stat.repeat_cnt=0; + demarcate_stat.step=4; + } + break; + case 10://延时5秒 + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>10) + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:delay 5s completed\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + break; + case 11://开YV19 + relay_set(RLY_YV19,ON,1); + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV19 ON\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + break; + case 12://延时18秒 + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>36) + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:delay 18s completed\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + break; + case 13://关YV19 + relay_set(RLY_YV19,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV19 OFF\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + break; + case 14://启动采样 + if(start_sample_data(0,4000,230)==0) + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:start sample sucessed\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + else + { + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>4) + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:start data sample failed,exit\n",demarcate_stat.step); + if(start_sample_heat(0,0)!=0)//停止感器加热 + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:stop sensor heat failed\n",demarcate_stat.step); + } + else + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:stop sensor heat OK\n",demarcate_stat.step); + } + relay_set(RLY_YV18,OFF,0);// + relay_set(RLY_YV20,OFF,1);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV18 OFF,YV20 OFF\n",demarcate_stat.step); + curr_state=MODE_IDLE; + memset(&my_action_state,0,sizeof(&my_action_state)); + return demarcate_stat.step; + } + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:WARNING:start data sample failed,Try again\n",demarcate_stat.step); + } + break; + case 15://查是否有数据 + if(query_sample_data((unsigned char *)&sample_data_length,sizeof(sample_data_length))==0) + { + if(sample_data_length>0) + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:sample data length is %d\n",demarcate_stat.step,sample_data_length); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + else + { + demarcate_stat.dly_cnt++; + } + } + else + { + demarcate_stat.dly_cnt++; + } + + if(demarcate_stat.dly_cnt>20*60*2) //大于20分钟 + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:wait data sample complete timeout,exit\n",demarcate_stat.step); + //关传感器加热,YV18,YV20 + if(start_sample_heat(0,0)!=0)//停止感器加热 + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:stop sensor heat failed\n",demarcate_stat.step); + } + else + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:stop sensor heat OK\n",demarcate_stat.step); + } + relay_set(RLY_YV18,OFF,0);// + relay_set(RLY_YV20,OFF,1);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV18 OFF,YV20 OFF\n",demarcate_stat.step); + curr_state=MODE_IDLE; + memset(&my_action_state,0,sizeof(&my_action_state)); + return demarcate_stat.step; + } + break; + case 16://读数据 + if(read_sample_data(4000)==0) + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:read sample data complete\n",demarcate_stat.step); + if(save_sample_data(8000)!=0) + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:WARNING:save data to file failed\n",demarcate_stat.step); + } + else + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:save sample data success\n",demarcate_stat.step); + } + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + else + { + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>4) + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:read sample data failed,exit\n",demarcate_stat.step); + //关传感器加热,YV18,YV20 + //stop_gas_make(demarcate_stat.step); + return demarcate_stat.step; + } + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:WARNING:read sample data failed,Try again\n",demarcate_stat.step); + } + break; + case 17://清除数据 + if(clear_sample_data()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:WARNING:clear sample data failed\n",demarcate_stat.step); + if(clear_sample_data()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:WARNING:clear sample data failed\n",demarcate_stat.step); + if(clear_sample_data()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:WARNING:clear sample data failed\n",demarcate_stat.step); + } + } + } + demarcate_stat.dly_cnt=0; + demarcate_stat.repeat_cnt=0; + demarcate_stat.step++; + break; + case 18://收尾 + if(start_sample_heat(0,0)==0)//关传感器加热 + { + relay_set(RLY_YV18,OFF,0);// + relay_set(RLY_YV20,OFF,1);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:Sensor heat stoped,YV18 OFF,YV20 OFF,All action have completed\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step=0; + curr_state=MODE_IDLE; + } + else + { + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>8) + { + relay_set(RLY_YV18,OFF,0);// + relay_set(RLY_YV20,OFF,1);// + curr_state=MODE_IDLE; + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:stop sensor heating failed,YV18 OFF,YV20 OFF\n",demarcate_stat.step); + return demarcate_stat.step; + } + } + break; + default: + break; + } +} + +void idle_process(void) +{ + +} + +int main_timeout_process(void) +{ + switch(curr_state) + { + case SIX_SAMPLE: + gas_make(); + break; + case CO2_SAMPLE: + break; + case DEMARCATE: + demarcate_process(); + break; + default: + idle_process(); + break; + } + return 0; +} + + + + + +int main(int argc,char *argv[]) +{ + extern int send_ctrl_message(void); + ACTION_MSG_TYPE my_action_msg; + time_t now,next_sample_time,today_sec,last_sample_time; + unsigned char val=0; + int i=0; + float env_temp;//环境温度 + float my_temp;// + int cabinet_count=0; + unsigned int start_time; + unsigned int sample_intval; + + signal(SIGINT,ctrlCfun); + + if((sample_fd=SerialOpen(SAMPLE_SERIAL_DEV,SAMPLE_SERIAL_SPEED))==-1) + { + printf("open sample serial device failed\n"); + exit(1); + } + + + mutex_init(); + + if((main_mq=create_mq(MAIN_MESSAGE_MQ,MAIN_MAX_MESSAGE,MAIN_MESSAGE_SIZE))<0) + { + printf("create main message queue failed\n"); + exit(2); + } + + LoadAllPara(&my_para_data); + + if(ctrl_init()!=0) + { + printf("create ctrl thread failed\n"); + exit(3); + } + + sleep(8); + + //my_para_data.start_time=8; + //my_para_data.sample_intval=4; + + my_temp=60; + set_pid_temp(TEMP_SPZ,&my_temp,0);//设置色谱柱温度 + my_temp=-40; + set_pid_temp(TEMP_LJ,&my_temp,0);//设置冷井温度 + + // my_output_data.temperature[TEMP_SAM] + set_pid_ch(PID_SPZ,PID_EN,0);//开启色谱柱温度控制 + //set_pid_ch(PID_SAMPLE,PID_EN,0);//开启采样室温度控制 + //relay_set(RLY_KA4,ON,0);//开采样单元风扇 + //relay_set(RLY_KA6,ON,1);//开冷井风扇 + + start_time=my_para_data.mach_run_para.start_hour*3600+my_para_data.mach_run_para.start_minute*60; + now=time(NULL);//获取当前时间 + today_sec=now%86400; + if(today_sec>start_time) + { + next_sample_time=(my_para_data.mach_run_para.start_interval*3600)-((today_sec-start_time)%(my_para_data.mach_run_para.start_interval*3600)); + next_sample_time+=now; + } + else + { + next_sample_time=now-today_sec+start_time; + } + LOG_DEBUG(TRACE_DEBUG,"system reset:next_sample_time is %s",ctime(&next_sample_time)); + last_sample_time=next_sample_time; + analysis_init(); + while(doIt) + { + if(recv_mq_wait(main_mq,(void *)main_rx_buf,sizeof(main_rx_buf),500000)>0) + { + memcpy(&my_action_msg,main_rx_buf,sizeof(my_action_msg)); + printf("receivd msg %d\n",my_action_msg.cmd); + main_message_process(&my_action_msg); + } + else + { + main_timeout_process(); + } + + now=time(NULL); + today_sec=now%86400; + start_time=my_para_data.mach_run_para.start_hour*3600+my_para_data.mach_run_para.start_minute*60; + if(curr_state==MODE_IDLE) + { + if((today_sec%3600)<3)//判断是否整点 + { + if(my_para_data.mach_run_para.start_interval>2) + { + //整点开始,YV20工作5分钟,停止3分钟 + } + if(my_para_data.mach_run_para.start_interval>4) + { + //每隔两小时,整点开始,YV18工作,延时20分钟开传感器加热,45分钟延时到,全停 + } + } + else + { + + } + //室外温度-室内温度>3度,开柜子风扇35分钟,停5分钟,直到室外温度-室内温度<=3度 + if((cabinet_count)%120==0) //1分钟检测一次 + { + get_temperature(TEMP_OUTSIDE,&my_temp);//获取室外温度 + get_temperature(TEMP_ENV,&env_temp);//获取环境温度(柜内温度) + if((my_temp-env_temp)>3) + { + //开柜子风扇KA3 35分钟,停5分钟, + } + else + { + + } + } + cabinet_count++; + } + + + //采样开始前45分钟查表设置采样室温度,同时检测室外温度看是否启动伴热带 + if(now>=(next_sample_time-45*60)) + { + if(my_action_state.smp_flg==0) + { + get_temperature(TEMP_ENV,&env_temp);//获取环境温度 + get_sample_temp(&env_temp,&my_temp); + LOG_DEBUG(TRACE_DEBUG,"Preaction:Cabinet temperature is %f,set sample room temperature to %f\n",env_temp,my_temp); + set_pid_temp(TEMP_SAM,&my_temp,0);//设置采样室温度 + relay_set(RLY_KA4,ON,0); //开采样室风扇 + set_pid_ch(PID_SAMPLE,PID_EN,1); //开采样室温度控制 + my_action_state.smp_flg=1; + LOG_DEBUG(TRACE_DEBUG,"Preaction:KA4 ON,Start sample room colding\n"); + } + } //passed + + //采样单元工作30分钟后开吹扫阀,即提前15分钟开 + if(now>=(next_sample_time-15*60)) + { + //提前15分钟开吹扫阀,开启 + if(my_action_state.csf_flg==0) + { + relay_set(RLY_YV18,ON,1); + my_action_state.csf_flg=1; + LOG_DEBUG(TRACE_DEBUG,"Preaction:YV18 ON\n"); + } + }//passed + + //传感器加热开始于采样开始后8分钟 + if(now>=(last_sample_time+8*60)) + { + if(my_action_state.heat_flg==0) + { + if(curr_state!=0) + { + if(start_sample_heat(0,1)==0) + { + LOG_DEBUG(TRACE_DEBUG,"Preheat:start sensor heat ok\n"); + my_action_state.heat_flg=1; + } + else + { + LOG_DEBUG(TRACE_DEBUG,"Preheat:start sensor heat failed\n"); + } + } + } + }//passed + + + if(now>=next_sample_time) + { + //启动采样 + if(SendActionReq(SIX_SAMPLE,0)!=0) + LOG_DEBUG(TRACE_DEBUG,"send start six sample request failed\n"); + else + LOG_DEBUG(TRACE_DEBUG,"send start six sample request ok\n"); + last_sample_time=now;//记录最后一次采样开始时刻 + next_sample_time+=(my_para_data.mach_run_para.start_interval*3600); //计算下一次采样开始时刻 + LOG_DEBUG(TRACE_DEBUG,"next start sample time is %s\n",ctime(&next_sample_time)); + if(my_action_state.csf_flg==0) + { + LOG_DEBUG(TRACE_DEBUG,"Warning:csf YV18 is not opened\n"); + } + if(my_action_state.heat_flg==0) + { + LOG_DEBUG(TRACE_DEBUG,"Warning:sensor heating is not started\n"); + } + } + + //采样完成后,延时10分钟关传感器加热,关吹扫阀,关YV20 + relay_dly_process(); + } + mq_close(main_mq); + return 0; +} diff --git a/src/database/main_back2.c b/src/database/main_back2.c new file mode 100644 index 0000000..d37ef07 --- /dev/null +++ b/src/database/main_back2.c @@ -0,0 +1,1724 @@ +/* + * main.c + * + * Created on: Apr 15, 2015 + * Author: root + */ + +#include +#include +#include +#include +#include +#include +#include "ysp_debug.h" +#include "msq.h" +#include "main.h" +#include "common.h" +#include "para.h" + +typedef struct +{ +int heat_flg; //传感器加热标志 +int csf_flg; //吹扫阀开启标志 +int smp_flg; //采样室温度控制标志 +}PRE_ACTION_STATE; + +extern int sample_fd; +CLEAN_STAT gas_clean_stat; +CLEAN_STAT gas_make_stat; +CLEAN_STAT demarcate_stat; +PRE_ACTION_STATE my_action_state; + +unsigned int relay_close_tick[61]; +unsigned int relay_open_tick[61]; + +unsigned char main_rx_buf[MAIN_MESSAGE_SIZE]; + +mqd_t main_mq=(mqd_t)(-1); +static int doIt=1; + +unsigned int curr_state=0; + +const float sample_temp_table[]={ +0,0,0,0,0,0,0,0,0,0,0,0,1.9,2.8,3.7,4.7,5.6,6.5,7.4,8.4,9.3,10.2,11.0,12.0,12.9,13.9,14.8,15.7,16.6,17.5 +}; + +//根据室温计算采样单元需要设定的温度 +void get_sample_temp(float *evn_temp,float *sample_temp) +{ + int temp; + temp=(int)(*evn_temp); + if(temp11) + { + *sample_temp=sample_temp_table[temp]; + } + else + { + *sample_temp=sample_temp_table[12]; + } +} + +void relay_dly_close_set(unsigned int rly_num,unsigned int dly_sec) +{ + if(rly_num>=60) + return; + relay_close_tick[rly_num]=2*dly_sec; +} + +void relay_dly_open_set(unsigned int rly_num,unsigned int dly_sec) +{ + if(rly_num>=60) + return; + relay_open_tick[rly_num]=2*dly_sec; +} + + +void relay_dly_process(void) +{ + static unsigned int relay_tick=0; + int i; + relay_tick++; + if((relay_tick&1)==0) + { + for(i=0;i<(sizeof(relay_close_tick)/sizeof(int));i++) + { + if(relay_open_tick[i]>0) + { + relay_open_tick[i]--; + if(relay_open_tick[i]==0) + { + if(i<60) + { + relay_set(i,ON,0); + } + else + { + if(start_sample_heat(0,1)!=0) + { + if(start_sample_heat(0,1)!=0) + { + if(start_sample_heat(0,1)!=0) + { + printf("start sensor heat failed\n"); + } + } + } + } + } + } + + if(relay_close_tick[i]>0) + { + relay_close_tick[i]--; + if(relay_close_tick[i]==0) + { + if(i<60) + { + relay_set(i,OFF,0); + } + else + { + if(start_sample_heat(0,0)!=0) + { + if(start_sample_heat(0,0)!=0) + { + if(start_sample_heat(0,0)!=0) + { + printf("stop sensor heat failed\n"); + } + } + } + } + } + } + } + } +} + +void ctrlCfun (int i) +{ + doIt = 0; +} + +void show_time(char *s) +{ + struct timeval now; + gettimeofday(&now,NULL); + printf("sec=%d.%d\n",now.tv_sec,now.tv_usec/1000); +} + +int SendActionMsg(ACTION_MSG_TYPE *msg) +{ + static mqd_t slave_main_mq=(mqd_t)-1; + unsigned char dumy_msg[16]; + if(slave_main_mq==-1) + { + if((slave_main_mq= open_mq(MAIN_MESSAGE_MQ))==((mqd_t)-1)) + return -1; + } + if(mq_send(slave_main_mq,(const char *)msg,sizeof(ACTION_MSG_TYPE),MAIN_MESSAGE_PRIO)==-1) + return -2; + + return 0; +} + +int SendActionReq(int cmd,int src) +{ + ACTION_MSG_TYPE msg; + msg.cmd=cmd; + msg.src=src; + if(SendActionMsg(&msg)==0) + return 0; + return 1; +} + +int main_message_process(ACTION_MSG_TYPE *msg) +{ + switch(curr_state) + { + case SIX_SAMPLE: + if(msg->cmd==STOP_SAMPLE) + { + memset(&gas_clean_stat,0,sizeof(gas_clean_stat)); + memset(&gas_make_stat,0,sizeof(gas_make_stat)); + set_pid_ch(PID_LJ,PID_DIS,0); + set_pid_ch(PID_SAMPLE,PID_DIS,0); + memset(&my_action_state,0,sizeof(&my_action_state)); + relay_dly_close_set(RLY_SENSOR,4);//延时关传感器加热 + relay_clr(); + curr_state=MODE_IDLE; + } + break; + case CO2_SAMPLE: + break; + case DEMARCATE: + break; + default: + if(msg->cmd==START_SIX_SAMPLE) + { + memset(&gas_clean_stat,0,sizeof(gas_clean_stat)); + memset(&gas_make_stat,0,sizeof(gas_make_stat)); + gas_clean_stat.step=1; + gas_make_stat.step=1; + //gas_make_stat.step=29; + curr_state=SIX_SAMPLE; + //relay_set(RLY_YV18,ON,0);//开吹扫阀 + printf("start six sample\n"); + relay_set(RLY_YV20,ON,1);//开YV20 + printf("YV20 ON\n"); + } + else if(msg->cmd==START_DEMARCATE) + { + curr_state=DEMARCATE; + } + break; + } + return 0; +} + +void stop_gas_clean(int reason) +{ + SendActionReq(STOP_SAMPLE,reason); + printf("clean gas failed\n"); +} + +void stop_gas_make(int reason) +{ + SendActionReq(STOP_SAMPLE,reason); + printf("make gas failed\n"); +} + +int gas_clean(void) +{ + switch(gas_clean_stat.step) + { + case 1://检查I6 + if(io_get(STA_I6)==ON) + { + gas_clean_stat.dly_cnt=0; + gas_clean_stat.repeat_cnt=0; + gas_clean_stat.step++; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:I6 is in right position\n",gas_clean_stat.step); + } + else + { + LOG_DEBUG(ERROR_DEBUG,"clean_step=%d:I6 is not in right pos\n",gas_clean_stat.step); + stop_gas_clean(gas_clean_stat.step); + return gas_clean_stat.step; + } + break; + case 2://开YV14 + relay_set(RLY_YV14,ON,1); + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV14 ON\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + case 3://开YV6 + if(gas_clean_stat.dly_cnt==0) + { + relay_set(RLY_YV7,OFF,0); + relay_set(RLY_YV6,ON,1); + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV6 ON YV7 OFF\n",gas_clean_stat.step); + gas_clean_stat.dly_cnt++; + } + else + { + //等待I7到位 + if(gas_clean_stat.dly_cnt>I7_WAIT_CNT) + { + if(io_get(STA_I7)==ON) + { + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:I7 is arrived in right position\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + } + else + { + if(gas_clean_stat.dly_cnt>I7_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"gas_step=%d:wait I7 ON timeout\n",gas_clean_stat.step); + stop_gas_clean(gas_clean_stat.step); + gas_clean_stat.dly_cnt=0; + gas_clean_stat.step=0; + return gas_clean_stat.step; + } + } + } + gas_clean_stat.dly_cnt++; + } + break; + case 4://开YV7 + if(gas_clean_stat.dly_cnt==0) + { + relay_set(RLY_YV6,OFF,0); + relay_set(RLY_YV7,ON,1); + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV7 ON YV6 OFF\n",gas_clean_stat.step); + gas_clean_stat.dly_cnt++; + } + else + { + //等待I6到位 + if(gas_clean_stat.dly_cnt>I6_WAIT_CNT) + { + if(io_get(STA_I6)==ON) + { + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:I6 is arrived in right position\n",gas_clean_stat.step); + gas_clean_stat.step++; + + break; + } + else + { + if(gas_clean_stat.dly_cnt>I6_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"gas_step=%d:wait I6 arrived in right position timeout\n",gas_clean_stat.step); + stop_gas_clean(gas_clean_stat.step); + gas_clean_stat.dly_cnt=0; + gas_clean_stat.step=0; + return gas_clean_stat.step; + } + } + } + gas_clean_stat.dly_cnt++; + } + break; + case 5://重复3-4 + gas_clean_stat.dly_cnt=0; + gas_clean_stat.repeat_cnt++; + LOG_DEBUG(ACTION_DEBUG,"%dst gas clean completed,curr_step=%d\n",gas_clean_stat.repeat_cnt,gas_clean_stat.step); + if(gas_clean_stat.repeat_cnt>=CLEAN_AIR_REPEAT_CNT) + { + gas_clean_stat.repeat_cnt=0; + gas_clean_stat.step++; + } + else + { + gas_clean_stat.step=3; + } + break; + case 6://关YV14 + relay_set(RLY_YV14,OFF,1); + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV14 OFF\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + case 7://开YV15 + relay_set(RLY_YV15,ON,1); + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV15 ON\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + case 8://开YV6 + if(gas_clean_stat.dly_cnt==0) + { + relay_set(RLY_YV7,OFF,0); + relay_set(RLY_YV6,ON,1); + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV6 ON YV7 OFF\n",gas_clean_stat.step); + gas_clean_stat.dly_cnt++; + } + else + { + //等待I7到位 + if(gas_clean_stat.dly_cnt>I7_WAIT_CNT) + { + if(io_get(STA_I7)==ON) + { + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:I7 have arrived in right position\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + } + else + { + if(gas_clean_stat.dly_cnt>I7_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"gas_step=%d:wait I7 arrvied in right position timeout\n",gas_clean_stat.step); + stop_gas_clean(gas_clean_stat.step); + gas_clean_stat.dly_cnt=0; + gas_clean_stat.step=0; + return gas_clean_stat.step; + } + } + } + gas_clean_stat.dly_cnt++; + } + break; + case 9://关YV15 + relay_set(RLY_YV15,OFF,1); + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV15 OFF\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + case 10://开YV10,延时6秒 + if(gas_clean_stat.dly_cnt==0) + { + relay_set(RLY_YV10,ON,1); + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV10 ON,Start delay 6s\n",gas_clean_stat.step); + gas_clean_stat.dly_cnt++; + } + else + { + //延时6秒 + if(gas_clean_stat.dly_cnt>YV10_ON_TIME) + { + gas_clean_stat.dly_cnt=0; + gas_clean_stat.step++; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:Delay 6s is completed\n",gas_clean_stat.step); + } + else + { + gas_clean_stat.dly_cnt++; + } + } + break; + case 11://关YV10 + relay_set(RLY_YV10,OFF,1); + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV10 OFF\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + case 12://开YV14 + relay_set(RLY_YV14,ON,1); + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV14 ON\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + case 13://开YV7 + if(gas_clean_stat.dly_cnt==0) + { + relay_set(RLY_YV6,OFF,0); + relay_set(RLY_YV7,ON,1); + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV7 ON YV6 OFF\n",gas_clean_stat.step); + gas_clean_stat.dly_cnt++; + } + else + { + //等待I6到位 + if(gas_clean_stat.dly_cnt>I6_WAIT_CNT) + { + if(io_get(STA_I6)==ON) + { + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:I6 have arrived in right position\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + } + else + { + if(gas_clean_stat.dly_cnt>I6_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"gas_step=%d:wait I6 arrived in right position timeout\n",gas_clean_stat.step); + stop_gas_clean(gas_clean_stat.step); + gas_clean_stat.dly_cnt=0; + gas_clean_stat.step=0; + return gas_clean_stat.step; + } + } + } + gas_clean_stat.dly_cnt++; + } + break; + case 14://关YV14 + relay_set(RLY_YV14,OFF,1); + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV14 OFF\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + case 15://重复7-14 + gas_clean_stat.dly_cnt=0; + gas_clean_stat.repeat_cnt++; + LOG_DEBUG(ACTION_DEBUG,"%dst gas clean completed,curr_step=%d\n",gas_clean_stat.repeat_cnt,gas_clean_stat.step); + if(gas_clean_stat.repeat_cnt>=CLEAN_CARRIER_REPEAT_CNT) + { + gas_clean_stat.repeat_cnt=0; + gas_clean_stat.step++; + } + else + { + gas_clean_stat.step=7; + } + break; + case 16://开YV6 + if(gas_clean_stat.dly_cnt==0) + { + relay_set(RLY_YV7,OFF,0); + relay_set(RLY_YV6,ON,1); + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV6 ON YV7 OFF\n",gas_clean_stat.step); + gas_clean_stat.dly_cnt++; + } + else + { + //等待I7到位 + if(gas_clean_stat.dly_cnt>I7_WAIT_CNT) + { + if(io_get(STA_I7)==ON) + { + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:I7 have arrived in right position\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + } + else + { + if(gas_clean_stat.dly_cnt>I7_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"gas_step=%d:wait I7 arrived in right position timeout\n",gas_clean_stat.step); + stop_gas_clean(gas_clean_stat.step); + gas_clean_stat.dly_cnt=0; + gas_clean_stat.step=0; + return gas_clean_stat.step; + } + } + } + gas_clean_stat.dly_cnt++; + } + break; + case 17://启动冷井工作 + relay_set(RLY_KA6,ON,0);//开冷井风扇 + set_pid_ch(PID_LJ,PID_EN,1);//开冷井控制 + gas_clean_stat.dly_cnt=0; + gas_clean_stat.repeat_cnt=0; + gas_clean_stat.step++; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:gas clean have completed,KA6 ON and start LJ cold\n",gas_clean_stat.step); + break; + case 18: + break; + default: + break; + } + return 0; +} + + +int gas_make(void) +{ + float fval; + unsigned int sample_data_length=0; + + if(io_get(STA_I9)==ON) + { + usleep(500000); + if(io_get(STA_I9)==ON) + { + LOG_DEBUG(ERROR_DEBUG,"gas_make_step=%d gas_clean_step=%d:I9 is not in right position,exit\n",gas_make_stat.step,gas_clean_stat.step); + gas_clean_stat.step=0; + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + } + + if(gas_clean()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"gas clean failed\n"); + return gas_make_stat.step; + } + switch(gas_make_stat.step) + { + case 1://打开电机 + if(io_get(STA_I4)!=ON) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:I4 is not in right position,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + if(io_get(STA_I8)==OFF) + { + usleep(500000); + if(io_get(STA_I8)==OFF) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:I8 is not in right position,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + } + relay_set(RLY_YV16,ON,0); + relay_set(RLY_YV13,ON,0); + relay_set(RLY_KA1,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV16 ON,YV13 ON,KA1 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + break; + case 2://延时3分钟 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>=MOTOR_RUN_TIME) + { + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 3 minutes completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 3://关电机 + relay_set(RLY_KA1,OFF,0); + relay_set(RLY_YV16,OFF,0); + relay_set(RLY_YV13,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:KA1 OFF,YV16 OFF,YV13 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + break; + case 4: + if(io_get(STA_I8)==OFF) + { + usleep(500000); + if(io_get(STA_I8)==OFF) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:I8 is not in right position,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + } + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + break; + case 5://延时2秒,等待气路清洗完成, + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>=4) + { + if(gas_clean_stat.step>GAS_CLEAN_MAX_STEP) + { + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 2 minutes completed\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + } + else + { + if(gas_make_stat.dly_cnt>GAS_CLEAN_MAX_TIME) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:gas clean timeout,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + } + } + break; + case 6://开YV4 + if(gas_make_stat.dly_cnt==0) + { + relay_set(RLY_YV5,OFF,0); + relay_set(RLY_YV4,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV4 ON,YV5 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt++; + } + else + { + //等待I5到位 + if(gas_make_stat.dly_cnt>I5_WAIT_CNT) + { + if(io_get(STA_I5)==ON) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:I5 have arrived in right position\n",gas_make_stat.step); + gas_make_stat.step++; + break; + } + else + { + if(gas_make_stat.dly_cnt>I5_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:wait I5 arrived ON timeout,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step=0; + return gas_make_stat.step; + } + } + } + gas_make_stat.dly_cnt++; + } + break; + case 7://开YV11 + relay_set(RLY_YV11,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV11 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 8://开YV12 + relay_set(RLY_YV12,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV12 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 9://开YV15 + relay_set(RLY_YV15,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV15 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 10://延时2分钟,制气时间 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>GAS_MAKE_TIME) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 2 minutes completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 11: + if(gas_make_stat.dly_cnt==0) + { + relay_set(RLY_YV7,OFF,0); + relay_set(RLY_YV6,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV6 ON YV7 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt++; + } + else + { + //等待I7到位 + if(gas_make_stat.dly_cnt>I7_WAIT_CNT) + { + if(io_get(STA_I7)==ON) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:I7 have arrived in right position\n",gas_make_stat.step); + gas_make_stat.step++; + break; + } + else + { + if(gas_make_stat.dly_cnt>I7_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:wait I7 arrived in right position timeout\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step=0; + return gas_make_stat.step; + } + } + } + gas_make_stat.dly_cnt++; + } + break; + case 12://延时1分钟,制气时间 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>120) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 1 minutes completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 13://关YV4,对应STM32上清洗油路第28步 + relay_set(RLY_YV4,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV4 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 14://开YV15 + relay_set(RLY_YV12,OFF,0); + relay_set(RLY_YV11,OFF,0); + relay_set(RLY_YV15,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV12 OFF,YV11 OFF,YV15 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 15: + relay_set(RLY_YV11,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV11 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 16://延时10秒,进气时间,admission + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>20) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 10s completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 17://关YV11 + relay_set(RLY_YV11,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV11 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 18://开YV4 + if(gas_make_stat.dly_cnt==0) + { + relay_set(RLY_YV5,OFF,0); + relay_set(RLY_YV4,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV4 ON,YV5 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt++; + } + else + { + //等待I5到位 + if(gas_make_stat.dly_cnt>I5_WAIT_CNT) + { + if(io_get(STA_I5)==ON) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:I5 have arrived in right position\n",gas_make_stat.step); + gas_make_stat.step++; + break; + } + else + { + if(gas_make_stat.dly_cnt>I5_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:wait I5 arrived ON timeout,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step=0; + return gas_make_stat.step; + } + } + } + gas_make_stat.dly_cnt++; + } + break; + case 19://延时10秒 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>20) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 10s completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 20: + relay_set(RLY_YV11,ON,0); + relay_set(RLY_YV12,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV11 ON,YV12 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 21://延时1分钟 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>120) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 1minutes completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 22: + relay_set(RLY_YV4,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV4 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 23: + relay_set(RLY_YV12,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV12 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 24: + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>4) + { + relay_set(RLY_YV11,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV11 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + } + break; + case 25://重复6-23 + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt++; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:%dst make gas completed\n",gas_make_stat.step,gas_make_stat.repeat_cnt); + if(gas_make_stat.repeat_cnt>=GAS_MAKE_REPEAT_CNT)//制气重复次数 + { + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + } + else + { + gas_make_stat.step=6; + } + break; + /*case 24://开YV5,延时1秒 + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + if(gas_make_stat.dly_cnt==0) + { + relay_set(RLY_YV5,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV5 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt++; + } + else + { + if(gas_make_stat.dly_cnt>=3) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 1s completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + else + { + gas_make_stat.dly_cnt++; + } + } + break;*/ + /* case 25://关YV11 + relay_set(RLY_YV11,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV11 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 26://关YV5 + relay_set(RLY_YV5,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV5 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break;*/ + case 26://等待冷井温度<-25 + get_temperature(TEMP_LJ,&fval); + if(fval>(-25)) + { + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>600)//5分钟未到达设置的温度 + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:wait lj temperature arrived -25 timeout %f,exit\n",gas_make_stat.step,fval); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + if((gas_make_stat.dly_cnt%16)==0) + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:leng jin temp is %f\n",gas_make_stat.step,fval); + break; + } + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:leng jin temp is %f\n",gas_make_stat.step,fval); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 27://开YV7,关YV6 + relay_set(RLY_YV6,OFF,0); + relay_set(RLY_YV7,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV7 ON,YV6 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 28://等待3分钟 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>120)//到达1分钟? + { + if(gas_make_stat.dly_cnt==121) + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:1 minutes arrived\n",gas_make_stat.step); + //查PA1,大于常压就开YV17,等于常压就关闭YV17 + CurrCnvToPresEx(0,&fval); + if(fval>DELT_PRES) + { + relay_set(RLY_YV17,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV17 ON,pres=%fMpa\n",gas_make_stat.step,fval); + } + else if(fabs(fval-DELT_PRES)<0.001) + { + relay_set(RLY_YV17,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV17 OFF,pres=%fMpa\n",gas_make_stat.step,fval); + } + if((gas_make_stat.dly_cnt%8)==0) + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:Pres=%fMpa\n",gas_make_stat.step,fval); + if(gas_make_stat.dly_cnt>360)//3分钟到? + { + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 3 minutes completed\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + } + } + break; + case 29://等待冷井温度<-28 + get_temperature(TEMP_LJ,&fval); + if(fval>(-28)) + { + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>600)//5分钟未到达设置的温度 + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:wait lj temperature arrived -28 timeout %f,exit\n",gas_make_stat.step,fval); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + if((gas_make_stat.dly_cnt%16)==0) + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:leng jin wendu is %f\n",gas_make_stat.step,fval); + break; + } + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:leng jin wen du is %f\n",gas_make_stat.step,fval); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 30://开YV19 + relay_set(RLY_YV20,ON,0);//和YV19一起开,和YV18一起关 + relay_set(RLY_YV19,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV20 ON,YV19 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 31://延时18秒 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>36) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 18s completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 32://关YV19 + relay_set(RLY_YV19,OFF,0); + relay_set(RLY_YV7,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV19 OFF,YV7 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 33://关冷井风扇和制冷,关采样单元风扇以及制冷输出,电柜顶上的风扇也关闭 + set_pid_ch(PID_LJ,PID_DIS,0); + relay_set(RLY_KA6,OFF,1);//冷井风扇 + + set_pid_ch(PID_SAMPLE,PID_DIS,0); + relay_set(RLY_KA4,OFF,1);//采样单元风扇 + + relay_set(RLY_KA3,OFF,1);//柜子风扇 + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:KA6 OFF,LengJin Ctrl disable,KA4 OFF,Sample room ctrl disable,KA3 OFF\n",gas_make_stat.step); + //关伴热带,目前未定义tmb + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 34://延时3秒 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>6) + { + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 3s completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 35://检查色谱柱温度 + if(get_spz_stable(&fval)==0) + { + //printf("spz wendu delt=%f is stable\n",fval); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:spz wendu delt=%f is stable\n",gas_make_stat.step,fval); + get_temperature(TEMP_SPZ,&fval); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:spz wendu is %f\n",gas_make_stat.step,fval); + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + } + else + { + gas_make_stat.repeat_cnt=0; + gas_make_stat.dly_cnt++; + if((gas_make_stat.dly_cnt%8)==0) + { + get_temperature(TEMP_SPZ,&fval); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:spz wendu is %f\n",gas_make_stat.step,fval); + } + if(gas_make_stat.dly_cnt>600)//5分钟内未达到,退出采样 + { + get_temperature(TEMP_SPZ,&fval); + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:chromatographic temperature is not stable for 5 minutes %f,exit\n",gas_make_stat.step,fval); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + } + /*if(fabs(fval-60)<=0.2) + { + gas_make_stat.repeat_cnt++; + if(gas_make_stat.repeat_cnt>120)//连续稳定1分钟,即可认为稳定 + { + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + } + } + else + { + gas_make_stat.repeat_cnt=0; + gas_make_stat.dly_cnt++; + if((gas_make_stat.dly_cnt%8)==0) + printf("spz wendu is %f\n",fval); + if(gas_make_stat.dly_cnt>600)//5分钟内未达到,退出采样 + { + printf("spz wendu %f is not statble,exit\n",fval); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + } */ + break; + case 36://启动采样 + get_temperature(TEMP_SAM,&fval); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:sample room temp is %f,sample_len=%d sample_intval=%dms\n",gas_make_stat.step,fval,my_para_data.mach_run_para.sample_len,my_para_data.mach_run_para.sample_rate); + if(start_sample_data(0,my_para_data.mach_run_para.sample_len,my_para_data.mach_run_para.sample_rate)==0) + { + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + } + else + { + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>8) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:start data sample failed,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:WARNING:start data sample failed,Try again\n",gas_make_stat.step); + } + break; + case 37: + if(query_sample_data((unsigned char *)&sample_data_length,sizeof(sample_data_length))==0) + { + if(sample_data_length>0) + { + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:sample data length is %d\n",gas_make_stat.step,sample_data_length); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + } + else + { + gas_make_stat.dly_cnt++; + } + } + else + { + gas_make_stat.dly_cnt++; + } + + if(gas_make_stat.dly_cnt>20*60*2) //大于20分钟 + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:wait data sample complete timeout,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + break; + case 38://读取数据 + if(read_sample_data(2*my_para_data.mach_run_para.sample_len)==0) + { + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:read sample data complete\n",gas_make_stat.step); + if(save_sample_data(2*my_para_data.mach_run_para.sample_len)!=0) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:WARNING:save data to file failed\n",gas_make_stat.step); + } + else + { + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:save sample data success\n",gas_make_stat.step); + } + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + } + else + { + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>4) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:read sample data failed,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:WARNING:read sample data failed,Try again\n",gas_make_stat.step); + } + break; + case 39://完成采样 + if(clear_sample_data()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:WARNING:clear sample data failed\n",gas_make_stat.step); + if(clear_sample_data()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:WARNING:clear sample data failed\n",gas_make_stat.step); + if(clear_sample_data()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:WARNING:clear sample data failed\n",gas_make_stat.step); + } + } + } + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:All action have completed\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + + relay_dly_close_set(RLY_YV18,10*60*2);//延时10分钟关吹扫阀 + relay_dly_close_set(RLY_YV20,10*60*2);//延时10分钟关YV20 + relay_dly_close_set(RLY_SENSOR,10*60*2);//延时10分钟关传感器加热 + break; + case 40://延时10分钟 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>10*60*2) + { + if(start_sample_heat(0,0)!=0)//停止感器加热 + { + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:stop sensor heat failed\n",gas_make_stat.step); + } + relay_set(RLY_YV18,OFF,0);// + relay_set(RLY_YV20,OFF,1);// + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV18 OFF,YV20 OFF\n",gas_make_stat.step); + curr_state=MODE_IDLE; + memset(&my_action_state,0,sizeof(&my_action_state)); + } + break; + default: + break; + } + return 0; +} +/* +开YV4,等待到位 +开YV11, +开YV12 +等待5秒 +关YV12 +等待4秒 +关YV4,开关到位后关YV11 +*/ +int demarcate_process(void) +{ + float fval; + unsigned int sample_data_length=0; + switch(demarcate_stat.step) + { + case 1: + if(start_sample_heat(0,1)==0)//开传感器加热 + { + relay_set(RLY_YV18,ON,0);// + relay_set(RLY_YV20,ON,1);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:Sensor heat started,YV18 ON,YV20 ON,start delay 15 minutes\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + else + { + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>4) + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:start sensor heating failed,exit\n",demarcate_stat.step); + curr_state=MODE_IDLE; + return demarcate_stat.step; + } + } + break; + case 2://延时15分钟 + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>(15*60*2)) + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:delay 15 minutes completed\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + break; + case 3: + relay_set(RLY_KA6,OFF,0);//关冷井风扇 + relay_set(RLY_KA4,OFF,0);//关采样单元风扇 + relay_set(RLY_KA3,OFF,0);//关柜子风扇 + set_pid_ch(PID_SAMPLE,PID_DIS,0);//关采样室温度控制电源 + set_pid_ch(PID_LJ,PID_DIS,1);//关冷井温度控制电源 + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:KA6 OFF,KA4 OFF,KA3 OFF,Sample room cold disable,lj cold disable\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + break; + case 4://开YV14,延时3秒,关YV14 + if(demarcate_stat.dly_cnt==0) + { + relay_set(RLY_YV14,ON,1);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV14 ON\n",demarcate_stat.step); + } + else + { + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>6) + { + relay_set(RLY_YV14,OFF,1);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV14 OFF\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + } + break; + case 5://开YV10 + relay_set(RLY_YV10,ON,0);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV10 ON\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + break; + case 6://延时6秒 + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>12) + { + demarcate_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:delay 6s completed\n",demarcate_stat.step); + demarcate_stat.step++; + } + break; + case 7://关YV10 + relay_set(RLY_YV10,OFF,0);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV10 OFF\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + break; + case 8://检测压力,DLY 3 SECOND + demarcate_stat.dly_cnt++; + CurrCnvToPresEx(0,&fval); + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:Pres=%fMpa\n",demarcate_stat.step,fval); + if(fval>DELT_PRES) + { + relay_set(RLY_YV17,ON,1); + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV17 ON\n",demarcate_stat.step); + } + else if(fabs(fval-DELT_PRES)<0.001) + { + relay_set(RLY_YV17,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV17 OFF\n",demarcate_stat.step); + } + if(demarcate_stat.dly_cnt>6) + { + relay_set(RLY_YV17,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:delay 3s completed,YV17 OFF\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + break; + case 9://重复4-8两次 + demarcate_stat.repeat_cnt++; + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:repeat %st completed\n",demarcate_stat.step,demarcate_stat.repeat_cnt); + if(demarcate_stat.repeat_cnt>=2) + { + demarcate_stat.dly_cnt=0; + demarcate_stat.repeat_cnt=0; + demarcate_stat.step++; + } + else + { + demarcate_stat.dly_cnt=0; + demarcate_stat.repeat_cnt=0; + demarcate_stat.step=4; + } + break; + case 10://延时5秒 + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>10) + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:delay 5s completed\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + break; + case 11://开YV19 + relay_set(RLY_YV19,ON,1); + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV19 ON\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + break; + case 12://延时18秒 + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>36) + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:delay 18s completed\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + break; + case 13://关YV19 + relay_set(RLY_YV19,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV19 OFF\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + break; + case 14://启动采样 + if(start_sample_data(0,4000,230)==0) + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:start sample sucessed\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + else + { + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>4) + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:start data sample failed,exit\n",demarcate_stat.step); + if(start_sample_heat(0,0)!=0)//停止感器加热 + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:stop sensor heat failed\n",demarcate_stat.step); + } + else + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:stop sensor heat OK\n",demarcate_stat.step); + } + relay_set(RLY_YV18,OFF,0);// + relay_set(RLY_YV20,OFF,1);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV18 OFF,YV20 OFF\n",demarcate_stat.step); + curr_state=MODE_IDLE; + memset(&my_action_state,0,sizeof(&my_action_state)); + return demarcate_stat.step; + } + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:WARNING:start data sample failed,Try again\n",demarcate_stat.step); + } + break; + case 15://查是否有数据 + if(query_sample_data((unsigned char *)&sample_data_length,sizeof(sample_data_length))==0) + { + if(sample_data_length>0) + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:sample data length is %d\n",demarcate_stat.step,sample_data_length); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + else + { + demarcate_stat.dly_cnt++; + } + } + else + { + demarcate_stat.dly_cnt++; + } + + if(demarcate_stat.dly_cnt>20*60*2) //大于20分钟 + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:wait data sample complete timeout,exit\n",demarcate_stat.step); + //关传感器加热,YV18,YV20 + if(start_sample_heat(0,0)!=0)//停止感器加热 + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:stop sensor heat failed\n",demarcate_stat.step); + } + else + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:stop sensor heat OK\n",demarcate_stat.step); + } + relay_set(RLY_YV18,OFF,0);// + relay_set(RLY_YV20,OFF,1);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV18 OFF,YV20 OFF\n",demarcate_stat.step); + curr_state=MODE_IDLE; + memset(&my_action_state,0,sizeof(&my_action_state)); + return demarcate_stat.step; + } + break; + case 16://读数据 + if(read_sample_data(4000)==0) + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:read sample data complete\n",demarcate_stat.step); + if(save_sample_data(8000)!=0) + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:WARNING:save data to file failed\n",demarcate_stat.step); + } + else + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:save sample data success\n",demarcate_stat.step); + } + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + else + { + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>4) + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:read sample data failed,exit\n",demarcate_stat.step); + //关传感器加热,YV18,YV20 + //stop_gas_make(demarcate_stat.step); + return demarcate_stat.step; + } + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:WARNING:read sample data failed,Try again\n",demarcate_stat.step); + } + break; + case 17://清除数据 + if(clear_sample_data()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:WARNING:clear sample data failed\n",demarcate_stat.step); + if(clear_sample_data()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:WARNING:clear sample data failed\n",demarcate_stat.step); + if(clear_sample_data()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:WARNING:clear sample data failed\n",demarcate_stat.step); + } + } + } + demarcate_stat.dly_cnt=0; + demarcate_stat.repeat_cnt=0; + demarcate_stat.step++; + break; + case 18://收尾 + if(start_sample_heat(0,0)==0)//关传感器加热 + { + relay_set(RLY_YV18,OFF,0);// + relay_set(RLY_YV20,OFF,1);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:Sensor heat stoped,YV18 OFF,YV20 OFF,All action have completed\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step=0; + curr_state=MODE_IDLE; + } + else + { + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>8) + { + relay_set(RLY_YV18,OFF,0);// + relay_set(RLY_YV20,OFF,1);// + curr_state=MODE_IDLE; + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:stop sensor heating failed,YV18 OFF,YV20 OFF\n",demarcate_stat.step); + return demarcate_stat.step; + } + } + break; + default: + break; + } +} + +void idle_process(void) +{ + +} + +int main_timeout_process(void) +{ + switch(curr_state) + { + case SIX_SAMPLE: + gas_make(); + break; + case CO2_SAMPLE: + break; + case DEMARCATE: + demarcate_process(); + break; + default: + idle_process(); + break; + } + return 0; +} + + + + + +int main(int argc,char *argv[]) +{ + extern int send_ctrl_message(void); + ACTION_MSG_TYPE my_action_msg; + time_t now,next_sample_time,today_sec,last_sample_time; + unsigned char val=0; + int i=0; + float env_temp;//环境温度 + float my_temp;// + int cabinet_count=0; + unsigned int start_time; + unsigned int sample_intval; + + signal(SIGINT,ctrlCfun); + + if((sample_fd=SerialOpen(SAMPLE_SERIAL_DEV,SAMPLE_SERIAL_SPEED))==-1) + { + printf("open sample serial device failed\n"); + exit(1); + } + + + mutex_init(); + + if((main_mq=create_mq(MAIN_MESSAGE_MQ,MAIN_MAX_MESSAGE,MAIN_MESSAGE_SIZE))<0) + { + printf("create main message queue failed\n"); + exit(2); + } + + LoadAllPara(&my_para_data); + + if(ctrl_init()!=0) + { + printf("create ctrl thread failed\n"); + exit(3); + } + + sleep(8); + + //my_para_data.start_time=8; + //my_para_data.sample_intval=4; + + my_temp=60; + set_pid_temp(TEMP_SPZ,&my_temp,0);//设置色谱柱温度 + my_temp=-40; + set_pid_temp(TEMP_LJ,&my_temp,0);//设置冷井温度 + + // my_output_data.temperature[TEMP_SAM] + set_pid_ch(PID_SPZ,PID_EN,0);//开启色谱柱温度控制 + //set_pid_ch(PID_SAMPLE,PID_EN,0);//开启采样室温度控制 + //relay_set(RLY_KA4,ON,0);//开采样单元风扇 + //relay_set(RLY_KA6,ON,1);//开冷井风扇 + + start_time=my_para_data.mach_run_para.start_hour*3600+my_para_data.mach_run_para.start_minute*60; + now=time(NULL);//获取当前时间 + today_sec=now%86400; + if(today_sec>start_time) + { + next_sample_time=(my_para_data.mach_run_para.start_interval*3600)-((today_sec-start_time)%(my_para_data.mach_run_para.start_interval*3600)); + next_sample_time+=now; + } + else + { + next_sample_time=now-today_sec+start_time; + } + LOG_DEBUG(TRACE_DEBUG,"system reset:next_sample_time is %s",ctime(&next_sample_time)); + last_sample_time=next_sample_time; + analysis_init(); + while(doIt) + { + if(recv_mq_wait(main_mq,(void *)main_rx_buf,sizeof(main_rx_buf),500000)>0) + { + memcpy(&my_action_msg,main_rx_buf,sizeof(my_action_msg)); + printf("receivd msg %d\n",my_action_msg.cmd); + main_message_process(&my_action_msg); + } + else + { + main_timeout_process(); + } + + now=time(NULL); + today_sec=now%86400; + start_time=my_para_data.mach_run_para.start_hour*3600+my_para_data.mach_run_para.start_minute*60; + if(curr_state==MODE_IDLE) + { + if((today_sec%3600)<3)//判断是否整点 + { + if(my_para_data.mach_run_para.start_interval>2) + { + //整点开始,YV20工作5分钟,停止3分钟 + } + if(my_para_data.mach_run_para.start_interval>4) + { + //每隔两小时,整点开始,YV18工作,延时20分钟开传感器加热,45分钟延时到,全停 + } + } + else + { + + } + //室外温度-室内温度>3度,开柜子风扇35分钟,停5分钟,直到室外温度-室内温度<=3度 + if((cabinet_count)%120==0) //1分钟检测一次 + { + get_temperature(TEMP_OUTSIDE,&my_temp);//获取室外温度 + get_temperature(TEMP_ENV,&env_temp);//获取环境温度(柜内温度) + if((my_temp-env_temp)>3) + { + //开柜子风扇KA3 35分钟,停5分钟, + } + else + { + + } + } + cabinet_count++; + } + + + //采样开始前45分钟查表设置采样室温度,同时检测室外温度看是否启动伴热带 + if(now>=(next_sample_time-45*60)) + { + if(my_action_state.smp_flg==0) + { + get_temperature(TEMP_ENV,&env_temp);//获取环境温度 + get_sample_temp(&env_temp,&my_temp); + LOG_DEBUG(TRACE_DEBUG,"Preaction:Cabinet temperature is %f,set sample room temperature to %f\n",env_temp,my_temp); + set_pid_temp(TEMP_SAM,&my_temp,0);//设置采样室温度 + relay_set(RLY_KA4,ON,0); //开采样室风扇 + set_pid_ch(PID_SAMPLE,PID_EN,1); //开采样室温度控制 + my_action_state.smp_flg=1; + LOG_DEBUG(TRACE_DEBUG,"Preaction:KA4 ON,Start sample room colding\n"); + } + } //passed + + //采样单元工作30分钟后开吹扫阀,即提前15分钟开 + if(now>=(next_sample_time-15*60)) + { + //提前15分钟开吹扫阀,开启 + if(my_action_state.csf_flg==0) + { + relay_set(RLY_YV18,ON,1); + my_action_state.csf_flg=1; + LOG_DEBUG(TRACE_DEBUG,"Preaction:YV18 ON\n"); + } + }//passed + + //传感器加热开始于采样开始后8分钟 + if(now>=(last_sample_time+8*60)) + { + if(my_action_state.heat_flg==0) + { + if(curr_state!=0) + { + if(start_sample_heat(0,1)==0) + { + LOG_DEBUG(TRACE_DEBUG,"Preheat:start sensor heat ok\n"); + my_action_state.heat_flg=1; + } + else + { + LOG_DEBUG(TRACE_DEBUG,"Preheat:start sensor heat failed\n"); + } + } + } + }//passed + + + if(now>=next_sample_time) + { + //启动采样 + if(SendActionReq(SIX_SAMPLE,0)!=0) + LOG_DEBUG(TRACE_DEBUG,"send start six sample request failed\n"); + else + LOG_DEBUG(TRACE_DEBUG,"send start six sample request ok\n"); + last_sample_time=now;//记录最后一次采样开始时刻 + next_sample_time+=(my_para_data.mach_run_para.start_interval*3600); //计算下一次采样开始时刻 + LOG_DEBUG(TRACE_DEBUG,"next start sample time is %s\n",ctime(&next_sample_time)); + if(my_action_state.csf_flg==0) + { + LOG_DEBUG(TRACE_DEBUG,"Warning:csf YV18 is not opened\n"); + } + if(my_action_state.heat_flg==0) + { + LOG_DEBUG(TRACE_DEBUG,"Warning:sensor heating is not started\n"); + } + } + + //采样完成后,延时10分钟关传感器加热,关吹扫阀,关YV20 + relay_dly_process(); + } + mq_close(main_mq); + return 0; +} diff --git a/src/database/ysp.db b/src/database/ysp.db new file mode 100644 index 0000000000000000000000000000000000000000..7fb8f04dc64303aace5c00045310b9646e839a84 GIT binary patch literal 8192 zcmeI#K}y3w6b9foNg*JVaTSqn-bxe@77=gdSD`5pM(Rp^^uH~3Th z=>KXXN&xhmFhc+W5P$##AOHafKmY;|fB*y_@c#mFFVr+tX_lxgNj0mpe5mqN$KkGA RsW|wRt5KfmSnSI6=nL^8IgS7T literal 0 HcmV?d00001 diff --git a/src/database/ysp_cfg.ini b/src/database/ysp_cfg.ini new file mode 100644 index 0000000..101f061 --- /dev/null +++ b/src/database/ysp_cfg.ini @@ -0,0 +1,1597 @@ +[MACH] +#汾 +version=1.0.1 +#վ +station=ٺӱվ +#豸 +device=1# + +#ʼʱ0-23 +start_hour=2 + +#ʼ0-59 +start_minute=0 + +# +sample_interval=2 + +#ѹͨ1ϵ +pres1_fac_a=0.534759 + +#ѹͨ1ƫ +pres1_fac_b=-0.169518 + +#ѹͨ2ϵ +pres2_fac_a=0.08 + +#ѹͨ2ƫ +pres2_fac_b=-0.1 + +#ѹͨ3ϵ +pres3_fac_a=7.005 + +#ѹͨ3ƫ +pres3_fac_b=-0.028 + +#ѹͨ4ϵ +pres4_fac_a=7.005 + +#ѹͨ4ƫ +pres4_fac_b=-0.028 + +#ѹͨ5ϵ +pres5_fac_a=7.005 + +#ѹͨ5ƫ +pres5_fac_b=-0.028 + +#ѹͨ6ϵ +pres6_fac_a=7.005 + +#ѹͨ6ƫ +pres6_fac_b=-0.028 + +#ѹͨ7ϵ +pres7_fac_a=7.005 + +#ѹͨ7ƫ +pres7_fac_b=-0.028 + +#ѹͨ8ϵ +pres8_fac_a=7.005 + +#ѹͨ8ƫ +pres8_fac_b=-0.028 + +#ѹͨ10-5 +volt_out1=0 + +#ѹͨ20-5 +volt_out2=0 + +#ɫ¶ +temp1=60 + +#Ԥͨ¶ +temp2=60 + +#侮¶ +temp3=-36 + +#ҿ¶ +temp4=0 + +#ɫ¶ȿʹ0ر1ʹ +pid_en1=1 + +#Ԥ¶ȿʹ0ر1ʹ +pid_en2=1 + +#侮¶ȿʹ0ر1ʹ +pid_en3=1 + +#¶ȿʹ0ر1ʹ +pid_en4=1 + +#ɫ¶ȿƱϵ +kp1=12 + +#ɫ¶ȿƻϵ +ki1=0.15 + +#ɫ¶ȿ΢ϵ +kd1=500 + +#Ԥͨ¶ȿƱϵ +kp2=12 + +#Ԥͨ¶ȿƻϵ +ki2=0.15 + +#Ԥͨ¶ȿ΢ϵ +kd2=500 + +#侮¶ȿƱϵ +kp3=20000 + +#侮¶ȿƻϵ +ki3=1000 + +#侮¶ȿ΢ϵ +kd3=2000 + +#Ԫ¶ȿƱϵ +kp4=20000 + +#Ԫ¶ȿƻϵ +ki4=1000 + +#Ԫ¶ȿ΢ϵ +kd4=2000 + +# +sample_len=4000 + +#,Ϊλ +sample_rate=220 + +#ƫ,0-4095 +sample_offs=1200 + +#H2Ũȼ +[H2_CAL] +#ʼλ +start=170 + +#嶥λ +peak=256 + +#λ +end=320 + +# +width=16 + +#ݶYmin +lYmin=16 + +#ݶXmax +lXmax=32 + +#ݶYmin +rYmin=4 + +#ݶXmax +rXmax=32 + +#k1ֵ +k1_fac1=0.00162 + +#k1Ũֵ +k1_fac2=0 + +#k1Ũֵ +k1_fac3=10 + +#k1С +k1_fac4=0.1 + +#k1 +k1_fac5=6768.6 + +#k1߼ƫֵ +k1_fac6=1 + +#k2ֵ +k2_fac1=0.00260 + +#k2Ũֵ +k2_fac2=10.001 + +#k2Ũֵ +k2_fac3=30 + +#k2С +k2_fac4=6768.7 + +#k2 +k2_fac5=15849.2 + +#k2߼ƫֵ +k2_fac6=1.61 + +#k3ֵ +k3_fac1=0.00443 + +#k3Ũֵ +k3_fac2=30.001 + +#k3Ũֵ +k3_fac3=60 + +#k3С +k3_fac4=15849.3 + +#k3 +k3_fac5=24799.4 + +#k3߼ƫֵ +k3_fac6=1.7 + +#k4ֵ +k4_fac1=0.00756 + +#k4Ũֵ +k4_fac2=60.001 + +#k4Ũֵ +k4_fac3=100 + +#k4С +k4_fac4=24799.5 + +#k4 +k4_fac5=32994 + +#k4߼ƫֵ +k4_fac6=1.71 + +#k5ֵ +k5_fac1=0.01305 + +#k5Ũֵ +k5_fac2=100.001 + +#k5Ũֵ +k5_fac3=150 + +#k5С +k5_fac4=32994.1 + +#k5 +k5_fac5=40378.5 + +#k5߼ƫֵ +k5_fac6=1.73 + +#k6ֵ +k6_fac1=0.02339 + +#k6Ũֵ +k6_fac2=150.001 + +#k6Ũֵ +k6_fac3=200 + +#k6С +k6_fac4=140378.6 + +#k6 +k6_fac5=146619.1 + +#k6߼ƫֵ +k6_fac6=1.79 + +#k7ֵ +k7_fac1=0.04206 + +#k1Ũֵ +k7_fac2=200.01 + +#k7Ũֵ +k7_fac3=250 + +#k1С +k7_fac4=466192 + +#k7 +k7_fac5=52421.1 + +#k7߼ƫֵ +k7_fac6=1.8 + +#k8ֵ +k8_fac1=0.07607 + +#k8Ũֵ +k8_fac2=250.001 + +#k8Ũֵ +k8_fac3=500 + +#k8С +k8_fac4=52421.2 + +#k8 +k8_fac5=61082.8 + +#k8߼ƫֵ +k8_fac6=1.81 + +#k9ֵ +k9_fac1=0.14073 + +#k9Ũֵ +k9_fac2=500.001 + +#k9Ũֵ +k9_fac3=1000 + +#k9С +k9_fac4=61082.9 + +#k9 +k9_fac5=70872.6 + +#k9߼ƫֵ +k9_fac6=1.85 + +#k10ֵ +k10_fac1=1 + +#k10Ũֵ +k10_fac2=1 + +#k10Ũֵ +k10_fac3=1 + +#k10С +k10_fac4=1 + +#k10 +k10_fac5=1 + +#k10߼ƫֵ +k10_fac6=1 + +#k11ֵ +k11_fac1=1 + +#k11Ũֵ +k11_fac2=1 + +#k11Ũֵ +k11_fac3=1 + +#k11С +k11_fac4=1 + +#k11 +k11_fac5=1 + +#k11߼ƫֵ +k11_fac6=1 + +#k12ֵ +k12_fac1=1 + +#k12Ũֵ +k12_fac2=1 + +#k12Ũֵ +k12_fac3=1 + +#k12С +k12_fac4=1 + +#k12 +k12_fac5=1 + +#k12߼ƫֵ +k12_fac6=1 + +#COŨȼ +[CO_CAL] +#ʼλ +start=290 + +#嶥λ +peak=350 + +#λ +end=440 + +# +width=20 + +#ݶYmin +lYmin=16 + +#ݶXmax +lXmax=32 + +#ݶYmin +rYmin=4 + +#ݶXmax +rXmax=32 + +#k1ֵ +k1_fac1=0.0048 + +#k1Ũֵ +k1_fac2=0 + +#k1Ũֵ +k1_fac3=30 + +#k1С +k1_fac4=0.1 + +#k1 +k1_fac5=5351.1 + +#k1߼ƫֵ +k1_fac6=1 + +#k2ֵ +k2_fac1=0.00624 + +#k2Ũֵ +k2_fac2=30.001 + +#k2Ũֵ +k2_fac3=80 + +#k2С +k2_fac4=5351.2 + +#k2 +k2_fac5=11440.3 + +#k2߼ƫֵ +k2_fac6=1.3 + +#k3ֵ +k3_fac1=0.00878 + +#k3Ũֵ +k3_fac2=80.001 + +#k3Ũֵ +k3_fac3=150 + +#k3С +k3_fac4=11440.4 + +#k3 +k3_fac5=116650.9 + +#k3߼ƫֵ +k3_fac6=1.41 + +#k4ֵ +k4_fac1=0.01293 + +#k4Ũֵ +k4_fac2=150.001 + +#k4Ũֵ +k4_fac3=230 + +#k4С +k4_fac4=16651 + +#k4 +k4_fac5=20466.3 + +#k4߼ƫֵ +k4_fac6=1.47 + +#k5ֵ +k5_fac1=0.01983 + +#k5Ũֵ +k5_fac2=230.001 + +#k5Ũֵ +k5_fac3=500 + +#k5С +k5_fac4=20466.4 + +#k5 +k5_fac5=29181.9 + +#k5߼ƫֵ +k5_fac6=1.53 + +#k6ֵ +k6_fac1=0.03049 + +#k6Ũֵ +k6_fac2=500.001 + +#k6Ũֵ +k6_fac3=1000 + +#k6С +k6_fac4=29182 + +#k6 +k6_fac5=39023.1 + +#k6߼ƫֵ +k6_fac6=1.54 + +#k7ֵ +k7_fac1=0.04815 + +#k1Ũֵ +k7_fac2=1000.001 + +#k7Ũֵ +k7_fac3=2000 + +#k1С +k7_fac4=39023.2 + +#k7 +k7_fac5=51189.7 + +#k7߼ƫֵ +k7_fac6=1.58 + +#k8ֵ +k8_fac1=0.07822 + +#k8Ũֵ +k8_fac2=2000.001 + +#k8Ũֵ +k8_fac3=3500 + +#k8С +k8_fac4=51189.8 + +#k8 +k8_fac5=60246.2 + +#k8߼ƫֵ +k8_fac6=1.62 + +#k9ֵ +k9_fac1=0.12897 + +#k9Ũֵ +k9_fac2=3500.001 + +#k9Ũֵ +k9_fac3=5500 + +#k9С +k9_fac4=60246.3 + +#k9 +k9_fac5=64857.8 + +#k9߼ƫֵ +k9_fac6=1.65 + +#k10ֵ +k10_fac1=1 + +#k10Ũֵ +k10_fac2=1 + +#k10Ũֵ +k10_fac3=1 + +#k10С +k10_fac4=1 + +#k10 +k10_fac5=1 + +#k10߼ƫֵ +k10_fac6=1 + +#k11ֵ +k11_fac1=1 + +#k11Ũֵ +k11_fac2=1 + +#k11Ũֵ +k11_fac3=1 + +#k11С +k11_fac4=1 + +#k11 +k11_fac5=1 + +#k11߼ƫֵ +k11_fac6=1 + +#k12ֵ +k12_fac1=1 + +#k12Ũֵ +k12_fac2=1 + +#k12Ũֵ +k12_fac3=1 + +#k12С +k12_fac4=1 + +#k12 +k12_fac5=1 + +#k12߼ƫֵ +k12_fac6=1 + +#CH4Ũȼ +[CH4_CAL] +#ʼλ +start=460 + +#嶥λ +peak=515 + +#λ +end=600 + +# +width=30 + +#ݶYmin +lYmin=10 + +#ݶXmax +lXmax=32 + +#ݶYmin +rYmin=4 + +#ݶXmax +rXmax=32 + +#k1ֵ +k1_fac1=0.00172 + +#k1Ũֵ +k1_fac2=0 + +#k1Ũֵ +k1_fac3=5 + +#k1С +k1_fac4=0.1 + +#k1 +k1_fac5=1792.3 + +#k1߼ƫֵ +k1_fac6=1 + +#k2ֵ +k2_fac1=0.00184 + +#k2Ũֵ +k2_fac2=5.001 + +#k2Ũֵ +k2_fac3=30 + +#k2С +k2_fac4=1792.4 + +#k2 +k2_fac5=9472.2 + +#k2߼ƫֵ +k2_fac6=1.07 + +#k3ֵ +k3_fac1=0.00200 + +#k3Ũֵ +k3_fac2=30.001 + +#k3Ũֵ +k3_fac3=50 + +#k3С +k3_fac4=9472.3 + +#k3 +k3_fac5=12153.2 + +#k3߼ƫֵ +k3_fac6=1.08 + +#k4ֵ +k4_fac1=0.00221 + +#k4Ũֵ +k4_fac2=50.001 + +#k4Ũֵ +k4_fac3=120 + +#k4С +k4_fac4=12153.3 + +#k4 +k4_fac5=27061.7 + +#k4߼ƫֵ +k4_fac6=1.11 + +#k5ֵ +k5_fac1=0.00250 + +#k5Ũֵ +k5_fac2=120.001 + +#k5Ũֵ +k5_fac3=180 + +#k5С +k5_fac4=27061.8 + +#k5 +k5_fac5=33001.2 + +#k5߼ƫֵ +k5_fac6=1.13 + +#k6ֵ +k6_fac1=0.00285 + +#k6Ũֵ +k6_fac2=180.001 + +#k6Ũֵ +k6_fac3=300 + +#k6С +k6_fac4=33001.3 + +#k6 +k6_fac5=48529.5 + +#k6߼ƫֵ +k6_fac6=1.14 + +#k7ֵ +k7_fac1=0.00327 + +#k1Ũֵ +k7_fac2=300.001 + +#k7Ũֵ +k7_fac3=500 + +#k1С +k7_fac4=48529.6 + +#k7 +k7_fac5=70883.4 + +#k7߼ƫֵ +k7_fac6=1.15 + +#k8ֵ +k8_fac1=0.00705 + +#k8Ũֵ +k8_fac2=500.001 + +#k8Ũֵ +k8_fac3=1000 + +#k8С +k8_fac4=70883.5 + +#k8 +k8_fac5=91580.6 + +#k8߼ƫֵ +k8_fac6=2.16 + +#k9ֵ +k9_fac1=1 + +#k9Ũֵ +k9_fac2=1 + +#k9Ũֵ +k9_fac3=1 + +#k9С +k9_fac4=1 + +#k9 +k9_fac5=1 + +#k9߼ƫֵ +k9_fac6=1 + +#k10ֵ +k10_fac1=1 + +#k10Ũֵ +k10_fac2=1 + +#k10Ũֵ +k10_fac3=1 + +#k10С +k10_fac4=1 + +#k10 +k10_fac5=1 + +#k10߼ƫֵ +k10_fac6=1 + +#k11ֵ +k11_fac1=1 + +#k11Ũֵ +k11_fac2=1 + +#k11Ũֵ +k11_fac3=1 + +#k11С +k11_fac4=1 + +#k11 +k11_fac5=1 + +#k11߼ƫֵ +k11_fac6=1 + +#k12ֵ +k12_fac1=1 + +#k12Ũֵ +k12_fac2=1 + +#k12Ũֵ +k12_fac3=1 + +#k12С +k12_fac4=1 + +#k12 +k12_fac5=1 + +#k12߼ƫֵ +k12_fac6=1 + +#C2H4Ũȼ +[C2H4_CAL] +#ʼλ +start=1600 + +#嶥λ +peak=1905 + +#λ +end=2200 + +# +width=64 + +#ݶYmin +lYmin=10 + +#ݶXmax +lXmax=32 + +#ݶYmin +rYmin=4 + +#ݶXmax +rXmax=32 + +#k1ֵ +k1_fac1=0.00137 + +#k1Ũֵ +k1_fac2=0 + +#k1Ũֵ +k1_fac3=5 + +#k1С +k1_fac4=0.1 + +#k1 +k1_fac5=3649.7 + +#k1߼ƫֵ +k1_fac6=1 + +#k2ֵ +k2_fac1=0.00227 + +#k2Ũֵ +k2_fac2=5.001 + +#k2Ũֵ +k2_fac3=30 + +#k2С +k2_fac4=3649.8 + +#k2 +k2_fac5=14667.3 + +#k2߼ƫֵ +k2_fac6=1.66 + +#k3ֵ +k3_fac1=0.00383 + +#k3Ũֵ +k3_fac2=30.001 + +#k3Ũֵ +k3_fac3=80 + +#k3С +k3_fac4=14667.4 + +#k3 +k3_fac5=27725.7 + +#k3߼ƫֵ +k3_fac6=1.69 + +#k4ֵ +k4_fac1=0.00661 + +#k4Ũֵ +k4_fac2=80.001 + +#k4Ũֵ +k4_fac3=120 + +#k4С +k4_fac4=27725.8 + +#k4 +k4_fac5=33773.5 + +#k4߼ƫֵ +k4_fac6=1.73 + +#k5ֵ +k5_fac1=0.01175 + +#k5Ũֵ +k5_fac2=120.001 + +#k5Ũֵ +k5_fac3=180 + +#k5С +k5_fac4=33773.6 + +#k5 +k5_fac5=38880.8 + +#k5߼ƫֵ +k5_fac6=1.78 + +#k6ֵ +k6_fac1=0.021129 + +#k6Ũֵ +k6_fac2=180.001 + +#k6Ũֵ +k6_fac3=250 + +#k6С +k6_fac4=38880.9 + +#k6 +k6_fac5=42168.6 + +#k6߼ƫֵ +k6_fac6=1.81 + +#k7ֵ +k7_fac1=0.08369 + +#k1Ũֵ +k7_fac2=250.001 + +#k7Ũֵ +k7_fac3=550 + +#k1С +k7_fac4=42168.7 + +#k7 +k7_fac5=49923.3 + +#k7߼ƫֵ +k7_fac6=1.82 + +#k8ֵ +k8_fac1=0.07088 + +#k8Ũֵ +k8_fac2=550.001 + +#k8Ũֵ +k8_fac3=1000 + +#k8С +k8_fac4=49923.4 + +#k8 +k8_fac5=56272.1 + +#k8߼ƫֵ +k8_fac6=.83 + +#k9ֵ +k9_fac1=1 + +#k9Ũֵ +k9_fac2=1 + +#k9Ũֵ +k9_fac3=1 + +#k9С +k9_fac4=1 + +#k9 +k9_fac5=1 + +#k9߼ƫֵ +k9_fac6=1 + +#k10ֵ +k10_fac1=1 + +#k10Ũֵ +k10_fac2=1 + +#k10Ũֵ +k10_fac3=1 + +#k10С +k10_fac4=1 + +#k10 +k10_fac5=1 + +#k10߼ƫֵ +k10_fac6=1 + +#k11ֵ +k11_fac1=1 + +#k11Ũֵ +k11_fac2=1 + +#k11Ũֵ +k11_fac3=1 + +#k11С +k11_fac4=1 + +#k11 +k11_fac5=1 + +#k11߼ƫֵ +k11_fac6=1 + +#k12ֵ +k12_fac1=1 + +#k12Ũֵ +k12_fac2=1 + +#k12Ũֵ +k12_fac3=1 + +#k12С +k12_fac4=1 + +#k12 +k12_fac5=1 + +#k12߼ƫֵ +k12_fac6=1 + +#C2H6Ũȼ +[C2H6_CAL] +#ʼλ +start=2200 + +#嶥λ +peak=2450 + +#λ +end=2700 + +# +width=32 + +#ݶYmin +lYmin=10 + +#ݶXmax +lXmax=32 + +#ݶYmin +rYmin=4 + +#ݶXmax +rXmax=32 + +#k1ֵ +k1_fac1=0.00239 + +#k1Ũֵ +k1_fac2=0 + +#k1Ũֵ +k1_fac3=5 + +#k1С +k1_fac4=0.1 + +#k1 +k1_fac5=2092.2 + +#k1߼ƫֵ +k1_fac6=1 + +#k2ֵ +k2_fac1=0.00363 + +#k2Ũֵ +k2_fac2=5.001 + +#k2Ũֵ +k2_fac3=30 + +#k2С +k2_fac4=2092.3 + +#k2 +k2_fac5=8972.2 + +#k2߼ƫֵ +k2_fac6=1.52 + +#k3ֵ +k3_fac1=0.00572 + +#k3Ũֵ +k3_fac2=30.001 + +#k3Ũֵ +k3_fac3=80 + +#k3С +k3_fac4=8972.3 + +#k3 +k3_fac5=17720.8 + +#k3߼ƫֵ +k3_fac6=1.57 + +#k4ֵ +k4_fac1=0.00905 + +#k4Ũֵ +k4_fac2=80.001 + +#k4Ũֵ +k4_fac3=120 + +#k4С +k4_fac4=17720.9 + +#k4 +k4_fac5=22140.4 + +#k4߼ƫֵ +k4_fac6=1.58 + +#k5ֵ +k5_fac1=0.01457 + +#k5Ũֵ +k5_fac2=120.001 + +#k5Ũֵ +k5_fac3=180 + +#k5С +k5_fac4=22140.5 + +#k5 +k5_fac5=26259.4 + +#k5߼ƫֵ +k5_fac6=1.61 + +#k6ֵ +k6_fac1=0.02421 + +#k6Ũֵ +k6_fac2=180.001 + +#k6Ũֵ +k6_fac3=250 + +#k6С +k6_fac4=26259.5 + +#k6 +k6_fac5=29150.3 + +#k6߼ƫֵ +k6_fac6=1.66 + +#k7ֵ +k7_fac1=0.04059 + +#k1Ũֵ +k7_fac2=250.001 + +#k7Ũֵ +k7_fac3=500 + +#k1С +k7_fac4=29150.4 + +#k7 +k7_fac5=35309.8 + +#k7߼ƫֵ +k7_fac6=1.68 + +#k8ֵ +k8_fac1=0.07007 + +#k8Ũֵ +k8_fac2=500.001 + +#k8Ũֵ +k8_fac3=1000 + +#k8С +k8_fac4=35309.9 + +#k8 +k8_fac5=42446 + +#k8߼ƫֵ +k8_fac6=1.73 + +#k9ֵ +k9_fac1=1 + +#k9Ũֵ +k9_fac2=1 + +#k9Ũֵ +k9_fac3=1 + +#k9С +k9_fac4=1 + +#k9 +k9_fac5=1 + +#k9߼ƫֵ +k9_fac6=1 + +#k10ֵ +k10_fac1=1 + +#k10Ũֵ +k10_fac2=1 + +#k10Ũֵ +k10_fac3=1 + +#k10С +k10_fac4=1 + +#k10 +k10_fac5=1 + +#k10߼ƫֵ +k10_fac6=1 + +#k11ֵ +k11_fac1=1 + +#k11Ũֵ +k11_fac2=1 + +#k11Ũֵ +k11_fac3=1 + +#k11С +k11_fac4=1 + +#k11 +k11_fac5=1 + +#k11߼ƫֵ +k11_fac6=1 + +#k12ֵ +k12_fac1=1 + +#k12Ũֵ +k12_fac2=1 + +#k12Ũֵ +k12_fac3=1 + +#k12С +k12_fac4=1 + +#k12 +k12_fac5=1 + +#k12߼ƫֵ +k12_fac6=1 + +#C2H2Ũȼ +[C2H2_CAL] +#ʼλ +start=2800 + +#嶥λ +peak=2980 + +#λ +end=3100 + +# +width=32 + +#ݶYmin +lYmin=8 + +#ݶXmax +lXmax=32 + +#ݶYmin +rYmin=4 + +#ݶXmax +rXmax=32 + +#k1ֵ +k1_fac1=0.00202 + +#k1Ũֵ +k1_fac2=0 + +#k1Ũֵ +k1_fac3=5 + +#k1С +k1_fac4=0.1 + +#k1 +k1_fac5=2475.3 + +#k1߼ƫֵ +k1_fac6=1 + +#k2ֵ +k2_fac1=0.00305 + +#k2Ũֵ +k2_fac2=5.001 + +#k2Ũֵ +k2_fac3=20 + +#k2С +k2_fac4=2475.4 + +#k2 +k2_fac5=7392.4 + +#k2߼ƫֵ +k2_fac6=1.51 + +#k3ֵ +k3_fac1=0.00483 + +#k3Ũֵ +k3_fac2=20.001 + +#k3Ũֵ +k3_fac3=50 + +#k3С +k3_fac4=7392.5 + +#k3 +k3_fac5=13608.9 + +#k3߼ƫֵ +k3_fac6=1.58 + +#k4ֵ +k4_fac1=0.00718 + +#k4Ũֵ +k4_fac2=50.001 + +#k4Ũֵ +k4_fac3=100 + +#k4С +k4_fac4=13609 + +#k4 +k4_fac5=20574.5 + +#k4߼ƫֵ +k4_fac6=1.49 + +#k5ֵ +k5_fac1=0.01068 + +#k5Ũֵ +k5_fac2=100.001 + +#k5Ũֵ +k5_fac3=150 + +#k5С +k5_fac4=20574.6 + +#k5 +k5_fac5=25255.4 + +#k5߼ƫֵ +k5_fac6=1.49 + +#k6ֵ +k6_fac1=0.01528 + +#k6Ũֵ +k6_fac2=150.001 + +#k6Ũֵ +k6_fac3=200 + +#k6С +k6_fac4=25255.5 + +#k6 +k6_fac5=28526.8 + +#k6߼ƫֵ +k6_fac6=1.43 + +#k7ֵ +k7_fac1=0.02249 + +#k1Ũֵ +k7_fac2=200.001 + +#k7Ũֵ +k7_fac3=300 + +#k1С +k7_fac4=28526.9 + +#k7 +k7_fac5=32972.5 + +#k7߼ƫֵ +k7_fac6=1.47 + +#k8ֵ +k8_fac1=1 + +#k8Ũֵ +k8_fac2=1 + +#k8Ũֵ +k8_fac3=1 + +#k8С +k8_fac4=1 + +#k8 +k8_fac5=1 + +#k8߼ƫֵ +k8_fac6=1 + +#k9ֵ +k9_fac1=1 + +#k9Ũֵ +k9_fac2=1 + +#k9Ũֵ +k9_fac3=1 + +#k9С +k9_fac4=1 + +#k9 +k9_fac5=1 + +#k9߼ƫֵ +k9_fac6=1 + +#k10ֵ +k10_fac1=1 + +#k10Ũֵ +k10_fac2=1 + +#k10Ũֵ +k10_fac3=1 + +#k10С +k10_fac4=1 + +#k10 +k10_fac5=1 + +#k10߼ƫֵ +k10_fac6=1 + +#k11ֵ +k11_fac1=1 + +#k11Ũֵ +k11_fac2=1 + +#k11Ũֵ +k11_fac3=1 + +#k11С +k11_fac4=1 + +#k11 +k11_fac5=1 + +#k11߼ƫֵ +k11_fac6=1 + +#k12ֵ +k12_fac1=1 + +#k12Ũֵ +k12_fac2=1 + +#k12Ũֵ +k12_fac3=1 + +#k12С +k12_fac4=1 + +#k12 +k12_fac5=1 + +#k12߼ƫֵ +k12_fac6=1 + + + + + + diff --git a/src/fileprocess b/src/fileprocess new file mode 100644 index 0000000..678d5eb --- /dev/null +++ b/src/fileprocess @@ -0,0 +1,7 @@ +#!/bin/sh +while true +do +echo -n "now start remove old file!" +find /COMTRADE -mtime +180 -type f -exec rm -f {} \; +sleep 604800 +done diff --git a/src/filter.csv b/src/filter.csv new file mode 100644 index 0000000..aff08cc --- /dev/null +++ b/src/filter.csv @@ -0,0 +1,4001 @@ +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +227 +231 +255 +309 +396 +524 +697 +921 +1200 +1532 +1908 +2314 +2753 +3211 +3686 +4169 +4653 +5133 +5601 +6057 +6490 +6905 +7295 +7664 +8008 +8329 +8628 +8902 +9159 +9389 +9602 +9791 +9959 +10104 +10225 +10320 +10389 +10435 +10448 +10434 +10388 +10311 +10204 +10066 +9899 +9701 +9480 +9235 +8971 +8691 +8399 +8099 +7792 +7486 +7177 +6875 +6576 +6286 +6005 +5732 +5472 +5221 +4985 +4758 +4545 +4342 +4151 +3972 +3800 +3641 +3487 +3345 +3207 +3079 +2957 +2841 +2732 +2627 +2529 +2433 +2344 +2256 +2174 +2096 +2023 +1957 +1897 +1846 +1806 +1778 +1764 +1768 +1795 +1844 +1921 +2025 +2160 +2324 +2517 +2735 +2971 +3226 +3489 +3762 +4034 +4307 +4572 +4828 +5074 +5306 +5527 +5732 +5925 +6100 +6264 +6412 +6549 +6675 +6787 +6891 +6979 +7061 +7129 +7185 +7227 +7258 +7275 +7272 +7256 +7217 +7163 +7089 +6998 +6886 +6755 +6611 +6449 +6278 +6092 +5900 +5699 +5492 +5283 +5070 +4860 +4648 +4444 +4242 +4050 +3864 +3687 +3520 +3360 +3213 +3072 +2942 +2818 +2702 +2593 +2489 +2394 +2301 +2216 +2133 +2055 +1980 +1910 +1843 +1779 +1721 +1662 +1610 +1558 +1511 +1466 +1423 +1384 +1343 +1309 +1274 +1244 +1214 +1187 +1162 +1136 +1114 +1086 +1062 +1034 +1008 +978 +949 +920 +890 +863 +833 +808 +780 +756 +731 +707 +687 +667 +650 +630 +615 +598 +583 +569 +553 +539 +525 +514 +500 +489 +478 +467 +459 +450 +441 +431 +423 +412 +403 +392 +381 +369 +359 +350 +340 +333 +325 +318 +313 +307 +302 +297 +293 +290 +289 +291 +297 +308 +325 +353 +392 +449 +524 +624 +753 +913 +1113 +1351 +1637 +1967 +2347 +2772 +3244 +3757 +4307 +4889 +5492 +6115 +6741 +7371 +7992 +8601 +9191 +9756 +10297 +10805 +11285 +11730 +12143 +12522 +12867 +13181 +13457 +13704 +13914 +14094 +14240 +14353 +14436 +14486 +14504 +14485 +14436 +14348 +14229 +14074 +13883 +13659 +13400 +13116 +12799 +12463 +12102 +11725 +11333 +10930 +10523 +10110 +9703 +9295 +8898 +8508 +8130 +7766 +7414 +7080 +6758 +6454 +6163 +5889 +5628 +5382 +5152 +4932 +4729 +4534 +4353 +4180 +4019 +3867 +3722 +3587 +3455 +3335 +3217 +3109 +3005 +2906 +2814 +2724 +2643 +2561 +2489 +2417 +2351 +2286 +2225 +2167 +2109 +2056 +2001 +1950 +1897 +1846 +1794 +1742 +1693 +1641 +1594 +1543 +1497 +1450 +1405 +1362 +1319 +1281 +1240 +1205 +1168 +1135 +1102 +1071 +1043 +1014 +989 +961 +937 +912 +890 +869 +848 +830 +797 +770 +744 +721 +700 +681 +665 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +650 +649 +649 +648 +646 +645 +643 +641 +638 +637 +634 +633 +631 +629 +628 +626 +626 +623 +622 +621 +620 +619 +617 +616 +614 +613 +611 +610 +609 +607 +605 +603 +602 +599 +598 +596 +594 +592 +590 +588 +586 +585 +582 +581 +578 +576 +573 +571 +569 +567 +566 +564 +563 +562 +560 +560 +558 +557 +555 +553 +551 +550 +548 +545 +544 +542 +541 +539 +538 +536 +536 +535 +534 +533 +531 +532 +530 +531 +531 +531 +532 +532 +533 +533 +534 +534 +534 +534 +533 +533 +532 +531 +529 +528 +526 +525 +523 +521 +519 +516 +514 +511 +508 +504 +500 +496 +491 +488 +483 +480 +477 +475 +473 +472 +471 +470 +470 +469 +469 +468 +468 +468 +468 +467 +466 +466 +465 +464 +463 +461 +460 +458 +456 +454 +453 +452 +450 +450 +449 +450 +451 +453 +453 +455 +458 +461 +466 +471 +477 +486 +495 +508 +520 +535 +550 +568 +589 +610 +636 +662 +694 +725 +763 +802 +846 +895 +948 +1010 +1075 +1152 +1235 +1328 +1431 +1544 +1670 +1803 +1953 +2110 +2284 +2469 +2669 +2883 +3111 +3357 +3614 +3892 +4182 +4491 +4815 +5155 +5513 +5885 +6277 +6680 +7103 +7537 +7988 +8451 +8927 +9417 +9916 +10429 +10947 +11477 +12012 +12556 +13106 +13658 +14216 +14773 +15336 +15895 +16456 +17014 +17570 +18123 +18669 +19212 +19747 +20277 +20798 +21311 +21814 +22306 +22789 +23257 +23716 +24159 +24591 +25007 +25410 +25797 +26169 +26527 +26866 +27193 +27500 +27792 +28066 +28323 +28564 +28786 +28994 +29180 +29353 +29505 +29642 +29760 +29860 +29944 +30009 +30057 +30088 +30105 +30103 +30087 +30054 +30004 +29940 +29861 +29767 +29654 +29530 +29391 +29238 +29072 +28890 +28700 +28493 +28277 +28046 +27805 +27552 +27287 +27014 +26727 +26434 +26128 +25817 +25495 +25167 +24831 +24487 +24140 +23783 +23426 +23060 +22691 +22317 +21940 +21561 +21177 +20795 +20407 +20022 +19634 +19248 +18862 +18476 +18094 +17709 +17332 +16952 +16579 +16207 +15840 +15477 +15117 +14763 +14411 +14068 +13727 +13394 +13065 +12743 +12427 +12115 +11812 +11512 +11222 +10936 +10658 +10387 +10120 +9863 +9608 +9365 +9124 +8892 +8664 +8443 +8229 +8020 +7819 +7620 +7431 +7245 +7066 +6891 +6722 +6559 +6398 +6246 +6095 +5952 +5810 +5674 +5542 +5413 +5289 +5167 +5052 +4936 +4828 +4720 +4618 +4518 +4420 +4328 +4234 +4147 +4059 +3976 +3895 +3815 +3740 +3664 +3594 +3522 +3456 +3390 +3327 +3266 +3205 +3148 +3090 +3038 +2983 +2933 +2882 +2833 +2786 +2739 +2695 +2649 +2608 +2564 +2523 +2482 +2442 +2405 +2367 +2333 +2295 +2262 +2228 +2196 +2165 +2134 +2104 +2073 +2045 +2014 +1987 +1958 +1931 +1904 +1877 +1852 +1823 +1800 +1773 +1750 +1725 +1702 +1679 +1656 +1637 +1616 +1597 +1576 +1557 +1537 +1517 +1500 +1480 +1461 +1442 +1426 +1408 +1391 +1375 +1358 +1344 +1329 +1316 +1299 +1285 +1270 +1256 +1242 +1229 +1215 +1201 +1190 +1175 +1162 +1149 +1136 +1124 +1111 +1099 +1087 +1077 +1065 +1054 +1043 +1031 +1020 +1009 +998 +987 +978 +967 +956 +946 +935 +924 +913 +903 +893 +883 +873 +863 +854 +845 +837 +828 +820 +811 +803 +795 +787 +780 +772 +765 +757 +750 +742 +735 +727 +719 +712 +704 +697 +690 +683 +676 +670 +663 +657 +653 +650 +647 +644 +642 +640 +638 +636 +631 +628 +624 +620 +616 +612 +608 +605 +601 +597 +594 +591 +588 +585 +581 +578 +574 +571 +568 +565 +562 +560 +557 +554 +551 +548 +544 +540 +537 +534 +530 +527 +524 +521 +518 +515 +511 +508 +505 +502 +498 +494 +491 +488 +485 +484 +482 +480 +479 +477 +477 +475 +475 +474 +473 +472 +470 +470 +467 +466 +464 +462 +460 +457 +455 +453 +451 +449 +448 +446 +444 +442 +440 +440 +437 +436 +434 +433 +431 +428 +426 +424 +422 +419 +418 +415 +413 +411 +409 +408 +405 +404 +401 +400 +399 +398 +397 +396 +396 +394 +394 +393 +392 +392 +391 +390 +389 +389 +388 +389 +388 +388 +388 +387 +387 +385 +386 +385 +386 +386 +387 +388 +390 +392 +394 +397 +400 +404 +411 +417 +424 +433 +441 +451 +461 +473 +484 +498 +512 +526 +545 +564 +588 +610 +638 +666 +698 +733 +769 +811 +851 +900 +949 +1004 +1061 +1123 +1191 +1261 +1340 +1419 +1508 +1600 +1699 +1804 +1914 +2033 +2156 +2290 +2427 +2574 +2725 +2886 +3053 +3227 +3411 +3599 +3797 +3999 +4211 +4429 +4654 +4886 +5122 +5369 +5616 +5875 +6135 +6404 +6677 +6954 +7238 +7522 +7816 +8108 +8408 +8708 +9013 +9319 +9626 +9937 +10246 +10560 +10871 +11184 +11496 +11807 +12118 +12426 +12735 +13039 +13343 +13642 +13939 +14232 +14521 +14807 +15085 +15364 +15632 +15899 +16158 +16412 +16661 +16903 +17141 +17368 +17593 +17807 +18017 +18219 +18413 +18601 +18779 +18952 +19114 +19271 +19417 +19558 +19689 +19811 +19926 +20030 +20129 +20216 +20298 +20370 +20435 +20491 +20537 +20576 +20605 +20627 +20641 +20648 +20645 +20635 +20617 +20592 +20561 +20520 +20473 +20415 +20353 +20282 +20204 +20121 +20028 +19932 +19825 +19714 +19595 +19471 +19342 +19205 +19064 +18914 +18763 +18603 +18440 +18271 +18097 +17920 +17735 +17550 +17356 +17163 +16963 +16762 +16557 +16348 +16138 +15923 +15710 +15490 +15272 +15050 +14828 +14604 +14377 +14153 +13924 +13700 +13472 +13246 +13020 +12794 +12570 +12344 +12124 +11900 +11681 +11460 +11242 +11026 +10810 +10599 +10386 +10179 +9971 +9768 +9565 +9367 +9171 +8977 +8788 +8598 +8414 +8231 +8053 +7876 +7704 +7536 +7369 +7208 +7045 +6890 +6735 +6585 +6436 +6290 +6148 +6006 +5872 +5736 +5607 +5480 +5356 +5236 +5116 +5003 +4888 +4781 +4672 +4569 +4467 +4368 +4272 +4177 +4087 +3996 +3912 +3826 +3745 +3665 +3587 +3513 +3438 +3369 +3297 +3231 +3164 +3100 +3038 +2977 +2920 +2862 +2809 +2755 +2704 +2655 +2608 +2563 +2517 +2475 +2431 +2391 +2350 +2312 +2274 +2236 +2201 +2164 +2131 +2095 +2064 +2031 +1999 +1969 +1937 +1910 +1879 +1854 +1826 +1802 +1777 +1753 +1731 +1708 +1689 +1666 +1647 +1627 +1607 +1588 +1568 +1551 +1530 +1514 +1494 +1477 +1458 +1441 +1425 +1408 +1395 +1380 +1368 +1356 +1345 +1333 +1322 +1312 +1301 +1290 +1279 +1268 +1256 +1246 +1236 +1225 +1214 +1204 +1194 +1184 +1176 +1166 +1157 +1148 +1139 +1131 +1123 +1115 +1108 +1102 +1094 +1087 +1080 +1073 +1067 +1060 +1053 +1045 +1039 +1032 +1025 +1019 +1012 +1006 +1000 +995 +988 +983 +977 +972 +966 +961 +956 +951 +947 +942 +937 +932 +926 +921 +916 +911 +906 +901 +896 +892 +887 +882 +878 +873 +869 +865 +861 +857 +852 +848 +844 +841 +837 +833 +828 +824 +819 +815 +811 +806 +801 +797 +794 +790 +787 +784 +782 +778 +776 +773 +770 +768 +765 +764 +760 +758 +755 +753 +750 +747 +745 +742 +740 +738 +737 +735 +733 +731 +729 +727 +724 +722 +720 +718 +716 +714 +712 +711 +710 +707 +706 +704 +702 +700 +698 +695 +692 +691 +688 +686 +683 +681 +679 +677 +675 +672 +671 +668 +666 +664 +662 +660 +658 +657 +655 +654 +651 +650 +649 +648 +646 +645 +644 +643 +642 +642 +641 +641 +641 +641 +640 +639 +639 +638 +637 +637 +636 +636 +636 +636 +636 +634 +633 +633 +633 +634 +635 +636 +638 +642 +646 +652 +658 +665 +673 +683 +692 +703 +714 +727 +739 +754 +770 +785 +804 +823 +846 +867 +892 +919 +947 +979 +1010 +1048 +1084 +1128 +1171 +1219 +1270 +1323 +1382 +1442 +1510 +1578 +1653 +1730 +1812 +1899 +1990 +2087 +2186 +2294 +2403 +2520 +2640 +2765 +2897 +3031 +3174 +3318 +3471 +3625 +3787 +3952 +4123 +4300 +4479 +4666 +4855 +5051 +5250 +5455 +5664 +5876 +6095 +6313 +6539 +6765 +6997 +7231 +7468 +7709 +7949 +8197 +8441 +8692 +8942 +9194 +9447 +9700 +9956 +10209 +10466 +10719 +10974 +11226 +11479 +11730 +11979 +12229 +12474 +12722 +12964 +13206 +13445 +13681 +13917 +14147 +14377 +14600 +14823 +15039 +15254 +15464 +15669 +15871 +16066 +16261 +16447 +16631 +16809 +16983 +17151 +17314 +17473 +17624 +17774 +17915 +18053 +18185 +18312 +18434 +18548 +18660 +18763 +18864 +18957 +19045 +19127 +19202 +19274 +19338 +19400 +19452 +19502 +19544 +19582 +19614 +19639 +19660 +19674 +19684 +19687 +19688 +19681 +19670 +19655 +19634 +19609 +19578 +19543 +19500 +19455 +19404 +19348 +19289 +19222 +19154 +19078 +19001 +18918 +18831 +18741 +18644 +18546 +18441 +18336 +18224 +18110 +17992 +17870 +17745 +17615 +17485 +17348 +17211 +17068 +16924 +16777 +16626 +16474 +16318 +16163 +16002 +15841 +15677 +15511 +15343 +15172 +15003 +14828 +14655 +14478 +14301 +14122 +13942 +13763 +13580 +13400 +13215 +13033 +12849 +12666 +12482 +12298 +12115 +11930 +11749 +11564 +11383 +11200 +11019 +10838 +10657 +10480 +10299 +10124 +9947 +9774 +9601 +9429 +9260 +9090 +8925 +8758 +8597 +8435 +8276 +8118 +7962 +7810 +7657 +7509 +7360 +7216 +7072 +6932 +6794 +6657 +6526 +6392 +6265 +6137 +6013 +5890 +5769 +5652 +5534 +5422 +5308 +5200 +5091 +4987 +4886 +4785 +4689 +4592 +4501 +4408 +4320 +4233 +4148 +4065 +3983 +3905 +3825 +3752 +3677 +3607 +3536 +3469 +3404 +3339 +3280 +3218 +3162 +3105 +3051 +2997 +2945 +2896 +2846 +2801 +2752 +2708 +2663 +2620 +2579 +2537 +2498 +2458 +2422 +2383 +2347 +2312 +2277 +2245 +2212 +2182 +2149 +2121 +2090 +2062 +2034 +2006 +1980 +1951 +1927 +1900 +1877 +1852 +1828 +1806 +1782 +1762 +1738 +1719 +1698 +1679 +1659 +1640 +1622 +1602 +1587 +1569 +1554 +1537 +1521 +1505 +1489 +1474 +1459 +1445 +1430 +1417 +1402 +1388 +1375 +1362 +1349 +1337 +1325 +1311 +1300 +1288 +1276 +1265 +1254 +1243 +1232 +1223 +1211 +1201 +1191 +1181 +1171 +1161 +1152 +1143 +1137 +1128 +1120 +1112 +1104 +1096 +1088 +1081 +1073 +1067 +1060 +1053 +1046 +1040 +1034 +1027 +1021 +1015 +1009 +1003 +997 +990 +984 +978 +972 +966 +959 +953 +947 +942 +936 +931 +926 +920 +916 +910 +905 +900 +894 +889 +883 +877 +872 +867 +862 +858 +853 +848 +844 +840 +836 +832 +827 +823 +818 +813 +808 +804 +800 +796 +793 +791 +788 +786 +783 +781 +778 +775 +773 +770 +767 +764 +762 +759 +756 +753 +751 +748 +746 +744 +741 +739 +736 +733 +730 +727 +725 +721 +719 +715 +713 +709 +707 +704 +701 +699 +696 +695 +692 +691 +690 +689 +687 +686 +686 +684 +684 +683 +682 +680 +677 +674 +671 +667 +663 +659 +656 +652 +650 +648 +647 +645 +644 +642 +641 +640 +640 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 +639 + diff --git a/src/goahead.c b/src/goahead.c new file mode 100644 index 0000000..ed5c19f --- /dev/null +++ b/src/goahead.c @@ -0,0 +1,2022 @@ +/* + goahead.c -- Main program for GoAhead + + Usage: goahead [options] [documents] [IP][:port] ... + Options: + --auth authFile # User and role configuration + --background # Run as a Linux daemon + --home directory # Change to directory to run + --log logFile:level # Log to file file at verbosity level + --route routeFile # Route configuration file + --verbose # Same as --log stdout:2 + --version # Output version information + + Copyright (c) All Rights Reserved. See details at the end of the file. + */ + +/********************************* Includes ***********************************/ + +#include "goahead.h" +#include "common.h" +#include +#include "para.h" +#include "minIni.h" +#include "ysp_debug.h" + +#include "sysinfo.h" + +/********************************* Defines ************************************/ + + +static int finished = 0; + +/********************************* Forwards ***********************************/ + +static void initPlatform(); +static void logHeader(); +static void usage(); + +static int show_sample_para(int eid, Webs *wp, int argc, char **argv); +static void sample_para_upload(Webs *wp); + +static int aspTest(int eid, Webs *wp, int argc, char **argv); +static int bigTest(int eid, Webs *wp, int argc, char **argv); + +#if ME_GOAHEAD_UPLOAD +static void uploadTest(Webs *wp); +#endif + + +#if WINDOWS +static void windowsClose(); +static int windowsInit(); +static LRESULT CALLBACK websWindProc(HWND hwnd, UINT msg, UINT wp, LPARAM lp); +#endif + +#if ME_UNIX_LIKE +static void sigHandler(int signo); +#endif + +static char *rly_name_array[32]={ +"unused", +"unused", +"unused", +"油缸退YV4", +"油缸进YV5", +"气缸退YV6", +"气缸进YV7", +"样气进气缸阀YV15", +"进油阀YV16", +"unused", +"气缸进油阀YV11", +"进气到集气缸阀YV12", +"出油阀YV13", +"清洗排空阀YV14", +"油泵YV3", +"unused", +"样气平衡阀YV17", +"吹扫阀YV18", +"定量阀YV19", +"传感器平衡阀YV20", +"CO2检测阀YV21", +"排水阀KA8", +"unused", +"柜子风扇KA3", +"采样单元风扇KA4", +"采样电源控制KA5", +"冷井风扇KA6", +"冷井电源控制KA7", +"unused", +"传感器加热", +"unused", +"气缸启停", +}; + +static char *io_name_array[8]={ +"油缸进I4", +"油缸退I5", +"气缸进I6", +"气缸退I7", +"备用1", +"备用2", +"油位I8", +"进油I9", +}; + + + +static void showTest(Webs *wp) +{ + WebsKey *s; + + websSetStatus(wp, 200); + websWriteHeaders(wp, -1, 0); + websWriteEndHeaders(wp); + websWrite(wp, "

    \n");
    +    for (s = hashFirst(wp->vars); s; s = hashNext(wp->vars, s)) {
    +        websWrite(wp,"%s=%s\n", s->name.value.string, s->content.value.string);
    +    }
    +    websWrite(wp, "
    \n"); + websDone(wp); +} + +static int web_get_para_f(int eid, Webs *wp, int argc, char **argv) +{ + char *sec_name,*key_name; + float f; + if(jsArgs(argc,argv,"%s %s",&sec_name,&key_name)<2) + { + websError(wp,400,"Insufficient args\n"); + return -1; + } + f=ini_getf(sec_name,key_name,0,ysp_cfg_file); + return (int) websWrite(wp,"\"%f\"",f); +} + +static int web_get_para_i(int eid, Webs *wp,int argc,char **argv) +{ + char *sec_name,*key_name; + int i; + if(jsArgs(argc,argv,"%s %s",&sec_name,&key_name)<2) + { + websError(wp,400,"Insufficient args\n"); + return -1; + } + i=ini_getl(sec_name,key_name,0,ysp_cfg_file); + return (int) websWrite(wp,"\"%d\"",i); +} +// +static int web_show_mx_data(int eid, Webs *wp,int argc,char **argv) +{ + ANALY_RESULT tmp_his_data; + YSP_PRI_DATA *tmp_pri_data; + int data_index; + int val; + float f; + struct tm *uptime; + load_last_result(&tmp_his_data); + tmp_pri_data=&tmp_his_data.result; + //if(load_last_result(&tmp_pri_data)==0) + //{ +// send_ysp_msg(&ysp_pri_data); + //} + if(jsArgs(argc,argv,"%d",&data_index)<1) + { + websError(wp,400,"Insufficient args\n"); + return -1; + } + if(data_index<9) + { + switch(data_index) + { + case 0://h2 + f=tmp_pri_data->H2ppm; + break; + case 1://co + f=tmp_pri_data->COppm; + break; + case 2://ch4 + f=tmp_pri_data->CH4ppm; + break; + case 3://c2h4 + f=tmp_pri_data->C2H4ppm; + break; + case 4://c2h6 + f=tmp_pri_data->C2H6ppm; + break; + case 5://c2h2 + f=tmp_pri_data->C2H2ppm; + break; + case 6://总烃 + f=tmp_pri_data->TotHyd; + break; + case 7://CO2 + f=0; + break; + case 8://H2O + f=0; + break; + default: + break; + } + return (int) websWrite(wp,"\"%f\"",f); + } + else if(data_index<15) + { + uptime=localtime(&(tmp_pri_data->SmpTm)); + switch(data_index) + { + case 9://year + val=uptime->tm_year+1900; + break; + case 10://month + val=uptime->tm_mon+1; + break; + case 11://day + val=uptime->tm_mday; + break; + case 12://hour + val=uptime->tm_hour; + break; + case 13://min + val=uptime->tm_min; + break; + case 14://sec + val=uptime->tm_sec; + break; + default: + break; + } + return (int) websWrite(wp,"\"%d\"",val); + } +} + +static int web_get_sys_time(int eid, Webs *wp,int argc,char **argv) +{ + int data_index; + time_t now; + int val; + + struct tm *uptime; + if(jsArgs(argc,argv,"%d",&data_index)<1) + { + websError(wp,400,"Insufficient args\n"); + return -1; + } + now=time(NULL); + uptime=localtime(&now); + switch(data_index) + { + case 0://year + val=uptime->tm_year+1900; + break; + case 1://month + val=uptime->tm_mon+1; + break; + case 2://day + val=uptime->tm_mday; + break; + case 3://hour + val=uptime->tm_hour; + break; + case 4://min + val=uptime->tm_min; + break; + case 5://sec + val=uptime->tm_sec; + break; + default: + break; + } + return (int) websWrite(wp,"\"%d\"",val); +} + + +static void web_mx_data_process(Webs *wp) +{ + char *str; + int i; + float f; + time_t now; + struct tm uptime; + ANALY_RESULT tmp_his_data; + YSP_PRI_DATA *tmp_pri_data; + tmp_pri_data=&tmp_his_data.result; + str=websGetVar(wp,"H2","0"); + if(str!=NULL) + { + f=atof(str); + tmp_pri_data->H2ppm=f; + } + str=websGetVar(wp,"CO","0"); + if(str!=NULL) + { + f=atof(str); + tmp_pri_data->COppm=f; + } + str=websGetVar(wp,"CH4","0"); + if(str!=NULL) + { + f=atof(str); + tmp_pri_data->CH4ppm=f; + } + str=websGetVar(wp,"C2H4","0"); + if(str!=NULL) + { + f=atof(str); + tmp_pri_data->C2H4ppm=f; + } + str=websGetVar(wp,"C2H6","0"); + if(str!=NULL) + { + f=atof(str); + tmp_pri_data->C2H6ppm=f; + } + str=websGetVar(wp,"C2H2","0"); + if(str!=NULL) + { + f=atof(str); + tmp_pri_data->C2H2ppm=f; + } + tmp_pri_data->TotHyd=tmp_pri_data->CH4ppm+tmp_pri_data->C2H2ppm+tmp_pri_data->C2H4ppm+tmp_pri_data->C2H6ppm; + str=websGetVar(wp,"year","2015"); + if(str!=NULL) + { + i=atoi(str); + uptime.tm_year=i-1900; + } + str=websGetVar(wp,"month","9"); + if(str!=NULL) + { + i=atoi(str); + uptime.tm_mon=i-1; + } + str=websGetVar(wp,"day","1"); + if(str!=NULL) + { + i=atoi(str); + uptime.tm_mday=i; + } + str=websGetVar(wp,"hour","0"); + if(str!=NULL) + { + i=atoi(str); + uptime.tm_hour=i; + } + str=websGetVar(wp,"min","0"); + if(str!=NULL) + { + i=atoi(str); + uptime.tm_min=i; + } + str=websGetVar(wp,"sec","0"); + if(str!=NULL) + { + i=atoi(str); + uptime.tm_sec=i; + } + now=mktime(&uptime); + tmp_pri_data->SmpTm=now; + save_last_result(&tmp_his_data); + send_ysp_msg(tmp_pri_data); + websRedirect(wp,"/show_data.jst"); +} + +static int web_io_show(int eid, Webs *wp, int argc, char **argv) +{ + INPUT_TYPE_DEF web_input; + int io_state;//=my_input_data.io_input; + int i; + float temp[7]; + + lock_input_data(); + memcpy(&web_input,&my_input_data,sizeof(web_input)); + unlock_input_data(); + io_state=web_input.io_input; + websWrite(wp,""); + for(i=0;i<8;i++) + { + if((io_state&(1<%s",i+1,io_name_array[i]); + } + else + { + websWrite(wp,"
    %s
    ",i+1,io_name_array[i]); + } + } + websWrite(wp,""); + memcpy(&temp,web_input.temperature,sizeof(web_input.temperature)); + get_presure(PRES_PA1,&temp[5]); + get_presure(PRES_GAS_PUMP,&temp[6]); + websWrite(wp,"色谱柱温度=%5.2f℃ 柜内温度=%5.2f℃ 冷井温度=%5.2f℃ 采样室温度=%5.2f℃ 柜外温度=%5.2f℃ 载气压力=%5.3fMpa 气缸压力=%5.3fMpa",temp[0],temp[1],temp[2],temp[3],temp[4],temp[5],temp[6]); + websWrite(wp,"色谱柱输出=%d 冷井输出=%d 采样室输出=%d ",web_input.pwm_out[0],web_input.vi_out[0],web_input.vi_out[1]); + if(web_input.com_flg) + { + //微水通讯失败 + websWrite(wp,"微水=--- 油温=---"); + } + else + { + //微水正常 + websWrite(wp,"微水=%5.2fppm 油温=%5.2f℃",web_input.water,web_input.temp); + } + websWrite(wp,""); + return 0; +} + + +static int web_relay_show(int eid, Webs *wp, int argc, char **argv) +{ + int relay_state; + int i,tmp; + relay_state=relay_get_all(NULL); + for(i=0;i<32;i+=2) + { + tmp=relay_state&(1<%sONOFF",rly_name_array[i],i+1,i+1,i+1); + else + websWrite(wp,"%sONOFF",rly_name_array[i],i+1,i+1,i+1); + tmp=relay_state&(1<<(i+1)); + if(tmp) + { + websWrite(wp,"%sONOFF",rly_name_array[i+1],i+2,i+2,i+2); + } + else + { + websWrite(wp,"%sONOFF",rly_name_array[i+1],i+2,i+2,i+2); + } + } + return 0; +} + +static int web_temp_para_show(int eid, Webs *wp, int argc, char **argv) +{ + websWrite(wp,"色谱柱温度控制输出使能"); + if(my_para_data.mach_run_para.pid_en[0]) + { + websWrite(wp,"关闭"); + websWrite(wp,"使能"); + } + else + { + websWrite(wp,"关闭"); + websWrite(wp,"使能"); + } + websWrite(wp,"冷井温度控制输出使能"); + + if(my_para_data.mach_run_para.pid_en[2]) + { + websWrite(wp,"关闭"); + websWrite(wp,"使能"); + } + else + { + websWrite(wp,"关闭"); + websWrite(wp,"使能"); + } + websWrite(wp,"采样室温度控制输出使能"); + + if(my_para_data.mach_run_para.pid_en[3]) + { + websWrite(wp,"关闭"); + websWrite(wp,"使能"); + } + else + { + websWrite(wp,"关闭"); + websWrite(wp,"使能"); + } + return 0; +} + +static void process_para_upload(Webs *wp) +{ + char *str; + int i; + float f; + str=websGetVar(wp,"volt_out1","0"); + if(str!=NULL) + { + f=atof(str); + my_para_data.mach_run_para.volt_output[0]=f; + i=(int)f; + my_output_data.man_output[0]=(unsigned short)i; + //HeatTuneRecord.tune_output=(unsigned short)i; + ini_putf("MACH","volt_out1",f,ysp_cfg_file); + } + str=websGetVar(wp,"volt_out2","0"); + if(str!=NULL) + { + f=atof(str); + my_para_data.mach_run_para.volt_output[1]=f; + ini_putf("MACH","volt_out2",f,ysp_cfg_file); + } + + str=websGetVar(wp,"temp1","0"); + if(str!=NULL) + { + f=atof(str); + my_para_data.mach_run_para.temperature[0]=f; + ini_putf("MACH","temp1",f,ysp_cfg_file); + } + + str=websGetVar(wp,"temp2","0"); + if(str!=NULL) + { + f=atof(str); + my_para_data.mach_run_para.temperature[1]=f; + ini_putf("MACH","temp2",f,ysp_cfg_file); + } + + str=websGetVar(wp,"temp3","0"); + if(str!=NULL) + { + f=atof(str); + my_para_data.mach_run_para.temperature[2]=f; + ini_putf("MACH","temp3",f,ysp_cfg_file); + } + + str=websGetVar(wp,"temp4","0"); + if(str!=NULL) + { + f=atof(str); + my_para_data.mach_run_para.temperature[3]=f; + ini_putf("MACH","temp4",f,ysp_cfg_file); + } + websRedirect(wp,"/process_param.jst"); +} + +static void pres_fac_process(Webs *wp) +{ + char *str; + char key_name[32]; + int i; + float f; + for(i=0;i<8;i++) + { + sprintf(key_name,"pres%d_fac_a",i+1); + str=websGetVar(wp,key_name,"1"); + if(str!=NULL) + { + f=atof(str); + my_para_data.mach_run_para.pres_fac[i].a=f; + ini_putf("MACH",key_name,f,ysp_cfg_file); + } + + + sprintf(key_name,"pres%d_fac_b",i+1); + str=websGetVar(wp,key_name,"0"); + if(str!=NULL) + { + f=atof(str); + my_para_data.mach_run_para.pres_fac[i].b=f; + ini_putf("MACH",key_name,f,ysp_cfg_file); + } + } + websRedirect(wp,"/press_factor.jst"); +} + +static void H2ParaProcess(Webs *wp) +{ + char *str; + char key_name[32]; + int i,n; + float f; + str=websGetVar(wp,"start","170"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_H2].position.start=i; + ini_putl("H2_CAL","start",i,ysp_cfg_file); + } + + str=websGetVar(wp,"peak","256"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_H2].position.peak=i; + ini_putl("H2_CAL","peak",i,ysp_cfg_file); + } + + str=websGetVar(wp,"end","320"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_H2].position.end=i; + ini_putl("H2_CAL","end",i,ysp_cfg_file); + } + + str=websGetVar(wp,"width","16"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_H2].position.width=i; + ini_putl("H2_CAL","width",i,ysp_cfg_file); + } + + str=websGetVar(wp,"lYmin","16"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_H2].gradient.lYmin=f; + ini_putf("H2_CAL","lYmin",f,ysp_cfg_file); + } + + str=websGetVar(wp,"lXmax","32"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_H2].gradient.lXmax=f; + ini_putf("H2_CAL","lXmax",f,ysp_cfg_file); + } + + str=websGetVar(wp,"rYmin","16"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_H2].gradient.rYmin=f; + ini_putf("H2_CAL","rYmin",f,ysp_cfg_file); + } + +str=websGetVar(wp,"rXmax","32"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_H2].gradient.rXmax=f; + ini_putf("H2_CAL","rXmax",f,ysp_cfg_file); + } + + for(i=0;i<12;i++) + { + for(n=0;n<6;n++) + { + sprintf(key_name,"k%d_fac%d",i+1,n+1); + str=websGetVar(wp,key_name,"1"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_H2].correct_fac.k[i].fac[n]=f; + ini_putf("H2_CAL",key_name,f,ysp_cfg_file); + } + } + } + websRedirect(wp,"/H2.jst"); +} + +static void COParaProcess(Webs *wp) +{ + char *str; + char key_name[32]; + int i,n; + float f; + str=websGetVar(wp,"start","290"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_CO].position.start=i; + ini_putl("CO_CAL","start",i,ysp_cfg_file); + } + + str=websGetVar(wp,"peak","350"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_CO].position.peak=i; + ini_putl("CO_CAL","peak",i,ysp_cfg_file); + } + + str=websGetVar(wp,"end","440"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_CO].position.end=i; + ini_putl("CO_CAL","end",i,ysp_cfg_file); + } + + str=websGetVar(wp,"width","20"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_CO].position.width=i; + ini_putl("CO_CAL","width",i,ysp_cfg_file); + } + + str=websGetVar(wp,"lYmin","4"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_CO].gradient.lYmin=f; + ini_putf("CO_CAL","lYmin",f,ysp_cfg_file); + } + + str=websGetVar(wp,"lXmax","16"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_CO].gradient.lXmax=f; + ini_putf("CO_CAL","lXmax",f,ysp_cfg_file); + } + + str=websGetVar(wp,"rYmin","4"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_CO].gradient.rYmin=f; + ini_putf("CO_CAL","rYmin",f,ysp_cfg_file); + } + +str=websGetVar(wp,"rXmax","16"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_CO].gradient.rXmax=f; + ini_putf("CO_CAL","rXmax",f,ysp_cfg_file); + } + + for(i=0;i<12;i++) + { + for(n=0;n<6;n++) + { + sprintf(key_name,"k%d_fac%d",i+1,n+1); + str=websGetVar(wp,key_name,"1"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_CO].correct_fac.k[i].fac[n]=f; + ini_putf("CO_CAL",key_name,f,ysp_cfg_file); + } + } + } + websRedirect(wp,"/CO.jst"); +} + +static void CH4ParaProcess(Webs *wp) +{ + char *str; + char key_name[32]; + int i,n; + float f; + str=websGetVar(wp,"start","460"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_CH4].position.start=i; + ini_putl("CH4_CAL","start",i,ysp_cfg_file); + } + + str=websGetVar(wp,"peak","515"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_CH4].position.peak=i; + ini_putl("CH4_CAL","peak",i,ysp_cfg_file); + } + + str=websGetVar(wp,"end","600"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_CH4].position.end=i; + ini_putl("CH4_CAL","end",i,ysp_cfg_file); + } + + str=websGetVar(wp,"width","30"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_CH4].position.width=i; + ini_putl("CH4_CAL","width",i,ysp_cfg_file); + } + + str=websGetVar(wp,"lYmin","4"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_CH4].gradient.lYmin=f; + ini_putf("CH4_CAL","lYmin",f,ysp_cfg_file); + } + + str=websGetVar(wp,"lXmax","16"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_CH4].gradient.lXmax=f; + ini_putf("CH4_CAL","lXmax",f,ysp_cfg_file); + } + + str=websGetVar(wp,"rYmin","4"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_CH4].gradient.rYmin=f; + ini_putf("CH4_CAL","rYmin",f,ysp_cfg_file); + } + +str=websGetVar(wp,"rXmax","16"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_CH4].gradient.rXmax=f; + ini_putf("CH4_CAL","rXmax",f,ysp_cfg_file); + } + + for(i=0;i<12;i++) + { + for(n=0;n<6;n++) + { + sprintf(key_name,"k%d_fac%d",i+1,n+1); + str=websGetVar(wp,key_name,"1"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_CH4].correct_fac.k[i].fac[n]=f; + ini_putf("CH4_CAL",key_name,f,ysp_cfg_file); + } + } + } + websRedirect(wp,"/CH4.jst"); +} + +static void C2H4ParaProcess(Webs *wp) +{ + char *str; + char key_name[32]; + int i,n; + float f; + str=websGetVar(wp,"start","1600"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_C2H4].position.start=i; + ini_putl("C2H4_CAL","start",i,ysp_cfg_file); + } + + str=websGetVar(wp,"peak","1900"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_C2H4].position.peak=i; + ini_putl("C2H4_CAL","peak",i,ysp_cfg_file); + } + + str=websGetVar(wp,"end","2200"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_C2H4].position.end=i; + ini_putl("C2H4_CAL","end",i,ysp_cfg_file); + } + + str=websGetVar(wp,"width","32"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_C2H4].position.width=i; + ini_putl("C2H4_CAL","width",i,ysp_cfg_file); + } + + str=websGetVar(wp,"lYmin","4"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_C2H4].gradient.lYmin=f; + ini_putf("C2H4_CAL","lYmin",f,ysp_cfg_file); + } + + str=websGetVar(wp,"lXmax","16"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_C2H4].gradient.lXmax=f; + ini_putf("C2H4_CAL","lXmax",f,ysp_cfg_file); + } + + str=websGetVar(wp,"rYmin","4"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_C2H4].gradient.rYmin=f; + ini_putf("C2H4_CAL","rYmin",f,ysp_cfg_file); + } + +str=websGetVar(wp,"rXmax","16"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_C2H4].gradient.rXmax=f; + ini_putf("C2H4_CAL","rXmax",f,ysp_cfg_file); + } + + for(i=0;i<12;i++) + { + for(n=0;n<6;n++) + { + sprintf(key_name,"k%d_fac%d",i+1,n+1); + str=websGetVar(wp,key_name,"1"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_C2H4].correct_fac.k[i].fac[n]=f; + ini_putf("C2H4_CAL",key_name,f,ysp_cfg_file); + } + } + } + websRedirect(wp,"/C2H4.jst"); +} + +static void C2H6ParaProcess(Webs *wp) +{ + char *str; + char key_name[32]; + int i,n; + float f; + str=websGetVar(wp,"start","2201"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_C2H6].position.start=i; + ini_putl("C2H6_CAL","start",i,ysp_cfg_file); + } + + str=websGetVar(wp,"peak","2430"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_C2H6].position.peak=i; + ini_putl("C2H6_CAL","peak",i,ysp_cfg_file); + } + + str=websGetVar(wp,"end","2800"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_C2H6].position.end=i; + ini_putl("C2H6_CAL","end",i,ysp_cfg_file); + } + + str=websGetVar(wp,"width","32"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_C2H6].position.width=i; + ini_putl("C2H6_CAL","width",i,ysp_cfg_file); + } + + str=websGetVar(wp,"lYmin","6"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_C2H6].gradient.lYmin=f; + ini_putf("C2H6_CAL","lYmin",f,ysp_cfg_file); + } + + str=websGetVar(wp,"lXmax","16"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_C2H6].gradient.lXmax=f; + ini_putf("C2H6_CAL","lXmax",f,ysp_cfg_file); + } + + str=websGetVar(wp,"rYmin","4"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_C2H6].gradient.rYmin=f; + ini_putf("C2H6_CAL","rYmin",f,ysp_cfg_file); + } + +str=websGetVar(wp,"rXmax","16"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_C2H6].gradient.rXmax=f; + ini_putf("C2H6_CAL","rXmax",f,ysp_cfg_file); + } + + for(i=0;i<12;i++) + { + for(n=0;n<6;n++) + { + sprintf(key_name,"k%d_fac%d",i+1,n+1); + str=websGetVar(wp,key_name,"1"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_C2H6].correct_fac.k[i].fac[n]=f; + ini_putf("C2H6_CAL",key_name,f,ysp_cfg_file); + } + } + } + websRedirect(wp,"/C2H6.jst"); +} + +static void C2H2ParaProcess(Webs *wp) +{ + char *str; + char key_name[32]; + int i,n; + float f; + str=websGetVar(wp,"start","2801"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_C2H2].position.start=i; + ini_putl("C2H2_CAL","start",i,ysp_cfg_file); + } + + str=websGetVar(wp,"peak","2930"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_C2H2].position.peak=i; + ini_putl("C2H2_CAL","peak",i,ysp_cfg_file); + } + + str=websGetVar(wp,"end","3300"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_C2H2].position.end=i; + ini_putl("C2H2_CAL","end",i,ysp_cfg_file); + } + + str=websGetVar(wp,"width","32"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.gas_cal_fac[INDEX_C2H2].position.width=i; + ini_putl("C2H2_CAL","width",i,ysp_cfg_file); + } + + str=websGetVar(wp,"lYmin","6"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_C2H2].gradient.lYmin=f; + ini_putf("C2H2_CAL","lYmin",f,ysp_cfg_file); + } + + str=websGetVar(wp,"lXmax","16"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_C2H2].gradient.lXmax=f; + ini_putf("C2H2_CAL","lXmax",f,ysp_cfg_file); + } + + str=websGetVar(wp,"rYmin","4"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_C2H2].gradient.rYmin=f; + ini_putf("C2H2_CAL","rYmin",f,ysp_cfg_file); + } + +str=websGetVar(wp,"rXmax","16"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_C2H2].gradient.rXmax=f; + ini_putf("C2H2_CAL","rXmax",f,ysp_cfg_file); + } + + for(i=0;i<12;i++) + { + for(n=0;n<6;n++) + { + sprintf(key_name,"k%d_fac%d",i+1,n+1); + str=websGetVar(wp,key_name,"1"); + if(str!=NULL) + { + f=atof(str); + my_para_data.gas_cal_fac[INDEX_C2H2].correct_fac.k[i].fac[n]=f; + ini_putf("C2H2_CAL",key_name,f,ysp_cfg_file); + } + } + } + websRedirect(wp,"/C2H2.jst"); +} + +static void CO2ParaProcess(Webs *wp) +{ + char *str; + char key_name[32]; + int i,n; + float f; + str=websGetVar(wp,"start","80"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.co2_cal_fac.position.start=i; + ini_putl("CO2_CAL","start",i,ysp_cfg_file); + } + + str=websGetVar(wp,"peak","100"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.co2_cal_fac.position.peak=i; + ini_putl("CO2_CAL","peak",i,ysp_cfg_file); + } + + str=websGetVar(wp,"end","120"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.co2_cal_fac.position.end=i; + ini_putl("CO2_CAL","end",i,ysp_cfg_file); + } + + str=websGetVar(wp,"width","16"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.co2_cal_fac.position.width=i; + ini_putl("CO2_CAL","width",i,ysp_cfg_file); + } + + str=websGetVar(wp,"lYmin","6"); + if(str!=NULL) + { + f=atof(str); + my_para_data.co2_cal_fac.gradient.lYmin=f; + ini_putf("CO2_CAL","lYmin",f,ysp_cfg_file); + } + + str=websGetVar(wp,"lXmax","16"); + if(str!=NULL) + { + f=atof(str); + my_para_data.co2_cal_fac.gradient.lXmax=f; + ini_putf("CO2_CAL","lXmax",f,ysp_cfg_file); + } + + str=websGetVar(wp,"rYmin","4"); + if(str!=NULL) + { + f=atof(str); + my_para_data.co2_cal_fac.gradient.rYmin=f; + ini_putf("CO2_CAL","rYmin",f,ysp_cfg_file); + } + +str=websGetVar(wp,"rXmax","16"); + if(str!=NULL) + { + f=atof(str); + my_para_data.co2_cal_fac.gradient.rXmax=f; + ini_putf("CO2_CAL","rXmax",f,ysp_cfg_file); + } + + for(i=0;i<12;i++) + { + for(n=0;n<6;n++) + { + sprintf(key_name,"k%d_fac%d",i+1,n+1); + str=websGetVar(wp,key_name,"1"); + if(str!=NULL) + { + f=atof(str); + my_para_data.co2_cal_fac.correct_fac.k[i].fac[n]=f; + ini_putf("CO2_CAL",key_name,f,ysp_cfg_file); + } + } + } + websRedirect(wp,"/CO2.jst"); +} + + +static int web_ctrl_state_show(int eid, Webs *wp, int argc, char **argv) +{ + if(curr_state==SIX_SAMPLE) + websWrite(wp,"启动采样"); + else + websWrite(wp,"启动采样"); + + if(curr_state==DEMARCATE) + websWrite(wp,"启动标定"); + else + websWrite(wp,"启动标定"); + + if(curr_state==REMOVE_GAS) + websWrite(wp,"启动脱气机"); + else + websWrite(wp,"启动脱气机"); + + if(curr_state==GAS_FAULT_PROCESS) + websWrite(wp,"脱气机故障处理"); + else + websWrite(wp,"脱气机故障处理"); + + if(curr_state==PUMP_OIL_PROCESS) + websWrite(wp,"启动油泵"); + else + websWrite(wp,"启动油泵"); + + if(curr_state==MODE_IDLE) + websWrite(wp,"终止当前操作"); + else + websWrite(wp,"终止当前操作"); + return 0; +} + +static int web_man_ctrl_show(int eid, Webs *wp, int argc, char **argv) +{ + websWrite(wp,""); + if(HeatTuneRecord.auto_turn) + { + websWrite(wp,"启动参数整定"); + websWrite(wp,"停止参数整定"); + } + else + { + websWrite(wp,"启动参数整定"); + websWrite(wp,"停止参数整定"); + } + websWrite(wp,""); + + websWrite(wp,""); + if(my_output_data.pid_en[PID_LJ]) + { + websWrite(wp,"启动冷井"); + websWrite(wp,"停止冷井"); + } + else + { + websWrite(wp,"启动冷井"); + websWrite(wp,"停止冷井"); + } + websWrite(wp,""); + + websWrite(wp,""); + if(my_output_data.pid_en[PID_SAMPLE]) + { + websWrite(wp,"启动采样单元"); + websWrite(wp,"停止采样单元"); + } + else + { + websWrite(wp,"启动采样单元"); + websWrite(wp,"停止采样单元"); + } + websWrite(wp,""); + return 0; +} + + +static void man_ctrl_process(Webs *wp) +{ + char *str; + int tmp; + str=websGetVar(wp,"autotune","0"); + if(str!=NULL) + { + tmp=atoi(str); + if(HeatTuneRecord.auto_turn==0) + { + if(tmp!=0) + { + HeatTuneRecord.tune_output=my_output_data.man_output[0]; + HeatAutoTuner.start_time=time(NULL); + } + } + else + { + if(tmp==0) + { + + } + } + HeatTuneRecord.auto_turn=tmp; + } + + str=websGetVar(wp,"command","0"); + if(str!=NULL) + { + tmp=atoi(str); + if(curr_state==0) + { + if(tmp!=0) + SendActionReq(tmp,0); + } + else + { + if(tmp==0) + { + stop_curr_process(0); + } + } + } + + str=websGetVar(wp,"lj","0"); + if(str!=NULL) + { + tmp=atoi(str); + if(curr_state==0) + { + if(tmp) + { + //启动冷井 + my_output_data.pid_en[PID_LJ]=1; + //relay_set(RLY_KA5,ON,0);//开冷井电源 + relay_set(RLY_KA6,ON,1);//开冷井风扇 + } + else + { + //停止冷井 + my_output_data.pid_en[PID_LJ]=0; + //relay_set(RLY_KA5,OFF,0);//关冷井电源 + relay_set(RLY_KA6,OFF,1);//关冷井风扇 + } + } + } + + str=websGetVar(wp,"cy","0"); + if(str!=NULL) + { + tmp=atoi(str); + if(curr_state==0) + { + if(tmp) + { + //启动采样单元 + my_output_data.pid_en[PID_SAMPLE]=1; + relay_set(RLY_FAN,ON,0); + relay_set(RLY_KA4,ON,1);// + + } + else + { + //停止采样单元 + my_output_data.pid_en[PID_SAMPLE]=0; + relay_set(RLY_FAN,OFF,0); + relay_set(RLY_KA4,OFF,1);// + //relay_set(RLY_KA5,OFF,1); + } + } + } + sleep(2); + websRedirect(wp,"/man_control.jst"); +} + + +static void web_temp_ctrl_process(Webs *wp) +{ + char *str; + int i; + float f; + str=websGetVar(wp,"pid_en1","1"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.mach_run_para.pid_en[0]=i; + my_output_data.pid_en[0]=i; + ini_putl("MACH","pid_en1",i,ysp_cfg_file); + } + + str=websGetVar(wp,"pid_en3","0"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.mach_run_para.pid_en[2]=i; + //my_output_data.pid_en[2]=i; + ini_putl("MACH","pid_en3",i,ysp_cfg_file); + } + + str=websGetVar(wp,"pid_en4","0"); + if(str!=NULL) + { + i=atoi(str); + my_para_data.mach_run_para.pid_en[3]=i; + //my_output_data.pid_en[3]=i; + ini_putl("MACH","pid_en4",i,ysp_cfg_file); + } + str=websGetVar(wp,"kp1","0"); + if(str!=NULL) + { + f=atof(str); + my_para_data.mach_run_para.pid_type_def[0].Kp=f; + my_output_data.pid_para[0].Kp=f; + ini_putf("MACH","kp1",f,ysp_cfg_file); + } + str=websGetVar(wp,"ki1","0"); + if(str!=NULL) + { + f=atof(str); + my_para_data.mach_run_para.pid_type_def[0].Ki=f; + my_output_data.pid_para[0].Ki=f; + ini_putf("MACH","ki1",f,ysp_cfg_file); + } + str=websGetVar(wp,"kd1","0"); + if(str!=NULL) + { + f=atof(str); + my_para_data.mach_run_para.pid_type_def[0].Kd=f; + my_output_data.pid_para[0].Kd=f; + ini_putf("MACH","kd1",f,ysp_cfg_file); + } + str=websGetVar(wp,"kp3","0"); + if(str!=NULL) + { + f=atof(str); + my_para_data.mach_run_para.pid_type_def[2].Kp=f; + my_output_data.pid_para[2].Kp=f; + ini_putf("MACH","kp3",f,ysp_cfg_file); + } + str=websGetVar(wp,"ki3","0"); + if(str!=NULL) + { + f=atof(str); + my_para_data.mach_run_para.pid_type_def[2].Ki=f; + my_output_data.pid_para[2].Ki=f; + ini_putf("MACH","ki3",f,ysp_cfg_file); + } + str=websGetVar(wp,"kd3","0"); + if(str!=NULL) + { + f=atof(str); + my_para_data.mach_run_para.pid_type_def[2].Kd=f; + my_output_data.pid_para[2].Kd=f; + ini_putf("MACH","kd3",f,ysp_cfg_file); + } + str=websGetVar(wp,"kp4","0"); + if(str!=NULL) + { + f=atof(str); + my_para_data.mach_run_para.pid_type_def[3].Kp=f; + my_output_data.pid_para[3].Kp=f; + ini_putf("MACH","kp4",f,ysp_cfg_file); + } + str=websGetVar(wp,"ki4","0"); + if(str!=NULL) + { + f=atof(str); + my_para_data.mach_run_para.pid_type_def[3].Ki=f; + my_output_data.pid_para[3].Ki=f; + ini_putf("MACH","ki4",f,ysp_cfg_file); + } + str=websGetVar(wp,"kd4","0"); + if(str!=NULL) + { + f=atof(str); + my_para_data.mach_run_para.pid_type_def[3].Kd=f; + my_output_data.pid_para[3].Kd=f; + ini_putf("MACH","kd4",f,ysp_cfg_file); + } + websRedirect(wp,"/temp_factor.jst"); +} + +static void web_relay_ctrl(Webs *wp) +{ + extern unsigned int curr_state; + int relay_val=0; + int i,tmp; + char *str; + char var_name[8]; + for(i=0;i<32;i++) + { + sprintf(var_name,"Y%d",i+1); + str=websGetVar(wp,var_name,"0"); + if(str!=NULL) + { + tmp=atoi(str); + if(tmp) + { + relay_val|=(1<4096) + { + send_analysis_req(file_path,strlen(file_path)); + sleep(1); + websRedirect(wp,"/show_data.jst"); + } + } + } + } + websRedirect(wp,"/sample_param.jst"); +} + +//保存用户上传的参数,用户提交保存按钮后的处理函数 +static void sample_para_upload(Webs *wp) +{ + char *str; + int tmp; + str=websGetVar(wp,"start_hour","4"); + if(str!=NULL) + { + tmp=atoi(str); + my_para_data.mach_run_para.start_hour=tmp; + ini_putl("MACH","start_hour",tmp,ysp_cfg_file); + } + + str=websGetVar(wp,"start_minute","0"); + if(str!=NULL) + { + tmp=atoi(str); + my_para_data.mach_run_para.start_minute=tmp; + ini_putl("MACH","start_minute",tmp,ysp_cfg_file); + } + + str=websGetVar(wp,"start_interval","4"); + if(str!=NULL) + { + tmp=atoi(str); + my_para_data.mach_run_para.start_interval=tmp; + ini_putl("MACH","sample_interval",tmp,ysp_cfg_file); + } + + str=websGetVar(wp,"sample_len","4000"); + if(str!=NULL) + { + tmp=atoi(str); + my_para_data.mach_run_para.sample_len=tmp; + ini_putl("MACH","sample_len",tmp,ysp_cfg_file); + } + + str=websGetVar(wp,"sample_rate","220"); + if(str!=NULL) + { + tmp=atoi(str); + my_para_data.mach_run_para.sample_rate=tmp; + ini_putl("MACH","sample_rate",tmp,ysp_cfg_file); + } + + str=websGetVar(wp,"sample_offs","1600"); + if(str!=NULL) + { + tmp=atoi(str); + my_para_data.mach_run_para.sample_offs=tmp; + ini_putl("MACH","sample_offs",tmp,ysp_cfg_file); + } + + str=websGetVar(wp,"co2_pos","0"); + if(str!=NULL) + { + tmp=atoi(str); + my_para_data.mach_run_para.co2_pos=tmp; + ini_putl("MACH","co2_pos",tmp,ysp_cfg_file); + } + + str=websGetVar(wp,"sample_cool_en","0"); + if(str!=NULL) + { + tmp=atoi(str); + my_para_data.mach_run_para.sample_cool_en=tmp; + ini_putl("MACH","sample_cool_en",tmp,ysp_cfg_file); + } + + str=websGetVar(wp,"h2o_en","0"); + if(str!=NULL) + { + tmp=atoi(str); + my_para_data.mach_run_para.h2o_en=tmp; + ini_putl("MACH","h2o_en",tmp,ysp_cfg_file); + } + + str=websGetVar(wp,"run_mode","0"); + if(str!=NULL) + { + tmp=atoi(str); + my_para_data.mach_run_para.run_mode=tmp; + ini_putl("MACH","run_mode",tmp,ysp_cfg_file); + } + + str=websGetVar(wp,"auto_gas_en","0"); + if(str!=NULL) + { + tmp=atoi(str); + my_para_data.mach_run_para.auto_gas_en=tmp; + ini_putl("MACH","auto_gas_en",tmp,ysp_cfg_file); + } + + str=websGetVar(wp,"upload_time","4"); + if(str!=NULL) + { + tmp=atoi(str); + my_para_data.mach_run_para.upload_time=tmp; + ini_putl("MACH","upload_time",tmp,ysp_cfg_file); + } + websRedirect(wp,"/sample_param.jst"); +} + +/*********************************** Code *************************************/ + +void *goahead(void *argv) +{ + char *argp, *home, *documents, *endpoints, *endpoint, *route, *auth, *tok, *lspec; + int argind; + + //sleep(16); + route = "route.txt"; + auth = "auth.txt"; + + documents = ME_GOAHEAD_DOCUMENTS; + if (argv != NULL) { + documents = (char *)argv; + } + //initPlatform(); + if (websOpen(documents, route) < 0) { + error("Cannot initialize server. Exiting."); + return -1; + } + if (websLoad(auth) < 0) { + error("Cannot load %s", auth); + return -1; + } + logHeader(); + /*if (argind < argc) { + while (argind < argc) { + endpoint = argv[argind++]; + if (websListen(endpoint) < 0) { + return -1; + } + } + } else {*/ + endpoints = sclone(ME_GOAHEAD_LISTEN); + for (endpoint = stok(endpoints, ", \t", &tok); endpoint; endpoint = stok(NULL, ", \t,", &tok)) { +#if !ME_COM_SSL + if (strstr(endpoint, "https")) continue; +#endif + if (websListen(endpoint) < 0) { + return -1; + } + } + wfree(endpoints); + //} +#if ME_ROM && KEEP + /* + If not using a route/auth config files, then manually create the routes like this: + If custom matching is required, use websSetRouteMatch. If authentication is required, use websSetRouteAuth. + */ + websAddRoute("/","file",0); +#endif + websDefineJst("show_sample_para",show_sample_para); + websDefineJst("show_rly_state",web_relay_show); + websDefineJst("show_io",web_io_show); + websDefineJst("temp_para_show",web_temp_para_show); + websDefineJst("get_para_f",web_get_para_f); + websDefineJst("get_para_i",web_get_para_i); + websDefineJst("man_ctrl_show",web_man_ctrl_show); + websDefineJst("show_mx_data",web_show_mx_data); + websDefineJst("showTest",showTest); + websDefineJst("ctrl_state_show",web_ctrl_state_show); + websDefineJst("get_sys_info",web_get_sys_para); + websDefineJst("get_sys_time",web_get_sys_time); + + websDefineAction("sample_para_upload",sample_para_upload); + websDefineAction("web_relay_ctrl",web_relay_ctrl); + websDefineAction("temp_ctrl_process",web_temp_ctrl_process); + websDefineAction("process_para_upload",process_para_upload); + websDefineAction("pres_fac_process",pres_fac_process); + websDefineAction("H2ParaProcess",H2ParaProcess); + websDefineAction("COParaProcess",COParaProcess); + websDefineAction("CH4ParaProcess",CH4ParaProcess); + websDefineAction("C2H4ParaProcess",C2H4ParaProcess); + websDefineAction("C2H6ParaProcess",C2H6ParaProcess); + websDefineAction("C2H2ParaProcess",C2H2ParaProcess); + websDefineAction("CO2ParaProcess",CO2ParaProcess); + websDefineAction("man_ctrl_process",man_ctrl_process); + websDefineAction("mx_data_process",web_mx_data_process); + websDefineAction("sys_reboot",sys_reboot); + websDefineAction("ethx_process",ethx_process); + websDefineAction("sntp_process",sntp_process); + websDefineAction("rtc_process",rtc_process); + websDefineAction("ied_rename",ied_rename_process); + websDefineAction("analysis_file_process",analysis_file_process); +#if ME_GOAHEAD_JAVASCRIPT + websDefineJst("aspTest",aspTest); +#endif + +#if ME_GOAHEAD_UPLOAD + websDefineAction("uploadTest",uploadTest); +#endif +/* +#if ME_UNIX_LIKE && !MACOSX + if (websGetBackground()) { + if (daemon(0, 0) < 0) { + error("Cannot run as daemon"); + return -1; + } + } +#endif*/ + websServiceEvents(&finished); + logmsg(1, "Instructed to exit"); + websClose(); +#if WINDOWS + windowsClose(); +#endif + return ((void *)0); +} + +//#if ME_GOAHEAD_JAVASCRIPT +/* + Parse the form variables: name, address and echo back + */ +static int aspTest(int eid, Webs *wp, int argc, char **argv) +{ + char *name, *address; + + if (jsArgs(argc, argv, "%s %s", &name, &address) < 2) { + websError(wp, 400, "Insufficient args\n"); + return -1; + } + return (int) websWrite(wp, "Name: %s, Address %s", name, address); +} + + +//显示参数 +static int show_sample_para(int eid, Webs *wp, int argc, char **argv) +{ + websWrite(wp,"开始采样时刻(0-23)分",my_para_data.mach_run_para.start_hour,my_para_data.mach_run_para.start_minute); + websWrite(wp,"采样间隔(2-24时)时",my_para_data.mach_run_para.start_interval); + websWrite(wp,"采样长度(100-5000)",my_para_data.mach_run_para.sample_len); + websWrite(wp,"采样速率(ms)",my_para_data.mach_run_para.sample_rate); + websWrite(wp,"采样偏置(0-4095)",my_para_data.mach_run_para.sample_offs); + websWrite(wp,"CO2切换位置(0-5000)",my_para_data.mach_run_para.co2_pos); + + websWrite(wp,"采样室制冷"); + if(my_para_data.mach_run_para.sample_cool_en) + websWrite(wp,"开启关闭"); + else + websWrite(wp,"开启关闭"); + + websWrite(wp,"微水检测使能"); + if(my_para_data.mach_run_para.h2o_en) + websWrite(wp,"开启关闭"); + else + websWrite(wp,"开启关闭"); + + if(my_para_data.mach_run_para.run_mode) + { + websWrite(wp,"运行模式调试正常"); + } + else + { + websWrite(wp,"运行模式调试正常"); + } + + if(my_para_data.mach_run_para.auto_gas_en) + { + websWrite(wp,"自动制气使能关闭"); + } + else + { + websWrite(wp,"自动制气使能关闭"); + } + websWrite(wp,"数据上传间隔(小时)",my_para_data.mach_run_para.upload_time); + return 0; +} + + + + + +//#endif + + +static void logHeader() +{ + char home[ME_GOAHEAD_LIMIT_STRING]; + + getcwd(home, sizeof(home)); + logmsg(2, "Configuration for %s", ME_TITLE); + logmsg(2, "---------------------------------------------"); + logmsg(2, "Version: %s", ME_VERSION); + logmsg(2, "BuildType: %s", ME_DEBUG ? "Debug" : "Release"); + logmsg(2, "CPU: %s", ME_CPU); + logmsg(2, "OS: %s", ME_OS); + logmsg(2, "Host: %s", websGetServer()); + logmsg(2, "Directory: %s", home); + logmsg(2, "Documents: %s", websGetDocuments()); + logmsg(2, "Configure: %s", ME_CONFIG_CMD); + logmsg(2, "---------------------------------------------"); +} + + +static void usage() { + fprintf(stdout, "\n%s Usage:\n\n" + " %s [options] [documents] [[IPaddress][:port] ...]\n\n" + " Options:\n" + " --auth authFile # User and role configuration\n" +#if ME_UNIX_LIKE && !MACOSX + " --background # Run as a Unix daemon\n" +#endif + " --debugger # Run in debug mode\n" + " --home directory # Change to directory to run\n" + " --log logFile:level # Log to file file at verbosity level\n" + " --route routeFile # Route configuration file\n" + " --verbose # Same as --log stdout:2\n" + " --version # Output version information\n\n", + ME_TITLE, ME_NAME); + exit(-1); +} + + +static void initPlatform() +{ +#if ME_UNIX_LIKE + signal(SIGTERM, sigHandler); + signal(SIGKILL, sigHandler); + #ifdef SIGPIPE + signal(SIGPIPE, SIG_IGN); + #endif +#elif ME_WIN_LIKE + _fmode=_O_BINARY; +#endif +} + + +#if ME_UNIX_LIKE +static void sigHandler(int signo) +{ + finished = 1; +} +#endif + + +#if WINDOWS +/* + Create a taskbar entry. Register the window class and create a window + */ +static int windowsInit() +{ + HINSTANCE inst; + WNDCLASS wc; /* Window class */ + HMENU hSysMenu; + HWND hwnd; + + inst = websGetInst(); + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = inst; + wc.hIcon = NULL; + wc.lpfnWndProc = (WNDPROC) websWindProc; + wc.lpszMenuName = wc.lpszClassName = ME_NAME; + if (! RegisterClass(&wc)) { + return -1; + } + /* + Create a window just so we can have a taskbar to close this web server + */ + hwnd = CreateWindow(ME_NAME, ME_TITLE, WS_MINIMIZE | WS_POPUPWINDOW, CW_USEDEFAULT, + 0, 0, 0, NULL, NULL, inst, NULL); + if (hwnd == NULL) { + return -1; + } + + /* + Add the about box menu item to the system menu + */ + hSysMenu = GetSystemMenu(hwnd, FALSE); + if (hSysMenu != NULL) { + AppendMenu(hSysMenu, MF_SEPARATOR, 0, NULL); + } + ShowWindow(hwnd, SW_SHOWNORMAL); + UpdateWindow(hwnd); + return 0; +} + + +static void windowsClose() +{ + HINSTANCE inst; + + inst = websGetInst(); + UnregisterClass(ME_NAME, inst); +} + + +/* + Main menu window message handler. + */ +static LRESULT CALLBACK websWindProc(HWND hwnd, UINT msg, UINT wp, LPARAM lp) +{ + switch (msg) { + case WM_DESTROY: + PostQuitMessage(0); + finished++; + return 0; + + case WM_SYSCOMMAND: + break; + } + return DefWindowProc(hwnd, msg, wp, lp); +} + + +/* + Check for Windows Messages + */ +WPARAM checkWindowsMsgLoop() +{ + MSG msg; + + if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { + if (!GetMessage(&msg, NULL, 0, 0) || msg.message == WM_QUIT) { + return msg.wParam; + } + TranslateMessage(&msg); + DispatchMessage(&msg); + } + return 0; +} + + +/* + Windows message handler + */ +static LRESULT CALLBACK websAboutProc(HWND hwndDlg, uint msg, uint wp, long lp) +{ + LRESULT lResult; + + lResult = DefWindowProc(hwndDlg, msg, wp, lp); + + switch (msg) { + case WM_CREATE: + break; + case WM_DESTROY: + break; + case WM_COMMAND: + break; + } + return lResult; +} + +#endif + +#if ME_GOAHEAD_UPLOAD +/* + Dump the file upload details. Don't actually do anything with the uploaded file. + */ +static void uploadTest(Webs *wp) +{ + WebsKey *s; + WebsUpload *up; + char *upfile; + + websSetStatus(wp, 200); + websWriteHeaders(wp, -1, 0); + websWriteHeader(wp, "Content-Type", "text/plain"); + websWriteEndHeaders(wp); + if (scaselessmatch(wp->method, "POST")) { + for (s = hashFirst(wp->files); s; s = hashNext(wp->files, s)) { + up = s->content.value.symbol; + websWrite(wp, "FILE: %s\r\n", s->name.value.string); + websWrite(wp, "FILENAME=%s\r\n", up->filename);///COMTRADE/tmp-0.tmp + websWrite(wp, "CLIENT=%s\r\n", up->clientFilename);//small.dat + websWrite(wp, "TYPE=%s\r\n", up->contentType); + websWrite(wp, "SIZE=%d\r\n", up->size); + //upfile = sfmt("%s/tmp/%s",websGetDocuments(),up->clientFilename); + upfile = sfmt("%s/%s","/COMTRADE",up->clientFilename); + printf("upfile=%s\n",upfile); + rename(up->filename, upfile); + wfree(upfile); + } + websWrite(wp, "\r\nVARS:\r\n"); + for (s = hashFirst(wp->vars); s; s = hashNext(wp->vars, s)) { + websWrite(wp, "%s=%s\r\n", s->name.value.string, s->content.value.string); + } + } + websDone(wp); +} +#endif + + +int goahead_init(void) +{ + pthread_t goahead_thread; + if((goahead_thread=task_create(goahead,WEB_DIR,0,0))==-1) + { + LOG_DEBUG(ERROR_DEBUG,"create goahead_routine failed\n"); + return 1; + } + return 0; +} + +/* + @copy default + + Copyright (c) Embedthis Software. All Rights Reserved. + + This software is distributed under commercial and open source licenses. + You may use the Embedthis GoAhead open source license or you may acquire + a commercial license from Embedthis Software. You agree to be fully bound + by the terms of either license. Consult the LICENSE.md distributed with + this software for full details and other copyrights. + + Local variables: + tab-width: 4 + c-basic-offset: 4 + End: + vim: sw=4 ts=4 expandtab + + @end + */ diff --git a/src/iec61850_process.c b/src/iec61850_process.c new file mode 100644 index 0000000..28cac76 --- /dev/null +++ b/src/iec61850_process.c @@ -0,0 +1,178 @@ +#include "common.h" +#include +#include "thread.h" +#include +#include "msq.h" +#include "serial.h" +#include "ysp_debug.h" +#include "scl_shm.h" +#include "iec61850_process.h" + +mqd_t iec61850_rx_mq;// +SCL_MSG_TYPE recv_iec_msg; +static char iec61850_rx_buf[1024]; + + +static YSP_PRI_DATA ysp_pri_data; +//static YSP_IEC_DATA ysp_last_data; + + +int iec61850_send_msg(void *msg,int msg_len) +{ + static mqd_t iec61850_rx_slave_mq=(mqd_t)-1; + if(iec61850_rx_slave_mq==-1) + { + if((iec61850_rx_slave_mq= open_mq(IEC61850_RX_MQ))==((mqd_t)-1)) + return -1; + } + if(mq_send(iec61850_rx_slave_mq,(const char *)msg,msg_len,IEC61850_RX_MQ_PRIO)==-1) + return -2; + + return 0; +} + +int send_ysp_msg(YSP_PRI_DATA *ysp_pri) +{ +static unsigned char ysp_msg_buf[512]; + unsigned int cmd; + cmd=CMD_SEND_PRI_DATA; + memcpy(ysp_msg_buf,&cmd,sizeof(cmd)); + memcpy(&ysp_msg_buf[4],(const void *)ysp_pri,sizeof(YSP_PRI_DATA)); + return iec61850_send_msg(ysp_msg_buf,sizeof(YSP_PRI_DATA)+4); +} + + +void conv_pri2iec(YSP_PRI_DATA *ysp_pri,YSP_IEC_DATA *ysp_iec,unsigned int q,time_t smp_time) +{ +time_t t; +if(smp_time!=0) + t=smp_time; +else + t=ysp_pri->SmpTm; + +ysp_iec->H2ppm.v.f=ysp_pri->H2ppm; +ysp_iec->H2ppm.q=q; +ysp_iec->H2ppm.t.secs=t; + +ysp_iec->COppm.v.f=ysp_pri->COppm; +ysp_iec->COppm.q=q; +ysp_iec->COppm.t.secs=t; + +ysp_iec->CH4ppm.v.f=ysp_pri->CH4ppm; +ysp_iec->CH4ppm.q=q; +ysp_iec->CH4ppm.t.secs=t; + +ysp_iec->C2H4ppm.v.f=ysp_pri->C2H4ppm; +ysp_iec->C2H4ppm.q=q; +ysp_iec->C2H4ppm.t.secs=t; + +ysp_iec->C2H6ppm.v.f=ysp_pri->C2H6ppm; +ysp_iec->C2H6ppm.q=q; +ysp_iec->C2H6ppm.t.secs=t; + +ysp_iec->C2H2ppm.v.f=ysp_pri->C2H2ppm; +ysp_iec->C2H2ppm.q=q; +ysp_iec->C2H2ppm.t.secs=t; + +ysp_iec->TotHyd.v.f=ysp_pri->TotHyd;//(ysp_pri->CH4ppm)+(ysp_pri->C2H4ppm)+(ysp_pri->C2H6ppm)+(ysp_pri->C2H2ppm); +ysp_iec->TotHyd.q=q; +ysp_iec->TotHyd.t.secs=t; + +ysp_iec->SmpTm.v.i=t; +ysp_iec->SmpTm.q=q; +ysp_iec->SmpTm.t.secs=t; + +ysp_iec->CO2ppm.v.f=ysp_pri->CO2ppm; +if(co2_is_ok) + { + ysp_iec->CO2ppm.q=GOOD; + } +else + { + ysp_iec->CO2ppm.q=INVALID; + } +ysp_iec->CO2ppm.t.secs=t; +} + +void iec61850_rx_routine(void *arg) +{ + int i; + time_t now; + float f=0; + start_scl_mem(); + if((iec61850_rx_mq=create_mq(IEC61850_RX_MQ,IEC61850_RX_MAX_MESSAGE,IEC61850_RX_MESSAGE_SIZE))<0) + { + LOG_DEBUG(ERROR_DEBUG,"create iec61850 rx message queue failed\n"); + exit(1); + } + + while(1) + { + if(recv_mq_wait(iec61850_rx_mq,(void *)iec61850_rx_buf,sizeof(iec61850_rx_buf),1000000)>0) + { + memcpy(&recv_iec_msg,iec61850_rx_buf,sizeof(recv_iec_msg)); + switch(recv_iec_msg.cmd) + { + case CMD_SEND_PRI_DATA: + LOG_DEBUG(IEC61850_TRACE_DEBUG,"receive CMD_SEND_PRI_DATA\n"); + memcpy(&ysp_pri_data,&iec61850_rx_buf[4],sizeof(YSP_PRI_DATA)); + now=time(NULL); + conv_pri2iec(&ysp_pri_data,&ysp_glb_data,0,0); + lock_scl_mem(); + put_mv_data(0,0,(USR_MV *)&ysp_glb_data,sizeof(ysp_glb_data)/sizeof(USR_MV)); + unlock_scl_mem(); + break; + default: + break; + } + } + else + { + now=time(NULL); + lock_input_data(); + ysp_glb_data.Tmp.v.f=my_input_data.temp; + ysp_glb_data.Mst.v.f=my_input_data.water; + if(my_input_data.com_flg) + { + ysp_glb_data.Tmp.q=INVALID; + ysp_glb_data.Mst.q=INVALID; + } + else + { + ysp_glb_data.Tmp.q=GOOD; + ysp_glb_data.Mst.q=GOOD; + } + unlock_input_data(); + + get_presure(PRES_PA1,&ysp_glb_data.GasPres.v.f); + conv_pri2iec(&ysp_pri_data,&ysp_glb_data,0,0); + ysp_glb_data.Tmp.t.secs=now; + ysp_glb_data.Mst.t.secs=now; + ysp_glb_data.GasPres.t.secs=now; + if(ysp_glb_data.MoDevConf.v.stVal) + { + ysp_glb_data.MoDevConf.q=INVALID; + } + else + { + ysp_glb_data.MoDevConf.q=GOOD; + } + lock_scl_mem(); + put_mv_data(0,0,(USR_MV *)&ysp_glb_data,sizeof(ysp_glb_data)/sizeof(USR_MV)); + unlock_scl_mem(); + } + } + stop_scl_mem(); +} + + +int iec61850_rx_init(void) +{ + pthread_t iec61850_rx_thread; + if((iec61850_rx_thread=task_create(iec61850_rx_routine,NULL,0,0))==-1) + { + LOG_DEBUG(ERROR_DEBUG,"create iec61850_rx_routine failed\n"); + return 1; + } + return 0; +} diff --git a/src/iec61850_process.h b/src/iec61850_process.h new file mode 100644 index 0000000..a19f888 --- /dev/null +++ b/src/iec61850_process.h @@ -0,0 +1,18 @@ +#ifndef _IEC61850_PROCESS_H +#define _IEC61850_PROCESS_H + +#include "scl_shm.h" + + +#define IEC61850_RX_MQ "/iec_rx_mq" +#define IEC61850_RX_MAX_MESSAGE 32 +#define IEC61850_RX_MESSAGE_SIZE 1024 +#define IEC61850_RX_MQ_PRIO 31 + + +#define CMD_SEND_PRI_DATA 16 + +extern int iec61850_rx_init(void); +extern int iec61850_send_msg(void *msg,int msg_len); + +#endif \ No newline at end of file diff --git a/src/interfaces b/src/interfaces new file mode 100644 index 0000000..af20327 --- /dev/null +++ b/src/interfaces @@ -0,0 +1,26 @@ +# Configure Loopback +auto lo +iface lo inet loopback + +#auto eth0 +#iface eth0 inet dhcp + +#iface eth1 inet manual +# pre-up ifconfig $IFACE up +# pre-down ifconfig $IFACE down +auto eth0 +iface eth0 inet static +address 192.168.1.199 +netmask 255.255.255.0 +network 192.168.1.0 +gateway 192.168.1.1 + +auto eth1 +iface eth1 inet static +address 192.169.1.199 +netmask 255.255.255.0 +network 192.169.1.0 +gateway 192.169.1.1 + + + diff --git a/src/left.txt b/src/left.txt new file mode 100644 index 0000000..3aeec93 --- /dev/null +++ b/src/left.txt @@ -0,0 +1,3 @@ +1.ݿ +2.͹ +3.Խӿ \ No newline at end of file diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..5d3001b --- /dev/null +++ b/src/main.c @@ -0,0 +1,3157 @@ +/* + * main.c + * + * Created on: Apr 15, 2015 + * Author: root + */ +#include +#include +#include +#include +#include +#include +#include +#include "ysp_debug.h" +#include "msq.h" +#include "main.h" +#include "common.h" +#include "para.h" +#include "analysis.h" +#include "serial.h" +#include "sample_process.h" +#include "ctrl_process.h" +#include "iec61850_process.h" + +#define APP_VERSION "ysp application v3.3(2016-07-14 12:00)" + + +typedef struct +{ + unsigned int room_start_time;//采样室开始时刻 + unsigned int heat_start_time;//传感器加热开始时刻 + unsigned int yv18_start_time;//吹扫阀开启时间 + unsigned int yv18_poll_time; // + unsigned int sample_start_time;//最近一次采样开始时刻 + unsigned int dummy_sample_time; +}TIME_RECORD_DEF; + +extern int sample_fd; +CLEAN_STAT gas_clean_stat; +CLEAN_STAT gas_make_stat; +CLEAN_STAT demarcate_stat; +//PRE_ACTION_STATE my_action_state; +TIME_RECORD_DEF time_record; + +SAMPLE_PARA_TYPE sample_para; + +unsigned int relay_close_tick[32]; +unsigned int relay_open_tick[32]; + +unsigned char main_rx_buf[MAIN_MESSAGE_SIZE]; + +mqd_t main_mq=(mqd_t)(-1); + +time_t last_sample_time_ex; +static int doIt=1; + +unsigned int curr_state=0; + +static char *rly_name[32]={ +"unused", +"unused", +"unused", +"油缸退YV4", +"油缸进YV5", +"气缸退YV6", +"气缸进YV7", +"样气进气缸阀YV15", +"进油阀YV16", +"unused", +"气缸进油阀YV11", +"进气到集气缸阀YV12", +"出油阀YV13", +"清洗排空阀YV14", +"油泵YV3", +"unused", +"样气平衡阀YV17", +"吹扫阀YV18", +"定量阀YV19", +"传感器平衡阀YV20", +"CO2检测阀YV21", +"排水阀KA8", +"unused", +"柜子风扇KA3", +"采样单元风扇KA4", +"采样电源控制KA5", +"冷井风扇KA6", +"冷井电源控制KA7", +"unused", +"传感器加热", +"unused", +"气缸启停", +}; +/* +const float sample_temp_table[]={ +0,0,0,0,0,0,0,0,0,0, +0,0,7,7,7,7,7,7,9,9, +9,12,12,12,14,14,14,17,17, +19,19,19,22,22,22,22,22,22,22, +22,22 +};*/ +const float sample_temp_table[]={ +0,0,0,0,0,0,0,0,0,0,0, +1,1,1,1,1,4,4,4,4,4, +10,10,10,10,10,15,15,15,15,15, +18,18,18,18,18,18,18,18,18,18, +18,18 +}; + +//根据室温计算采样单元需要设定的温度 +void cal_sample_temp(float *evn_temp,float *sample_temp) +{ + int temp; + temp=(int)(*evn_temp); + if(temp<0) + { + *sample_temp=0; + } + else if((temp>=(sizeof(sample_temp_table)/sizeof(float)))) + { + //*sample_temp=sample_temp_table[(sizeof(sample_temp_table)/sizeof(float))-1]-2; + *sample_temp=sample_temp_table[(sizeof(sample_temp_table)/sizeof(float))-1]; + } + else + { + //if(sample_temp_table[temp]>2) + // *sample_temp=sample_temp_table[temp]-2; + // else + *sample_temp=sample_temp_table[temp]; + } +}//年,月,日,时,分,秒,微水 + +void relay_dly_close_set(unsigned int rly_num,unsigned int dly_sec) +{ + if(rly_num>=32) + return; + relay_close_tick[rly_num]=dly_sec; + relay_open_tick[rly_num]=0; +} + +void relay_dly_open_set(unsigned int rly_num,unsigned int dly_sec) +{ + if(rly_num>=32) + return; + relay_open_tick[rly_num]=dly_sec; + relay_close_tick[rly_num]=0; +} + + +void relay_dly_process(void) +{ + static unsigned int relay_tick=0; + int i; + relay_tick++; + if((relay_tick&1)==0)//每秒钟运行一次 + { + for(i=0;i<(sizeof(relay_close_tick)/sizeof(int));i++) + { + if(relay_open_tick[i]>0) + { + relay_open_tick[i]--; + if(relay_open_tick[i]==0) + { + if(i<32) + { + relay_set(i,ON,0); + LOG_DEBUG(TRACE_DEBUG,"%s ON\n",rly_name[i]); + } + } + } + + if(relay_close_tick[i]>0) + { + relay_close_tick[i]--; + if(relay_close_tick[i]==0) + { + if(i<32) + { + relay_set(i,OFF,0); + LOG_DEBUG(TRACE_DEBUG,"%s OFF\n",rly_name[i]); + } + } + } + } + } +} + +void ctrlCfun (int i) +{ + doIt = 0; +} + +/* +void show_time(char *s) +{ + struct timeval now; + gettimeofday(&now,NULL); + printf("sec=%d.%d\n",now.tv_sec,now.tv_usec/1000); +}*/ + +int SendActionMsg(ACTION_MSG_TYPE *msg) +{ + static mqd_t slave_main_mq=(mqd_t)-1; + unsigned char dumy_msg[16]; + if(slave_main_mq==-1) + { + if((slave_main_mq= open_mq(MAIN_MESSAGE_MQ))==((mqd_t)-1)) + return -1; + } + if(mq_send(slave_main_mq,(const char *)msg,sizeof(ACTION_MSG_TYPE),MAIN_MESSAGE_PRIO)==-1) + return -2; + + return 0; +} + +int SendActionReq(int cmd,int src) +{ + ACTION_MSG_TYPE msg; + msg.cmd=cmd; + msg.src=src; + if(SendActionMsg(&msg)==0) + return 0; + return 1; +} + +//手动启动采样 +void man_start_sample(void) +{ + + //手动启动时,冷井和采样单元启动?传感器启动? + float my_temp=my_para_data.mach_run_para.temperature[TEMP_LJ]; + set_pid_temp(TEMP_LJ,&my_temp,0);//设置冷井温度 + + //printf(""); + //my_temp=my_para_data.mach_run_para.temperature[TEMP_SAM]; + //set_pid_temp(TEMP_SAM,&my_temp,0);//设置采样室温度 + //set_pid_ch(PID_SAMPLE,PID_EN,0);//开启采样室温度控制 + //relay_set(RLY_KA4,ON,0);//开采样单元风扇 + + //my_temp=my_para_data.mach_run_para.temperature[TEMP_LJ]; + //set_pid_temp(TEMP_LJ,&my_temp,0);//设置色谱柱温度 + //set_pid_ch(PID_LJ,PID_EN,0);//开启色谱柱温度控制 + //relay_set(RLY_KA6,ON,1);//开冷井风扇 +} + +int main_message_process(ACTION_MSG_TYPE *msg) +{ + float env_temp;//环境温度 + float my_temp;// + switch(curr_state) + { + case SIX_SAMPLE: + if(msg->cmd==STOP_SAMPLE) + { + memset(&gas_clean_stat,0,sizeof(gas_clean_stat)); + memset(&gas_make_stat,0,sizeof(gas_make_stat)); + set_pid_ch(PID_LJ,PID_DIS,0);//关冷井 + set_pid_ch(PID_SAMPLE,PID_DIS,0);//关采样单元 + //memset(&my_action_state,0,sizeof(&my_action_state)); + relay_dly_close_set(RLY_SENSOR,4);//延时关传感器加热 + relay_clr((1<cmd==STOP_SAMPLE) + { + memset(&gas_make_stat,0,sizeof(gas_make_stat)); + set_pid_ch(PID_LJ,PID_DIS,0);//关冷井 + set_pid_ch(PID_SAMPLE,PID_DIS,0);//关采样单元 + relay_clr((1<cmd==STOP_SAMPLE) + { + memset(&gas_make_stat,0,sizeof(gas_make_stat)); + //relay_clr((1<cmd==STOP_SAMPLE) + { + memset(&gas_make_stat,0,sizeof(gas_make_stat)); + //relay_clr((1<cmd==STOP_SAMPLE) + { + memset(&gas_make_stat,0,sizeof(gas_make_stat)); + ctrl_oil_pump(0);//停止 + curr_state=MODE_IDLE; + } + break; + default: + if(msg->cmd==START_SIX_SAMPLE) + { + //采样开始前45分钟查表设置采样室温度,同时检测室外温度看是否启动伴热带 + //启动采样室制冷 + //get_temperature(TEMP_ENV,&env_temp);//获取环境温度 + get_temperature(TEMP_OUTSIDE,&env_temp);//获取室外温度 + //if(env_temp>11) + // { + cal_sample_temp(&env_temp,&my_temp); + LOG_DEBUG(TRACE_DEBUG,"Preaction:Cabinet temperature is %f,set sample room temperature to %f\n",env_temp,my_temp); + + my_para_data.mach_run_para.temperature[TEMP_SAM]=my_temp; + set_pid_temp(TEMP_SAM,&my_temp,0);//设置采样室温度 + relay_set(RLY_KA4,ON,0); //开采样室风扇 + relay_set(RLY_FAN,ON,0); + set_pid_ch(PID_SAMPLE,PID_EN,1); //开采样室温度控制 + LOG_DEBUG(TRACE_DEBUG,"Preaction:KA4 KA5 ON,Start sample room colding\n"); + // } + // else + //{ + // LOG_DEBUG(TRACE_DEBUG,"Preaction:sample room colding will not start,env_temp=%f\n",env_temp); + // } + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step=50; + curr_state=SIX_SAMPLE; //开始标定 + } + else if(msg->cmd==START_DEMARCATE) + { + curr_state=DEMARCATE; //开始标定 + memset(&gas_make_stat,0,sizeof(gas_make_stat)); + gas_make_stat.step=1; + } + else if(msg->cmd==START_RM_GAS) + { + curr_state=REMOVE_GAS;//开始脱气 + memset(&gas_make_stat,0,sizeof(gas_make_stat)); + gas_make_stat.step=1; + } + else if(msg->cmd==START_FAULT_PROCESS) + { + curr_state=GAS_FAULT_PROCESS;//开始脱气故障处理 + memset(&gas_make_stat,0,sizeof(gas_make_stat)); + gas_make_stat.step=1; + } + else if(msg->cmd==START_OIL_PROCESS) + { + curr_state=PUMP_OIL_PROCESS;// + ctrl_oil_pump(1);//启动 + } + break; + } + return 0; +} + +void stop_gas_clean(int reason) +{ + SendActionReq(STOP_SAMPLE,reason); + printf("clean gas failed\n"); +} + +void stop_gas_make(int reason) +{ + SendActionReq(STOP_SAMPLE,reason); + printf("make gas failed\n"); +} + +void stop_curr_process(int reason) +{ + SendActionReq(STOP_SAMPLE,reason); + printf("stop current process\n"); +} + +int gas_clean(void) +{ + switch(gas_clean_stat.step) + { + case 1://检查I6 + if(io_get(STA_I6)==ON) + { + gas_clean_stat.dly_cnt=0; + gas_clean_stat.repeat_cnt=0; + gas_clean_stat.step++; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:I6 is in right position\n",gas_clean_stat.step); + } + else + { + LOG_DEBUG(ERROR_DEBUG,"clean_step=%d:I6 is not in right pos\n",gas_clean_stat.step); + stop_gas_clean(gas_clean_stat.step); + return gas_clean_stat.step; + } + break; + case 2://开YV14 + relay_set(RLY_YV14,ON,1); + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV14 ON\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + case 3://开YV6 + if(gas_clean_stat.dly_cnt==0) + { + relay_set(RLY_YV7,OFF,0); + relay_set(RLY_YV6,ON,1); + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV6 ON YV7 OFF\n",gas_clean_stat.step); + gas_clean_stat.dly_cnt++; + } + else + { + //等待I7到位 + if(gas_clean_stat.dly_cnt>I7_WAIT_CNT) + { + if(io_get(STA_I7)==ON) + { + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:I7 is arrived in right position\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + } + else + { + if(gas_clean_stat.dly_cnt>I7_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"gas_step=%d:wait I7 ON timeout\n",gas_clean_stat.step); + stop_gas_clean(gas_clean_stat.step); + gas_clean_stat.dly_cnt=0; + gas_clean_stat.step=0; + return gas_clean_stat.step; + } + } + } + gas_clean_stat.dly_cnt++; + } + break; + case 4://开YV7 + if(gas_clean_stat.dly_cnt==0) + { + relay_set(RLY_YV6,OFF,0); + relay_set(RLY_YV7,ON,1); + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV7 ON YV6 OFF\n",gas_clean_stat.step); + gas_clean_stat.dly_cnt++; + } + else + { + //等待I6到位 + if(gas_clean_stat.dly_cnt>I6_WAIT_CNT) + { + if(io_get(STA_I6)==ON) + { + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:I6 is arrived in right position\n",gas_clean_stat.step); + gas_clean_stat.step++; + + break; + } + else + { + if(gas_clean_stat.dly_cnt>I6_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"gas_step=%d:wait I6 arrived in right position timeout\n",gas_clean_stat.step); + stop_gas_clean(gas_clean_stat.step); + gas_clean_stat.dly_cnt=0; + gas_clean_stat.step=0; + return gas_clean_stat.step; + } + } + } + gas_clean_stat.dly_cnt++; + } + break; + case 5://重复3-4 + gas_clean_stat.dly_cnt=0; + gas_clean_stat.repeat_cnt++; + LOG_DEBUG(ACTION_DEBUG,"%dst gas clean completed,curr_step=%d\n",gas_clean_stat.repeat_cnt,gas_clean_stat.step); + if(gas_clean_stat.repeat_cnt>=CLEAN_AIR_REPEAT_CNT) + { + gas_clean_stat.repeat_cnt=0; + gas_clean_stat.step++; + } + else + { + gas_clean_stat.step=3; + } + break; + case 6://关YV14 + relay_set(RLY_YV14,OFF,1); + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV14 OFF\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + case 7://开YV15 + relay_set(RLY_YV15,ON,1); + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV15 ON\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + case 8://开YV6 + if(gas_clean_stat.dly_cnt==0) + { + relay_set(RLY_YV7,OFF,0); + relay_set(RLY_YV6,ON,1); + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV6 ON YV7 OFF\n",gas_clean_stat.step); + gas_clean_stat.dly_cnt++; + } + else + { + //等待I7到位 + if(gas_clean_stat.dly_cnt>I7_WAIT_CNT) + { + if(io_get(STA_I7)==ON) + { + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:I7 have arrived in right position\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + } + else + { + if(gas_clean_stat.dly_cnt>I7_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"gas_step=%d:wait I7 arrvied in right position timeout\n",gas_clean_stat.step); + stop_gas_clean(gas_clean_stat.step); + gas_clean_stat.dly_cnt=0; + gas_clean_stat.step=0; + return gas_clean_stat.step; + } + } + } + gas_clean_stat.dly_cnt++; + } + break; + case 9://关YV15 + relay_set(RLY_YV15,OFF,1); + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV15 OFF\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + case 10://开YV10,延时6秒 + if(gas_clean_stat.dly_cnt==0) + { + relay_set(RLY_YV10,ON,1); + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV10 ON,Start delay 6s\n",gas_clean_stat.step); + gas_clean_stat.dly_cnt++; + } + else + { + //延时6秒 + if(gas_clean_stat.dly_cnt>YV10_ON_TIME) + { + gas_clean_stat.dly_cnt=0; + gas_clean_stat.step++; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:Delay 6s is completed\n",gas_clean_stat.step); + } + else + { + gas_clean_stat.dly_cnt++; + } + } + break; + case 11://关YV10 + relay_set(RLY_YV10,OFF,1); + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV10 OFF\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + case 12://开YV14 + relay_set(RLY_YV14,ON,1); + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV14 ON\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + case 13://开YV7 + if(gas_clean_stat.dly_cnt==0) + { + relay_set(RLY_YV6,OFF,0); + relay_set(RLY_YV7,ON,1); + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV7 ON YV6 OFF\n",gas_clean_stat.step); + gas_clean_stat.dly_cnt++; + } + else + { + //等待I6到位 + if(gas_clean_stat.dly_cnt>I6_WAIT_CNT) + { + if(io_get(STA_I6)==ON) + { + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:I6 have arrived in right position\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + } + else + { + if(gas_clean_stat.dly_cnt>I6_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"gas_step=%d:wait I6 arrived in right position timeout\n",gas_clean_stat.step); + stop_gas_clean(gas_clean_stat.step); + gas_clean_stat.dly_cnt=0; + gas_clean_stat.step=0; + return gas_clean_stat.step; + } + } + } + gas_clean_stat.dly_cnt++; + } + break; + case 14://关YV14 + relay_set(RLY_YV14,OFF,1); + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV14 OFF\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + case 15://重复7-14 + gas_clean_stat.dly_cnt=0; + gas_clean_stat.repeat_cnt++; + LOG_DEBUG(ACTION_DEBUG,"%dst gas clean completed,curr_step=%d\n",gas_clean_stat.repeat_cnt,gas_clean_stat.step); + if(gas_clean_stat.repeat_cnt>=CLEAN_CARRIER_REPEAT_CNT) + { + gas_clean_stat.repeat_cnt=0; + gas_clean_stat.step++; + } + else + { + gas_clean_stat.step=7; + } + break; + case 16://开YV6 + if(gas_clean_stat.dly_cnt==0) + { + relay_set(RLY_YV7,OFF,0); + relay_set(RLY_YV6,ON,1); + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:YV6 ON YV7 OFF\n",gas_clean_stat.step); + gas_clean_stat.dly_cnt++; + } + else + { + //等待I7到位 + if(gas_clean_stat.dly_cnt>I7_WAIT_CNT) + { + if(io_get(STA_I7)==ON) + { + gas_clean_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:I7 have arrived in right position\n",gas_clean_stat.step); + gas_clean_stat.step++; + break; + } + else + { + if(gas_clean_stat.dly_cnt>I7_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"gas_step=%d:wait I7 arrived in right position timeout\n",gas_clean_stat.step); + stop_gas_clean(gas_clean_stat.step); + gas_clean_stat.dly_cnt=0; + gas_clean_stat.step=0; + return gas_clean_stat.step; + } + } + } + gas_clean_stat.dly_cnt++; + } + break; + case 17://启动冷井工作 + relay_set(RLY_KA6,ON,0);//开冷井风扇 + //relay_set(RLY_KA7,ON,0);//冷井电源 + set_pid_ch(PID_LJ,PID_EN,1);//开冷井控制 + gas_clean_stat.dly_cnt=0; + gas_clean_stat.repeat_cnt=0; + gas_clean_stat.step++; + LOG_DEBUG(ACTION_DEBUG,"clean_step=%d:gas clean have completed,KA6 ON KA7 ON and start LJ cold\n",gas_clean_stat.step); + break; + case 18: + break; + default: + break; + } + return 0; +} + +//启动停止油泵 +int ctrl_oil_pump(int str_or_stp) +{ + if(str_or_stp) + { + relay_set(RLY_YV16,ON,0); + relay_set(RLY_YV13,ON,1); + usleep(1000000); + relay_set(RLY_OIL,ON,1); + } + else + { + relay_set(RLY_OIL,OFF,1); + usleep(500000); + relay_set(RLY_YV16,OFF,0); + relay_set(RLY_YV13,OFF,1); + } + return 0; +} + +//脱气机故障处理 +int gas_flt_process(void) +{ + switch(gas_make_stat.step) + { + case 1://拉油缸 + relay_set(RLY_YV4,ON,1); + LOG_DEBUG(ACTION_DEBUG,"flt_step=%d:YV4 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 2://等油缸拉到位 + if(io_get(STA_I5)==ON) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"flt_step=%d:I5 have arrived in right position\n",gas_make_stat.step); + gas_make_stat.step++; + relay_set(RLY_YV11,ON,0);//开YV11,YV12 + relay_set(RLY_YV12,ON,1); + LOG_DEBUG(ACTION_DEBUG,"flt_step=%d:YV11 ON,Y12 ON\n",gas_make_stat.step); + break; + } + else + { + if(gas_make_stat.dly_cnt>I5_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"flt_step=%d:wait I5 arrived ON timeout,exit\n",gas_make_stat.step); + stop_curr_process(gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step=0; + return gas_make_stat.step; + } + gas_make_stat.dly_cnt++; + } + break; + case 3://延时3分钟 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>(180*2)) + { + relay_set(RLY_YV12,OFF,1);//关YV12 + usleep(1000000); + relay_set(RLY_YV4,OFF,1);//关YV4 + LOG_DEBUG(ACTION_DEBUG,"flt_step=%d:Y12 OFF,YV4 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + } + break; + case 4: + if(io_get(STA_I4)==ON) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"flt_step=%d:I4 have arrived in right position\n",gas_make_stat.step); + gas_make_stat.step++; + break; + } + else + { + if(gas_make_stat.dly_cnt>I4_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"flt_step=%d:wait I4 arrived ON timeout,exit\n",gas_make_stat.step); + stop_curr_process(gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step=0; + return gas_make_stat.step; + } + gas_make_stat.dly_cnt++; + } + break; + case 5: + if(io_get(STA_I8)==ON) + { + relay_set(RLY_YV11,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"flt_step=%d:YV11 OFF\n",gas_make_stat.step); + gas_make_stat.repeat_cnt=0; + gas_make_stat.dly_cnt=0; + gas_make_stat.step=0; + //停止动作 + stop_curr_process(gas_make_stat.step); + return gas_make_stat.step; + } + else + { + relay_set(RLY_YV5,ON,1); + LOG_DEBUG(ACTION_DEBUG,"flt_step=%d:YV5 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + } + break; + case 6: + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>8) + { + relay_set(RLY_YV11,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"flt_step=%d:YV11 OFF,YV5 OFF\n",gas_make_stat.step); + usleep(1000000); + relay_set(RLY_YV5,OFF,1); + if(io_get(STA_I8)==ON) + { + gas_make_stat.repeat_cnt=0; + gas_make_stat.dly_cnt=0; + gas_make_stat.step=0; + stop_curr_process(gas_make_stat.step); + return gas_make_stat.step; + } + else + { + gas_make_stat.repeat_cnt++; + if(gas_make_stat.repeat_cnt<2) + { + gas_make_stat.dly_cnt=0; + gas_make_stat.step=1; + } + else + { + //结束 + LOG_DEBUG(ERROR_DEBUG,"flt_step=%d:I8 is not in right position,exit\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step=0; + gas_make_stat.repeat_cnt=0; + stop_curr_process(gas_make_stat.step); + return gas_make_stat.step; + } + } + } + break; + default: + gas_make_stat.dly_cnt=0; + gas_make_stat.step=0; + gas_make_stat.repeat_cnt=0; + stop_curr_process(gas_make_stat.step); + break; + } + return 0; +} + +int remove_gas_process(void) +{ + switch(gas_make_stat.step) + { + case 1://打开电机 + if(io_get(STA_I4)!=ON) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:I4 is not in right position,exit\n",gas_make_stat.step); + //stop_gas_make(gas_make_stat.step); + stop_curr_process(gas_make_stat.step); + return gas_make_stat.step; + } + //y4 on,等到位,y11 onf,1分钟,y4 off,等油缸到位,再检测i8,y5 on 3s,再检测I8,关y11,关yv5 + if(io_get(STA_I8)==OFF) + { + usleep(500000); + if(io_get(STA_I8)==OFF) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:I8 is not in right position,exit\n",gas_make_stat.step); + //stop_gas_make(gas_make_stat.step); + stop_curr_process(gas_make_stat.step); + return gas_make_stat.step; + } + } + relay_set(RLY_YV16,ON,0); + relay_set(RLY_YV13,ON,0); + relay_set(RLY_KA1,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV16 ON,YV13 ON,KA1 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + break; + case 2://延时3分钟 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>=MOTOR_RUN_TIME) + { + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 3 minutes completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 3://关电机 + relay_set(RLY_KA1,OFF,0); + relay_set(RLY_YV16,OFF,0); + relay_set(RLY_YV13,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:KA1 OFF,YV16 OFF,YV13 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + break; + case 4: + if(io_get(STA_I8)==OFF) + { + usleep(500000); + if(io_get(STA_I8)==OFF) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:I8 is not in right position,exit\n",gas_make_stat.step); + //stop_gas_make(gas_make_stat.step); + stop_curr_process(gas_make_stat.step); + return gas_make_stat.step; + } + } + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + break; + case 5://延时2秒,等待气路清洗完成, + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>=4) + { + if(gas_clean_stat.step>GAS_CLEAN_MAX_STEP) + { + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 2 minutes completed\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + } + else + { + if(gas_make_stat.dly_cnt>GAS_CLEAN_MAX_TIME) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:gas clean timeout,exit\n",gas_make_stat.step); + //stop_gas_make(gas_make_stat.step); + stop_curr_process(gas_make_stat.step); + return gas_make_stat.step; + } + } + } + break; + case 6://开YV4 + if(gas_make_stat.dly_cnt==0) + { + relay_set(RLY_YV5,OFF,0); + relay_set(RLY_YV4,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV4 ON,YV5 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt++; + } + else + { + //等待I5到位 + if(gas_make_stat.dly_cnt>I5_WAIT_CNT) + { + if(io_get(STA_I5)==ON) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:I5 have arrived in right position\n",gas_make_stat.step); + gas_make_stat.step++; + break; + } + else + { + if(gas_make_stat.dly_cnt>I5_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:wait I5 arrived ON timeout,exit\n",gas_make_stat.step); + //stop_gas_make(gas_make_stat.step); + stop_curr_process(gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step=0; + return gas_make_stat.step; + } + } + } + gas_make_stat.dly_cnt++; + } + break; + case 7://开YV11 + relay_set(RLY_YV11,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV11 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 8://开YV12 + relay_set(RLY_YV12,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV12 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 9://延时2分钟,制气时间 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>GAS_MAKE_TIME) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 2 minutes completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 10://关YV4,对应STM32上清洗油路第28步 + relay_set(RLY_YV4,OFF,0); + relay_set(RLY_YV15,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV4 OFF,YV15 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 11://开YV15 + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 12://延时5秒,进气时间,admission + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>GAS_ADMISSION_TIME) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 5s completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 13://关YV12 + relay_set(RLY_YV12,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV12 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 14://关YV15 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt==1) + { + relay_set(RLY_YV15,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV15 OFF\n",gas_make_stat.step); + } + else + { + if(gas_make_stat.dly_cnt>=32) + { + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + } + } + break; + case 15://重复6-14, + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt++; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:%dst make gas completed\n",gas_make_stat.step,gas_make_stat.repeat_cnt); + if(gas_make_stat.repeat_cnt>=GAS_MAKE_REPEAT_CNT)//制气重复次数 + { + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + } + else + { + gas_make_stat.step=6; + } + break; + case 16://开YV5,延时1秒 + if(gas_make_stat.dly_cnt==0) + { + relay_set(RLY_YV5,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV5 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt++; + } + else + { + if(gas_make_stat.dly_cnt>=3) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 1s completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + else + { + gas_make_stat.dly_cnt++; + } + } + break; + case 17://关YV11 + relay_set(RLY_YV11,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV11 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 18://关YV5 + relay_set(RLY_YV5,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV5 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 19://开YV7,关YV6 + relay_set(RLY_YV6,OFF,0); + relay_set(RLY_YV7,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV7 ON,YV6 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 20: + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>=32) + { + relay_set(RLY_YV7,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV7 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step=0; + stop_gas_make(gas_make_stat.step); + } + break; + default: + break; + } + return 0; +} + +int gas_make(void) +{ + float fval; + static unsigned int yv17_on_flg; + static unsigned int yv17_on_tick; + unsigned int sample_data_length=0; + static unsigned int pres_flg=0; + + static time_t start_time,now; + static unsigned int co2_sample_state=0; + + if(gas_make_stat.step<44) + { + if(io_get(STA_I9)==ON) + { + usleep(500000); + if(io_get(STA_I9)==ON) + { + LOG_DEBUG(ERROR_DEBUG,"gas_make_step=%d gas_clean_step=%d:I9 is not in right position,exit\n",gas_make_stat.step,gas_clean_stat.step); + gas_clean_stat.step=0; + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + } + if(gas_clean()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"gas clean failed\n"); + return gas_make_stat.step; + } + } + if(time_record.heat_start_time) + { + if(time(NULL)>=time_record.heat_start_time) + { + //开传感器 + time_record.heat_start_time=0; + } + } + switch(gas_make_stat.step) + { + case 1://打开电机 + if(io_get(STA_I4)!=ON) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:I4 is not in right position,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + //y4 on,等到位,y11 onf,1分钟,y4 off,等油缸到位,再检测i8,y5 on 3s,再检测I8,关y11,关yv5 + if(io_get(STA_I8)==OFF) + { + usleep(500000); + if(io_get(STA_I8)==OFF) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:I8 is not in right position,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + } + relay_set(RLY_YV16,ON,0); + relay_set(RLY_YV13,ON,0); + relay_set(RLY_KA1,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV16 ON,YV13 ON,KA1 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + break; + case 2://延时3分钟 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>=MOTOR_RUN_TIME) + { + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 3 minutes completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 3://关电机 + relay_set(RLY_KA1,OFF,0); + relay_set(RLY_YV16,OFF,0); + relay_set(RLY_YV13,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:KA1 OFF,YV16 OFF,YV13 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + break; + case 4: + if(io_get(STA_I8)==OFF) + { + usleep(500000); + if(io_get(STA_I8)==OFF) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:I8 is not in right position,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + } + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + break; + case 5://延时2秒,等待气路清洗完成, + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>=4) + { + if(gas_clean_stat.step>GAS_CLEAN_MAX_STEP) + { + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 2 minutes completed\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + } + else + { + if(gas_make_stat.dly_cnt>GAS_CLEAN_MAX_TIME) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:gas clean timeout,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + } + } + break; + case 6://开YV4 + if(gas_make_stat.dly_cnt==0) + { + relay_set(RLY_YV5,OFF,0); + relay_set(RLY_YV4,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV4 ON,YV5 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt++; + } + else + { + //等待I5到位 + if(gas_make_stat.dly_cnt>I5_WAIT_CNT) + { + if(io_get(STA_I5)==ON) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:I5 have arrived in right position\n",gas_make_stat.step); + gas_make_stat.step++; + break; + } + else + { + if(gas_make_stat.dly_cnt>I5_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:wait I5 arrived ON timeout,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step=0; + return gas_make_stat.step; + } + } + } + gas_make_stat.dly_cnt++; + } + break; + case 7://开YV11 + relay_set(RLY_YV11,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV11 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 8://开YV12 + relay_set(RLY_YV12,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV12 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 9://延时2分钟,制气时间 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>GAS_MAKE_TIME) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 2 minutes completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 10://关YV4,对应STM32上清洗油路第28步 + relay_set(RLY_YV4,OFF,0); + relay_set(RLY_YV15,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV4 OFF,YV15 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 11://开YV15 + // relay_set(RLY_YV15,ON,1); + //LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV15 ON\n",gas_make_stat.step); + // gas_make_stat.dly_cnt++; + //if(gas_make_stat.dly_cnt>20) + // { + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + // } + break; + case 12://延时5秒,进气时间,admission + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>GAS_ADMISSION_TIME) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 5s completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 13://关YV12 + relay_set(RLY_YV12,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV12 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 14://关YV15 + /*relay_set(RLY_YV15,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV15 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++;*/ + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt==1) + { + relay_set(RLY_YV15,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV15 OFF\n",gas_make_stat.step); + } + else + { + if(gas_make_stat.dly_cnt>=32) + { + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + } + } + break; + case 15://重复6-14, + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt++; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:%dst make gas completed\n",gas_make_stat.step,gas_make_stat.repeat_cnt); + if(gas_make_stat.repeat_cnt>=GAS_MAKE_REPEAT_CNT)//制气重复次数 + { + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + } + else + { + gas_make_stat.step=6; + } + break; + case 16://开YV5,延时1秒 + if(gas_make_stat.dly_cnt==0) + { + relay_set(RLY_YV5,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV5 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt++; + } + else + { + if(gas_make_stat.dly_cnt>=3) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 1s completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + else + { + gas_make_stat.dly_cnt++; + } + } + break; + case 17://关YV11 + relay_set(RLY_YV11,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV11 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 18://关YV5 + relay_set(RLY_YV5,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV5 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 19://等待冷井温度<-25 + get_temperature(TEMP_LJ,&fval); + //if(fval>(-25)) + if(fval>(-20))//2016-07-03 + { + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>600)//5分钟未到达设置的温度 + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:wait lj temperature arrived -25 timeout %f,exit\n",gas_make_stat.step,fval); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + if((gas_make_stat.dly_cnt%16)==0) + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:leng jin temp is %f\n",gas_make_stat.step,fval); + break; + } + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:leng jin temp is %f\n",gas_make_stat.step,fval); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 20://开YV7,关YV6 + relay_set(RLY_YV6,OFF,0); + relay_set(RLY_YV7,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV7 ON,YV6 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + yv17_on_flg=0; + yv17_on_tick=0; + break; + case 21://等待3分钟 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>120)//到达1分钟? + { + if(gas_make_stat.dly_cnt==121) + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:1 minutes arrived\n",gas_make_stat.step); + //查PA1,大于常压就开YV17,等于常压就关闭YV17 + //VoltCnvToPresEx(PRES_PA1,&fval); + get_presure(PRES_GAS_PUMP,&fval); + switch(yv17_on_flg) + { + case 0: + if(fval>DELT_PRES) + { + relay_set(RLY_YV17,ON,1); + yv17_on_flg=1; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV17 ON,pres=%fMpa\n",gas_make_stat.step,fval); + } + break; + case 1: + yv17_on_flg=2; + break; + case 2: + yv17_on_flg=3; + break; + case 3: + relay_set(RLY_YV17,OFF,1); + yv17_on_flg=4; + yv17_on_tick=gas_make_stat.dly_cnt; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV17 OFF,pres=%fMpa\n",gas_make_stat.step,fval); + break; + case 4: + if(gas_make_stat.dly_cnt>=(yv17_on_tick+40)) + yv17_on_flg=5; + break; + case 5: + if(fval>DELT_PRES) + { + relay_set(RLY_YV17,ON,1); + yv17_on_flg=6; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV17 ON,pres=%fMpa\n",gas_make_stat.step,fval); + } + break; + case 6: + yv17_on_flg=7; + break; + case 7: + yv17_on_flg=8; + break; + case 8: + relay_set(RLY_YV17,OFF,1); + yv17_on_flg=9; + yv17_on_tick=gas_make_stat.dly_cnt; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV17 OFF,pres=%fMpa\n",gas_make_stat.step,fval); + break; + default: + break; + } + /* if(yv17_on_flg<2) + { + if(fval>DELT_PRES) + { + relay_set(RLY_YV17,ON,1); + if(pres_flg==0) + { + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV17 ON,pres=%fMpa\n",gas_make_stat.step,fval); + } + pres_flg=1; + yv17_on_flg++; + } + }*/ + /* + if(yv17_on_flg==0) + { + if(fval>DELT_PRES) + { + relay_set(RLY_YV17,ON,0); + if(pres_flg==0) + { + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV17 ON,pres=%fMpa\n",gas_make_stat.step,fval); + } + pres_flg=1; + } + else if(fabs(fval-DELT_PRES)<0.001) + { + relay_set(RLY_YV17,OFF,0); + yv17_on_flg=1; + if(pres_flg==1) + { + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV17 OFF,pres=%fMpa\n",gas_make_stat.step,fval); + } + pres_flg=0; + } + }*/ + //if((gas_make_stat.dly_cnt%8)==0) + // LOG_DEBUG(ACTION_DEBUG,"make_step=%d:Pres=%fMpa\n",gas_make_stat.step,fval); + if(gas_make_stat.dly_cnt>360)//3分钟到? + { + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 3 minutes completed\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + relay_set(RLY_YV17,OFF,0); + } + } + break; + case 22://等待冷井温度<-28 + get_temperature(TEMP_LJ,&fval); + //if(fval>(-28)) + if(fval>(-25))//2016-07-03 + { + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>600)//5分钟未到达设置的温度 + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:wait lj temperature arrived -28 timeout %f,exit\n",gas_make_stat.step,fval); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + if((gas_make_stat.dly_cnt%16)==0) + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:leng jin wendu is %f\n",gas_make_stat.step,fval); + break; + } + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:leng jin wen du is %f\n",gas_make_stat.step,fval); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 23://开YV19 + //relay_set(RLY_YV20,ON,0);//和YV19一起开,和YV18一起关 + relay_set(RLY_YV19,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV20 ON,YV19 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 24://延时18秒 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>36) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 18s completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 25://关YV19 + //relay_set(RLY_YV19,OFF,1); + //LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV19 OFF\n",gas_make_stat.step); + relay_set(RLY_YV7,OFF,0);//张帅提出要添加的 + relay_set(RLY_YV19,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV19 OFF,YV7 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 26://关冷井风扇和制冷,关采样单元风扇以及制冷输出,电柜顶上的风扇也关闭 + set_pid_ch(PID_LJ,PID_DIS,0); + relay_set(RLY_KA6,OFF,0);//冷井风扇 + //relay_set(RLY_KA7,OFF,0);//冷井电源 + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:KA6 OFF,KA7 OFF,LengJin Ctrl disable\n",gas_make_stat.step); + + if(my_para_data.mach_run_para.sample_cool_en==0) + { + set_pid_ch(PID_SAMPLE,PID_DIS,0); + relay_set(RLY_FAN,OFF,0); + relay_set(RLY_KA4,OFF,0);//采样单元风扇 + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:Sample room ctrl disable,KA3 OFF\n",gas_make_stat.step); + } + relay_set(RLY_KA3,OFF,1);//柜子风扇 + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:柜子风扇KA3 OFF\n",gas_make_stat.step); + //关伴热带,目前未定义tmb + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 27://延时3秒 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>6) + { + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 3s completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 28://检查色谱柱温度 + if(get_spz_stable(&fval)==0) + { + //printf("spz wendu delt=%f is stable\n",fval); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:spz wendu delt=%f is stable\n",gas_make_stat.step,fval); + get_temperature(TEMP_SPZ,&fval); + ana_result.spzTemp1=fval; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:spz wendu is %f\n",gas_make_stat.step,fval); + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + } + else + { + gas_make_stat.repeat_cnt=0; + gas_make_stat.dly_cnt++; + if((gas_make_stat.dly_cnt%8)==0) + { + get_temperature(TEMP_SPZ,&fval); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:spz wendu is %f\n",gas_make_stat.step,fval); + } + if(gas_make_stat.dly_cnt>600)//5分钟内未达到,退出采样 + { + get_temperature(TEMP_SPZ,&fval); + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:chromatographic temperature is not stable for 5 minutes %f,exit\n",gas_make_stat.step,fval); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + } + break; + case 29://启动采样 + get_temperature(TEMP_SAM,&fval); + ana_result.samTemp1=fval; + ana_result.result.temp=my_input_data.temp;//油温 + ana_result.result.Mst=my_input_data.water;//微水 + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:sample room temp is %f,sample_len=%d sample_intval=%dms\n",gas_make_stat.step,fval,my_para_data.mach_run_para.sample_len,my_para_data.mach_run_para.sample_rate); + if(query_sample_data(NULL,sizeof(SAMPLE_INPUT_TYPE))==0) + { + LOG_DEBUG(ACTION_DEBUG,"sample_len=%d sen_in=%f amp_in=%f\r\n",sample_data_length,3.3*my_sample_data.sen_in/4096,3.3*my_sample_data.amp_in/4096); + } + else if(query_sample_data(NULL,sizeof(SAMPLE_INPUT_TYPE))==0) + { + LOG_DEBUG(ACTION_DEBUG,"sample_len=%d sen_in=%f amp_in=%f\r\n",sample_data_length,3.3*my_sample_data.sen_in/4096,3.3*my_sample_data.amp_in/4096); + } + else if(query_sample_data(NULL,sizeof(SAMPLE_INPUT_TYPE))==0) + { + LOG_DEBUG(ACTION_DEBUG,"sample_len=%d sen_in=%f amp_in=%f\r\n",sample_data_length,3.3*my_sample_data.sen_in/4096,3.3*my_sample_data.amp_in/4096); + } + else + { + LOG_DEBUG(ERROR_DEBUG,"query sample data failed\n"); + } + sample_para.len=my_para_data.mach_run_para.sample_len; + sample_para.intval=my_para_data.mach_run_para.sample_rate; + sample_para.offs=my_para_data.mach_run_para.sample_offs; + sample_para.co2_pos=my_para_data.mach_run_para.co2_pos;//CO2切换位置 + sample_para.co2_len=CO2_SAMPLE_LEN;//CO2采样长度 + if(start_sample_data(0,&sample_para)==0) + { + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + start_time=time(NULL);//记录采样开始时刻 + co2_sample_state=0; // + } + else + { + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>8) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:start data sample failed,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:WARNING:start data sample failed,Try again\n",gas_make_stat.step); + } + break; + case 30: + if(my_para_data.mach_run_para.co2_pos) + { + switch(co2_sample_state) + { + case 0: + now=time(NULL); + //提前CO2_BACK_NUM个点切换co2检测阀 + if(now>=(((my_para_data.mach_run_para.co2_pos-CO2_BACK_NUM)*my_para_data.mach_run_para.sample_rate)/1000+start_time)) + { + //打开CO2阀门 + co2_sample_state=1; + start_time=now+CO2_SAMPLE_LEN*3+(((CO2_BACK_NUM)*my_para_data.mach_run_para.sample_rate)/1000); + relay_set(RLY_YV21,ON,1);// + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV21 ON for co2\n",gas_make_stat.step); + } + break; + case 1: + now=time(NULL); + if((now>start_time)) + { + //关闭CO2阀门 + co2_sample_state=2; + relay_set(RLY_YV21,OFF,1);// + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV21 OFF\n",gas_make_stat.step); + } + break; + default: + break; + } + } + my_sample_data.co2_len=0; + if(query_sample_data((unsigned char *)&sample_data_length,sizeof(SAMPLE_INPUT_TYPE))==0) + { + if(my_para_data.mach_run_para.co2_pos) + { + if(my_sample_data.co2_len>0) + { + //读CO2数据 + LOG_DEBUG(TRACE_DEBUG,"make_step=%d:co2_len=%d\n",gas_make_stat.step,my_sample_data.co2_len); + if(read_co2_data(2*my_sample_data.co2_len)==0) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:read co2 data ok\n",gas_make_stat.step); + if(save_co2_data(2*my_sample_data.co2_len)==0) + { + if(clear_co2_data()!=0) + { + if(clear_co2_data()!=0) + { + if(clear_co2_data()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:clear co2 data failed\n",gas_make_stat.step); + } + } + } + } + else + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:save co2 data failed\n",gas_make_stat.step); + } + } + else if(read_co2_data(2*my_sample_data.co2_len)==0) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:read co2 data ok\n",gas_make_stat.step); + if(save_co2_data(2*my_sample_data.co2_len)==0) + { + if(clear_co2_data()!=0) + { + if(clear_co2_data()!=0) + { + if(clear_co2_data()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:clear co2 data failed\n",gas_make_stat.step); + } + } + } + } + else + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:save co2 data failed\n",gas_make_stat.step); + } + } + else if(read_co2_data(2*my_sample_data.co2_len)==0) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:read co2 data ok\n",gas_make_stat.step); + if(save_co2_data(2*my_sample_data.co2_len)==0) + { + if(clear_co2_data()!=0) + { + if(clear_co2_data()!=0) + { + if(clear_co2_data()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:clear co2 data failed\n",gas_make_stat.step); + } + } + } + } + else + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:save co2 data failed\n",gas_make_stat.step); + } + } + else + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:read co2 data failed\n",gas_make_stat.step); + } + } + } + if(sample_data_length>0) + { + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:sample data length is %d\n",gas_make_stat.step,sample_data_length); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + } + else + { + gas_make_stat.dly_cnt++; + } + } + else + { + gas_make_stat.dly_cnt++; + } + + if(gas_make_stat.dly_cnt>20*60*2) //大于20分钟 + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:wait data sample complete timeout,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + break; + case 31://读取数据 + if(read_sample_data(2*my_para_data.mach_run_para.sample_len)==0) + { + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:read sample data complete\n",gas_make_stat.step); + if(save_sample_data(2*my_para_data.mach_run_para.sample_len)!=0) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:WARNING:save data to file failed\n",gas_make_stat.step); + } + else + { + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:save sample data success\n",gas_make_stat.step); + } + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + + if(my_para_data.mach_run_para.sample_cool_en!=0) + { + set_pid_ch(PID_SAMPLE,PID_DIS,0); + relay_set(RLY_FAN,OFF,0);//采样单元电源 + relay_set(RLY_KA4,OFF,1);//采样单元风扇 + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:disable sample room cool,KA5 OFF KA4 OFF\n",gas_make_stat.step); + } + } + else + { + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>4) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:read sample data failed,exit\n",gas_make_stat.step); + if(my_para_data.mach_run_para.sample_cool_en!=0) + { + set_pid_ch(PID_SAMPLE,PID_DIS,0); + relay_set(RLY_FAN,OFF,0);//采样单元电源 + relay_set(RLY_KA4,OFF,1);//采样单元风扇 + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:disable sample room cool,KA4 OFF KA5 OFF\n",gas_make_stat.step); + } + stop_gas_make(gas_make_stat.step); + return gas_make_stat.step; + } + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:WARNING:read sample data failed,Try again\n",gas_make_stat.step); + } + break; + case 32://完成采样 + if(clear_sample_data()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:WARNING:clear sample data failed\n",gas_make_stat.step); + if(clear_sample_data()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:WARNING:clear sample data failed\n",gas_make_stat.step); + if(clear_sample_data()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:WARNING:clear sample data failed\n",gas_make_stat.step); + } + } + } + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:All action have completed\n",gas_make_stat.step); + get_temperature(TEMP_SPZ,&fval); + ana_result.spzTemp2=fval; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:色谱柱温度=%f度\n",gas_make_stat.step,fval); + get_temperature(TEMP_SAM,&fval); + ana_result.samTemp2=fval; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:采样室温度=%f度\n",gas_make_stat.step,fval); + get_presure(PRES_PA1,&fval); + ana_result.pres=fval; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:载气压力=%fMpa\n",gas_make_stat.step,fval); + relay_dly_close_set(RLY_YV18,1*60*2);//延时10分钟关吹扫阀 + //relay_dly_close_set(RLY_YV20,10*60*2);//延时10分钟关YV20 + relay_dly_close_set(RLY_SENSOR,1*60*2);//延时10分钟关传感器加热 + gas_make_stat.dly_cnt=0; + if(io_get(STA_I8)==ON) + { + gas_make_stat.step=43; + } + else + { + gas_make_stat.step++; + } + break; +//此处开始新添加的 + case 33: + if(gas_make_stat.dly_cnt==0) + { + relay_set(RLY_YV5,OFF,0); + relay_set(RLY_YV4,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV4 ON,YV5 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt++; + } + else + { + //等待I5到位 + if(gas_make_stat.dly_cnt>I5_WAIT_CNT) + { + if(io_get(STA_I5)==ON) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:I5 have arrived in right position\n",gas_make_stat.step); + gas_make_stat.step++; + break; + } + else + { + if(gas_make_stat.dly_cnt>I5_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:wait I5 arrived ON timeout,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step=0; + return gas_make_stat.step; + } + } + } + gas_make_stat.dly_cnt++; + } + break; + case 34: + relay_set(RLY_YV11,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV11 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 35: + relay_set(RLY_YV12,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV12 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 36://等待2分钟 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>(180*2)) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 1min completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 37: + relay_set(RLY_YV12,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV12 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 38://等待5秒 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>GAS_ADMISSION_TIME) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:delay 5s completed\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 39://开YV5,关YV4,等待到位 + if(gas_make_stat.dly_cnt==0) + { + //relay_set(RLY_YV13,ON,0); + //relay_set(RLY_YV5,ON,0); + relay_set(RLY_YV4,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV4 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt++; + } + else + { + //等待I4到位 + if(gas_make_stat.dly_cnt>I4_WAIT_CNT) + { + if(io_get(STA_I4)==ON) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:I4 have arrived in right position\n",gas_make_stat.step); + gas_make_stat.step++; + break; + } + else + { + if(gas_make_stat.dly_cnt>32) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:wait I4 arrived ON timeout,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step=0; + return gas_make_stat.step; + } + } + } + gas_make_stat.dly_cnt++; + } + break; + case 40://关YV11 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>32) + { + if(io_get(STA_I8)==ON) + { + relay_set(RLY_YV11,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV11 OFF\n",gas_make_stat.step); + } + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + //检测I8,有信号就不用开YV5,无信号就开YV5,等待3秒,再检测I8,有的话关YV11,YV5 + } + break; +//此处开始新添加的结束 + case 41: + if(io_get(STA_I8)==OFF) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:I8 is not in right position,YV5 ON\n",gas_make_stat.step); + relay_set(RLY_YV5,ON,1); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + } + else + { + gas_make_stat.dly_cnt=0; + gas_make_stat.step+=2; + } + break; + case 42: + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>=8) + { + if(io_get(STA_I8)==OFF) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:I8 is not in right position,exit\n",gas_make_stat.step); + } + relay_set(RLY_YV11,OFF,1); + usleep(1000000); + relay_set(RLY_YV5,OFF,1); + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:YV11 OFF,YV5 OFF\n",gas_make_stat.step); + gas_make_stat.step++; + } + break; + case 43://延时2分钟 + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>1*60*2) + { + relay_set(RLY_SENSOR,OFF,0);// + relay_set(RLY_YV18,OFF,0);// + //relay_set(RLY_YV20,OFF,1);// + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV18 OFF,YV20 OFF\n",gas_make_stat.step); + curr_state=MODE_IDLE; + gas_make_stat.step=0;//2015-08-17 22:06添加 + //memset(&my_action_state,0,sizeof(&my_action_state)); + } + break; + //I8,I9故障处理 + //y4 on,等到位,y11 onf,1分钟,y4 off,等油缸到位,再检测i8,y5 on 3s,再检测I8,关y11,关yv5 + case 44: + relay_set(RLY_YV4,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV4 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + break; + case 45: + if(io_get(STA_I5)==ON) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:I5 have arrived in right position\n",gas_make_stat.step); + gas_make_stat.step++; + relay_set(RLY_YV11,ON,0); + relay_set(RLY_YV12,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV11 ON\n",gas_make_stat.step); + break; + } + else + { + if(gas_make_stat.dly_cnt>I5_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:wait I5 arrived ON timeout,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step=0; + return gas_make_stat.step; + } + gas_make_stat.dly_cnt++; + } + break; + case 46: + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>(180*2)) + { + relay_set(RLY_YV12,OFF,1); + usleep(1000000); + relay_set(RLY_YV4,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV4 OFF\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + } + break; + case 47: + if(io_get(STA_I4)==ON) + { + gas_make_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:I4 have arrived in right position\n",gas_make_stat.step); + gas_make_stat.step++; + break; + } + else + { + if(gas_make_stat.dly_cnt>I4_WAIT_MAX) + { + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:wait I4 arrived ON timeout,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step=0; + return gas_make_stat.step; + } + gas_make_stat.dly_cnt++; + } + break; + case 48: + //if(io_get(STA_I8)==ON) + if((io_get(STA_I8)==ON)&&(io_get(STA_I9)==OFF)) + { + relay_set(RLY_YV11,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV11 OFF\n",gas_make_stat.step); + gas_make_stat.repeat_cnt=0; + gas_make_stat.dly_cnt=0; + gas_make_stat.step=1; + //开始动作 + } + else + { + relay_set(RLY_YV5,ON,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV5 ON\n",gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step++; + } + break; + case 49: + gas_make_stat.dly_cnt++; + if(gas_make_stat.dly_cnt>8) + { + relay_set(RLY_YV11,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"make_step=%d:YV11 OFF,YV5 OFF\n",gas_make_stat.step); + usleep(1000000); + relay_set(RLY_YV5,OFF,1); + //if(io_get(STA_I8)==ON) + if((io_get(STA_I8)==ON)&&(io_get(STA_I9)==OFF)) + { + gas_make_stat.repeat_cnt=0; + gas_make_stat.dly_cnt=0; + gas_make_stat.step=1; + //开始动作 + } + else + { + if(gas_make_stat.repeat_cnt<2) + { + gas_make_stat.repeat_cnt++; + gas_make_stat.dly_cnt=0; + gas_make_stat.step=44; + } + else + { + //结束 + LOG_DEBUG(ERROR_DEBUG,"make_step=%d:I8 is not in right position,exit\n",gas_make_stat.step); + stop_gas_make(gas_make_stat.step); + gas_make_stat.dly_cnt=0; + gas_make_stat.step=0; + gas_make_stat.repeat_cnt=0; + return gas_make_stat.step; + } + } + } + break; + case 50://提前15分钟开吹扫阀 + if(time(NULL)>=(time_record.sample_start_time+30*60)) + { + //提前15分钟开吹扫阀,开启 + relay_set(RLY_YV18,ON,1); + LOG_DEBUG(TRACE_DEBUG,"Preaction:YV18 ON\n"); + gas_make_stat.dly_cnt=0; + gas_make_stat.repeat_cnt=0; + gas_make_stat.step++; + }//passed + break; + case 51://启动动作流程, + if(time(NULL)>=(time_record.sample_start_time+45*60)) + { + memset(&gas_clean_stat,0,sizeof(gas_clean_stat)); + memset(&gas_make_stat,0,sizeof(gas_make_stat)); + gas_clean_stat.step=1;//设置清洗步奏 + if((io_get(STA_I8)==ON)&&(io_get(STA_I9)==OFF)) + { + LOG_DEBUG(ACTION_DEBUG,"enter normal make gas\n"); + gas_make_stat.step=1;//设置制气步奏 + } + else + { + LOG_DEBUG(ACTION_DEBUG,"enter fault process for make gas\n"); + gas_make_stat.step=44; + } + relay_set(RLY_YV18,ON,0);//开吹扫阀 + relay_set(RLY_KA3,OFF,0);//关柜子风扇 + time_record.heat_start_time=time(NULL)+60;//一分钟后开传感器加热 + relay_dly_open_set(RLY_SENSOR,1*60);//1分钟后开启 + } + break; + default: + break; + } + return 0; +} + +int sensor_test(unsigned int num) +{ + unsigned int sample_data_length=0; + SAMPLE_PARA_TYPE tmp_sample_para; + relay_set(RLY_YV18,ON,1); + //while(start_sample_data(0,num,220,my_para_data.mach_run_para.sample_offs)!=0) + // sleep(3); + tmp_sample_para.len=num; + tmp_sample_para.intval=my_para_data.mach_run_para.sample_rate; + tmp_sample_para.offs=my_para_data.mach_run_para.sample_offs; + tmp_sample_para.co2_pos=my_para_data.mach_run_para.co2_pos;//CO2切换位置 + tmp_sample_para.co2_len=CO2_SAMPLE_LEN;//CO2采样长度 +if(start_sample_data(0,&tmp_sample_para)==0) + { + sleep((num*220+1000)/1000+4); + if(query_sample_data((unsigned char *)&sample_data_length,sizeof(SAMPLE_INPUT_TYPE))==0) + { + printf("sample_len=%d sen_in=%f amp_in=%f\r\n",sample_data_length,3.3*my_sample_data.sen_in/4096,3.3*my_sample_data.amp_in/4096); + printf("co2_len=%d co2_ppm=%d\r\n",my_sample_data.co2_len,my_sample_data.co2_ppm); + if(read_sample_data(2*num)==0) + { + if(save_sample_data(2*num)==0) + { + if(clear_sample_data()!=0) + { + printf("clear data failed\r\n"); + } + } + else + { + printf("save data failed\r\n"); + } + } + else + { + printf("read data failed\r\n"); + } + } + else + { + printf("query data failed\r\n"); + } + } + else + { + printf("start sample failed\r\n"); + } + relay_set(RLY_YV18,OFF,1); + return 0; +} +/* +开YV4,等待到位 +开YV11, +开YV12 +等待5秒 +关YV12 +等待4秒 +关YV4,开关到位后关YV11 +*/ +int demarcate_process(void) +{ + float fval; + unsigned int sample_data_length=0; + switch(demarcate_stat.step) + { + case 1: + //if(start_sample_heat(0,1)==0)//开传感器加热 + //{ + relay_set(RLY_SENSOR,ON,0);// + relay_set(RLY_YV18,ON,0);// + //relay_set(RLY_YV20,ON,1);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:Sensor heat started,YV18 ON,YV20 ON,start delay 15 minutes\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + //} + /*else + { + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>4) + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:start sensor heating failed,exit\n",demarcate_stat.step); + curr_state=MODE_IDLE; + return demarcate_stat.step; + } + }*/ + break; + case 2://延时15分钟 + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>(15*60*2)) + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:delay 15 minutes completed\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + break; + case 3: + relay_set(RLY_KA6,OFF,0);//关冷井风扇 + //relay_set(RLY_KA7,OFF,0);//冷井电源 + relay_set(RLY_KA4,OFF,0);//关采样单元风扇 + relay_set(RLY_FAN,OFF,0);//采样单元电源 + relay_set(RLY_KA3,OFF,0);//关柜子风扇 + set_pid_ch(PID_SAMPLE,PID_DIS,0);//关采样室温度控制电源 + set_pid_ch(PID_LJ,PID_DIS,1);//关冷井温度控制电源 + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:KA6 KA7 OFF,KA4 KA5 OFF,KA3 OFF,Sample room cold disable,lj cold disable\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + break; + case 4://开YV14,延时3秒,关YV14 + if(demarcate_stat.dly_cnt==0) + { + relay_set(RLY_YV14,ON,1);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV14 ON\n",demarcate_stat.step); + } + else + { + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>6) + { + relay_set(RLY_YV14,OFF,1);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV14 OFF\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + } + break; + case 5://开YV10 + relay_set(RLY_YV10,ON,0);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV10 ON\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + break; + case 6://延时6秒 + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>12) + { + demarcate_stat.dly_cnt=0; + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:delay 6s completed\n",demarcate_stat.step); + demarcate_stat.step++; + } + break; + case 7://关YV10 + relay_set(RLY_YV10,OFF,0);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV10 OFF\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + break; + case 8://检测压力,DLY 3 SECOND + demarcate_stat.dly_cnt++; + //VoltCnvToPresEx(PRES_PA1,&fval); + get_presure(PRES_GAS_PUMP,&fval); + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:Pres=%fMpa\n",demarcate_stat.step,fval); + if(fval>DELT_PRES) + { + relay_set(RLY_YV17,ON,1); + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV17 ON\n",demarcate_stat.step); + } + else if(fabs(fval-DELT_PRES)<0.001) + { + relay_set(RLY_YV17,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV17 OFF\n",demarcate_stat.step); + } + if(demarcate_stat.dly_cnt>6) + { + relay_set(RLY_YV17,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:delay 3s completed,YV17 OFF\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + break; + case 9://重复4-8两次 + demarcate_stat.repeat_cnt++; + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:repeat %dst completed\n",demarcate_stat.step,demarcate_stat.repeat_cnt); + if(demarcate_stat.repeat_cnt>=2) + { + demarcate_stat.dly_cnt=0; + demarcate_stat.repeat_cnt=0; + demarcate_stat.step++; + } + else + { + demarcate_stat.dly_cnt=0; + demarcate_stat.repeat_cnt=0; + demarcate_stat.step=4; + } + break; + case 10://延时5秒 + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>10) + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:delay 5s completed\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + break; + case 11://开YV19 + relay_set(RLY_YV19,ON,1); + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV19 ON\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + break; + case 12://延时18秒 + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>36) + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:delay 18s completed\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + break; + case 13://关YV19 + relay_set(RLY_YV19,OFF,1); + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV19 OFF\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + break; + case 14://启动采样 + sample_para.len=my_para_data.mach_run_para.sample_len; + sample_para.intval=my_para_data.mach_run_para.sample_rate; + sample_para.offs=my_para_data.mach_run_para.sample_offs; + sample_para.co2_pos=my_para_data.mach_run_para.co2_pos; + sample_para.co2_len=CO2_SAMPLE_LEN; + if(start_sample_data(0,&sample_para)==0) + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:start sample sucessed\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + else + { + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>4) + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:start data sample failed,exit\n",demarcate_stat.step); + relay_set(RLY_SENSOR,OFF,0); + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:stop sensor heat OK\n",demarcate_stat.step); + //} + relay_set(RLY_YV18,OFF,0);// + //relay_set(RLY_YV20,OFF,1);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV18 OFF,YV20 OFF\n",demarcate_stat.step); + curr_state=MODE_IDLE; + //memset(&my_action_state,0,sizeof(&my_action_state)); + return demarcate_stat.step; + } + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:WARNING:start data sample failed,Try again\n",demarcate_stat.step); + } + break; + case 15://查是否有数据 + if(query_sample_data((unsigned char *)&sample_data_length,sizeof(SAMPLE_INPUT_TYPE))==0) + { + if(sample_data_length>0) + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:sample data length is %d\n",demarcate_stat.step,sample_data_length); + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + else + { + demarcate_stat.dly_cnt++; + } + } + else + { + demarcate_stat.dly_cnt++; + } + + if(demarcate_stat.dly_cnt>20*60*2) //大于20分钟 + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:wait data sample complete timeout,exit\n",demarcate_stat.step); + //关传感器加热,YV18,YV20 + /*if(start_sample_heat(0,0)!=0)//停止感器加热 + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:stop sensor heat failed\n",demarcate_stat.step); + } + else + {*/ + relay_set(RLY_SENSOR,OFF,0); + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:stop sensor heat OK\n",demarcate_stat.step); + // } + relay_set(RLY_YV18,OFF,0);// + //relay_set(RLY_YV20,OFF,1);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:YV18 OFF,YV20 OFF\n",demarcate_stat.step); + curr_state=MODE_IDLE; + //memset(&my_action_state,0,sizeof(&my_action_state)); + return demarcate_stat.step; + } + break; + case 16://读数据 + if(read_sample_data(4000)==0) + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:read sample data complete\n",demarcate_stat.step); + if(save_sample_data(8000)!=0) + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:WARNING:save data to file failed\n",demarcate_stat.step); + } + else + { + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:save sample data success\n",demarcate_stat.step); + } + demarcate_stat.dly_cnt=0; + demarcate_stat.step++; + } + else + { + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>4) + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:read sample data failed,exit\n",demarcate_stat.step); + //关传感器加热,YV18,YV20 + //stop_gas_make(demarcate_stat.step); + return demarcate_stat.step; + } + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:WARNING:read sample data failed,Try again\n",demarcate_stat.step); + } + break; + case 17://清除数据 + if(clear_sample_data()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:WARNING:clear sample data failed\n",demarcate_stat.step); + if(clear_sample_data()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:WARNING:clear sample data failed\n",demarcate_stat.step); + if(clear_sample_data()!=0) + { + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:WARNING:clear sample data failed\n",demarcate_stat.step); + } + } + } + demarcate_stat.dly_cnt=0; + demarcate_stat.repeat_cnt=0; + demarcate_stat.step++; + break; + case 18://收尾 + //if(start_sample_heat(0,0)==0)//关传感器加热 + // { + relay_set(RLY_SENSOR,OFF,0); + relay_set(RLY_YV18,OFF,0);// + //relay_set(RLY_YV20,OFF,1);// + LOG_DEBUG(ACTION_DEBUG,"demarcate_step=%d:Sensor heat stoped,YV18 OFF,YV20 OFF,All action have completed\n",demarcate_stat.step); + demarcate_stat.dly_cnt=0; + demarcate_stat.step=0; + curr_state=MODE_IDLE; + /* } + else + { + demarcate_stat.dly_cnt++; + if(demarcate_stat.dly_cnt>8) + { + relay_set(RLY_YV18,OFF,0);// + relay_set(RLY_YV20,OFF,1);// + curr_state=MODE_IDLE; + LOG_DEBUG(ERROR_DEBUG,"demarcate_step=%d:stop sensor heating failed,YV18 OFF,YV20 OFF\n",demarcate_stat.step); + return demarcate_stat.step; + } + }*/ + break; + default: + break; + } + return 0; +} + +void idle_process(void) +{ + +} + +int main_timeout_process(void) +{ + switch(curr_state) + { + case SIX_SAMPLE: + gas_make(); + break; + case DEMARCATE: + demarcate_process(); + break; + case REMOVE_GAS://脱气 + remove_gas_process(); + break; + case GAS_FAULT_PROCESS://脱气故障处理 + gas_flt_process(); + break; + case PUMP_OIL_PROCESS: + break; + default: + idle_process(); + break; + } + return 0; +} + + +void gas_pump_process(void) +{ + static unsigned int run_tick=0; + static unsigned int less_tick=0; + static unsigned int larg_tick=0; + static unsigned int on_time_tick=0; + static float start_pres; + unsigned char curr_state; + float curr_pres,pre_pres; + run_tick++; + if((run_tick&1)==0) + { + get_presure(PRES_PA1,&curr_pres);//获取载气压力 + relay_get(RLY_PUMP,&curr_state);//获取当前状态 + if(curr_state==ON)//当前处于开启状态 + { + on_time_tick++; + if(on_time_tick==2) + { + start_pres=curr_pres; + } + if(on_time_tick==16) + { + if(curr_pres<(start_pres+0.1)) + { + relay_set(RLY_PUMP,OFF,1); + on_time_tick=0; + LOG_DEBUG(ERROR_DEBUG,"gas pump working bad,pres_pres=%fMpa,curr_pres=%fMpa\r\n",start_pres,curr_pres); + my_para_data.mach_run_para.auto_gas_en=0; + //载气异常告警 + ysp_glb_data.ActCyGasSta.v.stVal=1; + ysp_glb_data.ActCyGasSta.q=0; + ysp_glb_data.ActCyGasSta.t.secs=time(NULL); + return; + } + else + { + ysp_glb_data.ActCyGasSta.v.stVal=0; + ysp_glb_data.ActCyGasSta.q=0; + ysp_glb_data.ActCyGasSta.t.secs=time(NULL); + } + } + if(on_time_tick>20)//计时超过20秒就关闭 + { + relay_set(RLY_PUMP,OFF,1); + LOG_DEBUG(ERROR_DEBUG,"Stop gas pump for timeout,pres=%fMpa\r\n",curr_pres); + } + } + else + { + on_time_tick=0; + } + + if(curr_pres2) + { + if(curr_state==OFF) + { + if(comunication_flg) + relay_set(RLY_PUMP,ON,1); + LOG_DEBUG(TRACE_DEBUG,"Start gas pump,pres=%fMpa\r\n",curr_pres); + } + //启动气缸 + } + larg_tick=0; + } + else + { + less_tick=0; + } + + if(curr_pres>STOP_PRES)//气压高就停止气缸 + { + //停止气缸 + /*larg_tick++; + if(larg_tick>2) + { + //停止气缸 + }*/ + if(curr_state==ON) + { + relay_set(RLY_PUMP,OFF,1); + LOG_DEBUG(TRACE_DEBUG,"Stop gas pump,pres=%fMpa\r\n",curr_pres); + } + less_tick=0; + } + else + { + larg_tick=0; + } + pre_pres=curr_pres; + } +} + +void save_tune_data(float *ptr,int size) +{ + FILE *fp; + int i; + fp=fopen("tune.csv","w"); + if(fp==NULL) + { + LOG_DEBUG(ERROR_DEBUG,"Creat tune.csv failed\r\n"); + return -1; + } + for(i=0;inow)&&(((HeatAutoTuner.start_time)-now))>3600) + if((now-last_time)>=4) + { + get_temperature(0,&fval); + HeatTuneRecord.tune_input=fval; + tune_data[tune_index++]=fval; + if(PID_ATune_Runtime(&HeatAutoTuner,now)==1) + { + HeatTuneRecord.auto_turn=0; + LOG_DEBUG(TRACE_DEBUG,"auto tune complete\n"); + LOG_DEBUG(TRACE_DEBUG,"Ku=%f Pu=%f absMax=%f absMin=%f\n",HeatAutoTuner.Ku,HeatAutoTuner.Pu,HeatAutoTuner.absMax,HeatAutoTuner.absMin); + LOG_DEBUG(TRACE_DEBUG,"peak1=%d peak2=%d peakCount=%d\n",HeatAutoTuner.peak1,HeatAutoTuner.peak2,HeatAutoTuner.peakCount); + LOG_DEBUG(TRACE_DEBUG,"noiseBand=%f oStep=%d nLookBack=%d sampleTime=%d\n",HeatAutoTuner.noiseBand,HeatAutoTuner.oStep,HeatAutoTuner.nLookBack,HeatAutoTuner.sampleTime); + LOG_DEBUG(TRACE_DEBUG,"pk_1=%f pk_2=%f pk_3=%f\n",HeatAutoTuner.peaks[HeatAutoTuner.peakCount-1],HeatAutoTuner.peaks[HeatAutoTuner.peakCount-2],HeatAutoTuner.peaks[HeatAutoTuner.peakCount-3]); + PID_ATune_GetKp(&HeatAutoTuner,&fval); + my_para_data.mach_run_para.pid_type_def[0].Kp=fval; + ini_putf("MACH","kp1",my_para_data.mach_run_para.pid_type_def[0].Kp,ysp_cfg_file); + PID_ATune_GetKi(&HeatAutoTuner,&fval); + my_para_data.mach_run_para.pid_type_def[0].Ki=fval; + ini_putf("MACH","ki1",my_para_data.mach_run_para.pid_type_def[0].Ki,ysp_cfg_file); + PID_ATune_GetKd(&HeatAutoTuner,&fval); + my_para_data.mach_run_para.pid_type_def[0].Kd=fval; + ini_putf("MACH","kd1",my_para_data.mach_run_para.pid_type_def[0].Kd,ysp_cfg_file); + save_tune_data(tune_data,tune_index); + + LOG_DEBUG(TRACE_DEBUG,"kp=%f ki=%f kd=%f\n",my_para_data.mach_run_para.pid_type_def[0].Kp,my_para_data.mach_run_para.pid_type_def[0].Ki,my_para_data.mach_run_para.pid_type_def[0].Kd); + } + else + { + set_man_out(0,HeatTuneRecord.tune_output); + } + last_time=now; + //printf("auto tune running\r\n"); + } + } + else + { + tune_index=0; + } +} + +int get_rand(float *percent) +{ +int ret; +struct timeval tpstart; +gettimeofday(&tpstart,NULL); +srand(tpstart.tv_usec); +//1+(int) (100.0*rand()/(RAND_MAX+1.0));//1-100 +ret=(rand()%8)+1; +if((ret%2)==0) + ret=-ret; +if(percent!=NULL) + *percent=(float)(100+ret)/100;//产生一个分数 +return ret; +} + + +void old_log_process(time_t now) +{ + static time_t last_remove_time=0; + if((last_remove_time+604800)=3) + { + if(strcmp(argv[1],"-d")==0) + { + if(stat(argv[2],&st)==0) + { + printf ("change work dir to %s\n",argv[2]); + chdir(argv[2]); + } + else + { + printf("change work dir to default work dir\n"); + chdir("/usr/shxy/ysp/app"); + } + } + } + + printf("%s\n",APP_VERSION); + + signal(SIGINT,ctrlCfun); + + comunication_flg=0; + my_input_data.com_flg=1; + + if((sample_fd=SerialOpen(SAMPLE_SERIAL_DEV,SAMPLE_SERIAL_SPEED))==-1) + { + printf("open sample serial device failed\n"); + exit(1); + } + + mutex_init(); + + my_log_init(); + + if((main_mq=create_mq(MAIN_MESSAGE_MQ,MAIN_MAX_MESSAGE,MAIN_MESSAGE_SIZE))<0) + { + printf("create main message queue failed\n"); + exit(2); + } + + LoadAllPara(&my_para_data); + + if(ctrl_init()!=0) + { + printf("create ctrl thread failed\n"); + exit(3); + } + + sleep(8); + + my_temp=my_para_data.mach_run_para.temperature[TEMP_SPZ]; + set_pid_temp(TEMP_SPZ,&my_temp,0);//设置色谱柱温度 + if(my_para_data.mach_run_para.pid_en[PID_SPZ]) + set_pid_ch(PID_SPZ,PID_EN,0);//开启色谱柱温度控制 + else + set_pid_ch(PID_SPZ,PID_DIS,0);//关闭色谱柱 + + my_temp=my_para_data.mach_run_para.temperature[TEMP_LJ]; + set_pid_temp(TEMP_LJ,&my_temp,0);//设置冷井温度 + + //printf(""); + //my_temp=my_para_data.mach_run_para.temperature[TEMP_SAM]; + //set_pid_temp(TEMP_SAM,&my_temp,0);//设置采样室温度 + //set_pid_ch(PID_SAMPLE,PID_EN,0);//开启采样室温度控制 + //relay_set(RLY_KA4,ON,0);//开采样单元风扇 + + //my_temp=my_para_data.mach_run_para.temperature[TEMP_LJ]; + //set_pid_temp(TEMP_LJ,&my_temp,0);//设置色谱柱温度 + //set_pid_ch(PID_LJ,PID_EN,0);//开启色谱柱温度控制 + //relay_set(RLY_KA6,ON,1);//开冷井风扇 + + + start_time=my_para_data.mach_run_para.start_hour*3600+my_para_data.mach_run_para.start_minute*60; + now=time(NULL);//获取当前时间 + today_sec=now%86400; + if(today_sec>start_time) + {//当天的时间已经大于设定的起始时间 + next_sample_time=(my_para_data.mach_run_para.start_interval*3600)-((today_sec-start_time)%(my_para_data.mach_run_para.start_interval*3600)); + next_sample_time+=(now-45*60); + } + else + { //当天的时间小于设定的起始时间 + next_sample_time=now-today_sec+start_time-45*60; + } + LOG_DEBUG(TRACE_DEBUG,"system reset:next_sample_time is %s\n",ctime(&next_sample_time)); + last_sample_time=next_sample_time-(my_para_data.mach_run_para.start_interval*3600); + last_sample_time_ex=last_sample_time; + time_record.dummy_sample_time=0; + + /*time_record.room_start_time=next_sample_time-45*60; + time_record.yv18_start_time=next_sample_time-15*60; + time_record.heat_start_time=next_sample_time+1*60; */ + analysis_init(); + //sleep(4); + iec61850_rx_init(); + //send_analysis_req("/COMTRADE/20150907_235546.bin",strlen("/COMTRADE/20150907_235546.bin")); + //sensor_test(1000); + //return 1; + goahead_init(); + printf("version is v3.3:2015-11-24 10:57\n"); + smp_len=0; + if(query_sample_data((unsigned char *)&smp_len,sizeof(SAMPLE_INPUT_TYPE))!=0) + { + sleep(1); + if(query_sample_data((unsigned char *)&smp_len,sizeof(SAMPLE_INPUT_TYPE))!=0) + { + sleep(1); + if(query_sample_data((unsigned char *)&smp_len,sizeof(SAMPLE_INPUT_TYPE))!=0) + { + LOG_DEBUG(TRACE_DEBUG,"query_sample_data failed:sample board is bad\n"); + } + } + } + /* printf("co2_len=%d\n",my_sample_data.co2_len); + if(read_co2_data(2*my_sample_data.co2_len)==0) + { + printf("read co2 ok\n"); + if(save_co2_data(2*my_sample_data.co2_len)==0) + { + printf("save co2 ok\n"); + } + else + { + printf("save co2 failed\n"); + } + } + else + { + printf("read co2 failed\n"); + }*/ + + if(smp_len>0) + { + if(read_sample_data(2*my_para_data.mach_run_para.sample_len)==0) + { + LOG_DEBUG(ACTION_DEBUG,"read sample data complete\n"); + if(save_sample_data(2*my_para_data.mach_run_para.sample_len)!=0) + { + LOG_DEBUG(ERROR_DEBUG,"WARNING:save data to file failed\n"); + } + else + { + LOG_DEBUG(ACTION_DEBUG,"save sample data success\n"); + } + if(clear_sample_data()!=0) + { + if(clear_sample_data()!=0) + if(clear_sample_data()!=0) + LOG_DEBUG(ERROR_DEBUG,"clr sample data failed\n"); + } + } + else + { + LOG_DEBUG(ERROR_DEBUG,"WARNING:read sample data failed,Try again\n"); + if(read_sample_data(2*my_para_data.mach_run_para.sample_len)==0) + { + LOG_DEBUG(ACTION_DEBUG,"read sample data complete\n"); + if(save_sample_data(2*my_para_data.mach_run_para.sample_len)!=0) + { + LOG_DEBUG(ERROR_DEBUG,"WARNING:save data to file failed\n"); + } + else + { + LOG_DEBUG(ACTION_DEBUG,"save sample data success\n"); + } + if(clear_sample_data()!=0) + { + if(clear_sample_data()!=0) + if(clear_sample_data()!=0) + LOG_DEBUG(ERROR_DEBUG,"clr sample data failed\n"); + } + } + else + { + LOG_DEBUG(ERROR_DEBUG,"EEROR:read sample data failed\n"); + } + } + } + + //sensor_test(256); + while(doIt) + { + if(recv_mq_wait(main_mq,(void *)main_rx_buf,sizeof(main_rx_buf),500000)>0) + { + memcpy(&my_action_msg,main_rx_buf,sizeof(my_action_msg)); + LOG_DEBUG(TRACE_DEBUG,"receivd msg %d\n",my_action_msg.cmd); + main_message_process(&my_action_msg); + } + else + { + main_timeout_process(); + } + + now=time(NULL); + + today_sec=now%86400;//计算当天的秒数 + + start_time=my_para_data.mach_run_para.start_hour*3600+my_para_data.mach_run_para.start_minute*60; + if(curr_state==MODE_IDLE) + { + //当前时间处于采样完1小时后和下次采样前50分钟 + if((now>=(last_sample_time+6290))&&(now<(next_sample_time-3000))) + { + if((today_sec%3600)<3)//判断是否整点 + { + /*if(my_para_data.mach_run_para.start_interval>2) + { + //整点开始,YV20工作5分钟,停止3分钟 + } */ + if(my_para_data.mach_run_para.start_interval>2) + { + //每隔两小时,整点开始,YV18工作,延时20分钟开传感器加热,45分钟延时到,全停 + //if(time_record.yv18_poll_time=now) + if(relay_get(RLY_YV18,NULL)!=ON) + { + LOG_DEBUG(TRACE_DEBUG,"YV18 ON,Start sensor heating\n"); + relay_set(RLY_YV18,ON,0); + relay_set(RLY_SENSOR,ON,1); + relay_dly_close_set(RLY_YV18,20*60);//开20分钟 + relay_dly_close_set(RLY_SENSOR,20*60);//开20分钟 + time_record.yv18_poll_time=now; + } + } + } + else + { + //if(now>) + } + } + //室外温度-室内温度>3度,开柜子风扇35分钟,停5分钟,直到室外温度-室内温度<=3度 + if((cabinet_count)%120==0) //1分钟检测一次 + { + get_temperature(TEMP_OUTSIDE,&my_temp);//获取室外温度 + get_temperature(TEMP_ENV,&env_temp);//获取环境温度(柜内温度) + if((env_temp-my_temp)>8) + { + //开柜子风扇KA3 3分钟,停5分钟, + if((KA3_Tick%10)==0) + { + relay_set(RLY_KA3,ON,0); + } + else if((KA3_Tick%10)==1) + { + relay_set(RLY_KA3,OFF,0); + } + KA3_Tick++; + } + else + { + relay_set(RLY_KA3,OFF,0); + KA3_Tick=0; + } + } + cabinet_count++; + } + + if(now>=next_sample_time) + { + time_record.sample_start_time=now;//记录采样开始时刻 + //启动采样 + LoadAllPara(&my_para_data); + LOG_DEBUG(TRACE_DEBUG,"reload all parameter\n"); + //run_mod=0表示正常模式,并且要upload_time(实际采样间隔)大于两倍的采样间隔才生效 + if((my_para_data.mach_run_para.run_mode==0)&&(my_para_data.mach_run_para.upload_time>=(2*my_para_data.mach_run_para.start_interval))) + { + //正常模式 + //计算采样间隔次数 + sample_cnt=(my_para_data.mach_run_para.upload_time/my_para_data.mach_run_para.start_interval); + if((upload_tick%sample_cnt)==0) + { + //启动硬采样 + if(SendActionReq(SIX_SAMPLE,0)!=0) + LOG_DEBUG(TRACE_DEBUG,"send start six sample request failed\n"); + else + LOG_DEBUG(TRACE_DEBUG,"send start six sample request ok\n"); + } + else + { + //启动软采样,上传数据 + time_record.dummy_sample_time=now+75*60+get_rand(&percent); + } + upload_tick++; + } + else + { + //调试模式 + if(SendActionReq(SIX_SAMPLE,0)!=0) + LOG_DEBUG(TRACE_DEBUG,"send start six sample request failed\n"); + else + LOG_DEBUG(TRACE_DEBUG,"send start six sample request ok\n"); + } + + last_sample_time=now; //记录最后一次采样开始时刻 + last_sample_time_ex=now;//记录最后一次采样开始时刻 + + if(start_time!=(my_para_data.mach_run_para.start_hour*3600+my_para_data.mach_run_para.start_minute*60)) + { + start_time=(my_para_data.mach_run_para.start_hour*3600+my_para_data.mach_run_para.start_minute*60); + today_sec=now%86400; + if(today_sec>start_time) + { //当天的时间大于采样开始时间 + next_sample_time=(my_para_data.mach_run_para.start_interval*3600)-((today_sec-start_time)%(my_para_data.mach_run_para.start_interval*3600)); + next_sample_time+=(now-45*60); + } + else + { //当天的时间小于采样开始时间 + next_sample_time=now-today_sec+start_time-45*60; + } + LOG_DEBUG(TRACE_DEBUG,"sample start time changed to %d:%d\n",my_para_data.mach_run_para.start_hour,my_para_data.mach_run_para.start_minute); + } + else + { + next_sample_time+=(my_para_data.mach_run_para.start_interval*3600); //计算下一次采样开始时刻 + } + LOG_DEBUG(TRACE_DEBUG,"next start sample time is %s\n",ctime(&next_sample_time)); + } + + if(time_record.dummy_sample_time) + { + if(now>=time_record.dummy_sample_time) + { + //上传软数据 + get_rand(&percent); + LOG_DEBUG(TRACE_DEBUG,"send dummy data:percent=%f\n",percent); + dumy_ysp_data.H2ppm=ana_result.result.H2ppm*percent; + dumy_ysp_data.COppm=ana_result.result.COppm*percent; + dumy_ysp_data.CH4ppm=ana_result.result.CH4ppm*percent; + dumy_ysp_data.C2H4ppm=ana_result.result.C2H4ppm*percent; + dumy_ysp_data.C2H6ppm=ana_result.result.C2H6ppm*percent; + dumy_ysp_data.C2H2ppm=ana_result.result.C2H2ppm*percent; + dumy_ysp_data.TotHyd=ana_result.result.TotHyd*percent; + dumy_ysp_data.CO2ppm=ana_result.result.CO2ppm*percent; + LOG_DEBUG(TRACE_DEBUG,"H2=%f CO=%f CH4=%f C2H4=%f\n",dumy_ysp_data.H2ppm,dumy_ysp_data.COppm,dumy_ysp_data.CH4ppm,dumy_ysp_data.C2H4ppm); + LOG_DEBUG(TRACE_DEBUG,"C2H6=%f C2H2=%f TotHyd=%f CO2=%f\n",dumy_ysp_data.C2H6ppm,dumy_ysp_data.C2H2ppm,dumy_ysp_data.TotHyd,dumy_ysp_data.CO2ppm); + //dumy_ysp_data.Mst=ana_result.result.Mst; + //dumy_ysp_data.temp=ana_result.result + dumy_ysp_data.SmpTm=now; + send_ysp_msg(&dumy_ysp_data); + time_record.dummy_sample_time=0; + } + } + + if(my_para_data.mach_run_para.auto_gas_en) + { + gas_pump_process(); + } + //采样完成后,延时10分钟关传感器加热,关吹扫阀,关YV20 + relay_dly_process(); + HeatAutoTuneProcess(now); + old_log_process(now); + } + mq_close(main_mq); + return 0; +} diff --git a/src/main.h b/src/main.h new file mode 100644 index 0000000..27f73de --- /dev/null +++ b/src/main.h @@ -0,0 +1,16 @@ +/* + * main.h + * + * Created on: Apr 15, 2015 + * Author: root + */ + +#ifndef MAIN_H_ +#define MAIN_H_ + +#define MAIN_MESSAGE_MQ "/main_mq" +#define MAIN_MAX_MESSAGE 8 +#define MAIN_MESSAGE_SIZE 1024 +#define MAIN_MESSAGE_PRIO 30 + +#endif /* MAIN_H_ */ diff --git a/src/minGlue.h b/src/minGlue.h new file mode 100644 index 0000000..28b7790 --- /dev/null +++ b/src/minGlue.h @@ -0,0 +1,31 @@ +/* Glue functions for the minIni library, based on the C/C++ stdio library + * + * Or better said: this file contains macros that maps the function interface + * used by minIni to the standard C/C++ file I/O functions. + * + * By CompuPhase, 2008-2012 + * This "glue file" is in the public domain. It is distributed without + * warranties or conditions of any kind, either express or implied. + */ + +/* map required file I/O types and functions to the standard C library */ +#include + +#define INI_FILETYPE FILE* +#define ini_openread(filename,file) ((*(file) = fopen((filename),"rb")) != NULL) +#define ini_openwrite(filename,file) ((*(file) = fopen((filename),"wb")) != NULL) +#define ini_close(file) (fclose(*(file)) == 0) +#define ini_read(buffer,size,file) (fgets((buffer),(size),*(file)) != NULL) +#define ini_write(buffer,file) (fputs((buffer),*(file)) >= 0) +#define ini_rename(source,dest) (rename((source), (dest)) == 0) +#define ini_remove(filename) (remove(filename) == 0) + +#define INI_FILEPOS fpos_t +#define ini_tell(file,pos) (fgetpos(*(file), (pos)) == 0) +#define ini_seek(file,pos) (fsetpos(*(file), (pos)) == 0) + + +/* for floating-point support, define additional types and functions */ +#define INI_REAL float +#define ini_ftoa(string,value) sprintf((string),"%f",(value)) +#define ini_atof(string) (INI_REAL)strtod((string),NULL) diff --git a/src/minIni.c b/src/minIni.c new file mode 100644 index 0000000..4100353 --- /dev/null +++ b/src/minIni.c @@ -0,0 +1,831 @@ +/* minIni - Multi-Platform INI file parser, suitable for embedded systems + * + * These routines are in part based on the article "Multiplatform .INI Files" + * by Joseph J. Graf in the March 1994 issue of Dr. Dobb's Journal. + * + * Copyright (c) CompuPhase, 2008-2012 + * + * Licensed 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. + * + * Version: $Id: minIni.c 45 2012-05-14 11:53:09Z thiadmer.riemersma $ + */ + +#if (defined _UNICODE || defined __UNICODE__ || defined UNICODE) && !defined MININI_ANSI +# if !defined UNICODE /* for Windows */ +# define UNICODE +# endif +# if !defined _UNICODE /* for C library */ +# define _UNICODE +# endif +#endif + +#define MININI_IMPLEMENTATION +#include "minIni.h" +#if defined NDEBUG + #define assert(e) +#else + #include +#endif + +#if !defined __T + #include + #include + #include + #define TCHAR char + #define __T(s) s + #define _tcscat strcat + #define _tcschr strchr + #define _tcscmp strcmp + #define _tcscpy strcpy + #define _tcsicmp stricmp + #define _tcslen strlen + #define _tcsncmp strncmp + #define _tcsnicmp strnicmp + #define _tcsrchr strrchr + #define _tcstol strtol + #define _tcstod strtod + #define _totupper toupper + #define _stprintf sprintf + #define _tfgets fgets + #define _tfputs fputs + #define _tfopen fopen + #define _tremove remove + #define _trename rename +#endif + +#if defined __linux || defined __linux__ + #define __LINUX__ +#elif defined FREEBSD && !defined __FreeBSD__ + #define __FreeBSD__ +#elif defined(_MSC_VER) + #pragma warning(disable: 4996) /* for Microsoft Visual C/C++ */ +#endif +#if !defined strnicmp && !defined PORTABLE_STRNICMP + #if defined __LINUX__ || defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__ + #define strnicmp strncasecmp + #endif +#endif + +#if !defined INI_LINETERM + #define INI_LINETERM __T("\n") +#endif +#if !defined INI_FILETYPE + #error Missing definition for INI_FILETYPE. +#endif + +#if !defined sizearray + #define sizearray(a) (sizeof(a) / sizeof((a)[0])) +#endif + +enum quote_option { + QUOTE_NONE, + QUOTE_ENQUOTE, + QUOTE_DEQUOTE, +}; + +#if defined PORTABLE_STRNICMP +int strnicmp(const TCHAR *s1, const TCHAR *s2, size_t n) +{ + register int c1, c2; + + while (n-- != 0 && (*s1 || *s2)) { + c1 = *s1++; + if ('a' <= c1 && c1 <= 'z') + c1 += ('A' - 'a'); + c2 = *s2++; + if ('a' <= c2 && c2 <= 'z') + c2 += ('A' - 'a'); + if (c1 != c2) + return c1 - c2; + } /* while */ + return 0; +} +#endif /* PORTABLE_STRNICMP */ + +static TCHAR *skipleading(const TCHAR *str) +{ + assert(str != NULL); + while (*str != '\0' && *str <= ' ') + str++; + return (TCHAR *)str; +} + +static TCHAR *skiptrailing(const TCHAR *str, const TCHAR *base) +{ + assert(str != NULL); + assert(base != NULL); + while (str > base && *(str-1) <= ' ') + str--; + return (TCHAR *)str; +} + +static TCHAR *striptrailing(TCHAR *str) +{ + TCHAR *ptr = skiptrailing(_tcschr(str, '\0'), str); + assert(ptr != NULL); + *ptr = '\0'; + return str; +} + +static TCHAR *save_strncpy(TCHAR *dest, const TCHAR *source, size_t maxlen, enum quote_option option) +{ + size_t d, s; + + assert(maxlen>0); + assert(dest <= source || dest >= source + maxlen); + if (option == QUOTE_ENQUOTE && maxlen < 3) + option = QUOTE_NONE; /* cannot store two quotes and a terminating zero in less than 3 characters */ + + switch (option) { + case QUOTE_NONE: + for (d = 0; d < maxlen - 1 && source[d] != '\0'; d++) + dest[d] = source[d]; + assert(d < maxlen); + dest[d] = '\0'; + break; + case QUOTE_ENQUOTE: + d = 0; + dest[d++] = '"'; + for (s = 0; source[s] != '\0' && d < maxlen - 2; s++, d++) { + if (source[s] == '"') { + if (d >= maxlen - 3) + break; /* no space to store the escape character plus the one that follows it */ + dest[d++] = '\\'; + } /* if */ + dest[d] = source[s]; + } /* for */ + dest[d++] = '"'; + dest[d] = '\0'; + break; + case QUOTE_DEQUOTE: + for (d = s = 0; source[s] != '\0' && d < maxlen - 1; s++, d++) { + if ((source[s] == '"' || source[s] == '\\') && source[s + 1] == '"') + s++; + dest[d] = source[s]; + } /* for */ + dest[d] = '\0'; + break; + default: + assert(0); + } /* switch */ + + return dest; +} + +static TCHAR *cleanstring(TCHAR *string, enum quote_option *quotes) +{ + int isstring; + TCHAR *ep; + + assert(string != NULL); + assert(quotes != NULL); + + /* Remove a trailing comment */ + isstring = 0; + for (ep = string; *ep != '\0' && ((*ep != ';' && *ep != '#') || isstring); ep++) { + if (*ep == '"') { + if (*(ep + 1) == '"') + ep++; /* skip "" (both quotes) */ + else + isstring = !isstring; /* single quote, toggle isstring */ + } else if (*ep == '\\' && *(ep + 1) == '"') { + ep++; /* skip \" (both quotes */ + } /* if */ + } /* for */ + assert(ep != NULL && (*ep == '\0' || *ep == ';' || *ep == '#')); + *ep = '\0'; /* terminate at a comment */ + striptrailing(string); + /* Remove double quotes surrounding a value */ + *quotes = QUOTE_NONE; + if (*string == '"' && (ep = _tcschr(string, '\0')) != NULL && *(ep - 1) == '"') { + string++; + *--ep = '\0'; + *quotes = QUOTE_DEQUOTE; /* this is a string, so remove escaped characters */ + } /* if */ + return string; +} + +static int getkeystring(INI_FILETYPE *fp, const TCHAR *Section, const TCHAR *Key, + int idxSection, int idxKey, TCHAR *Buffer, int BufferSize) +{ + TCHAR *sp, *ep; + int len, idx; + enum quote_option quotes; + TCHAR LocalBuffer[INI_BUFFERSIZE]; + + assert(fp != NULL); + /* Move through file 1 line at a time until a section is matched or EOF. If + * parameter Section is NULL, only look at keys above the first section. If + * idxSection is postive, copy the relevant section name. + */ + len = (Section != NULL) ? _tcslen(Section) : 0; + if (len > 0 || idxSection >= 0) { + idx = -1; + do { + if (!ini_read(LocalBuffer, INI_BUFFERSIZE, fp)) + return 0; + sp = skipleading(LocalBuffer); + ep = _tcschr(sp, ']'); + } while (*sp != '[' || ep == NULL || (((int)(ep-sp-1) != len || _tcsnicmp(sp+1,Section,len) != 0) && ++idx != idxSection)); + if (idxSection >= 0) { + if (idx == idxSection) { + assert(ep != NULL); + assert(*ep == ']'); + *ep = '\0'; + save_strncpy(Buffer, sp + 1, BufferSize, QUOTE_NONE); + return 1; + } /* if */ + return 0; /* no more section found */ + } /* if */ + } /* if */ + + /* Now that the section has been found, find the entry. + * Stop searching upon leaving the section's area. + */ + assert(Key != NULL || idxKey >= 0); + len = (Key != NULL) ? (int)_tcslen(Key) : 0; + idx = -1; + do { + if (!ini_read(LocalBuffer,INI_BUFFERSIZE,fp) || *(sp = skipleading(LocalBuffer)) == '[') + return 0; + sp = skipleading(LocalBuffer); + ep = _tcschr(sp, '='); /* Parse out the equal sign */ + if (ep == NULL) + ep = _tcschr(sp, ':'); + } while (*sp == ';' || *sp == '#' || ep == NULL || (((int)(skiptrailing(ep,sp)-sp) != len || _tcsnicmp(sp,Key,len) != 0) && ++idx != idxKey)); + if (idxKey >= 0) { + if (idx == idxKey) { + assert(ep != NULL); + assert(*ep == '=' || *ep == ':'); + *ep = '\0'; + striptrailing(sp); + save_strncpy(Buffer, sp, BufferSize, QUOTE_NONE); + return 1; + } /* if */ + return 0; /* no more key found (in this section) */ + } /* if */ + + /* Copy up to BufferSize chars to buffer */ + assert(ep != NULL); + assert(*ep == '=' || *ep == ':'); + sp = skipleading(ep + 1); + sp = cleanstring(sp, "es); /* Remove a trailing comment */ + save_strncpy(Buffer, sp, BufferSize, quotes); + return 1; +} + +/** ini_gets() + * \param Section the name of the section to search for + * \param Key the name of the entry to find the value of + * \param DefValue default string in the event of a failed read + * \param Buffer a pointer to the buffer to copy into + * \param BufferSize the maximum number of characters to copy + * \param Filename the name and full path of the .ini file to read from + * + * \return the number of characters copied into the supplied buffer + */ +int ini_gets(const TCHAR *Section, const TCHAR *Key, const TCHAR *DefValue, + TCHAR *Buffer, int BufferSize, const TCHAR *Filename) +{ + INI_FILETYPE fp; + int ok = 0; + + if (Buffer == NULL || BufferSize <= 0 || Key == NULL) + return 0; + if (ini_openread(Filename, &fp)) { + ok = getkeystring(&fp, Section, Key, -1, -1, Buffer, BufferSize); + (void)ini_close(&fp); + } /* if */ + if (!ok) + save_strncpy(Buffer, DefValue, BufferSize, QUOTE_NONE); + return _tcslen(Buffer); +} + +/** ini_getl() + * \param Section the name of the section to search for + * \param Key the name of the entry to find the value of + * \param DefValue the default value in the event of a failed read + * \param Filename the name of the .ini file to read from + * + * \return the value located at Key + */ +long ini_getl(const TCHAR *Section, const TCHAR *Key, long DefValue, const TCHAR *Filename) +{ + TCHAR LocalBuffer[64]; + int len = ini_gets(Section, Key, __T(""), LocalBuffer, sizearray(LocalBuffer), Filename); + return (len == 0) ? DefValue + : ((len >= 2 && _totupper(LocalBuffer[1]) == 'X') ? _tcstol(LocalBuffer, NULL, 16) + : _tcstol(LocalBuffer, NULL, 10)); +} + +#if defined INI_REAL +/** ini_getf() + * \param Section the name of the section to search for + * \param Key the name of the entry to find the value of + * \param DefValue the default value in the event of a failed read + * \param Filename the name of the .ini file to read from + * + * \return the value located at Key + */ +INI_REAL ini_getf(const TCHAR *Section, const TCHAR *Key, INI_REAL DefValue, const TCHAR *Filename) +{ + TCHAR LocalBuffer[64]; + int len = ini_gets(Section, Key, __T(""), LocalBuffer, sizearray(LocalBuffer), Filename); + return (len == 0) ? DefValue : ini_atof(LocalBuffer); +} +#endif + +/** ini_getbool() + * \param Section the name of the section to search for + * \param Key the name of the entry to find the value of + * \param DefValue default value in the event of a failed read; it should + * zero (0) or one (1). + * \param Buffer a pointer to the buffer to copy into + * \param BufferSize the maximum number of characters to copy + * \param Filename the name and full path of the .ini file to read from + * + * A true boolean is found if one of the following is matched: + * - A string starting with 'y' or 'Y' + * - A string starting with 't' or 'T' + * - A string starting with '1' + * + * A false boolean is found if one of the following is matched: + * - A string starting with 'n' or 'N' + * - A string starting with 'f' or 'F' + * - A string starting with '0' + * + * \return the true/false flag as interpreted at Key + */ +int ini_getbool(const TCHAR *Section, const TCHAR *Key, int DefValue, const TCHAR *Filename) +{ + TCHAR LocalBuffer[2]; + int ret; + + ini_gets(Section, Key, __T(""), LocalBuffer, sizearray(LocalBuffer), Filename); + LocalBuffer[0] = (TCHAR)toupper(LocalBuffer[0]); + if (LocalBuffer[0] == 'Y' || LocalBuffer[0] == '1' || LocalBuffer[0] == 'T') + ret = 1; + else if (LocalBuffer[0] == 'N' || LocalBuffer[0] == '0' || LocalBuffer[0] == 'F') + ret = 0; + else + ret = DefValue; + + return(ret); +} + +/** ini_getsection() + * \param idx the zero-based sequence number of the section to return + * \param Buffer a pointer to the buffer to copy into + * \param BufferSize the maximum number of characters to copy + * \param Filename the name and full path of the .ini file to read from + * + * \return the number of characters copied into the supplied buffer + */ +int ini_getsection(int idx, TCHAR *Buffer, int BufferSize, const TCHAR *Filename) +{ + INI_FILETYPE fp; + int ok = 0; + + if (Buffer == NULL || BufferSize <= 0 || idx < 0) + return 0; + if (ini_openread(Filename, &fp)) { + ok = getkeystring(&fp, NULL, NULL, idx, -1, Buffer, BufferSize); + (void)ini_close(&fp); + } /* if */ + if (!ok) + *Buffer = '\0'; + return _tcslen(Buffer); +} + +/** ini_getkey() + * \param Section the name of the section to browse through, or NULL to + * browse through the keys outside any section + * \param idx the zero-based sequence number of the key to return + * \param Buffer a pointer to the buffer to copy into + * \param BufferSize the maximum number of characters to copy + * \param Filename the name and full path of the .ini file to read from + * + * \return the number of characters copied into the supplied buffer + */ +int ini_getkey(const TCHAR *Section, int idx, TCHAR *Buffer, int BufferSize, const TCHAR *Filename) +{ + INI_FILETYPE fp; + int ok = 0; + + if (Buffer == NULL || BufferSize <= 0 || idx < 0) + return 0; + if (ini_openread(Filename, &fp)) { + ok = getkeystring(&fp, Section, NULL, -1, idx, Buffer, BufferSize); + (void)ini_close(&fp); + } /* if */ + if (!ok) + *Buffer = '\0'; + return _tcslen(Buffer); +} + + +#if !defined INI_NOBROWSE +/** ini_browse() + * \param Callback a pointer to a function that will be called for every + * setting in the INI file. + * \param UserData arbitrary data, which the function passes on the the + * \c Callback function + * \param Filename the name and full path of the .ini file to read from + * + * \return 1 on success, 0 on failure (INI file not found) + * + * \note The \c Callback function must return 1 to continue + * browsing through the INI file, or 0 to stop. Even when the + * callback stops the browsing, this function will return 1 + * (for success). + */ +int ini_browse(INI_CALLBACK Callback, const void *UserData, const TCHAR *Filename) +{ + TCHAR LocalBuffer[INI_BUFFERSIZE]; + TCHAR *sp, *ep; + int lenSec, lenKey; + enum quote_option quotes; + INI_FILETYPE fp; + + if (Callback == NULL) + return 0; + if (!ini_openread(Filename, &fp)) + return 0; + + LocalBuffer[0] = '\0'; /* copy an empty section in the buffer */ + lenSec = _tcslen(LocalBuffer) + 1; + for ( ;; ) { + if (!ini_read(LocalBuffer + lenSec, INI_BUFFERSIZE - lenSec, &fp)) + break; + sp = skipleading(LocalBuffer + lenSec); + /* ignore empty strings and comments */ + if (*sp == '\0' || *sp == ';' || *sp == '#') + continue; + /* see whether we reached a new section */ + ep = _tcschr(sp, ']'); + if (*sp == '[' && ep != NULL) { + *ep = '\0'; + save_strncpy(LocalBuffer, sp + 1, INI_BUFFERSIZE, QUOTE_NONE); + lenSec = _tcslen(LocalBuffer) + 1; + continue; + } /* if */ + /* not a new section, test for a key/value pair */ + ep = _tcschr(sp, '='); /* test for the equal sign or colon */ + if (ep == NULL) + ep = _tcschr(sp, ':'); + if (ep == NULL) + continue; /* invalid line, ignore */ + *ep++ = '\0'; /* split the key from the value */ + striptrailing(sp); + save_strncpy(LocalBuffer + lenSec, sp, INI_BUFFERSIZE - lenSec, QUOTE_NONE); + lenKey = _tcslen(LocalBuffer + lenSec) + 1; + /* clean up the value */ + sp = skipleading(ep); + sp = cleanstring(sp, "es); /* Remove a trailing comment */ + save_strncpy(LocalBuffer + lenSec + lenKey, sp, INI_BUFFERSIZE - lenSec - lenKey, quotes); + /* call the callback */ + if (!Callback(LocalBuffer, LocalBuffer + lenSec, LocalBuffer + lenSec + lenKey, UserData)) + break; + } /* for */ + + (void)ini_close(&fp); + return 1; +} +#endif /* INI_NOBROWSE */ + +#if ! defined INI_READONLY +static void ini_tempname(TCHAR *dest, const TCHAR *source, int maxlength) +{ + TCHAR *p; + + save_strncpy(dest, source, maxlength, QUOTE_NONE); + p = _tcsrchr(dest, '\0'); + assert(p != NULL); + *(p - 1) = '~'; +} + +static enum quote_option check_enquote(const TCHAR *Value) +{ + const TCHAR *p; + + /* run through the value, if it has trailing spaces, or '"', ';' or '#' + * characters, enquote it + */ + assert(Value != NULL); + for (p = Value; *p != '\0' && *p != '"' && *p != ';' && *p != '#'; p++) + /* nothing */; + return (*p != '\0' || (p > Value && *(p - 1) == ' ')) ? QUOTE_ENQUOTE : QUOTE_NONE; +} + +static void writesection(TCHAR *LocalBuffer, const TCHAR *Section, INI_FILETYPE *fp) +{ + TCHAR *p; + + if (Section != NULL && _tcslen(Section) > 0) { + LocalBuffer[0] = '['; + save_strncpy(LocalBuffer + 1, Section, INI_BUFFERSIZE - 4, QUOTE_NONE); /* -1 for '[', -1 for ']', -2 for '\r\n' */ + p = _tcsrchr(LocalBuffer, '\0'); + assert(p != NULL); + *p++ = ']'; + _tcscpy(p, INI_LINETERM); /* copy line terminator (typically "\n") */ + (void)ini_write(LocalBuffer, fp); + } /* if */ +} + +static void writekey(TCHAR *LocalBuffer, const TCHAR *Key, const TCHAR *Value, INI_FILETYPE *fp) +{ + TCHAR *p; + enum quote_option option = check_enquote(Value); + save_strncpy(LocalBuffer, Key, INI_BUFFERSIZE - 3, QUOTE_NONE); /* -1 for '=', -2 for '\r\n' */ + p = _tcsrchr(LocalBuffer, '\0'); + assert(p != NULL); + *p++ = '='; + save_strncpy(p, Value, INI_BUFFERSIZE - (p - LocalBuffer) - 2, option); /* -2 for '\r\n' */ + p = _tcsrchr(LocalBuffer, '\0'); + assert(p != NULL); + _tcscpy(p, INI_LINETERM); /* copy line terminator (typically "\n") */ + (void)ini_write(LocalBuffer, fp); +} + +static int cache_accum(const TCHAR *string, int *size, int max) +{ + int len = _tcslen(string); + if (*size + len >= max) + return 0; + *size += len; + return 1; +} + +static int cache_flush(TCHAR *buffer, int *size, + INI_FILETYPE *rfp, INI_FILETYPE *wfp, INI_FILEPOS *mark) +{ + int pos = 0; + + (void)ini_seek(rfp, mark); + assert(buffer != NULL); + buffer[0] = '\0'; + assert(size != NULL); + while (pos < *size) { + (void)ini_read(buffer + pos, INI_BUFFERSIZE - pos, rfp); + pos += _tcslen(buffer + pos); + assert(pos <= *size); + } /* while */ + if (buffer[0] != '\0') + (void)ini_write(buffer, wfp); + (void)ini_tell(rfp, mark); /* update mark */ + *size = 0; + /* return whether the buffer ended with a line termination */ + return (_tcscmp(buffer + pos - _tcslen(INI_LINETERM), INI_LINETERM) == 0); +} + +static int close_rename(INI_FILETYPE *rfp, INI_FILETYPE *wfp, const TCHAR *filename, TCHAR *buffer) +{ + (void)ini_close(rfp); + (void)ini_close(wfp); + (void)ini_remove(filename); + (void)ini_tempname(buffer, filename, INI_BUFFERSIZE); + (void)ini_rename(buffer, filename); + return 1; +} + +/** ini_puts() + * \param Section the name of the section to write the string in + * \param Key the name of the entry to write, or NULL to erase all keys in the section + * \param Value a pointer to the buffer the string, or NULL to erase the key + * \param Filename the name and full path of the .ini file to write to + * + * \return 1 if successful, otherwise 0 + */ +int ini_puts(const TCHAR *Section, const TCHAR *Key, const TCHAR *Value, const TCHAR *Filename) +{ + INI_FILETYPE rfp; + INI_FILETYPE wfp; + INI_FILEPOS mark; + TCHAR *sp, *ep; + TCHAR LocalBuffer[INI_BUFFERSIZE]; + int len, match, flag, cachelen; + + assert(Filename != NULL); + if (!ini_openread(Filename, &rfp)) { + /* If the .ini file doesn't exist, make a new file */ + if (Key != NULL && Value != NULL) { + if (!ini_openwrite(Filename, &wfp)) + return 0; + writesection(LocalBuffer, Section, &wfp); + writekey(LocalBuffer, Key, Value, &wfp); + (void)ini_close(&wfp); + } /* if */ + return 1; + } /* if */ + + /* If parameters Key and Value are valid (so this is not an "erase" request) + * and the setting already exists and it already has the correct value, do + * nothing. This early bail-out avoids rewriting the INI file for no reason. + */ + if (Key != NULL && Value != NULL) { + (void)ini_tell(&rfp, &mark); + match = getkeystring(&rfp, Section, Key, -1, -1, LocalBuffer, sizearray(LocalBuffer)); + if (match && _tcscmp(LocalBuffer,Value) == 0) { + (void)ini_close(&rfp); + return 1; + } /* if */ + /* key not found, or different value -> proceed (but rewind the input file first) */ + (void)ini_seek(&rfp, &mark); + } /* if */ + + /* Get a temporary file name to copy to. Use the existing name, but with + * the last character set to a '~'. + */ + ini_tempname(LocalBuffer, Filename, INI_BUFFERSIZE); + if (!ini_openwrite(LocalBuffer, &wfp)) { + (void)ini_close(&rfp); + return 0; + } /* if */ + (void)ini_tell(&rfp, &mark); + cachelen = 0; + + /* Move through the file one line at a time until a section is + * matched or until EOF. Copy to temp file as it is read. + */ + len = (Section != NULL) ? _tcslen(Section) : 0; + if (len > 0) { + do { + if (!ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp)) { + /* Failed to find section, so add one to the end */ + flag = cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); + if (Key!=NULL && Value!=NULL) { + if (!flag) + (void)ini_write(INI_LINETERM, &wfp); /* force a new line behind the last line of the INI file */ + writesection(LocalBuffer, Section, &wfp); + writekey(LocalBuffer, Key, Value, &wfp); + } /* if */ + return close_rename(&rfp, &wfp, Filename, LocalBuffer); /* clean up and rename */ + } /* if */ + /* Copy the line from source to dest, but not if this is the section that + * we are looking for and this section must be removed + */ + sp = skipleading(LocalBuffer); + ep = _tcschr(sp, ']'); + match = (*sp == '[' && ep != NULL && (int)(ep-sp-1) == len && _tcsnicmp(sp + 1,Section,len) == 0); + if (!match || Key != NULL) { + if (!cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE)) { + cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); + (void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp); + cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE); + } /* if */ + } /* if */ + } while (!match); + } /* if */ + cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); + /* when deleting a section, the section head that was just found has not been + * copied to the output file, but because this line was not "accumulated" in + * the cache, the position in the input file was reset to the point just + * before the section; this must now be skipped (again) + */ + if (Key == NULL) { + (void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp); + (void)ini_tell(&rfp, &mark); + } /* if */ + + /* Now that the section has been found, find the entry. Stop searching + * upon leaving the section's area. Copy the file as it is read + * and create an entry if one is not found. + */ + len = (Key!=NULL) ? _tcslen(Key) : 0; + for( ;; ) { + if (!ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp)) { + /* EOF without an entry so make one */ + flag = cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); + if (Key!=NULL && Value!=NULL) { + if (!flag) + (void)ini_write(INI_LINETERM, &wfp); /* force a new line behind the last line of the INI file */ + writekey(LocalBuffer, Key, Value, &wfp); + } /* if */ + return close_rename(&rfp, &wfp, Filename, LocalBuffer); /* clean up and rename */ + } /* if */ + sp = skipleading(LocalBuffer); + ep = _tcschr(sp, '='); /* Parse out the equal sign */ + if (ep == NULL) + ep = _tcschr(sp, ':'); + match = (ep != NULL && (int)(skiptrailing(ep,sp)-sp) == len && _tcsnicmp(sp,Key,len) == 0); + if ((Key != NULL && match) || *sp == '[') + break; /* found the key, or found a new section */ + /* copy other keys in the section */ + if (Key == NULL) { + (void)ini_tell(&rfp, &mark); /* we are deleting the entire section, so update the read position */ + } else { + if (!cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE)) { + cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); + (void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp); + cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE); + } /* if */ + } /* if */ + } /* for */ + /* the key was found, or we just dropped on the next section (meaning that it + * wasn't found); in both cases we need to write the key, but in the latter + * case, we also need to write the line starting the new section after writing + * the key + */ + flag = (*sp == '['); + cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); + if (Key != NULL && Value != NULL) + writekey(LocalBuffer, Key, Value, &wfp); + /* cache_flush() reset the "read pointer" to the start of the line with the + * previous key or the new section; read it again (because writekey() destroyed + * the buffer) + */ + (void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp); + if (flag) { + /* the new section heading needs to be copied to the output file */ + cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE); + } else { + /* forget the old key line */ + (void)ini_tell(&rfp, &mark); + } /* if */ + /* Copy the rest of the INI file */ + while (ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp)) { + if (!cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE)) { + cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); + (void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp); + cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE); + } /* if */ + } /* while */ + cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark); + return close_rename(&rfp, &wfp, Filename, LocalBuffer); /* clean up and rename */ +} + +/* Ansi C "itoa" based on Kernighan & Ritchie's "Ansi C" book. */ +#define ABS(v) ((v) < 0 ? -(v) : (v)) + +static void strreverse(TCHAR *str) +{ + TCHAR t; + int i, j; + + for (i = 0, j = _tcslen(str) - 1; i < j; i++, j--) { + t = str[i]; + str[i] = str[j]; + str[j] = t; + } /* for */ +} + +static void long2str(long value, TCHAR *str) +{ + int i = 0; + long sign = value; + int n; + + /* generate digits in reverse order */ + do { + n = (int)(value % 10); /* get next lowest digit */ + str[i++] = (TCHAR)(ABS(n) + '0'); /* handle case of negative digit */ + } while (value /= 10); /* delete the lowest digit */ + if (sign < 0) + str[i++] = '-'; + str[i] = '\0'; + + strreverse(str); +} + +/** ini_putl() + * \param Section the name of the section to write the value in + * \param Key the name of the entry to write + * \param Value the value to write + * \param Filename the name and full path of the .ini file to write to + * + * \return 1 if successful, otherwise 0 + */ +int ini_putl(const TCHAR *Section, const TCHAR *Key, long Value, const TCHAR *Filename) +{ + TCHAR LocalBuffer[32]; + long2str(Value, LocalBuffer); + return ini_puts(Section, Key, LocalBuffer, Filename); +} + +#if defined INI_REAL +/** ini_putf() + * \param Section the name of the section to write the value in + * \param Key the name of the entry to write + * \param Value the value to write + * \param Filename the name and full path of the .ini file to write to + * + * \return 1 if successful, otherwise 0 + */ +int ini_putf(const TCHAR *Section, const TCHAR *Key, INI_REAL Value, const TCHAR *Filename) +{ + TCHAR LocalBuffer[64]; + ini_ftoa(LocalBuffer, Value); + return ini_puts(Section, Key, LocalBuffer, Filename); +} +#endif /* INI_REAL */ +#endif /* !INI_READONLY */ diff --git a/src/minIni.h b/src/minIni.h new file mode 100644 index 0000000..6ac00dd --- /dev/null +++ b/src/minIni.h @@ -0,0 +1,152 @@ +/* minIni - Multi-Platform INI file parser, suitable for embedded systems + * + * Copyright (c) CompuPhase, 2008-2012 + * + * Licensed 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. + * + * Version: $Id: minIni.h 44 2012-01-04 15:52:56Z thiadmer.riemersma@gmail.com $ + */ +#ifndef MININI_H +#define MININI_H + +#include "minGlue.h" + +#if (defined _UNICODE || defined __UNICODE__ || defined UNICODE) && !defined MININI_ANSI + #include + #define mTCHAR TCHAR +#else + /* force TCHAR to be "char", but only for minIni */ + #define mTCHAR char +#endif + +#if !defined INI_BUFFERSIZE + #define INI_BUFFERSIZE 512 +#endif + +#if defined __cplusplus + extern "C" { +#endif + +int ini_getbool(const mTCHAR *Section, const mTCHAR *Key, int DefValue, const mTCHAR *Filename); +long ini_getl(const mTCHAR *Section, const mTCHAR *Key, long DefValue, const mTCHAR *Filename); +int ini_gets(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *DefValue, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename); +int ini_getsection(int idx, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename); +int ini_getkey(const mTCHAR *Section, int idx, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename); + +#if defined INI_REAL +INI_REAL ini_getf(const mTCHAR *Section, const mTCHAR *Key, INI_REAL DefValue, const mTCHAR *Filename); +#endif + +#if !defined INI_READONLY +int ini_putl(const mTCHAR *Section, const mTCHAR *Key, long Value, const mTCHAR *Filename); +int ini_puts(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *Value, const mTCHAR *Filename); +#if defined INI_REAL +int ini_putf(const mTCHAR *Section, const mTCHAR *Key, INI_REAL Value, const mTCHAR *Filename); +#endif +#endif /* INI_READONLY */ + +#if !defined INI_NOBROWSE +typedef int (*INI_CALLBACK)(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *Value, const void *UserData); +int ini_browse(INI_CALLBACK Callback, const void *UserData, const mTCHAR *Filename); +#endif /* INI_NOBROWSE */ + +#if defined __cplusplus + } +#endif + + +#if defined __cplusplus + +#if defined __WXWINDOWS__ + #include "wxMinIni.h" +#else + #include + + /* The C++ class in minIni.h was contributed by Steven Van Ingelgem. */ + class minIni + { + public: + minIni(const std::string& filename) : iniFilename(filename) + { } + + bool getbool(const std::string& Section, const std::string& Key, bool DefValue=false) const + { return ini_getbool(Section.c_str(), Key.c_str(), int(DefValue), iniFilename.c_str()) != 0; } + + long getl(const std::string& Section, const std::string& Key, long DefValue=0) const + { return ini_getl(Section.c_str(), Key.c_str(), DefValue, iniFilename.c_str()); } + + int geti(const std::string& Section, const std::string& Key, int DefValue=0) const + { return static_cast(this->getl(Section, Key, long(DefValue))); } + + std::string gets(const std::string& Section, const std::string& Key, const std::string& DefValue="") const + { + char buffer[INI_BUFFERSIZE]; + ini_gets(Section.c_str(), Key.c_str(), DefValue.c_str(), buffer, INI_BUFFERSIZE, iniFilename.c_str()); + return buffer; + } + + std::string getsection(int idx) const + { + char buffer[INI_BUFFERSIZE]; + ini_getsection(idx, buffer, INI_BUFFERSIZE, iniFilename.c_str()); + return buffer; + } + + std::string getkey(const std::string& Section, int idx) const + { + char buffer[INI_BUFFERSIZE]; + ini_getkey(Section.c_str(), idx, buffer, INI_BUFFERSIZE, iniFilename.c_str()); + return buffer; + } + +#if defined INI_REAL + INI_REAL getf(const std::string& Section, const std::string& Key, INI_REAL DefValue=0) const + { return ini_getf(Section.c_str(), Key.c_str(), DefValue, iniFilename.c_str()); } +#endif + +#if ! defined INI_READONLY + bool put(const std::string& Section, const std::string& Key, long Value) const + { return ini_putl(Section.c_str(), Key.c_str(), Value, iniFilename.c_str()) != 0; } + + bool put(const std::string& Section, const std::string& Key, int Value) const + { return ini_putl(Section.c_str(), Key.c_str(), (long)Value, iniFilename.c_str()) != 0; } + + bool put(const std::string& Section, const std::string& Key, bool Value) const + { return ini_putl(Section.c_str(), Key.c_str(), (long)Value, iniFilename.c_str()) != 0; } + + bool put(const std::string& Section, const std::string& Key, const std::string& Value) const + { return ini_puts(Section.c_str(), Key.c_str(), Value.c_str(), iniFilename.c_str()) != 0; } + + bool put(const std::string& Section, const std::string& Key, const char* Value) const + { return ini_puts(Section.c_str(), Key.c_str(), Value, iniFilename.c_str()) != 0; } + +#if defined INI_REAL + bool put(const std::string& Section, const std::string& Key, INI_REAL Value) const + { return ini_putf(Section.c_str(), Key.c_str(), Value, iniFilename.c_str()) != 0; } +#endif + + bool del(const std::string& Section, const std::string& Key) const + { return ini_puts(Section.c_str(), Key.c_str(), 0, iniFilename.c_str()) != 0; } + + bool del(const std::string& Section) const + { return ini_puts(Section.c_str(), 0, 0, iniFilename.c_str()) != 0; } +#endif + + private: + std::string iniFilename; + }; + +#endif /* __WXWINDOWS__ */ +#endif /* __cplusplus */ + +#endif /* MININI_H */ diff --git a/src/mk_ied.sh b/src/mk_ied.sh new file mode 100644 index 0000000..d61b267 --- /dev/null +++ b/src/mk_ied.sh @@ -0,0 +1,7 @@ +#!/bin/sh +eval $(awk '/IEDName/ { printf("old_ied=%s",$2) }' /scl_srvr/startup.cfg ) +new_ied=$1 +sed -i "s/$old_ied/$new_ied/g" /scl_srvr/startup.cfg +sed -i "s/$old_ied/$new_ied/g" /scl_srvr/TEMPLATE.icd +sed -i "s/$old_ied/$new_ied/g" /scl_srvr/datamap.cfg +echo "Change $old_ied to $new_ied successfull" diff --git a/src/msq.c b/src/msq.c new file mode 100644 index 0000000..7bbc0e8 --- /dev/null +++ b/src/msq.c @@ -0,0 +1,52 @@ +#include "msq.h" +#include + +mqd_t create_mq(const char *mq_name,long int mq_maxmsg,long int mq_msgsize) +{ + mqd_t my_mq=(mqd_t)(-1); + struct mq_attr my_attr; + + my_attr.mq_flags=0; + my_attr.mq_maxmsg=mq_maxmsg; + my_attr.mq_msgsize=mq_msgsize; + + my_mq=mq_open(mq_name,O_CREAT|O_RDONLY/*|O_NONBLOCK*/,S_IRWXU|S_IRWXG|S_IRWXO,&my_attr); + + return my_mq; +} + + +mqd_t open_mq(const char *mq_name) +{ + return mq_open(mq_name,O_WRONLY|O_NONBLOCK,0,NULL); +} + + +//timeouts is in us +ssize_t recv_mq_wait(mqd_t mq,void *msg,int size,int timeouts) +{ + struct timespec timeout; + struct timeval now; + ssize_t length; + + /* if(timeouts<0) + { + mq_receive(mq,(char *)msg,size,unsigned int *proip); + }*/ + gettimeofday(&now,NULL); + now.tv_usec+=timeouts; + if(now.tv_usec>=1000000) + { + now.tv_sec+=(now.tv_usec/1000000); + now.tv_usec=now.tv_usec%1000000; + } + timeout.tv_sec=now.tv_sec; + timeout.tv_nsec= now.tv_usec*1000; + length=mq_timedreceive(mq,(char*)msg,size,NULL,&timeout); + return length; +} + + + + + diff --git a/src/msq.h b/src/msq.h new file mode 100644 index 0000000..7911fe3 --- /dev/null +++ b/src/msq.h @@ -0,0 +1,15 @@ +#ifndef _MSQ_H +#define _MSQ_H + +#include +#include +#include +#include +#include +#include + +mqd_t create_mq(const char *mq_name,long int mq_maxmsg,long int mq_msgsize); +mqd_t open_mq(const char *mq_name); +ssize_t recv_mq_wait(mqd_t mq,void *msg,int size,int timeouts); + +#endif \ No newline at end of file diff --git a/src/netMr.c b/src/netMr.c new file mode 100644 index 0000000..96b3079 --- /dev/null +++ b/src/netMr.c @@ -0,0 +1,8 @@ +/* + * netMr.c + * + * Created on: Apr 15, 2015 + * Author: root + */ + + diff --git a/src/ofilter.csv b/src/ofilter.csv new file mode 100644 index 0000000..34d42fd --- /dev/null +++ b/src/ofilter.csv @@ -0,0 +1,4001 @@ +12128 +12128 +12128 +12128 +12128 +12176 +12233 +12298 +12369 +12444 +12519 +12587 +12644 +12689 +12718 +12728 +12723 +12706 +12679 +12650 +12619 +12586 +12554 +12525 +12499 +12472 +12450 +12425 +12405 +12384 +12367 +12352 +12338 +12328 +12319 +12313 +12307 +12302 +12297 +12295 +12296 +12297 +12300 +12305 +12310 +12316 +12321 +12324 +12325 +12323 +12318 +12311 +12300 +12287 +12271 +12253 +12234 +12213 +12195 +12176 +12161 +12144 +12130 +12116 +12104 +12093 +12083 +12074 +12066 +12061 +12055 +12052 +12048 +12046 +12044 +12043 +12041 +12041 +12041 +12042 +12043 +12044 +12045 +12043 +12042 +12040 +12035 +12031 +12025 +12019 +12012 +12006 +12000 +11993 +11988 +11981 +11975 +11969 +11962 +11956 +11949 +11943 +11938 +11933 +11929 +11927 +11924 +11922 +11920 +11919 +11918 +11918 +11918 +11918 +11918 +11918 +11918 +11919 +11921 +11923 +11926 +11931 +11937 +11943 +11951 +11959 +11968 +11976 +11984 +11992 +12001 +12009 +12016 +12024 +12032 +12042 +12051 +12060 +12069 +12078 +12086 +12093 +12099 +12101 +12103 +12104 +12102 +12100 +12096 +12093 +12091 +12089 +12088 +12090 +12092 +12096 +12103 +12110 +12116 +12123 +12128 +12131 +12134 +12135 +12134 +12130 +12126 +12121 +12117 +12113 +12110 +12108 +12108 +12110 +12113 +12117 +12122 +12128 +12134 +12140 +12146 +12152 +12157 +12162 +12165 +12165 +12161 +12156 +12147 +12137 +12125 +12113 +12102 +12091 +12084 +12078 +12075 +12075 +12076 +12078 +12081 +12084 +12088 +12090 +12092 +12092 +12091 +12090 +12090 +12089 +12089 +12090 +12091 +12093 +12104 +12115 +12139 +12171 +12208 +12266 +12342 +12442 +12559 +12702 +12867 +13052 +13271 +13507 +13760 +14033 +14317 +14612 +14911 +15217 +15519 +15815 +16110 +16388 +16661 +16923 +17170 +17405 +17620 +17827 +18012 +18189 +18350 +18491 +18617 +18719 +18806 +18867 +18909 +18928 +18917 +18881 +18821 +18737 +18632 +18501 +18357 +18191 +18013 +17818 +17620 +17426 +17224 +17028 +16821 +16625 +16439 +16261 +16085 +15911 +15743 +15582 +15436 +15291 +15152 +15017 +14894 +14775 +14666 +14566 +14468 +14376 +14289 +14210 +14129 +14057 +13988 +13923 +13863 +13802 +13749 +13701 +13659 +13618 +13579 +13540 +13505 +13473 +13438 +13402 +13366 +13331 +13300 +13274 +13252 +13234 +13224 +13222 +13230 +13246 +13272 +13308 +13356 +13416 +13483 +13563 +13651 +13748 +13851 +13957 +14070 +14185 +14302 +14414 +14526 +14634 +14735 +14829 +14913 +14988 +15055 +15118 +15172 +15219 +15263 +15301 +15336 +15365 +15388 +15404 +15411 +15406 +15392 +15368 +15327 +15277 +15214 +15143 +15065 +14980 +14891 +14798 +14708 +14609 +14518 +14427 +14337 +14252 +14167 +14089 +14013 +13945 +13883 +13825 +13773 +13724 +13680 +13635 +13592 +13555 +13516 +13479 +13443 +13405 +13367 +13332 +13304 +13269 +13236 +13207 +13176 +13152 +13131 +13111 +13089 +13072 +13058 +13044 +13034 +13023 +13012 +13002 +12996 +12989 +12981 +12972 +12964 +12956 +12948 +12940 +12931 +12923 +12913 +12902 +12889 +12872 +12854 +12833 +12807 +12775 +12744 +12715 +12683 +12654 +12627 +12603 +12583 +12570 +12553 +12538 +12527 +12518 +12510 +12505 +12501 +12501 +12505 +12508 +12511 +12512 +12517 +12517 +12519 +12519 +12520 +12522 +12524 +12527 +12526 +12526 +12528 +12530 +12534 +12535 +12538 +12540 +12543 +12546 +12548 +12548 +12546 +12544 +12540 +12537 +12533 +12530 +12524 +12517 +12510 +12504 +12500 +12496 +12493 +12489 +12490 +12491 +12493 +12496 +12499 +12502 +12506 +12509 +12513 +12516 +12519 +12521 +12521 +12520 +12517 +12512 +12508 +12505 +12502 +12499 +12498 +12497 +12497 +12499 +12496 +12495 +12494 +12495 +12497 +12499 +12504 +12509 +12520 +12530 +12541 +12555 +12569 +12584 +12595 +12606 +12614 +12622 +12629 +12632 +12633 +12634 +12634 +12632 +12629 +12623 +12614 +12602 +12589 +12574 +12560 +12545 +12532 +12520 +12511 +12502 +12495 +12486 +12479 +12471 +12461 +12451 +12438 +12426 +12412 +12400 +12387 +12375 +12364 +12355 +12349 +12343 +12340 +12337 +12337 +12337 +12337 +12338 +12341 +12341 +12341 +12339 +12337 +12335 +12331 +12330 +12324 +12321 +12317 +12315 +12314 +12312 +12312 +12309 +12309 +12308 +12310 +12310 +12308 +12308 +12307 +12305 +12303 +12302 +12300 +12299 +12298 +12298 +12297 +12298 +12299 +12300 +12301 +12300 +12297 +12293 +12290 +12286 +12282 +12281 +12278 +12276 +12276 +12278 +12282 +12288 +12295 +12300 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12336 +12323 +12324 +12328 +12331 +12333 +12336 +12338 +12339 +12341 +12342 +12344 +12343 +12344 +12344 +12344 +12345 +12346 +12346 +12345 +12346 +12346 +12346 +12346 +12347 +12349 +12349 +12350 +12351 +12350 +12350 +12350 +12348 +12348 +12347 +12347 +12346 +12346 +12348 +12349 +12350 +12352 +12353 +12353 +12353 +12353 +12351 +12349 +12347 +12345 +12343 +12342 +12341 +12340 +12340 +12341 +12340 +12340 +12339 +12338 +12333 +12328 +12323 +12317 +12310 +12304 +12298 +12291 +12288 +12286 +12284 +12284 +12286 +12289 +12290 +12294 +12296 +12297 +12299 +12301 +12301 +12302 +12304 +12305 +12305 +12306 +12308 +12309 +12312 +12315 +12318 +12320 +12323 +12326 +12328 +12330 +12331 +12332 +12332 +12333 +12333 +12333 +12336 +12338 +12340 +12341 +12344 +12346 +12347 +12350 +12352 +12354 +12356 +12359 +12361 +12362 +12365 +12366 +12367 +12367 +12368 +12368 +12368 +12368 +12369 +12368 +12369 +12370 +12371 +12370 +12371 +12372 +12372 +12373 +12374 +12375 +12376 +12378 +12381 +12382 +12385 +12388 +12390 +12392 +12394 +12396 +12396 +12397 +12396 +12394 +12392 +12390 +12388 +12385 +12382 +12380 +12378 +12377 +12377 +12374 +12374 +12374 +12374 +12375 +12377 +12378 +12379 +12382 +12384 +12385 +12386 +12386 +12386 +12384 +12384 +12383 +12383 +12382 +12383 +12383 +12383 +12383 +12383 +12383 +12381 +12380 +12378 +12375 +12372 +12369 +12366 +12363 +12361 +12359 +12356 +12354 +12353 +12351 +12351 +12350 +12349 +12348 +12349 +12349 +12348 +12348 +12350 +12352 +12352 +12354 +12356 +12357 +12359 +12361 +12361 +12362 +12363 +12363 +12363 +12364 +12365 +12366 +12368 +12370 +12373 +12375 +12378 +12381 +12382 +12384 +12385 +12387 +12388 +12390 +12392 +12393 +12395 +12397 +12398 +12400 +12400 +12401 +12399 +12399 +12398 +12395 +12393 +12392 +12389 +12386 +12384 +12381 +12377 +12374 +12371 +12366 +12361 +12358 +12354 +12349 +12346 +12344 +12342 +12341 +12340 +12341 +12341 +12342 +12344 +12345 +12349 +12353 +12358 +12363 +12370 +12378 +12385 +12395 +12404 +12414 +12422 +12432 +12443 +12452 +12463 +12474 +12487 +12497 +12510 +12523 +12535 +12548 +12561 +12574 +12587 +12602 +12616 +12631 +12646 +12662 +12678 +12695 +12714 +12732 +12751 +12770 +12790 +12808 +12827 +12847 +12865 +12884 +12902 +12921 +12938 +12958 +12977 +12995 +13016 +13035 +13056 +13075 +13095 +13115 +13134 +13153 +13171 +13190 +13206 +13224 +13241 +13256 +13272 +13286 +13301 +13312 +13323 +13333 +13342 +13351 +13359 +13364 +13369 +13374 +13379 +13383 +13388 +13392 +13395 +13399 +13403 +13405 +13406 +13407 +13407 +13404 +13401 +13397 +13392 +13385 +13379 +13370 +13359 +13349 +13339 +13328 +13315 +13302 +13289 +13274 +13261 +13246 +13230 +13214 +13197 +13181 +13162 +13146 +13128 +13110 +13092 +13076 +13059 +13041 +13025 +13008 +12992 +12976 +12961 +12946 +12930 +12917 +12902 +12888 +12874 +12861 +12847 +12834 +12821 +12808 +12794 +12780 +12768 +12755 +12744 +12732 +12722 +12710 +12700 +12691 +12681 +12672 +12663 +12654 +12643 +12633 +12624 +12614 +12605 +12597 +12589 +12581 +12576 +12570 +12564 +12560 +12555 +12549 +12544 +12540 +12535 +12529 +12524 +12520 +12515 +12512 +12509 +12507 +12504 +12504 +12503 +12501 +12500 +12499 +12497 +12494 +12491 +12489 +12485 +12483 +12480 +12477 +12475 +12473 +12472 +12470 +12470 +12470 +12469 +12469 +12469 +12469 +12469 +12469 +12469 +12467 +12467 +12466 +12465 +12463 +12461 +12459 +12456 +12453 +12451 +12448 +12445 +12443 +12440 +12437 +12434 +12432 +12428 +12425 +12423 +12421 +12417 +12415 +12413 +12409 +12407 +12404 +12402 +12399 +12397 +12397 +12395 +12396 +12397 +12397 +12397 +12398 +12399 +12398 +12399 +12400 +12400 +12401 +12402 +12404 +12404 +12406 +12407 +12407 +12408 +12409 +12410 +12410 +12410 +12410 +12409 +12408 +12408 +12407 +12405 +12404 +12403 +12400 +12398 +12396 +12392 +12389 +12386 +12383 +12380 +12378 +12377 +12375 +12374 +12374 +12374 +12371 +12368 +12365 +12361 +12357 +12352 +12347 +12341 +12336 +12332 +12328 +12326 +12325 +12325 +12326 +12329 +12332 +12336 +12340 +12344 +12348 +12351 +12353 +12356 +12357 +12358 +12360 +12359 +12360 +12360 +12360 +12359 +12359 +12358 +12357 +12357 +12356 +12355 +12354 +12353 +12352 +12350 +12348 +12346 +12344 +12342 +12341 +12341 +12340 +12340 +12341 +12340 +12341 +12342 +12343 +12343 +12344 +12345 +12345 +12345 +12345 +12345 +12344 +12344 +12344 +12343 +12342 +12343 +12342 +12342 +12343 +12342 +12343 +12344 +12344 +12345 +12345 +12346 +12348 +12349 +12351 +12352 +12353 +12353 +12355 +12356 +12357 +12356 +12356 +12357 +12357 +12358 +12360 +12360 +12360 +12361 +12361 +12362 +12361 +12360 +12359 +12358 +12356 +12355 +12354 +12352 +12352 +12351 +12351 +12350 +12350 +12350 +12350 +12350 +12351 +12351 +12350 +12351 +12351 +12352 +12351 +12351 +12351 +12350 +12349 +12349 +12347 +12345 +12345 +12343 +12342 +12341 +12339 +12338 +12337 +12336 +12336 +12335 +12336 +12338 +12339 +12342 +12344 +12346 +12349 +12350 +12351 +12355 +12357 +12358 +12360 +12361 +12363 +12364 +12365 +12366 +12366 +12366 +12368 +12368 +12368 +12369 +12369 +12370 +12370 +12369 +12370 +12369 +12368 +12369 +12368 +12367 +12366 +12364 +12364 +12362 +12361 +12360 +12358 +12356 +12355 +12354 +12352 +12352 +12351 +12351 +12351 +12351 +12351 +12351 +12352 +12354 +12355 +12355 +12357 +12358 +12361 +12364 +12365 +12368 +12370 +12372 +12375 +12376 +12378 +12379 +12381 +12383 +12384 +12385 +12387 +12387 +12387 +12388 +12387 +12386 +12385 +12384 +12384 +12383 +12381 +12381 +12381 +12380 +12382 +12381 +12382 +12382 +12382 +12382 +12381 +12378 +12376 +12373 +12370 +12368 +12364 +12361 +12359 +12356 +12355 +12352 +12350 +12349 +12347 +12346 +12347 +12348 +12350 +12352 +12354 +12357 +12359 +12361 +12363 +12365 +12366 +12369 +12370 +12372 +12374 +12376 +12377 +12377 +12378 +12379 +12380 +12380 +12382 +12384 +12387 +12391 +12395 +12400 +12404 +12408 +12413 +12417 +12421 +12426 +12429 +12434 +12439 +12444 +12450 +12454 +12458 +12464 +12469 +12473 +12480 +12485 +12490 +12496 +12502 +12509 +12514 +12519 +12525 +12528 +12533 +12538 +12542 +12546 +12552 +12557 +12564 +12571 +12578 +12588 +12596 +12605 +12613 +12622 +12629 +12637 +12643 +12649 +12655 +12660 +12666 +12670 +12676 +12682 +12688 +12696 +12704 +12711 +12718 +12724 +12730 +12738 +12744 +12748 +12753 +12757 +12764 +12770 +12777 +12783 +12789 +12795 +12803 +12809 +12814 +12820 +12824 +12829 +12833 +12837 +12840 +12843 +12845 +12848 +12850 +12851 +12852 +12853 +12853 +12854 +12853 +12853 +12852 +12850 +12847 +12844 +12840 +12837 +12832 +12828 +12825 +12821 +12817 +12815 +12810 +12807 +12803 +12799 +12794 +12789 +12783 +12779 +12773 +12767 +12762 +12755 +12750 +12744 +12739 +12733 +12727 +12721 +12716 +12709 +12702 +12696 +12688 +12683 +12676 +12669 +12664 +12659 +12654 +12650 +12646 +12641 +12637 +12633 +12629 +12624 +12618 +12613 +12607 +12600 +12594 +12587 +12580 +12573 +12567 +12562 +12557 +12551 +12548 +12543 +12539 +12535 +12530 +12526 +12522 +12518 +12514 +12511 +12507 +12505 +12502 +12499 +12498 +12495 +12493 +12490 +12487 +12484 +12481 +12477 +12474 +12470 +12465 +12462 +12458 +12454 +12451 +12447 +12445 +12443 +12440 +12439 +12437 +12435 +12434 +12432 +12430 +12429 +12427 +12426 +12424 +12422 +12422 +12421 +12420 +12420 +12419 +12419 +12419 +12418 +12418 +12416 +12415 +12415 +12413 +12412 +12412 +12411 +12410 +12409 +12408 +12407 +12405 +12403 +12400 +12397 +12394 +12391 +12388 +12385 +12383 +12381 +12381 +12380 +12379 +12378 +12377 +12376 +12376 +12375 +12373 +12373 +12372 +12372 +12371 +12370 +12371 +12370 +12370 +12371 +12371 +12371 +12372 +12372 +12373 +12372 +12372 +12373 +12373 +12374 +12376 +12376 +12377 +12378 +12379 +12379 +12379 +12378 +12377 +12376 +12374 +12374 +12372 +12371 +12371 +12370 +12371 +12371 +12370 +12370 +12370 +12368 +12368 +12366 +12364 +12364 +12363 +12364 +12363 +12363 +12364 +12365 +12365 +12366 +12366 +12366 +12368 +12367 +12368 +12367 +12366 +12366 +12366 +12365 +12366 +12366 +12365 +12365 +12365 +12365 +12365 +12364 +12364 +12363 +12363 +12364 +12363 +12364 +12364 +12364 +12365 +12365 +12365 +12366 +12366 +12365 +12367 +12367 +12367 +12368 +12368 +12368 +12368 +12367 +12368 +12367 +12366 +12366 +12364 +12363 +12362 +12360 +12360 +12358 +12357 +12357 +12356 +12355 +12356 +12357 +12357 +12359 +12360 +12362 +12363 +12364 +12366 +12366 +12366 +12366 +12365 +12364 +12365 +12364 +12363 +12362 +12361 +12360 +12359 +12357 +12356 +12354 +12352 +12352 +12350 +12350 +12349 +12348 +12348 +12348 +12347 +12348 +12348 +12348 +12349 +12349 +12349 +12349 +12349 +12349 +12348 +12348 +12349 +12350 +12352 +12354 +12354 +12350 +12351 +12352 +12354 +12354 +12354 +12354 +12354 +12354 +12354 +12353 +12354 +12353 +12353 +12352 +12350 +12350 +12348 +12347 +12345 +12345 +12343 +12344 +12343 +12344 +12344 +12345 +12345 +12345 +12346 +12347 +12348 +12349 +12350 +12351 +12354 +12354 +12355 +12355 +12355 +12355 +12356 +12355 +12354 +12354 +12353 +12353 +12352 +12351 +12349 +12347 +12345 +12344 +12341 +12340 +12338 +12335 +12334 +12332 +12331 +12330 +12330 +12329 +12329 +12328 +12329 +12328 +12329 +12328 +12329 +12328 +12328 +12329 +12329 +12330 +12329 +12330 +12330 +12331 +12331 +12332 +12333 +12335 +12337 +12337 +12339 +12340 +12343 +12344 +12345 +12346 +12347 +12347 +12348 +12348 +12349 +12347 +12347 +12346 +12345 +12345 +12344 +12344 +12343 +12343 +12342 +12341 +12340 +12339 +12337 +12337 +12334 +12332 +12332 +12330 +12329 +12327 +12328 +12327 +12329 +12330 +12333 +12334 +12337 +12339 +12342 +12344 +12345 +12348 +12349 +12351 +12353 +12355 +12356 +12358 +12359 +12361 +12361 +12363 +12365 +12366 +12368 +12369 +12371 +12372 +12374 +12374 +12375 +12375 +12376 +12376 +12378 +12378 +12378 +12380 +12382 +12385 +12388 +12391 +12393 +12396 +12399 +12402 +12405 +12409 +12413 +12417 +12420 +12424 +12428 +12433 +12437 +12441 +12446 +12450 +12457 +12462 +12469 +12475 +12482 +12489 +12496 +12505 +12512 +12521 +12528 +12536 +12544 +12553 +12561 +12569 +12576 +12583 +12591 +12599 +12606 +12613 +12621 +12627 +12634 +12641 +12648 +12654 +12661 +12667 +12674 +12681 +12690 +12696 +12702 +12709 +12715 +12722 +12727 +12734 +12738 +12744 +12749 +12755 +12759 +12765 +12770 +12776 +12781 +12786 +12792 +12796 +12801 +12805 +12810 +12813 +12816 +12819 +12823 +12825 +12828 +12829 +12830 +12833 +12835 +12837 +12839 +12842 +12844 +12846 +12847 +12850 +12850 +12851 +12851 +12851 +12850 +12848 +12848 +12846 +12845 +12844 +12842 +12840 +12839 +12836 +12835 +12831 +12828 +12823 +12819 +12815 +12810 +12806 +12800 +12795 +12791 +12786 +12781 +12777 +12772 +12767 +12762 +12757 +12753 +12747 +12742 +12737 +12732 +12728 +12725 +12720 +12716 +12711 +12707 +12702 +12698 +12692 +12686 +12682 +12676 +12672 +12667 +12663 +12657 +12653 +12647 +12643 +12637 +12631 +12624 +12617 +12612 +12605 +12601 +12594 +12590 +12584 +12579 +12573 +12568 +12562 +12557 +12552 +12547 +12543 +12538 +12534 +12530 +12526 +12522 +12519 +12515 +12512 +12509 +12506 +12502 +12500 +12496 +12492 +12488 +12484 +12481 +12476 +12473 +12469 +12466 +12462 +12460 +12457 +12455 +12452 +12449 +12446 +12442 +12440 +12436 +12434 +12432 +12430 +12428 +12427 +12424 +12424 +12421 +12420 +12418 +12416 +12415 +12413 +12412 +12410 +12410 +12408 +12407 +12406 +12405 +12403 +12402 +12400 +12398 +12396 +12394 +12393 +12391 +12390 +12389 +12388 +12387 +12386 +12385 +12384 +12383 +12382 +12380 +12379 +12378 +12377 +12376 +12375 +12375 +12374 +12374 +12373 +12373 +12371 +12371 +12370 +12369 +12369 +12368 +12369 +12368 +12368 +12367 +12367 +12367 +12367 +12367 +12367 +12367 +12367 +12366 +12365 +12365 +12364 +12364 +12363 +12362 +12362 +12361 +12360 +12360 +12360 +12360 +12359 +12358 +12358 +12358 +12358 +12357 +12357 +12356 +12356 +12354 +12354 +12353 +12352 +12351 +12351 +12350 +12349 +12349 +12348 +12348 +12347 +12347 +12347 +12348 +12348 +12349 +12349 +12350 +12350 +12350 +12350 +12349 +12348 +12347 +12347 +12346 +12345 +12344 +12345 +12345 +12346 +12345 +12346 +12346 +12345 +12347 +12347 +12348 +12348 +12350 +12351 +12353 +12354 +12355 +12356 +12357 +12357 +12357 +12358 +12358 +12359 +12359 +12359 +12359 +12359 +12358 +12358 +12357 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 +12356 + diff --git a/src/para.c b/src/para.c new file mode 100644 index 0000000..a9e697a --- /dev/null +++ b/src/para.c @@ -0,0 +1,143 @@ +#include "para.h" +#include "common.h" +#include "string.h" +#include "stdio.h" +#include "minIni.h" +#include "ysp_debug.h" + + +int LoadGasSection(char *sec_name,GAS_CAL_PARA *gas_para) +{ + int i,n; + char key_name[32]; + gas_para->position.start=ini_getl(sec_name,"start",0,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"%s_start=%d\n",sec_name,gas_para->position.start); + gas_para->position.peak=ini_getl(sec_name,"peak",0,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"%s_peak=%d\n",sec_name,gas_para->position.peak); + gas_para->position.end=ini_getl(sec_name,"end",0,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"%s_end=%d\n",sec_name,gas_para->position.end); + gas_para->position.width=ini_getl(sec_name,"width",10,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"%s_width=%d\n",sec_name,gas_para->position.width); + + gas_para->gradient.lYmin=ini_getf(sec_name,"lYmin",0,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"%s_lYmin=%f\n",sec_name,gas_para->gradient.lYmin); + + gas_para->gradient.lXmax=ini_getf(sec_name,"lXmax",0,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"%s_lXmax=%f\n",sec_name,gas_para->gradient.lXmax); + + gas_para->gradient.rYmin=ini_getf(sec_name,"rYmin",0,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"%s_rYmin=%f\n",sec_name,gas_para->gradient.rYmin); + + gas_para->gradient.rXmax=ini_getf(sec_name,"rXmax",0,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"%s_rXmax=%f\n",sec_name,gas_para->gradient.rXmax); + + gas_para->gradient.rXmax=ini_getf(sec_name,"rXmax",0,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"%s_rXmax=%f\n",sec_name,gas_para->gradient.rXmax); + for(i=0;i<12;i++) + { + for(n=0;n<6;n++) + { + sprintf(key_name,"k%d_fac%d",i+1,n+1); + gas_para->correct_fac.k[i].fac[n]=ini_getf(sec_name,key_name,0,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"%s_%s=%f\n",sec_name,key_name,gas_para->correct_fac.k[i].fac[n]); + } + } + return 0; +} + +int LoadAllPara(YSP_PARA *para_ptr) +{ + //float f; + int i; + char key_name[64]; + + ini_gets("MACH","version","1.00",para_ptr->mach_run_para.version,16,ysp_cfg_file); + ini_gets("MACH","station","dummy station",para_ptr->mach_run_para.station,64,ysp_cfg_file); + ini_gets("MACH","device","dummy device",para_ptr->mach_run_para.device,64,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"version=%s\n",para_ptr->mach_run_para.version); + LOG_DEBUG(PARA_TRACE_DEBUG,"station=%s\n",para_ptr->mach_run_para.station); + LOG_DEBUG(PARA_TRACE_DEBUG,"device=%s\n",para_ptr->mach_run_para.device); + para_ptr->mach_run_para.start_hour=ini_getl("MACH","start_hour",10,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"start_hour=%d\n",para_ptr->mach_run_para.start_hour); + //printf("start_hour=%d\n",para_ptr->mach_run_para.start_hour); + para_ptr->mach_run_para.start_minute=ini_getl("MACH","start_minute",0,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"start_minute=%d\n",para_ptr->mach_run_para.start_minute); + //printf("start_minute=%d\n",para_ptr->mach_run_para.start_minute); + para_ptr->mach_run_para.start_interval=ini_getl("MACH","sample_interval",4,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"sample_interval=%d\n",para_ptr->mach_run_para.start_interval); + //printf("sample_interval=%d\n",para_ptr->mach_run_para.start_interval); + for(i=0;i<8;i++) + { + sprintf(key_name,"pres%d_fac_a",i+1); + para_ptr->mach_run_para.pres_fac[i].a=ini_getf("MACH",key_name,0.4,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"%s=%f\n",key_name,para_ptr->mach_run_para.pres_fac[i].a); + sprintf(key_name,"pres%d_fac_b",i+1); + para_ptr->mach_run_para.pres_fac[i].b=ini_getf("MACH",key_name,0,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"%s=%f\n",key_name,para_ptr->mach_run_para.pres_fac[i].b); + } + para_ptr->mach_run_para.volt_output[0]=ini_getf("MACH","volt_out1",0,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"volt_out1=%f\n",para_ptr->mach_run_para.volt_output[0]); + para_ptr->mach_run_para.volt_output[1]=ini_getf("MACH","volt_out2",0,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"volt_out2=%f\n",para_ptr->mach_run_para.volt_output[1]); + para_ptr->mach_run_para.temperature[0]=ini_getf("MACH","temp1",60,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"temp1=%f\n",para_ptr->mach_run_para.temperature[0]); + para_ptr->mach_run_para.temperature[1]=ini_getf("MACH","temp2",60,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"temp2=%f\n",para_ptr->mach_run_para.temperature[1]); + para_ptr->mach_run_para.temperature[2]=ini_getf("MACH","temp3",-40,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"temp3=%f\n",para_ptr->mach_run_para.temperature[2]); + para_ptr->mach_run_para.temperature[3]=ini_getf("MACH","temp3",0,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"temp3=%f\n",para_ptr->mach_run_para.temperature[3]); + for(i=0;i<4;i++) + { + sprintf(key_name,"pid_en%d",i+1); + para_ptr->mach_run_para.pid_en[i]=ini_getf("MACH",key_name,0,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"%s=%d\n",key_name,para_ptr->mach_run_para.pid_en[i]); + } + + for(i=0;i<4;i++) + { + sprintf(key_name,"kp%d",i+1); + para_ptr->mach_run_para.pid_type_def[i].Kp=ini_getf("MACH",key_name,12,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"%s=%f\n",key_name,para_ptr->mach_run_para.pid_type_def[i].Kp); + sprintf(key_name,"ki%d",i+1); + para_ptr->mach_run_para.pid_type_def[i].Ki=ini_getf("MACH",key_name,0.15,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"%s=%f\n",key_name,para_ptr->mach_run_para.pid_type_def[i].Ki); + sprintf(key_name,"kd%d",i+1); + para_ptr->mach_run_para.pid_type_def[i].Kd=ini_getf("MACH",key_name,500,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"%s=%f\n",key_name,para_ptr->mach_run_para.pid_type_def[i].Kd); + } + para_ptr->mach_run_para.sample_len=ini_getl("MACH","sample_len",4000,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"sample_len=%d\n",para_ptr->mach_run_para.sample_len); + para_ptr->mach_run_para.sample_rate=ini_getl("MACH","sample_rate",220,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"sample_rate=%d\n",para_ptr->mach_run_para.sample_rate); + para_ptr->mach_run_para.sample_offs=ini_getl("MACH","sample_offs",1800,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"sample_offs=%d\n",para_ptr->mach_run_para.sample_offs); + + para_ptr->mach_run_para.sample_cool_en=ini_getl("MACH","sample_cool_en",0,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"sample_cool_en=%d\n",para_ptr->mach_run_para.sample_cool_en); + + para_ptr->mach_run_para.co2_pos=ini_getl("MACH","co2_pos",0,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"co2_pos=%d\n",para_ptr->mach_run_para.co2_pos); + + para_ptr->mach_run_para.h2o_en=ini_getl("MACH","h2o_en",0,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"h2o_en=%d\n",para_ptr->mach_run_para.h2o_en); + + para_ptr->mach_run_para.auto_gas_en=ini_getl("MACH","auto_gas_en",0,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"auto_gas_en=%d\n",para_ptr->mach_run_para.auto_gas_en); + + para_ptr->mach_run_para.run_mode=ini_getl("MACH","run_mode",0,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"run_mode=%d\n",para_ptr->mach_run_para.run_mode); + + para_ptr->mach_run_para.upload_time=ini_getl("MACH","upload_time",0,ysp_cfg_file); + LOG_DEBUG(PARA_TRACE_DEBUG,"upload_time=%d\n",para_ptr->mach_run_para.upload_time); + + LoadGasSection("H2_CAL",¶_ptr->gas_cal_fac[0]); + LoadGasSection("CO_CAL",¶_ptr->gas_cal_fac[1]); + LoadGasSection("CH4_CAL",¶_ptr->gas_cal_fac[2]); + LoadGasSection("C2H4_CAL",¶_ptr->gas_cal_fac[3]); + LoadGasSection("C2H6_CAL",¶_ptr->gas_cal_fac[4]); + LoadGasSection("C2H2_CAL",¶_ptr->gas_cal_fac[5]); + LoadGasSection("CO2_CAL",¶_ptr->co2_cal_fac); + return 0; +} + diff --git a/src/para.h b/src/para.h new file mode 100644 index 0000000..3856be6 --- /dev/null +++ b/src/para.h @@ -0,0 +1,14 @@ +#ifndef _PARA_H +#define _PARA_H + +#include "common.h" + +#define ysp_cfg_file "/usr_app/ysp_cfg.ini" + + +int LoadAllPara(YSP_PARA *para_ptr); + +#define INI_DEBUG + +#endif + diff --git a/src/rcS b/src/rcS new file mode 100644 index 0000000..912f166 --- /dev/null +++ b/src/rcS @@ -0,0 +1,159 @@ +#!/bin/sh + +# insmod modules and select an appropriate pointercal file depends on the bootargs +#if grep "lcd7ic" /proc/cmdline > /dev/null; then +# insmod /lib/modules/3.2.0/kernel/drivers/ft5x0x.ko +# ln -sf /etc/pointercal_7.0c /etc/pointercal +#elif grep "hdmi" /proc/cmdline > /dev/null; then +# insmod /lib/modules/3.2.0/kernel/drivers/tda998x.ko +#else +# insmod /lib/modules/3.2.0/kernel/drivers/ti_tscadc.ko +#fi + +#if grep "lcd4i3" /proc/cmdline > /dev/null; then +# ln -sf /etc/pointercal_4.3 /etc/pointercal +#elif grep "lcd7ir" /proc/cmdline > /dev/null; then +# ln -sf /etc/pointercal_7.0r /etc/pointercal +#fi + +# Set the QT env +#if [ -e /etc/init.d/qt.sh ];then +# . /etc/init.d/qt.sh +#fi + +export HOME=/root + +echo 60 > /proc/sys/net/ipv4/tcp_keepalive_time +echo 8 > /proc/sys/net/ipv4/tcp_keepalive_intvl +echo 4 > /proc/sys/net/ipv4/tcp_keepalive_probes + +if [ -f /COMTRADE/S81srvrd ];then + #if [ -f /etc/init.d/S81srvrd ];then + # echo -n "now backup S81srvrd" + # mv /etc/init.d/S81srvrd /etc/init.d/K81srvrd + #fi + echo -n "now update S81srvrd" + mv /COMTRADE/S81srvrd /etc/init.d/S81srvrd + chmod +x /etc/init.d/S81srvrd +fi + +if [ -f /COMTRADE/S90app ];then + #if [ -f /etc/init.d/S90app ];then + # echo -n "now backup S90app" + # mv /etc/init.d/S90app /etc/init.d/K90app + #fi + echo -n "now update S90app" + mv /COMTRADE/S90app /etc/init.d/S90app + chmod +x /etc/init.d/S90app +fi + +if [ -f /COMTRADE/S71ntpdate ];then + #if [ -f /etc/init.d/S71ntpdate ];then + # echo -n "now backup S71ntpdate" + # mv /etc/init.d/S71ntpdate /etc/init.d/K71ntpdate + #fi + echo -n "now update S71ntpdate" + mv /COMTRADE/S71ntpdate /etc/init.d/S71ntpdate + chmod +x /etc/init.d/S71ntpdate +fi + +if [ -f /COMTRADE/app ];then + #if [ -f /usr_app/app ];then + # echo "now backup user app" + # mv /usr_app/app /usr_app/app_bk + #fi + echo "now update user app" + mv /COMTRADE/app /usr_app/app + chmod +x /usr_app/app +fi + +if [ -f /COMTRADE/scl_srvr_ld ];then + #if [ -f "$srvrd" ];then + # echo -n "now backup srvrd" + # mv "$srvrd" /usr/sbin/scl_srvr_bk + #fi + echo -n "now update srvrd" + mv /COMTRADE/scl_srvr_ld /usr/sbin/scl_srvr_ld + chmod +x /usr/sbin/scl_srvr_ld +fi + +if [ -f /COMTRADE/TEMPLATE.icd ];then + if [ -f /scl_srvr/TEMPLATE.icd ];then + echo -n "now backup icd" + mv /scl_srvr/TEMPLATE.icd /scl_srvr/TEMPLATE.bk + fi + echo -n "now update icd" + mv /COMTRADE/TEMPLATE.icd /scl_srvr/TEMPLATE.icd +fi + +if [ -f /COMTRADE/datamap.cfg ];then + if [ -f /scl_srvr/datamap.cfg ];then + echo -n "now backup datamap" + mv /scl_srvr/datamap.cfg /scl_srvr/datamap.bk + fi + echo -n "now update datamap" + mv /COMTRADE/datamap.cfg /scl_srvr/datamap.cfg +fi + +if [ -f /COMTRADE/startup.cfg ];then + if [ -f /scl_srvr/startup.cfg ];then + echo -n "now backup startup" + mv /scl_srvr/startup.cfg /scl_srvr/startup.bk + fi + echo -n "now update startup" + mv /COMTRADE/startup.cfg /scl_srvr/startup.cfg +fi + +if [ -f /COMTRADE/osicfg.xml ];then + if [ -f /scl_srvr/osicfg.xml ];then + echo -n "now backup osicfg" + mv /scl_srvr/osicfg.xml /scl_srvr/osicfg.bk + fi + echo -n "now update osicfg" + mv /COMTRADE/osicfg.xml /scl_srvr/osicfg.xml +fi + +if [ -f /COMTRADE/interfaces ];then + if [ -f /etc/network/interfaces ];then + echo -n "now backup interfaces" + mv /etc/network/interfaces /etc/network/bkinterfaces + fi + echo -n "now update interfaces" + mv /COMTRADE/interfaces /etc/network/interfaces + chmod +x /etc/network/interfaces +fi + +if [ -f /COMTRADE/ntpdate ];then + #if [ -f /usr/sbin/ntpdate ];then + # echo -n "now backup ntpdate" + # mv /usr/sbin/ntpdate /usr/sbin/bkntpdate + #fi + echo -n "now update ntpdate" + mv /COMTRADE/ntpdate /usr/sbin/ntpdate + chmod +x /usr/sbin/ntpdate +fi + + +# Start all init scripts in /etc/init.d +# executing them in numerical order. +# +for i in /etc/init.d/S??* ;do + + # Ignore dangling symlinks (if any). + [ ! -f "$i" ] && continue + + case "$i" in + *.sh) + # Source shell script for speed. + ( + trap - INT QUIT TSTP + set start + . $i + ) + ;; + *) + # No sh extension, so fork subprocess. + $i start + ;; + esac +done diff --git a/src/reduce.csv b/src/reduce.csv new file mode 100644 index 0000000..368453c --- /dev/null +++ b/src/reduce.csv @@ -0,0 +1,4001 @@ +65 +65 +65 +65 +65 +68 +71 +73 +75 +77 +78 +80 +81 +82 +83 +84 +85 +86 +87 +87 +87 +87 +87 +86 +86 +86 +86 +86 +87 +87 +88 +89 +90 +90 +91 +91 +91 +91 +91 +91 +91 +91 +91 +91 +91 +92 +92 +93 +94 +94 +95 +96 +97 +98 +100 +101 +101 +102 +103 +104 +104 +104 +104 +104 +104 +104 +104 +104 +104 +104 +104 +103 +103 +103 +102 +102 +102 +101 +101 +100 +100 +100 +99 +99 +99 +99 +100 +100 +101 +102 +102 +102 +103 +103 +103 +103 +103 +102 +102 +102 +102 +102 +102 +102 +102 +102 +102 +102 +103 +103 +103 +104 +104 +104 +104 +105 +105 +105 +105 +105 +105 +105 +104 +104 +103 +103 +102 +102 +101 +100 +99 +99 +98 +97 +96 +96 +95 +95 +94 +94 +94 +94 +94 +94 +94 +95 +95 +96 +96 +97 +97 +97 +97 +98 +97 +97 +97 +97 +97 +97 +97 +97 +97 +97 +97 +98 +98 +98 +99 +99 +100 +100 +100 +101 +101 +101 +102 +102 +103 +103 +104 +104 +105 +105 +105 +106 +106 +107 +107 +107 +107 +107 +107 +107 +107 +106 +106 +106 +105 +105 +105 +104 +104 +104 +104 +104 +104 +104 +104 +104 +104 +104 +104 +104 +104 +104 +104 +105 +106 +108 +112 +116 +123 +131 +143 +158 +176 +199 +227 +260 +297 +340 +387 +438 +493 +550 +610 +669 +729 +787 +844 +899 +950 +1000 +1046 +1089 +1129 +1166 +1200 +1232 +1260 +1286 +1309 +1329 +1346 +1360 +1370 +1377 +1379 +1378 +1373 +1363 +1350 +1332 +1310 +1284 +1256 +1223 +1189 +1151 +1113 +1072 +1032 +991 +950 +910 +870 +832 +795 +760 +726 +694 +663 +634 +607 +581 +557 +534 +513 +493 +475 +457 +441 +426 +411 +398 +385 +374 +363 +352 +343 +334 +326 +318 +311 +304 +298 +292 +287 +283 +279 +276 +274 +272 +272 +272 +275 +278 +283 +290 +299 +310 +322 +336 +350 +366 +382 +398 +415 +431 +448 +464 +479 +493 +508 +521 +533 +545 +555 +565 +574 +582 +589 +595 +599 +603 +605 +606 +605 +603 +600 +595 +589 +581 +572 +562 +550 +538 +524 +510 +495 +480 +465 +449 +433 +418 +403 +389 +375 +362 +349 +338 +327 +316 +307 +298 +289 +281 +273 +266 +259 +253 +247 +242 +237 +233 +229 +224 +221 +217 +214 +210 +207 +204 +201 +198 +195 +193 +190 +188 +186 +184 +183 +181 +180 +179 +178 +177 +176 +175 +174 +173 +172 +171 +171 +170 +169 +168 +167 +166 +165 +164 +163 +162 +161 +160 +160 +159 +158 +157 +156 +155 +154 +153 +152 +151 +150 +149 +148 +147 +146 +145 +145 +144 +144 +143 +143 +142 +142 +141 +141 +140 +139 +139 +138 +137 +137 +136 +135 +135 +134 +134 +133 +133 +133 +132 +132 +132 +132 +132 +131 +131 +131 +131 +131 +131 +131 +131 +131 +132 +132 +133 +135 +136 +137 +139 +141 +143 +145 +147 +149 +151 +153 +155 +157 +159 +161 +162 +164 +166 +168 +169 +170 +172 +173 +174 +175 +176 +176 +177 +177 +177 +177 +176 +175 +175 +174 +173 +172 +170 +169 +167 +166 +164 +163 +161 +159 +158 +156 +155 +153 +152 +150 +149 +148 +147 +146 +145 +144 +144 +143 +142 +141 +140 +140 +139 +138 +136 +136 +134 +133 +132 +131 +131 +130 +129 +128 +128 +127 +127 +127 +126 +127 +127 +127 +127 +128 +128 +128 +128 +129 +129 +129 +130 +130 +130 +131 +131 +131 +131 +131 +131 +131 +131 +130 +130 +130 +130 +130 +130 +131 +131 +131 +131 +132 +132 +132 +132 +132 +132 +132 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +130 +130 +130 +130 +130 +130 +130 +131 +131 +131 +131 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +130 +130 +130 +130 +130 +129 +129 +129 +129 +128 +128 +128 +128 +127 +127 +127 +127 +127 +126 +126 +126 +126 +126 +126 +126 +126 +126 +126 +127 +127 +127 +127 +127 +128 +128 +128 +128 +128 +128 +129 +129 +129 +130 +130 +131 +131 +131 +132 +132 +133 +133 +133 +133 +133 +133 +133 +133 +133 +133 +133 +133 +132 +132 +132 +132 +132 +131 +131 +131 +131 +131 +131 +131 +130 +130 +130 +130 +130 +130 +130 +130 +130 +130 +130 +130 +130 +130 +130 +130 +130 +130 +130 +130 +130 +131 +131 +131 +131 +132 +132 +132 +132 +132 +132 +132 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +130 +130 +130 +130 +130 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +130 +130 +130 +130 +131 +131 +131 +131 +132 +132 +132 +132 +133 +133 +133 +134 +134 +134 +135 +135 +135 +136 +136 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +147 +148 +150 +151 +153 +155 +156 +158 +160 +163 +165 +167 +170 +173 +176 +178 +181 +184 +186 +189 +192 +195 +197 +200 +203 +206 +208 +211 +214 +217 +220 +222 +225 +228 +231 +234 +236 +239 +242 +245 +247 +250 +252 +254 +256 +258 +260 +262 +263 +265 +266 +268 +269 +270 +271 +272 +272 +273 +273 +273 +274 +274 +274 +274 +273 +273 +272 +272 +271 +270 +269 +268 +266 +265 +263 +261 +260 +257 +255 +253 +251 +249 +246 +244 +242 +239 +237 +235 +232 +230 +228 +225 +223 +221 +218 +216 +214 +211 +209 +207 +204 +202 +200 +198 +196 +194 +192 +190 +188 +186 +184 +182 +180 +178 +177 +175 +173 +172 +170 +169 +167 +166 +165 +164 +163 +162 +161 +160 +159 +158 +157 +157 +156 +155 +154 +153 +152 +152 +151 +150 +149 +149 +148 +147 +147 +146 +145 +145 +144 +144 +144 +143 +143 +142 +142 +142 +141 +141 +141 +141 +141 +140 +140 +140 +140 +139 +139 +139 +139 +138 +138 +138 +138 +137 +137 +137 +137 +137 +136 +136 +136 +136 +136 +136 +136 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +134 +134 +134 +134 +133 +133 +133 +133 +133 +133 +132 +132 +132 +132 +132 +132 +132 +133 +133 +133 +133 +133 +133 +133 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +135 +134 +135 +135 +134 +134 +134 +134 +134 +133 +133 +133 +132 +132 +132 +132 +132 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +132 +131 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +131 +131 +131 +131 +131 +131 +131 +131 +131 +130 +130 +130 +130 +130 +130 +130 +129 +129 +130 +130 +130 +130 +130 +130 +131 +131 +131 +131 +131 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +133 +133 +133 +133 +133 +133 +133 +133 +133 +133 +133 +133 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +135 +135 +135 +135 +135 +135 +135 +136 +136 +136 +137 +137 +138 +138 +139 +139 +140 +141 +141 +142 +143 +144 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +161 +162 +163 +164 +166 +167 +168 +170 +171 +173 +174 +175 +177 +178 +179 +181 +182 +183 +185 +186 +188 +189 +191 +192 +193 +194 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +208 +209 +210 +211 +211 +212 +213 +213 +214 +214 +215 +215 +215 +216 +216 +216 +216 +216 +216 +216 +216 +216 +216 +216 +215 +215 +215 +214 +214 +213 +213 +212 +212 +211 +210 +209 +208 +207 +206 +205 +203 +202 +200 +199 +198 +196 +195 +193 +192 +191 +190 +189 +188 +187 +186 +184 +183 +182 +181 +180 +179 +178 +177 +176 +175 +174 +173 +172 +171 +170 +170 +169 +168 +168 +167 +166 +166 +165 +164 +164 +163 +162 +161 +160 +160 +159 +158 +157 +156 +155 +154 +153 +152 +152 +151 +151 +150 +150 +149 +149 +148 +148 +148 +147 +147 +147 +146 +146 +145 +145 +145 +144 +144 +144 +143 +143 +143 +143 +143 +143 +143 +142 +142 +142 +142 +142 +142 +141 +141 +141 +141 +141 +140 +140 +140 +140 +140 +140 +140 +140 +139 +139 +139 +139 +139 +139 +139 +139 +138 +138 +138 +138 +139 +139 +139 +139 +139 +139 +139 +139 +139 +139 +138 +139 +138 +138 +138 +138 +138 +138 +138 +138 +138 +138 +138 +138 +138 +138 +138 +138 +137 +137 +137 +137 +137 +137 +137 +137 +137 +137 +137 +136 +136 +136 +136 +136 +136 +137 +137 +137 +137 +137 +137 +137 +137 +137 +137 +137 +137 +137 +137 +137 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +136 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +134 +134 +134 +134 +134 +133 +133 +133 +133 +133 +133 +133 +133 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +132 +131 +132 +132 +132 +132 +132 +132 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +130 +130 +130 +130 +130 +130 +130 +130 +131 +131 +131 +132 +132 +132 +132 +133 +133 +133 +133 +133 +133 +133 +133 +133 +133 +133 +133 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +135 +135 +135 +135 +135 +135 +135 +136 +136 +136 +136 +136 +136 +136 +136 +136 +137 +137 +137 +137 +137 +137 +138 +138 +138 +139 +139 +140 +140 +141 +142 +143 +143 +144 +145 +146 +147 +147 +148 +149 +149 +150 +150 +151 +151 +152 +152 +152 +153 +154 +154 +155 +156 +157 +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 +198 +199 +200 +201 +201 +202 +202 +203 +203 +204 +204 +204 +205 +205 +205 +206 +206 +206 +207 +207 +207 +207 +208 +208 +208 +207 +207 +207 +207 +207 +207 +206 +206 +206 +206 +205 +205 +205 +204 +204 +204 +203 +202 +202 +201 +200 +199 +199 +198 +197 +196 +195 +194 +193 +192 +192 +190 +190 +189 +188 +187 +186 +185 +184 +183 +182 +181 +180 +180 +179 +178 +177 +176 +176 +175 +174 +173 +172 +171 +170 +169 +169 +168 +167 +166 +165 +164 +164 +163 +162 +161 +160 +159 +158 +158 +157 +156 +155 +155 +154 +154 +153 +153 +152 +151 +151 +150 +150 +149 +148 +148 +147 +146 +146 +145 +145 +144 +144 +144 +143 +143 +142 +142 +142 +141 +141 +140 +140 +139 +139 +139 +138 +138 +138 +138 +137 +137 +137 +137 +136 +136 +136 +136 +136 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +135 +134 +134 +134 +133 +133 +133 +132 +132 +132 +132 +132 +131 +131 +131 +131 +131 +131 +131 +131 +131 +131 +132 +132 +132 +132 +131 +131 +131 +131 +131 +131 +131 +131 +130 +130 +130 +130 +130 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +130 +130 +130 +130 +130 +130 +130 +130 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +130 +130 +130 +130 +130 +130 +130 +130 +130 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +129 +130 +130 +130 +130 +130 +130 +130 +130 +131 +131 +131 +131 +131 +131 +131 +132 +132 +132 +132 +132 +132 +132 +133 +133 +133 +133 +133 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 +134 + diff --git a/src/result.txt b/src/result.txt new file mode 100644 index 0000000..a87238c --- /dev/null +++ b/src/result.txt @@ -0,0 +1,21 @@ + +//COǶԵ +find_mask=0 +start=283 peak=332 area=0.000000 +start=500 peak=500 area=0.000000 +start=596 peak=629 area=0.000000 +start=2185 peak=2274 area=0.000000 +start=2830 peak=2910 area=0.000000 +start=3439 peak=3524 area=0.000000 +H2=0.000000 CO=0.000000 CH4=0.000000 C2H4=0.000000 C2H6=0.000000 C2H2=0.000000 + + + +find_mask=61 +start=281 peak=332 area=2194.000000 +start=-1 peak=332 area=0.000000 +start=595 peak=629 area=655.000000 +start=2066 peak=2274 area=24486.439453 +start=2805 peak=2910 area=6110.720215 +start=3409 peak=3524 area=7706.600098 +H2=4.442850 CO=0.000000 CH4=3.046405 C2H4=2.962859 C2H6=1.454351 C2H2=1.140577 diff --git a/src/sample_process.c b/src/sample_process.c new file mode 100644 index 0000000..de44094 --- /dev/null +++ b/src/sample_process.c @@ -0,0 +1,734 @@ +#include +#include +#include +#include "serial.h" +#include "common.h" +#include "sample_process.h" +#include "analysis.h" +#include "ysp_debug.h" + +#define COMTADE_DIR "/COMTRADE" + +#define VIN 4.096 //ѹ +#define GND_OFFS 0.254 //˷׼ƫ +#define AMP 5.94 //˷ŷŴ +#define IN_OFFS //˷Ÿƫõѹ +#define MCU_VREF 3.3 +/* +typedef struct{ +unsigned int data_flg1; +unsigned int data_flg2; +float cold_temp; +unsigned char working_state[2]; +unsigned char relay_state[4]; +unsigned char sensor_state[4]; +unsigned char health_state; +}SAMPLE_INPUT_TYPE; +*/ + +/* +typedef struct{ +unsigned char relay_ctrl[4]; +unsigned char sensor_ctrl[4]; +unsigned int sample_interval; +unsigned int sample_length; +float temperature; +//PID_SET pid_para; +unsigned int rsv[3]; +}SAMPLE_OUTPUT_TYPE; +*/ +static const char *dir_store_data=COMTADE_DIR; +static unsigned char sample_rx_buf[SEGMENT_LENGTH+7]; +static unsigned char sample_tx_buf[128]; +static unsigned short data_buf[10000]; +extern int sample_fd; + +//SAMPLE_OUTPUT_TYPE sample_output_data; +//SAMPLE_INPUT_TYPE sample_input_data; + + + +unsigned int sample_encode(unsigned char *buf,unsigned char cmd,void *args,unsigned int args_len) +{ + unsigned int length=7; + buf[0]=0xAA; + buf[1]=0x1;//address + buf[2]=(unsigned char)args_len; + buf[3]=(unsigned char)(args_len>>8); + buf[4]=cmd; + if(args!=NULL&&args_len!=0) + { + memcpy(&buf[5],(unsigned char *)args,args_len); + length=args_len+7; + } + buf[length-2]=cal_sum(buf,length-2); + buf[length-1]=0x55; + return length; +} + +int sample_check(unsigned char *buf,unsigned char cmd,unsigned int buf_len) +{ + unsigned int length; + if(buf[0]!=0xAA) + return -1; + if(buf[buf_len-1]!=0x55) + return -2; + if(buf[4]!=cmd) + return -3; + length=(unsigned int)256*buf[3]+buf[2]; + if((length+7)!=buf_len) + return -4; + if(chk_sum(buf,buf_len-2,buf[buf_len-2])!=0) + return -5; + return 0; +} + + +//ѯǷв +unsigned int query_sample_data(unsigned char *ret_data,int len) +{ + int length; + int chk_rlt; + length=sample_encode(sample_tx_buf,CMD_NORMAL_READ,NULL,0); + if(SerialWrite(sample_fd,sample_tx_buf,length)=(len+7)) + { + if((chk_rlt=sample_check(sample_rx_buf,CMD_NORMAL_READ,length))==0) + { + memcpy(&my_sample_data,&sample_rx_buf[5],sizeof(my_sample_data)); + //if(ret_data!=NULL&&len!=0) + if(ret_data!=NULL) + memcpy(ret_data,&my_sample_data.data_flg,sizeof(unsigned int)); + return 0; + } + else + { + LOG_DEBUG(ERROR_DEBUG,"query_sample_data chk_rlt=%d\n",chk_rlt); + } + } + else + { + LOG_DEBUG(ERROR_DEBUG,"query_sample_data read resp failed length=%d\n",length); + return 2; + } + return 3; +} + +/* +unsigned int query_sample_data_ex(unsigned char *ret_data,int len) +{ + int length; + length=sample_encode(sample_tx_buf,CMD_NORMAL_READ,NULL,0); + if(SerialWrite(sample_fd,sample_tx_buf,length)=(sizeof(SAMPLE_INPUT_TYPE)+7)) + { + if(sample_check(sample_rx_buf,CMD_NORMAL_READ,length)==0) + { + if(ret_data!=NULL&&len!=0) + memcpy(ret_data,&sample_rx_buf[5],len); + return 0; + } + } + else + { + return 2; + } + return 3; +}*/ + + +// +unsigned int clear_sample_data(void) +{ + int length; + length=sample_encode(sample_tx_buf,CMD_CLR_DATA,NULL,0); + if(SerialWrite(sample_fd,sample_tx_buf,length)=8) + { + if(sample_check(sample_rx_buf,CMD_CLR_DATA,length)==0) + { + if(sample_rx_buf[5]==SUCCESSFULL) + return 0; + } + else + { + LOG_DEBUG(ERROR_DEBUG,"clear_sample_data check sum error\n"); + } + } + else + { + LOG_DEBUG(ERROR_DEBUG,"clear_sample_data read resp failed length=%d\n",length); + return 2; + } + return 3; +} + + +// +unsigned int clear_co2_data(void) +{ + int length; + length=sample_encode(sample_tx_buf,CMD_CLR_CO2,NULL,0); + if(SerialWrite(sample_fd,sample_tx_buf,length)=8) + { + if(sample_check(sample_rx_buf,CMD_CLR_CO2,length)==0) + { + if(sample_rx_buf[5]==SUCCESSFULL) + return 0; + } + else + { + LOG_DEBUG(ERROR_DEBUG,"clear_co2_data check sum error\n"); + } + } + else + { + LOG_DEBUG(ERROR_DEBUG,"clear_co2_data read resp failed length=%d\n",length); + return 2; + } + return 3; +} + +// +int start_sample_data(unsigned int ch,SAMPLE_PARA_TYPE *sample_para) +{ + int length; + unsigned char arg_buf[12]; + arg_buf[0]=(unsigned char)ch; + arg_buf[1]=(unsigned char)(ch>>8); + arg_buf[2]=(unsigned char)(sample_para->len); + arg_buf[3]=(unsigned char)((sample_para->len)>>8); + arg_buf[4]=(unsigned char)(sample_para->intval); + arg_buf[5]=(unsigned char)((sample_para->intval)>>8); + arg_buf[6]=(unsigned char)(sample_para->offs); + arg_buf[7]=(unsigned char)((sample_para->offs)>>8); + arg_buf[8]=(unsigned char)(sample_para->co2_pos); + arg_buf[9]=(unsigned char)((sample_para->co2_pos)>>8); + arg_buf[10]=(unsigned char)(sample_para->co2_len); + arg_buf[11]=(unsigned char)((sample_para->co2_len)>>8); + length=sample_encode(sample_tx_buf,CMD_START_SAMPLE,arg_buf,sizeof(arg_buf)); + if(SerialWrite(sample_fd,sample_tx_buf,length)=8) + { + if(sample_check(sample_rx_buf,CMD_START_SAMPLE,length)==0) + { + if(sample_rx_buf[5]==SUCCESSFULL) + return 0; + } + else + { + LOG_DEBUG(ERROR_DEBUG,"start_sample_data check sum error\n"); + } + } + else + { + LOG_DEBUG(ERROR_DEBUG,"start_sample_data read resp failed length=%d\n",length); + return 2; + } + return 3; +} + +/* +// +int start_sample_heat(unsigned char ch,unsigned char flg) +{ + int length; + unsigned char buf[2]; + buf[0]=ch; + buf[1]=flg; + length=sample_encode(sample_tx_buf,CMD_SET_RLY,buf,sizeof(buf)); + if(SerialWrite(sample_fd,sample_tx_buf,length)=8) + { + if(sample_check(sample_rx_buf,CMD_SET_RLY,length)==0) + { + if(sample_rx_buf[5]==SUCCESSFULL) + return 0; + } + } + else + { + return 2; + } + return 3; +}*/ + +// +//start_pos=ʼλ(ֽ),len=ȡ(ֽ) +int read_co2_segment(int start_pos,int len) +{ + int length; + unsigned char arg_buf[4]; + unsigned char *ptr; + ptr=(unsigned char *)&data_buf[0]; + arg_buf[0]=(unsigned char)start_pos; + arg_buf[1]=(unsigned char)(start_pos>>8); + arg_buf[2]=(unsigned char)len; + arg_buf[3]=(unsigned char)(len>>8); + length=sample_encode(sample_tx_buf,CMD_READ_CO2,arg_buf,sizeof(arg_buf)); + if(SerialWrite(sample_fd,sample_tx_buf,length)=(len+7)) + { + if(sample_check(sample_rx_buf,CMD_READ_CO2,length)==0) + { + ptr+=start_pos; + memcpy((void *)ptr,(const void *)&sample_rx_buf[5],len); + return 0; + } + else + { + LOG_DEBUG(ERROR_DEBUG,"read_co2_segment check sum failed\n"); + } + } + else + { + LOG_DEBUG(ERROR_DEBUG,"read_co2_segment read resp failed:received %d bytes\n",length); + return 2; + } + return 3; +} + +//total_lenֽڳ +unsigned int read_co2_data(unsigned int total_len) +{ + unsigned int i; + for(i=0;i<(total_len/SEGMENT_LENGTH);i++) + { + if(read_co2_segment(i*SEGMENT_LENGTH,SEGMENT_LENGTH)!=0) + { + LOG_DEBUG(ERROR_DEBUG,"read co2 segment %d total_len=%d failed\n",i,total_len); + if(read_co2_segment(i*SEGMENT_LENGTH,SEGMENT_LENGTH)!=0) + { + LOG_DEBUG(ERROR_DEBUG,"read co2 segment %d failed\n",i); + if(read_co2_segment(i*SEGMENT_LENGTH,SEGMENT_LENGTH)!=0) + { + if(read_co2_segment(i*SEGMENT_LENGTH,SEGMENT_LENGTH)!=0) + { + if(read_co2_segment(i*SEGMENT_LENGTH,SEGMENT_LENGTH)!=0) + { + LOG_DEBUG(ERROR_DEBUG,"read co2 segment %d failed\n",i); + return i+1; + } + //LOG_DEBUG(ERROR_DEBUG,"read segment %d failed\n",i); + //return i+1; + } + //LOG_DEBUG(ERROR_DEBUG,"read segment %d failed\n",i); + //return i+1; + } + } + } + } + if((total_len%SEGMENT_LENGTH)!=0) + { + //printf("read segment %d\n",i); + if(read_co2_segment(i*SEGMENT_LENGTH,total_len%SEGMENT_LENGTH)!=0) + { + LOG_DEBUG(ERROR_DEBUG,"read co2 segment %d failed\n",i); + if(read_co2_segment(i*SEGMENT_LENGTH,total_len%SEGMENT_LENGTH)!=0) + { + LOG_DEBUG(ERROR_DEBUG,"read co2 segment %d failed\n",i); + if(read_co2_segment(i*SEGMENT_LENGTH,total_len%SEGMENT_LENGTH)!=0) + { + LOG_DEBUG(ERROR_DEBUG,"read co2 segment %d failed\n",i); + return i+1; + } + } + } + } + return 0; +} + + + +// +//start_pos=ʼλ(ֽ),len=ȡ(ֽ) +int read_segment_data(int start_pos,int len) +{ + int length; + unsigned char arg_buf[4]; + unsigned char *ptr; + ptr=(unsigned char *)&data_buf[0]; + arg_buf[0]=(unsigned char)start_pos; + arg_buf[1]=(unsigned char)(start_pos>>8); + arg_buf[2]=(unsigned char)len; + arg_buf[3]=(unsigned char)(len>>8); + length=sample_encode(sample_tx_buf,CMD_READ_SAMPLE,arg_buf,sizeof(arg_buf)); + if(SerialWrite(sample_fd,sample_tx_buf,length)=(len+7)) + { + if(sample_check(sample_rx_buf,CMD_READ_SAMPLE,length)==0) + { + ptr+=start_pos; + memcpy((void *)ptr,(const void *)&sample_rx_buf[5],len); + return 0; + } + else + { + LOG_DEBUG(ERROR_DEBUG,"read_segment_data check sum failed\n"); + } + } + else + { + LOG_DEBUG(ERROR_DEBUG,"read_segment_data read resp failed:received %d bytes\n",length); + return 2; + } + return 3; +} + +//total_lenֽڳ +unsigned int read_sample_data(unsigned int total_len) +{ + unsigned int i; + for(i=0;i<(total_len/SEGMENT_LENGTH);i++) + { + if(read_segment_data(i*SEGMENT_LENGTH,SEGMENT_LENGTH)!=0) + { + LOG_DEBUG(ERROR_DEBUG,"read segment %d total_len=%d failed\n",i,total_len); + if(read_segment_data(i*SEGMENT_LENGTH,SEGMENT_LENGTH)!=0) + { + LOG_DEBUG(ERROR_DEBUG,"read segment %d failed\n",i); + if(read_segment_data(i*SEGMENT_LENGTH,SEGMENT_LENGTH)!=0) + { + if(read_segment_data(i*SEGMENT_LENGTH,SEGMENT_LENGTH)!=0) + { + if(read_segment_data(i*SEGMENT_LENGTH,SEGMENT_LENGTH)!=0) + { + LOG_DEBUG(ERROR_DEBUG,"read segment %d failed\n",i); + return i+1; + } + //LOG_DEBUG(ERROR_DEBUG,"read segment %d failed\n",i); + //return i+1; + } + //LOG_DEBUG(ERROR_DEBUG,"read segment %d failed\n",i); + //return i+1; + } + } + } + } + if((total_len%SEGMENT_LENGTH)!=0) + { + //printf("read segment %d\n",i); + if(read_segment_data(i*SEGMENT_LENGTH,total_len%SEGMENT_LENGTH)!=0) + { + LOG_DEBUG(ERROR_DEBUG,"read segment %d failed\n",i); + if(read_segment_data(i*SEGMENT_LENGTH,total_len%SEGMENT_LENGTH)!=0) + { + LOG_DEBUG(ERROR_DEBUG,"read segment %d failed\n",i); + if(read_segment_data(i*SEGMENT_LENGTH,total_len%SEGMENT_LENGTH)!=0) + { + LOG_DEBUG(ERROR_DEBUG,"read segment %d failed\n",i); + return i+1; + } + } + } + } + return 0; +} + + + +char *make_data_file_name(time_t now,unsigned int i) +{ + static char file_name[128]; + char date_str[32]; + memset(file_name,0,sizeof(file_name)); + if(i==0) + strftime(date_str,sizeof(date_str),"%Y%m%d_%H%M%S.bin",localtime(&now)); + else if(i==1) + strftime(date_str,sizeof(date_str),"%Y%m%d_%H%M%S.csv",localtime(&now)); + else if(i==2) + strftime(date_str,sizeof(date_str),"%Y%m%d_%H%M%S.co2",localtime(&now)); + else + strftime(date_str,sizeof(date_str),"%Y%m%d_%H%M%S.csv",localtime(&now)); + sprintf(file_name,"%s/%s",dir_store_data,date_str); + return file_name; +} + + +int savefile(const char *file,long offs,void *ptr,unsigned int size) +{ + FILE *fp; + fp=fopen(file,"w"); + if(fp==NULL) + { + LOG_DEBUG(ERROR_DEBUG,"Creat file %s failed when savefile\r\n",file); + return -1; + } + if(offs!=0) + { + fseek(fp,offs,SEEK_SET); + } + if(fwrite((const void *)ptr,size,1,fp)!=1) + { + fclose(fp); + LOG_DEBUG(ERROR_DEBUG,"Write file %s failed when savefile\r\n",file); + return -2; + } + fclose(fp); + return 0; +} + +//ֱӴ32λ,sizeΪֽڳ +int save_hex_file(const char *file,long offs,void *ptr,unsigned int size) +{ + FILE *fp; + int i; + static int hex_buf[5000]; + fp=fopen(file,"w"); + if(fp==NULL) + { + LOG_DEBUG(ERROR_DEBUG,"Creat file %s failed when savefile\r\n",file); + return -1; + } + if(offs!=0) + { + fseek(fp,offs,SEEK_SET); + } + for(i=0;i<(size>>1);i++) + { + memcpy(&hex_buf[i],ptr,sizeof(short)); + ptr+=2; + } + if(fwrite((const void *)hex_buf,size*2,1,fp)!=1) + { + fclose(fp); + LOG_DEBUG(ERROR_DEBUG,"Write file %s failed when savefile\r\n",file); + return -2; + } + fclose(fp); + return 0; +} + +/* +//ݴɶƸ +int save_float_file(const char *file,long offs,void *ptr,unsigned int size) +{ + static float file_buf[5000]; + FILE *fp; + int i; + unsigned char *data_ptr; + + if(size>10000) + { + LOG_DEBUG(ERROR_DEBUG,"save_float_file faile due to size=%d\r\n",size); + return -1; + } + + data_ptr=(unsigned char *)ptr; + for(i=0;i<(size/2);i++) + { + file_buf[i]=(float)((*data_ptr)+256*(*(data_ptr+1))); + data_ptr+=2; + } + fp=fopen(file,"w"); + if(fp==NULL) + { + LOG_DEBUG(ERROR_DEBUG,"Creat file %s failed when savefile\r\n",file); + return -2; + } + if(offs!=0) + { + fseek(fp,offs,SEEK_SET); + } + if(fwrite((const void *)file_buf,2*size,1,fp)!=1) + { + fclose(fp); + LOG_DEBUG(ERROR_DEBUG,"Write file %s failed when savefile\r\n",file); + return -3; + } + fclose(fp); + return 0; +} +*/ + +void RawConvVolt(int tmp,float *volt) +{ + float temp; + temp=((VIN*tmp)/65536-GND_OFFS)/AMP+((MCU_VREF*my_para_data.mach_run_para.sample_offs)/4096); + if(volt!=NULL) + *volt=temp; +} + +/* +//תɵѹٴɶƸ +int save_float_file_ex(const char *file,long offs,void *ptr,unsigned int size) +{ + static float file_buf[5000]; + int tmp; + int i; + FILE *fp; + unsigned char *data_ptr; + + if(size>10000) + { + LOG_DEBUG(ERROR_DEBUG,"save_float_file_ex faile due to size=%d\r\n",size); + return -1; + } + + data_ptr=(unsigned char *)ptr; + for(i=0;i<(size/2);i++) + { + tmp=(int)256*(*(data_ptr+1))+(*data_ptr); + RawConvVolt(tmp,&file_buf[i]); + data_ptr+=2; + } + fp=fopen(file,"w"); + if(fp==NULL) + { + LOG_DEBUG(ERROR_DEBUG,"Creat file %s failed when savefile\r\n",file); + return -2; + } + if(offs!=0) + { + fseek(fp,offs,SEEK_SET); + } + if(fwrite((const void *)file_buf,2*size,1,fp)!=1) + { + fclose(fp); + LOG_DEBUG(ERROR_DEBUG,"Write file %s failed when savefile\r\n",file); + return -3; + } + fclose(fp); + return 0; +} +*/ + +int save_csv_file(const char *file,long offs,void *ptr,unsigned int size) +{ + FILE *fp; + unsigned int i; + int tmp; + unsigned char *data_ptr; + //float voltage; + data_ptr=(unsigned char *)ptr; + fp=fopen(file,"w"); + if(fp==NULL) + { + LOG_DEBUG(ERROR_DEBUG,"Creat file %s failed when savefile\r\n",file); + return -1; + } + if(offs!=0) + { + fseek(fp,offs,SEEK_SET); + } + for(i=0;i<(size/2);i++) + { + tmp=(int)256*(*(data_ptr+1))+(*data_ptr); + //RawConvVolt(tmp,&voltage); + fprintf(fp,"%d\n",tmp); + data_ptr+=2; + } + fprintf(fp,"\n"); + fclose(fp); + return 0; +} + + +//,lenΪֽڳ +int save_sample_data(unsigned int len) +{ + int ret; + char *my_file_name; + time_t now; + + now=time(NULL); + last_sample_time=now; + + my_file_name=make_data_file_name(now,0);//binļ + + if((ret=save_hex_file(my_file_name,0,(void *)data_buf,len))!=0) + { + LOG_DEBUG(ERROR_DEBUG,"save bin file failed %s\n",my_file_name); + return -1; + } + /*if(ret=save_float_file_ex(my_file_name,0,(void *)data_buf,len)!=0) + { + LOG_DEBUG(ERROR_DEBUG,"save float file failed %s\n",my_file_name); + return -1; + }*/ + + if(send_analysis_req(my_file_name,strlen(my_file_name))!=0) + { + LOG_DEBUG(ERROR_DEBUG,"Send analysis request failed:file name is %s\n",my_file_name); + return -2; + } + + my_file_name=make_data_file_name(now,1);//csvļ + if((ret=save_csv_file(my_file_name,0,(void *)data_buf,len))!=0) + { + LOG_DEBUG(ERROR_DEBUG,"save csv file failed %s\n",my_file_name); + return -3; + } + + return ret; +} + +//,lenΪֽڳ +int save_co2_data(unsigned int len) +{ + extern int analysis_co2(unsigned short *buf,unsigned int buf_len,float *result); + int ret=0; + char *my_file_name; + time_t now; + float co2_ppm; + + now=time(NULL); + //last_sample_time=now; + if(analysis_co2(data_buf,len,&co2_ppm)==0) + { + last_co2_ppm=co2_ppm; + co2_is_ok=1; + LOG_DEBUG(TRACE_DEBUG,"analysis co2=%fppm\n",co2_ppm); + } + else + { + // last_co2_ppm=0; + last_co2_ppm=co2_ppm;//2015-11-11ֱߵʱԻΪֵ + co2_is_ok=0; + LOG_DEBUG(ERROR_DEBUG,"analysis co2 failed co2=%fppm\n",co2_ppm); + } + my_file_name=make_data_file_name(now,2);//co2ļ + if((ret=save_hex_file(my_file_name,0,(void *)data_buf,len))!=0) + { + LOG_DEBUG(ERROR_DEBUG,"save bin file failed %s\n",my_file_name); + return -1; + } + + my_file_name=make_data_file_name(now,3);//csvļ + if((ret=save_csv_file(my_file_name,0,(void *)data_buf,len))!=0) + { + LOG_DEBUG(ERROR_DEBUG,"save csv file failed %s\n",my_file_name); + return -2; + } + + return ret; +} + + + diff --git a/src/sample_process.h b/src/sample_process.h new file mode 100644 index 0000000..6efc9b6 --- /dev/null +++ b/src/sample_process.h @@ -0,0 +1,42 @@ +#ifndef _SMAPLE_PROCESS_H +#define _SMAPLE_PROCESS_H + + +#define CMD_NORMAL_READ 1 +#define CMD_READ_SAMPLE 2 +#define CMD_CLR_DATA 3 +#define CMD_START_SAMPLE 4 +#define CMD_STOP_SAMPLE 5 +#define CMD_READ_CO2 6 +#define CMD_CLR_CO2 7 +#define CMD_SYS_RESET 8 + +#define SUCCESSFULL 0x5A +#define FAILURE 0xA5 + +#define SEGMENT_LENGTH 500 + +typedef struct +{ +unsigned short len; +unsigned short intval; +unsigned short offs; +unsigned short co2_pos; +unsigned short co2_len; +}SAMPLE_PARA_TYPE; + +extern unsigned int clear_sample_data(void); +extern int start_sample_data(unsigned int ch,SAMPLE_PARA_TYPE *sample_para); +extern int start_sample_heat(unsigned char ch,unsigned char flg); +extern unsigned int read_sample_data(unsigned int total_len); +extern int save_sample_data(unsigned int len); +extern unsigned int query_sample_data(unsigned char *ret_data,int len); +extern unsigned int clear_co2_data(void); +extern unsigned int read_co2_data(unsigned int total_len); +extern int save_co2_data(unsigned int len); + + +#endif + + + diff --git a/src/scl_shm.h b/src/scl_shm.h new file mode 100644 index 0000000..c323412 --- /dev/null +++ b/src/scl_shm.h @@ -0,0 +1,137 @@ +#ifndef _SHM_H +#define _SHM_H + + +#define TYPE_MX 1 +#define TYPE_ST 2 +#define TYPE_SE 3 +#define TYPE_SG 4 +#define TYPE_SGCB 5 +#define TYPE_CO 6 +#define TYPE_SP 7 +#define TYPE_SV 8 + +#define CMD_WR_MX 1 +#define CMD_WR_ST 2 +#define CMD_WR_SE 3 +#define CMD_WR_SG 4 +#define CMD_WR_SGCB 5 +#define CMD_WR_CO 6 +#define CMD_WR_SP 7 +#define CMD_WR_SV 8 + +typedef union +{ +float f; +int i; +char stVal; +void *ptr; +}GEN_VAL; + +typedef struct{ +unsigned int secs; +unsigned int ms; +}TimeStamp; + + +typedef struct utc_time_tag +{ + unsigned int secs; // Number of seconds since January 1, 1970 + unsigned int fraction; // Fraction of a second + unsigned int qflags; // Quality flags, 8 least-significant bits only +} UTC_TIME; + + +typedef struct{ +GEN_VAL v; +int q; +TimeStamp t; +//#ifdef SUB_ENABLE +int subEna; +GEN_VAL subVal; +int subQ; +//#endif +}SCL_MV; //ýṹڹڴ + + +typedef struct{ +GEN_VAL v; +int q; +TimeStamp t; +}USR_MV; //ýṹڹڴ + + +typedef struct{ +GEN_VAL ctlVal; +char ctlNum; +TimeStamp t; +char Test; +char Check; +int valType; +}SCL_CO; + +typedef struct +{ +unsigned char NumOfSG; //1-n +unsigned char ActSG; //1-n +unsigned char EditSG; //0-n,0 +unsigned char CnfEdit; +UTC_TIME LActTm;// TimeStamp +}SGCB_CTRL; + + +typedef union +{ +USR_MV ana_mv; +SCL_MV scl_mv; +SCL_CO scl_co; +SGCB_CTRL sgcb_ctrl; +}SCL_VAL;//ͨDO + + +typedef struct{ +int type; //USER_MAPͱ,ȱʾñMX͵ĻST͵,CO͵ +int grp; //,ָʾĸڴ +int num; //ƫ,ָʾڹڴĵoff_numSCL_MXṹ +int ofs; //v,q,tֱ0,1,2ʾ +GEN_VAL v; +}SCL_DATA_SPEC; + +typedef struct{ +int cmd; +union +{ + SCL_DATA_SPEC data_spec; +}u; +}SCL_MSG_TYPE; + + +int start_scl_mem(); +int stop_scl_mem(); +void lock_scl_mem(); +void unlock_scl_mem(); + + +char *put_scl_data(int grp,int index,void *ptr,int num_bytes); +char *get_scl_data(int grp,int index,void *ptr,int num_bytes); + +SCL_VAL* put_mv_data(int grp,int index,USR_MV *usr_mv,int num_do); +SCL_VAL* get_mv_data(int grp,int index,USR_MV *usr_data,int num_do); +SCL_VAL *put_do_data(int grp,int index,SCL_VAL *scl_do,int num_of_do); +SCL_VAL *get_do_data(int grp,int index,SCL_VAL *scl_do,int num_of_do); + +SGCB_CTRL* get_sgcb_data(int index,SGCB_CTRL *sgcb); +SGCB_CTRL* put_sgcb_data(int index,SGCB_CTRL *sgcb); +char *get_sg_data(int grp,int index,char *ptr,int num_bytes); +char *put_sg_data(int grp,int index,char *ptr,int num_bytes); +char *get_se_data(int grp,int index,char *ptr,int num_bytes); +char *put_se_data(int grp,int index,char *ptr,int num_bytes); + +int get_usr_data(int offs,void *ptr,int num_bytes); +int put_usr_data(int offs,void *ptr,int num_bytes); + +int write_scl_msg(int cmd,SCL_DATA_SPEC *data_spec); + + +#endif + diff --git a/src/scl_srvr.tar.gz b/src/scl_srvr.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..df76e564fb1662474ab19f347815c96acd534c65 GIT binary patch literal 102400 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 literal 0 HcmV?d00001 diff --git a/src/serial.c b/src/serial.c new file mode 100644 index 0000000..71889b1 --- /dev/null +++ b/src/serial.c @@ -0,0 +1,208 @@ +#include "serial.h" + +static int speed_arr[] = {B115200,B57600,B38400,B19200,B9600,B4800,B2400,B1200,B300}; +static int name_arr[] = {115200,57600,38400,19200,9600,4800,2400,1200,300}; + +// Common Helper ///////////////////////////////////////////////////////////// +// +static void SetACommMode(int fd,int combaud,int databit,int stopbit,int checkmode) +{ + struct termios tty_termios; + int flags; + unsigned int i; + + if ((tcgetattr(fd, &tty_termios) == -1)) { + printf ("tcgetattr()"); + return; + } + cfmakeraw(&tty_termios); + for (i=0; i0) + timeout /= 500; + + +#ifdef DEBUG_COM + int i; + printf("RX:\t"); +#endif + + for(;;) + { + iDataNum = read(m_comFd,buf+rxlen,sz-rxlen); +#ifdef DEBUG_COM + for (int i = 0; i < iDataNum; i++) { + printf("%02X ", buf[rxlen + i]); + if (!((i + 1) % 10)) + printf("\n\t"); + } +#endif + + if (iDataNum <= 0) { + if (recvflag==0 && timeout--) + usleep(500000);//500ms + else + break; + } else { + recvflag = 1; + rxlen += iDataNum; + } + } + +#ifdef DEBUG_COM + printf("\n"); + fflush(stdout); +#endif + + return (rxlen > 0) ? rxlen : 0; +} + +//timeout is in 30ms +int SerialReadEx(int m_comFd,unsigned char *buf,int sz,int timeout) +{ + int curr_length=0,last_length=0,rx_length=0; + tcflush(m_comFd,TCIFLUSH); + while(timeout--) + { + usleep(30000);//wait 30ms + curr_length=read(m_comFd,buf+rx_length,sz-rx_length); + if(curr_length>0) + { + rx_length+=curr_length; + last_length=curr_length; + if(rx_length>=sz) + return rx_length; + } + else + { + if(last_length>0) + { + return rx_length; + } + last_length=0; + rx_length=0; + } + } + return rx_length; +} + +/** + * Write to Serial device + */ +int SerialWrite(int m_comFd,const unsigned char *buf,int sz) +{ + // Avoid rush + usleep(10000); + //tcflush(m_comFd,TCOFLUSH); + if (write(m_comFd, buf, sz) != sz) { + printf("SerialWrite:write()\n"); + return -1; + } + +#ifdef DEBUG_COM + int i; + printf("\nTX:\t"); + for (i = 0; i < len; i++) { + printf("%02X ", buf[i]); + if (!((i + 1) % 10)) + printf("\n\t"); + } + printf("\n"); + fflush(stdout); +#endif + return sz; +} diff --git a/src/serial.h b/src/serial.h new file mode 100644 index 0000000..17fe79b --- /dev/null +++ b/src/serial.h @@ -0,0 +1,17 @@ +#ifndef _SERIAL_H +#define _SERIAL_H + +#include +#include +#include +#include +#include +#include +#include + +int SerialOpen(const char *dev_name,int baud); +int SerialRead(int m_comFd,unsigned char *buf,int sz,int timeout); +int SerialWrite(int m_comFd,const unsigned char *buf,int sz); +int SerialReadEx(int m_comFd,unsigned char *buf,int sz,int timeout); + +#endif \ No newline at end of file diff --git a/src/slope.csv b/src/slope.csv new file mode 100644 index 0000000..0cdcf8d --- /dev/null +++ b/src/slope.csv @@ -0,0 +1,501 @@ +0 +0 +2 +2 +1 +4 +7 +1 +-4 +-1 +2 +1 +2 +8 +2 +-2 +-1 +-3 +-3 +0 +0 +1 +1 +-1 +-1 +0 +1 +6 +46 +106 +117 +67 +-12 +-71 +-72 +-52 +-35 +-24 +-12 +-4 +0 +-2 +-3 +-7 +-9 +-6 +-3 +-4 +-5 +-5 +-3 +-3 +-2 +0 +0 +1 +2 +2 +-1 +0 +2 +5 +6 +5 +0 +-2 +-5 +-3 +-1 +1 +0 +1 +1 +0 +-1 +0 +0 +-1 +0 +1 +-2 +-2 +0 +1 +1 +1 +3 +5 +2 +1 +-1 +-1 +-2 +-1 +0 +0 +1 +1 +1 +-1 +0 +1 +3 +4 +3 +0 +1 +2 +1 +2 +2 +1 +3 +1 +-1 +0 +1 +1 +1 +3 +3 +0 +0 +2 +1 +2 +2 +0 +-1 +1 +3 +1 +2 +1 +2 +1 +1 +2 +3 +0 +-1 +3 +2 +0 +1 +2 +4 +1 +1 +0 +2 +1 +2 +3 +2 +2 +1 +2 +2 +2 +2 +1 +0 +2 +3 +1 +0 +3 +2 +1 +0 +1 +2 +5 +3 +1 +1 +1 +2 +2 +2 +3 +4 +3 +2 +2 +2 +2 +2 +3 +3 +2 +0 +2 +2 +0 +0 +2 +2 +0 +3 +1 +2 +2 +2 +3 +3 +1 +1 +0 +2 +4 +3 +1 +1 +1 +2 +2 +1 +3 +3 +3 +1 +0 +0 +3 +3 +0 +0 +2 +2 +1 +3 +4 +3 +1 +3 +4 +4 +7 +9 +9 +11 +9 +5 +4 +2 +-1 +-2 +-4 +-4 +-4 +-3 +-2 +-1 +-1 +0 +1 +2 +1 +1 +2 +0 +1 +2 +3 +1 +1 +1 +2 +2 +4 +3 +2 +1 +1 +2 +2 +1 +1 +1 +2 +3 +2 +1 +1 +3 +3 +1 +2 +2 +2 +3 +2 +2 +2 +0 +3 +2 +4 +2 +2 +4 +4 +4 +6 +5 +5 +6 +6 +6 +4 +4 +2 +2 +1 +0 +-2 +-2 +-2 +-1 +-1 +-2 +-1 +-1 +0 +1 +0 +1 +2 +1 +1 +2 +0 +3 +3 +2 +1 +1 +2 +-1 +0 +2 +2 +1 +2 +2 +3 +1 +1 +2 +3 +1 +1 +2 +2 +2 +2 +3 +2 +1 +1 +1 +3 +1 +3 +3 +1 +2 +2 +2 +3 +3 +4 +5 +6 +5 +2 +4 +5 +4 +2 +2 +0 +-2 +-1 +-1 +-2 +-3 +-1 +1 +0 +0 +0 +1 +1 +0 +0 +0 +0 +0 +2 +1 +1 +1 +1 +2 +2 +1 +2 +1 +1 +2 +1 +0 +1 +2 +1 +0 +2 +1 +2 +3 +2 +1 +1 +1 +3 +1 +1 +-1 +-1 +-1 +1 +1 +1 +2 +2 +2 +1 +-1 +-1 +0 +0 +1 +2 +1 +0 +1 +1 +3 +2 +3 +1 +-2 +0 +0 +0 +2 +2 +0 +0 +1 +2 +1 +0 +0 +1 +2 +2 +0 +1 +1 +3 +1 +1 +0 +1 +1 +1 +0 +1 +1 +0 +1 +2 +1 +1 +-2 +0 +1 +2 +1 +2 +-1 +0 +0 +2 +1 +-1 + diff --git a/src/sqlite3.c b/src/sqlite3.c new file mode 100644 index 0000000..6708aa2 --- /dev/null +++ b/src/sqlite3.c @@ -0,0 +1,155865 @@ +/****************************************************************************** +** This file is an amalgamation of many separate C source files from SQLite +** version 3.8.10.1. By combining all the individual C code files into this +** single large file, the entire code can be compiled as a single translation +** unit. This allows many compilers to do optimizations that would not be +** possible if the files were compiled separately. Performance improvements +** of 5% or more are commonly seen when SQLite is compiled as a single +** translation unit. +** +** This file is all you need to compile SQLite. To use SQLite in other +** programs, you need this file and the "sqlite3.h" header file that defines +** the programming interface to the SQLite library. (If you do not have +** the "sqlite3.h" header file at hand, you will find a copy embedded within +** the text of this file. Search for "Begin file sqlite3.h" to find the start +** of the embedded sqlite3.h header file.) Additional code files may be needed +** if you want a wrapper to interface SQLite with your choice of programming +** language. The code for the "sqlite3" command-line shell is also in a +** separate file. This file contains only code for the core SQLite library. +*/ +#define SQLITE_CORE 1 +#define SQLITE_AMALGAMATION 1 +#ifndef SQLITE_PRIVATE +# define SQLITE_PRIVATE static +#endif +/************** Begin file sqliteInt.h ***************************************/ +/* +** 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. +** +*/ +#ifndef _SQLITEINT_H_ +#define _SQLITEINT_H_ + +/* +** Include the header file used to customize the compiler options for MSVC. +** This should be done first so that it can successfully prevent spurious +** compiler warnings due to subsequent content in this file and other files +** that are included by this file. +*/ +/************** Include msvc.h in the middle of sqliteInt.h ******************/ +/************** Begin file msvc.h ********************************************/ +/* +** 2015 January 12 +** +** 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 that is specific to MSVC. +*/ +#ifndef _MSVC_H_ +#define _MSVC_H_ + +#if defined(_MSC_VER) +#pragma warning(disable : 4054) +#pragma warning(disable : 4055) +#pragma warning(disable : 4100) +#pragma warning(disable : 4127) +#pragma warning(disable : 4130) +#pragma warning(disable : 4152) +#pragma warning(disable : 4189) +#pragma warning(disable : 4206) +#pragma warning(disable : 4210) +#pragma warning(disable : 4232) +#pragma warning(disable : 4244) +#pragma warning(disable : 4305) +#pragma warning(disable : 4306) +#pragma warning(disable : 4702) +#pragma warning(disable : 4706) +#endif /* defined(_MSC_VER) */ + +#endif /* _MSVC_H_ */ + +/************** End of msvc.h ************************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ + +/* +** Special setup for VxWorks +*/ +/************** Include vxworks.h in the middle of sqliteInt.h ***************/ +/************** Begin file vxworks.h *****************************************/ +/* +** 2015-03-02 +** +** 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 that is specific to Wind River's VxWorks +*/ +#if defined(__RTP__) || defined(_WRS_KERNEL) +/* This is VxWorks. Set up things specially for that OS +*/ +#include +#include /* amalgamator: dontcache */ +#define OS_VXWORKS 1 +#define SQLITE_OS_OTHER 0 +#define SQLITE_HOMEGROWN_RECURSIVE_MUTEX 1 +#define SQLITE_OMIT_LOAD_EXTENSION 1 +#define SQLITE_ENABLE_LOCKING_STYLE 0 +#define HAVE_UTIME 1 +#else +/* This is not VxWorks. */ +#define OS_VXWORKS 0 +#endif /* defined(_WRS_KERNEL) */ + +/************** End of vxworks.h *********************************************/ +/************** Continuing where we left off in 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. +** +** Ticket #2739: The _LARGEFILE_SOURCE macro must appear before any +** system #includes. Hence, this block of code must be the very first +** code in all source files. +** +** 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: Red Hat 7.2) but you want your code to work +** on an older machine (ex: Red Hat 6.0). If you compile on Red Hat 7.2 +** without this option, LFS is enable. But LFS does not exist in the kernel +** in Red Hat 6.0, so the code won't work. Hence, for maximum binary +** portability you should omit LFS. +** +** The previous paragraph was written in 2005. (This paragraph is written +** on 2008-11-28.) These days, all Linux kernels support large files, so +** you should probably leave LFS enabled. But some embedded platforms might +** lack LFS in which case the SQLITE_DISABLE_LFS macro might still be useful. +** +** Similar is true for Mac OS X. LFS is only supported on Mac OS X 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 + +/* Needed for various definitions... */ +#if defined(__GNUC__) && !defined(_GNU_SOURCE) +# define _GNU_SOURCE +#endif + +#if defined(__OpenBSD__) && !defined(_BSD_SOURCE) +# define _BSD_SOURCE +#endif + +/* +** For MinGW, check to see if we can include the header file containing its +** version information, among other things. Normally, this internal MinGW +** header file would [only] be included automatically by other MinGW header +** files; however, the contained version information is now required by this +** header file to work around binary compatibility issues (see below) and +** this is the only known way to reliably obtain it. This entire #if block +** would be completely unnecessary if there was any other way of detecting +** MinGW via their preprocessor (e.g. if they customized their GCC to define +** some MinGW-specific macros). When compiling for MinGW, either the +** _HAVE_MINGW_H or _HAVE__MINGW_H (note the extra underscore) macro must be +** defined; otherwise, detection of conditions specific to MinGW will be +** disabled. +*/ +#if defined(_HAVE_MINGW_H) +# include "mingw.h" +#elif defined(_HAVE__MINGW_H) +# include "_mingw.h" +#endif + +/* +** For MinGW version 4.x (and higher), check to see if the _USE_32BIT_TIME_T +** define is required to maintain binary compatibility with the MSVC runtime +** library in use (e.g. for Windows XP). +*/ +#if !defined(_USE_32BIT_TIME_T) && !defined(_USE_64BIT_TIME_T) && \ + defined(_WIN32) && !defined(_WIN64) && \ + defined(__MINGW_MAJOR_VERSION) && __MINGW_MAJOR_VERSION >= 4 && \ + defined(__MSVCRT__) +# define _USE_32BIT_TIME_T +#endif + +/* The public SQLite interface. The _FILE_OFFSET_BITS macro must appear +** first in QNX. Also, the _USE_32BIT_TIME_T macro must appear first for +** MinGW. +*/ +/************** Include sqlite3.h in the middle of sqliteInt.h ***************/ +/************** Begin file sqlite3.h *****************************************/ +/* +** 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. +** +************************************************************************* +** This header file defines the interface that the SQLite library +** presents to client programs. If a C-function, structure, datatype, +** or constant definition does not appear in this file, then it is +** not a published API of SQLite, is subject to change without +** notice, and should not be referenced by programs that use SQLite. +** +** Some of the definitions that are in this file are marked as +** "experimental". Experimental interfaces are normally new +** features recently added to SQLite. We do not anticipate changes +** to experimental interfaces but reserve the right to make minor changes +** if experience from use "in the wild" suggest such changes are prudent. +** +** The official C-language API documentation for SQLite is derived +** from comments in this file. This file is the authoritative source +** on how SQLite interfaces are suppose to operate. +** +** The name of this file under configuration management is "sqlite.h.in". +** The makefile makes some minor changes to this file (such as inserting +** the version number) and changes its name to "sqlite3.h" as +** part of the build process. +*/ +#ifndef _SQLITE3_H_ +#define _SQLITE3_H_ +#include /* Needed for the definition of va_list */ + +/* +** Make sure we can call this stuff from C++. +*/ +#if 0 +extern "C" { +#endif + + +/* +** Provide the ability to override linkage features of the interface. +*/ +#ifndef SQLITE_EXTERN +# define SQLITE_EXTERN extern +#endif +#ifndef SQLITE_API +# define SQLITE_API +#endif +#ifndef SQLITE_CDECL +# define SQLITE_CDECL +#endif +#ifndef SQLITE_STDCALL +# define SQLITE_STDCALL +#endif + +/* +** These no-op macros are used in front of interfaces to mark those +** interfaces as either deprecated or experimental. New applications +** should not use deprecated interfaces - they are supported for backwards +** compatibility only. Application writers should be aware that +** experimental interfaces are subject to change in point releases. +** +** These macros used to resolve to various kinds of compiler magic that +** would generate warning messages when they were used. But that +** compiler magic ended up generating such a flurry of bug reports +** that we have taken it all out and gone back to using simple +** noop macros. +*/ +#define SQLITE_DEPRECATED +#define SQLITE_EXPERIMENTAL + +/* +** Ensure these symbols were not defined by some previous header file. +*/ +#ifdef SQLITE_VERSION +# undef SQLITE_VERSION +#endif +#ifdef SQLITE_VERSION_NUMBER +# undef SQLITE_VERSION_NUMBER +#endif + +/* +** CAPI3REF: Compile-Time Library Version Numbers +** +** ^(The [SQLITE_VERSION] C preprocessor macro in the sqlite3.h header +** evaluates to a string literal that is the SQLite version in the +** format "X.Y.Z" where X is the major version number (always 3 for +** SQLite3) and Y is the minor version number and Z is the release number.)^ +** ^(The [SQLITE_VERSION_NUMBER] C preprocessor macro resolves to an integer +** with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same +** numbers used in [SQLITE_VERSION].)^ +** The SQLITE_VERSION_NUMBER for any given release of SQLite will also +** be larger than the release from which it is derived. Either Y will +** be held constant and Z will be incremented or else Y will be incremented +** and Z will be reset to zero. +** +** Since version 3.6.18, SQLite source code has been stored in the +**
    Fossil configuration management +** system. ^The SQLITE_SOURCE_ID macro evaluates to +** a string which identifies a particular check-in of SQLite +** within its configuration management system. ^The SQLITE_SOURCE_ID +** string contains the date and time of the check-in (UTC) and an SHA1 +** hash of the entire source tree. +** +** See also: [sqlite3_libversion()], +** [sqlite3_libversion_number()], [sqlite3_sourceid()], +** [sqlite_version()] and [sqlite_source_id()]. +*/ +#define SQLITE_VERSION "3.8.10.1" +#define SQLITE_VERSION_NUMBER 3008010 +#define SQLITE_SOURCE_ID "2015-05-09 12:14:55 05b4b1f2a937c06c90db70c09890038f6c98ec40" + +/* +** CAPI3REF: Run-Time Library Version Numbers +** KEYWORDS: sqlite3_version, sqlite3_sourceid +** +** These interfaces provide the same information as the [SQLITE_VERSION], +** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros +** but are associated with the library instead of the header file. ^(Cautious +** programmers might include assert() statements in their application to +** verify that values returned by these interfaces match the macros in +** the header, and thus insure that the application is +** compiled with matching library and header files. +** +**
    +** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
    +** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
    +** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
    +** 
    )^ +** +** ^The sqlite3_version[] string constant contains the text of [SQLITE_VERSION] +** macro. ^The sqlite3_libversion() function returns a pointer to the +** to the sqlite3_version[] string constant. The sqlite3_libversion() +** function is provided for use in DLLs since DLL users usually do not have +** direct access to string constants within the DLL. ^The +** sqlite3_libversion_number() function returns an integer equal to +** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns +** a pointer to a string constant whose value is the same as the +** [SQLITE_SOURCE_ID] C preprocessor macro. +** +** See also: [sqlite_version()] and [sqlite_source_id()]. +*/ +SQLITE_API const char sqlite3_version[] = SQLITE_VERSION; +SQLITE_API const char *SQLITE_STDCALL sqlite3_libversion(void); +SQLITE_API const char *SQLITE_STDCALL sqlite3_sourceid(void); +SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void); + +/* +** CAPI3REF: Run-Time Library Compilation Options Diagnostics +** +** ^The sqlite3_compileoption_used() function returns 0 or 1 +** indicating whether the specified option was defined at +** compile time. ^The SQLITE_ prefix may be omitted from the +** option name passed to sqlite3_compileoption_used(). +** +** ^The sqlite3_compileoption_get() function allows iterating +** over the list of options that were defined at compile time by +** returning the N-th compile time option string. ^If N is out of range, +** sqlite3_compileoption_get() returns a NULL pointer. ^The SQLITE_ +** prefix is omitted from any strings returned by +** sqlite3_compileoption_get(). +** +** ^Support for the diagnostic functions sqlite3_compileoption_used() +** and sqlite3_compileoption_get() may be omitted by specifying the +** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time. +** +** See also: SQL functions [sqlite_compileoption_used()] and +** [sqlite_compileoption_get()] and the [compile_options pragma]. +*/ +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS +SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName); +SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N); +#endif + +/* +** CAPI3REF: Test To See If The Library Is Threadsafe +** +** ^The sqlite3_threadsafe() function returns zero if and only if +** SQLite was compiled with mutexing code omitted due to the +** [SQLITE_THREADSAFE] compile-time option being set to 0. +** +** SQLite can be compiled with or without mutexes. When +** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes +** are enabled and SQLite is threadsafe. When the +** [SQLITE_THREADSAFE] macro is 0, +** the mutexes are omitted. Without the mutexes, it is not safe +** to use SQLite concurrently from more than one thread. +** +** Enabling mutexes incurs a measurable performance penalty. +** So if speed is of utmost importance, it makes sense to disable +** the mutexes. But for maximum safety, mutexes should be enabled. +** ^The default behavior is for mutexes to be enabled. +** +** This interface can be used by an application to make sure that the +** version of SQLite that it is linking against was compiled with +** the desired setting of the [SQLITE_THREADSAFE] macro. +** +** This interface only reports on the compile-time mutex setting +** of the [SQLITE_THREADSAFE] flag. If SQLite is compiled with +** SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but +** can be fully or partially disabled using a call to [sqlite3_config()] +** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD], +** or [SQLITE_CONFIG_SERIALIZED]. ^(The return value of the +** sqlite3_threadsafe() function shows only the compile-time setting of +** thread safety, not any run-time changes to that setting made by +** sqlite3_config(). In other words, the return value from sqlite3_threadsafe() +** is unchanged by calls to sqlite3_config().)^ +** +** See the [threading mode] documentation for additional information. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void); + +/* +** CAPI3REF: Database Connection Handle +** KEYWORDS: {database connection} {database connections} +** +** Each open SQLite database is represented by a pointer to an instance of +** the opaque structure named "sqlite3". It is useful to think of an sqlite3 +** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and +** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()] +** and [sqlite3_close_v2()] are its destructors. There are many other +** interfaces (such as +** [sqlite3_prepare_v2()], [sqlite3_create_function()], and +** [sqlite3_busy_timeout()] to name but three) that are methods on an +** sqlite3 object. +*/ +typedef struct sqlite3 sqlite3; + +/* +** CAPI3REF: 64-Bit Integer Types +** KEYWORDS: sqlite_int64 sqlite_uint64 +** +** Because there is no cross-platform way to specify 64-bit integer types +** SQLite includes typedefs for 64-bit signed and unsigned integers. +** +** The sqlite3_int64 and sqlite3_uint64 are the preferred type definitions. +** The sqlite_int64 and sqlite_uint64 types are supported for backwards +** compatibility only. +** +** ^The sqlite3_int64 and sqlite_int64 types can store integer values +** between -9223372036854775808 and +9223372036854775807 inclusive. ^The +** sqlite3_uint64 and sqlite_uint64 types can store integer values +** between 0 and +18446744073709551615 inclusive. +*/ +#ifdef SQLITE_INT64_TYPE + typedef SQLITE_INT64_TYPE sqlite_int64; + typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; +#elif defined(_MSC_VER) || defined(__BORLANDC__) + typedef __int64 sqlite_int64; + typedef unsigned __int64 sqlite_uint64; +#else + typedef long long int sqlite_int64; + typedef unsigned long long int sqlite_uint64; +#endif +typedef sqlite_int64 sqlite3_int64; +typedef sqlite_uint64 sqlite3_uint64; + +/* +** If compiling for a processor that lacks floating point support, +** substitute integer for floating-point. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# define double sqlite3_int64 +#endif + +/* +** CAPI3REF: Closing A Database Connection +** DESTRUCTOR: sqlite3 +** +** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors +** for the [sqlite3] object. +** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if +** the [sqlite3] object is successfully destroyed and all associated +** resources are deallocated. +** +** ^If the database connection is associated with unfinalized prepared +** statements or unfinished sqlite3_backup objects then sqlite3_close() +** will leave the database connection open and return [SQLITE_BUSY]. +** ^If sqlite3_close_v2() is called with unfinalized prepared statements +** and/or unfinished sqlite3_backups, then the database connection becomes +** an unusable "zombie" which will automatically be deallocated when the +** last prepared statement is finalized or the last sqlite3_backup is +** finished. The sqlite3_close_v2() interface is intended for use with +** host languages that are garbage collected, and where the order in which +** destructors are called is arbitrary. +** +** Applications should [sqlite3_finalize | finalize] all [prepared statements], +** [sqlite3_blob_close | close] all [BLOB handles], and +** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated +** with the [sqlite3] object prior to attempting to close the object. ^If +** sqlite3_close_v2() is called on a [database connection] that still has +** outstanding [prepared statements], [BLOB handles], and/or +** [sqlite3_backup] objects then it returns [SQLITE_OK] and the deallocation +** of resources is deferred until all [prepared statements], [BLOB handles], +** and [sqlite3_backup] objects are also destroyed. +** +** ^If an [sqlite3] object is destroyed while a transaction is open, +** the transaction is automatically rolled back. +** +** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)] +** must be either a NULL +** pointer or an [sqlite3] object pointer obtained +** from [sqlite3_open()], [sqlite3_open16()], or +** [sqlite3_open_v2()], and not previously closed. +** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer +** argument is a harmless no-op. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3*); +SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3*); + +/* +** The type for a callback function. +** This is legacy and deprecated. It is included for historical +** compatibility and is not documented. +*/ +typedef int (*sqlite3_callback)(void*,int,char**, char**); + +/* +** CAPI3REF: One-Step Query Execution Interface +** METHOD: sqlite3 +** +** The sqlite3_exec() interface is a convenience wrapper around +** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()], +** that allows an application to run multiple statements of SQL +** without having to use a lot of C code. +** +** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded, +** semicolon-separate SQL statements passed into its 2nd argument, +** in the context of the [database connection] passed in as its 1st +** argument. ^If the callback function of the 3rd argument to +** sqlite3_exec() is not NULL, then it is invoked for each result row +** coming out of the evaluated SQL statements. ^The 4th argument to +** sqlite3_exec() is relayed through to the 1st argument of each +** callback invocation. ^If the callback pointer to sqlite3_exec() +** is NULL, then no callback is ever invoked and result rows are +** ignored. +** +** ^If an error occurs while evaluating the SQL statements passed into +** sqlite3_exec(), then execution of the current statement stops and +** subsequent statements are skipped. ^If the 5th parameter to sqlite3_exec() +** is not NULL then any error message is written into memory obtained +** from [sqlite3_malloc()] and passed back through the 5th parameter. +** To avoid memory leaks, the application should invoke [sqlite3_free()] +** on error message strings returned through the 5th parameter of +** of sqlite3_exec() after the error message string is no longer needed. +** ^If the 5th parameter to sqlite3_exec() is not NULL and no errors +** occur, then sqlite3_exec() sets the pointer in its 5th parameter to +** NULL before returning. +** +** ^If an sqlite3_exec() callback returns non-zero, the sqlite3_exec() +** routine returns SQLITE_ABORT without invoking the callback again and +** without running any subsequent SQL statements. +** +** ^The 2nd argument to the sqlite3_exec() callback function is the +** number of columns in the result. ^The 3rd argument to the sqlite3_exec() +** callback is an array of pointers to strings obtained as if from +** [sqlite3_column_text()], one for each column. ^If an element of a +** result row is NULL then the corresponding string pointer for the +** sqlite3_exec() callback is a NULL pointer. ^The 4th argument to the +** sqlite3_exec() callback is an array of pointers to strings where each +** entry represents the name of corresponding result column as obtained +** from [sqlite3_column_name()]. +** +** ^If the 2nd parameter to sqlite3_exec() is a NULL pointer, a pointer +** to an empty string, or a pointer that contains only whitespace and/or +** SQL comments, then no SQL statements are evaluated and the database +** is not changed. +** +** Restrictions: +** +**
      +**
    • The application must insure that the 1st parameter to sqlite3_exec() +** is a valid and open [database connection]. +**
    • The application must not close the [database connection] specified by +** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. +**
    • The application must not modify the SQL statement text passed into +** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. +**
    +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_exec( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be evaluated */ + int (*callback)(void*,int,char**,char**), /* Callback function */ + void *, /* 1st argument to callback */ + char **errmsg /* Error msg written here */ +); + +/* +** CAPI3REF: Result Codes +** KEYWORDS: {result code definitions} +** +** Many SQLite functions return an integer result code from the set shown +** here in order to indicate success or failure. +** +** New error codes may be added in future versions of SQLite. +** +** See also: [extended result code definitions] +*/ +#define SQLITE_OK 0 /* Successful result */ +/* beginning-of-error-codes */ +#define SQLITE_ERROR 1 /* SQL error or missing database */ +#define SQLITE_INTERNAL 2 /* 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 /* Unknown opcode in sqlite3_file_control() */ +#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 /* String or BLOB exceeds size limit */ +#define SQLITE_CONSTRAINT 19 /* Abort due to constraint 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_NOTICE 27 /* Notifications from sqlite3_log() */ +#define SQLITE_WARNING 28 /* Warnings from sqlite3_log() */ +#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ +#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ +/* end-of-error-codes */ + +/* +** CAPI3REF: Extended Result Codes +** KEYWORDS: {extended result code definitions} +** +** In its default configuration, SQLite API routines return one of 30 integer +** [result codes]. However, experience has shown that many of +** these result codes are too coarse-grained. They do not provide as +** much information about problems as programmers might like. In an effort to +** address this, newer versions of SQLite (version 3.3.8 and later) include +** support for additional result codes that provide more detailed information +** about errors. These [extended result codes] are enabled or disabled +** on a per database connection basis using the +** [sqlite3_extended_result_codes()] API. Or, the extended code for +** the most recent error can be obtained using +** [sqlite3_extended_errcode()]. +*/ +#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) +#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) +#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) +#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) +#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) +#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) +#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) +#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) +#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) +#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8)) +#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8)) +#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8)) +#define SQLITE_IOERR_ACCESS (SQLITE_IOERR | (13<<8)) +#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8)) +#define SQLITE_IOERR_LOCK (SQLITE_IOERR | (15<<8)) +#define SQLITE_IOERR_CLOSE (SQLITE_IOERR | (16<<8)) +#define SQLITE_IOERR_DIR_CLOSE (SQLITE_IOERR | (17<<8)) +#define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8)) +#define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) +#define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) +#define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) +#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) +#define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) +#define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) +#define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) +#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8)) +#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) +#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) +#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) +#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) +#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) +#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) +#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) +#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) +#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) +#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) +#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) +#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8)) +#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) +#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8)) +#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8)) +#define SQLITE_CONSTRAINT_FOREIGNKEY (SQLITE_CONSTRAINT | (3<<8)) +#define SQLITE_CONSTRAINT_FUNCTION (SQLITE_CONSTRAINT | (4<<8)) +#define SQLITE_CONSTRAINT_NOTNULL (SQLITE_CONSTRAINT | (5<<8)) +#define SQLITE_CONSTRAINT_PRIMARYKEY (SQLITE_CONSTRAINT | (6<<8)) +#define SQLITE_CONSTRAINT_TRIGGER (SQLITE_CONSTRAINT | (7<<8)) +#define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8<<8)) +#define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8)) +#define SQLITE_CONSTRAINT_ROWID (SQLITE_CONSTRAINT |(10<<8)) +#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8)) +#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8)) +#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) +#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) + +/* +** CAPI3REF: Flags For File Open Operations +** +** These bit values are intended for use in the +** 3rd parameter to the [sqlite3_open_v2()] interface and +** in the 4th parameter to the [sqlite3_vfs.xOpen] method. +*/ +#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ +#define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ +#define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */ +#define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_MEMORY 0x00000080 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */ +#define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */ +#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */ +#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */ +#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */ +#define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ +#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ +#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_WAL 0x00080000 /* VFS only */ + +/* Reserved: 0x00F00000 */ + +/* +** CAPI3REF: Device Characteristics +** +** The xDeviceCharacteristics method of the [sqlite3_io_methods] +** object returns an integer which is a vector of these +** bit values expressing I/O characteristics of the mass storage +** device that holds the file that the [sqlite3_io_methods] +** refers to. +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that +** after reboot following a crash or power loss, the only bytes in a +** file that were written at the application level might have changed +** and that adjacent bytes, even bytes within the same sector are +** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN +** flag indicate that a file cannot be deleted when open. The +** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on +** read-only media and cannot be changed even by processes with +** elevated privileges. +*/ +#define SQLITE_IOCAP_ATOMIC 0x00000001 +#define SQLITE_IOCAP_ATOMIC512 0x00000002 +#define SQLITE_IOCAP_ATOMIC1K 0x00000004 +#define SQLITE_IOCAP_ATOMIC2K 0x00000008 +#define SQLITE_IOCAP_ATOMIC4K 0x00000010 +#define SQLITE_IOCAP_ATOMIC8K 0x00000020 +#define SQLITE_IOCAP_ATOMIC16K 0x00000040 +#define SQLITE_IOCAP_ATOMIC32K 0x00000080 +#define SQLITE_IOCAP_ATOMIC64K 0x00000100 +#define SQLITE_IOCAP_SAFE_APPEND 0x00000200 +#define SQLITE_IOCAP_SEQUENTIAL 0x00000400 +#define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 +#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 +#define SQLITE_IOCAP_IMMUTABLE 0x00002000 + +/* +** CAPI3REF: File Locking Levels +** +** SQLite uses one of these integer values as the second +** argument to calls it makes to the xLock() and xUnlock() methods +** of an [sqlite3_io_methods] object. +*/ +#define SQLITE_LOCK_NONE 0 +#define SQLITE_LOCK_SHARED 1 +#define SQLITE_LOCK_RESERVED 2 +#define SQLITE_LOCK_PENDING 3 +#define SQLITE_LOCK_EXCLUSIVE 4 + +/* +** CAPI3REF: Synchronization Type Flags +** +** When SQLite invokes the xSync() method of an +** [sqlite3_io_methods] object it uses a combination of +** these integer values as the second argument. +** +** When the SQLITE_SYNC_DATAONLY flag is used, it means that the +** sync operation only needs to flush data to mass storage. Inode +** information need not be flushed. If the lower four bits of the flag +** equal SQLITE_SYNC_NORMAL, that means to use normal fsync() semantics. +** If the lower four bits equal SQLITE_SYNC_FULL, that means +** to use Mac OS X style fullsync instead of fsync(). +** +** Do not confuse the SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags +** with the [PRAGMA synchronous]=NORMAL and [PRAGMA synchronous]=FULL +** settings. The [synchronous pragma] determines when calls to the +** xSync VFS method occur and applies uniformly across all platforms. +** The SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags determine how +** energetic or rigorous or forceful the sync operations are and +** only make a difference on Mac OSX for the default SQLite code. +** (Third-party VFS implementations might also make the distinction +** between SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL, but among the +** operating systems natively supported by SQLite, only Mac OSX +** cares about the difference.) +*/ +#define SQLITE_SYNC_NORMAL 0x00002 +#define SQLITE_SYNC_FULL 0x00003 +#define SQLITE_SYNC_DATAONLY 0x00010 + +/* +** CAPI3REF: OS Interface Open File Handle +** +** An [sqlite3_file] object represents an open file in the +** [sqlite3_vfs | OS interface layer]. Individual OS interface +** implementations will +** want to subclass this object by appending additional fields +** for their own use. The pMethods entry is a pointer to an +** [sqlite3_io_methods] object that defines methods for performing +** I/O operations on the open file. +*/ +typedef struct sqlite3_file sqlite3_file; +struct sqlite3_file { + const struct sqlite3_io_methods *pMethods; /* Methods for an open file */ +}; + +/* +** CAPI3REF: OS Interface File Virtual Methods Object +** +** Every file opened by the [sqlite3_vfs.xOpen] method populates an +** [sqlite3_file] object (or, more commonly, a subclass of the +** [sqlite3_file] object) with a pointer to an instance of this object. +** This object defines the methods used to perform various operations +** against the open file represented by the [sqlite3_file] object. +** +** If the [sqlite3_vfs.xOpen] method sets the sqlite3_file.pMethods element +** to a non-NULL pointer, then the sqlite3_io_methods.xClose method +** may be invoked even if the [sqlite3_vfs.xOpen] reported that it failed. The +** only way to prevent a call to xClose following a failed [sqlite3_vfs.xOpen] +** is for the [sqlite3_vfs.xOpen] to set the sqlite3_file.pMethods element +** to NULL. +** +** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or +** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). +** The second choice is a Mac OS X style fullsync. The [SQLITE_SYNC_DATAONLY] +** flag may be ORed in to indicate that only the data of the file +** and not its inode needs to be synced. +** +** The integer values to xLock() and xUnlock() are one of +**
      +**
    • [SQLITE_LOCK_NONE], +**
    • [SQLITE_LOCK_SHARED], +**
    • [SQLITE_LOCK_RESERVED], +**
    • [SQLITE_LOCK_PENDING], or +**
    • [SQLITE_LOCK_EXCLUSIVE]. +**
    +** xLock() increases the lock. xUnlock() decreases the lock. +** The xCheckReservedLock() method checks whether any database connection, +** either in this process or in some other process, is holding a RESERVED, +** PENDING, or EXCLUSIVE lock on the file. It returns true +** if such a lock exists and false otherwise. +** +** The xFileControl() method is a generic interface that allows custom +** VFS implementations to directly control an open file using the +** [sqlite3_file_control()] interface. The second "op" argument is an +** integer opcode. The third argument is a generic pointer intended to +** point to a structure that may contain arguments or space in which to +** write return values. Potential uses for xFileControl() might be +** functions to enable blocking locks with timeouts, to change the +** locking strategy (for example to use dot-file locks), to inquire +** about the status of a lock, or to break stale locks. The SQLite +** core reserves all opcodes less than 100 for its own use. +** A [file control opcodes | list of opcodes] less than 100 is available. +** Applications that define a custom xFileControl method should use opcodes +** greater than 100 to avoid conflicts. VFS implementations should +** return [SQLITE_NOTFOUND] for file control opcodes that they do not +** recognize. +** +** The xSectorSize() method returns the sector size of the +** device that underlies the file. The sector size is the +** minimum write that can be performed without disturbing +** other bytes in the file. The xDeviceCharacteristics() +** method returns a bit vector describing behaviors of the +** underlying device: +** +**
      +**
    • [SQLITE_IOCAP_ATOMIC] +**
    • [SQLITE_IOCAP_ATOMIC512] +**
    • [SQLITE_IOCAP_ATOMIC1K] +**
    • [SQLITE_IOCAP_ATOMIC2K] +**
    • [SQLITE_IOCAP_ATOMIC4K] +**
    • [SQLITE_IOCAP_ATOMIC8K] +**
    • [SQLITE_IOCAP_ATOMIC16K] +**
    • [SQLITE_IOCAP_ATOMIC32K] +**
    • [SQLITE_IOCAP_ATOMIC64K] +**
    • [SQLITE_IOCAP_SAFE_APPEND] +**
    • [SQLITE_IOCAP_SEQUENTIAL] +**
    +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +** +** If xRead() returns SQLITE_IOERR_SHORT_READ it must also fill +** in the unread portions of the buffer with zeros. A VFS that +** fails to zero-fill short reads might seem to work. However, +** failure to zero-fill short reads will eventually lead to +** database corruption. +*/ +typedef struct sqlite3_io_methods sqlite3_io_methods; +struct sqlite3_io_methods { + int iVersion; + int (*xClose)(sqlite3_file*); + int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); + int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); + int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); + int (*xSync)(sqlite3_file*, int flags); + int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); + int (*xLock)(sqlite3_file*, int); + int (*xUnlock)(sqlite3_file*, int); + int (*xCheckReservedLock)(sqlite3_file*, int *pResOut); + int (*xFileControl)(sqlite3_file*, int op, void *pArg); + int (*xSectorSize)(sqlite3_file*); + int (*xDeviceCharacteristics)(sqlite3_file*); + /* Methods above are valid for version 1 */ + int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**); + int (*xShmLock)(sqlite3_file*, int offset, int n, int flags); + void (*xShmBarrier)(sqlite3_file*); + int (*xShmUnmap)(sqlite3_file*, int deleteFlag); + /* Methods above are valid for version 2 */ + int (*xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); + int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p); + /* Methods above are valid for version 3 */ + /* Additional methods may be added in future releases */ +}; + +/* +** CAPI3REF: Standard File Control Opcodes +** KEYWORDS: {file control opcodes} {file control opcode} +** +** These integer constants are opcodes for the xFileControl method +** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()] +** interface. +** +**
      +**
    • [[SQLITE_FCNTL_LOCKSTATE]] +** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This +** opcode causes the xFileControl method to write the current state of +** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], +** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) +** into an integer that the pArg argument points to. This capability +** is used during testing and is only available when the SQLITE_TEST +** compile-time option is used. +** +**
    • [[SQLITE_FCNTL_SIZE_HINT]] +** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS +** layer a hint of how large the database file will grow to be during the +** current transaction. This hint is not guaranteed to be accurate but it +** is often close. The underlying VFS might choose to preallocate database +** file space based on this hint in order to help writes to the database +** file run faster. +** +**
    • [[SQLITE_FCNTL_CHUNK_SIZE]] +** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS +** extends and truncates the database file in chunks of a size specified +** by the user. The fourth argument to [sqlite3_file_control()] should +** point to an integer (type int) containing the new chunk-size to use +** for the nominated database. Allocating database file space in large +** chunks (say 1MB at a time), may reduce file-system fragmentation and +** improve performance on some systems. +** +**
    • [[SQLITE_FCNTL_FILE_POINTER]] +** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer +** to the [sqlite3_file] object associated with a particular database +** connection. See the [sqlite3_file_control()] documentation for +** additional information. +** +**
    • [[SQLITE_FCNTL_SYNC_OMITTED]] +** No longer in use. +** +**
    • [[SQLITE_FCNTL_SYNC]] +** The [SQLITE_FCNTL_SYNC] opcode is generated internally by SQLite and +** sent to the VFS immediately before the xSync method is invoked on a +** database file descriptor. Or, if the xSync method is not invoked +** because the user has configured SQLite with +** [PRAGMA synchronous | PRAGMA synchronous=OFF] it is invoked in place +** of the xSync method. In most cases, the pointer argument passed with +** this file-control is NULL. However, if the database file is being synced +** as part of a multi-database commit, the argument points to a nul-terminated +** string containing the transactions master-journal file name. VFSes that +** do not need this signal should silently ignore this opcode. Applications +** should not call [sqlite3_file_control()] with this opcode as doing so may +** disrupt the operation of the specialized VFSes that do require it. +** +**
    • [[SQLITE_FCNTL_COMMIT_PHASETWO]] +** The [SQLITE_FCNTL_COMMIT_PHASETWO] opcode is generated internally by SQLite +** and sent to the VFS after a transaction has been committed immediately +** but before the database is unlocked. VFSes that do not need this signal +** should silently ignore this opcode. Applications should not call +** [sqlite3_file_control()] with this opcode as doing so may disrupt the +** operation of the specialized VFSes that do require it. +** +**
    • [[SQLITE_FCNTL_WIN32_AV_RETRY]] +** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic +** retry counts and intervals for certain disk I/O operations for the +** windows [VFS] in order to provide robustness in the presence of +** anti-virus programs. By default, the windows VFS will retry file read, +** file write, and file delete operations up to 10 times, with a delay +** of 25 milliseconds before the first retry and with the delay increasing +** by an additional 25 milliseconds with each subsequent retry. This +** opcode allows these two values (10 retries and 25 milliseconds of delay) +** to be adjusted. The values are changed for all database connections +** within the same process. The argument is a pointer to an array of two +** integers where the first integer i the new retry count and the second +** integer is the delay. If either integer is negative, then the setting +** is not changed but instead the prior value of that setting is written +** into the array entry, allowing the current retry settings to be +** interrogated. The zDbName parameter is ignored. +** +**
    • [[SQLITE_FCNTL_PERSIST_WAL]] +** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the +** persistent [WAL | Write Ahead Log] setting. By default, the auxiliary +** write ahead log and shared memory files used for transaction control +** are automatically deleted when the latest connection to the database +** closes. Setting persistent WAL mode causes those files to persist after +** close. Persisting the files is useful when other processes that do not +** have write permission on the directory containing the database file want +** to read the database file, as the WAL and shared memory files must exist +** in order for the database to be readable. The fourth parameter to +** [sqlite3_file_control()] for this opcode should be a pointer to an integer. +** That integer is 0 to disable persistent WAL mode or 1 to enable persistent +** WAL mode. If the integer is -1, then it is overwritten with the current +** WAL persistence setting. +** +**
    • [[SQLITE_FCNTL_POWERSAFE_OVERWRITE]] +** ^The [SQLITE_FCNTL_POWERSAFE_OVERWRITE] opcode is used to set or query the +** persistent "powersafe-overwrite" or "PSOW" setting. The PSOW setting +** determines the [SQLITE_IOCAP_POWERSAFE_OVERWRITE] bit of the +** xDeviceCharacteristics methods. The fourth parameter to +** [sqlite3_file_control()] for this opcode should be a pointer to an integer. +** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage +** mode. If the integer is -1, then it is overwritten with the current +** zero-damage mode setting. +** +**
    • [[SQLITE_FCNTL_OVERWRITE]] +** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening +** a write transaction to indicate that, unless it is rolled back for some +** reason, the entire database file will be overwritten by the current +** transaction. This is used by VACUUM operations. +** +**
    • [[SQLITE_FCNTL_VFSNAME]] +** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of +** all [VFSes] in the VFS stack. The names are of all VFS shims and the +** final bottom-level VFS are written into memory obtained from +** [sqlite3_malloc()] and the result is stored in the char* variable +** that the fourth parameter of [sqlite3_file_control()] points to. +** The caller is responsible for freeing the memory when done. As with +** all file-control actions, there is no guarantee that this will actually +** do anything. Callers should initialize the char* variable to a NULL +** pointer in case this file-control is not implemented. This file-control +** is intended for diagnostic use only. +** +**
    • [[SQLITE_FCNTL_PRAGMA]] +** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA] +** file control is sent to the open [sqlite3_file] object corresponding +** to the database file to which the pragma statement refers. ^The argument +** to the [SQLITE_FCNTL_PRAGMA] file control is an array of +** pointers to strings (char**) in which the second element of the array +** is the name of the pragma and the third element is the argument to the +** pragma or NULL if the pragma has no argument. ^The handler for an +** [SQLITE_FCNTL_PRAGMA] file control can optionally make the first element +** of the char** argument point to a string obtained from [sqlite3_mprintf()] +** or the equivalent and that string will become the result of the pragma or +** the error message if the pragma fails. ^If the +** [SQLITE_FCNTL_PRAGMA] file control returns [SQLITE_NOTFOUND], then normal +** [PRAGMA] processing continues. ^If the [SQLITE_FCNTL_PRAGMA] +** file control returns [SQLITE_OK], then the parser assumes that the +** VFS has handled the PRAGMA itself and the parser generates a no-op +** prepared statement if result string is NULL, or that returns a copy +** of the result string if the string is non-NULL. +** ^If the [SQLITE_FCNTL_PRAGMA] file control returns +** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means +** that the VFS encountered an error while handling the [PRAGMA] and the +** compilation of the PRAGMA fails with an error. ^The [SQLITE_FCNTL_PRAGMA] +** file control occurs at the beginning of pragma statement analysis and so +** it is able to override built-in [PRAGMA] statements. +** +**
    • [[SQLITE_FCNTL_BUSYHANDLER]] +** ^The [SQLITE_FCNTL_BUSYHANDLER] +** file-control may be invoked by SQLite on the database file handle +** shortly after it is opened in order to provide a custom VFS with access +** to the connections busy-handler callback. The argument is of type (void **) +** - an array of two (void *) values. The first (void *) actually points +** to a function of type (int (*)(void *)). In order to invoke the connections +** busy-handler, this function should be invoked with the second (void *) in +** the array as the only argument. If it returns non-zero, then the operation +** should be retried. If it returns zero, the custom VFS should abandon the +** current operation. +** +**
    • [[SQLITE_FCNTL_TEMPFILENAME]] +** ^Application can invoke the [SQLITE_FCNTL_TEMPFILENAME] file-control +** to have SQLite generate a +** temporary filename using the same algorithm that is followed to generate +** temporary filenames for TEMP tables and other internal uses. The +** argument should be a char** which will be filled with the filename +** written into memory obtained from [sqlite3_malloc()]. The caller should +** invoke [sqlite3_free()] on the result to avoid a memory leak. +** +**
    • [[SQLITE_FCNTL_MMAP_SIZE]] +** The [SQLITE_FCNTL_MMAP_SIZE] file control is used to query or set the +** maximum number of bytes that will be used for memory-mapped I/O. +** The argument is a pointer to a value of type sqlite3_int64 that +** is an advisory maximum number of bytes in the file to memory map. The +** pointer is overwritten with the old value. The limit is not changed if +** the value originally pointed to is negative, and so the current limit +** can be queried by passing in a pointer to a negative number. This +** file-control is used internally to implement [PRAGMA mmap_size]. +** +**
    • [[SQLITE_FCNTL_TRACE]] +** The [SQLITE_FCNTL_TRACE] file control provides advisory information +** to the VFS about what the higher layers of the SQLite stack are doing. +** This file control is used by some VFS activity tracing [shims]. +** The argument is a zero-terminated string. Higher layers in the +** SQLite stack may generate instances of this file control if +** the [SQLITE_USE_FCNTL_TRACE] compile-time option is enabled. +** +**
    • [[SQLITE_FCNTL_HAS_MOVED]] +** The [SQLITE_FCNTL_HAS_MOVED] file control interprets its argument as a +** pointer to an integer and it writes a boolean into that integer depending +** on whether or not the file has been renamed, moved, or deleted since it +** was first opened. +** +**
    • [[SQLITE_FCNTL_WIN32_SET_HANDLE]] +** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This +** opcode causes the xFileControl method to swap the file handle with the one +** pointed to by the pArg argument. This capability is used during testing +** and only needs to be supported when SQLITE_TEST is defined. +** +**
    • [[SQLITE_FCNTL_WAL_BLOCK]] +** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might +** be advantageous to block on the next WAL lock if the lock is not immediately +** available. The WAL subsystem issues this signal during rare +** circumstances in order to fix a problem with priority inversion. +** Applications should not use this file-control. +** +**
    +*/ +#define SQLITE_FCNTL_LOCKSTATE 1 +#define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 +#define SQLITE_FCNTL_SET_LOCKPROXYFILE 3 +#define SQLITE_FCNTL_LAST_ERRNO 4 +#define SQLITE_FCNTL_SIZE_HINT 5 +#define SQLITE_FCNTL_CHUNK_SIZE 6 +#define SQLITE_FCNTL_FILE_POINTER 7 +#define SQLITE_FCNTL_SYNC_OMITTED 8 +#define SQLITE_FCNTL_WIN32_AV_RETRY 9 +#define SQLITE_FCNTL_PERSIST_WAL 10 +#define SQLITE_FCNTL_OVERWRITE 11 +#define SQLITE_FCNTL_VFSNAME 12 +#define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13 +#define SQLITE_FCNTL_PRAGMA 14 +#define SQLITE_FCNTL_BUSYHANDLER 15 +#define SQLITE_FCNTL_TEMPFILENAME 16 +#define SQLITE_FCNTL_MMAP_SIZE 18 +#define SQLITE_FCNTL_TRACE 19 +#define SQLITE_FCNTL_HAS_MOVED 20 +#define SQLITE_FCNTL_SYNC 21 +#define SQLITE_FCNTL_COMMIT_PHASETWO 22 +#define SQLITE_FCNTL_WIN32_SET_HANDLE 23 +#define SQLITE_FCNTL_WAL_BLOCK 24 + +/* deprecated names */ +#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE +#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE +#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO + + +/* +** CAPI3REF: Mutex Handle +** +** The mutex module within SQLite defines [sqlite3_mutex] to be an +** abstract type for a mutex object. The SQLite core never looks +** at the internal representation of an [sqlite3_mutex]. It only +** deals with pointers to the [sqlite3_mutex] object. +** +** Mutexes are created using [sqlite3_mutex_alloc()]. +*/ +typedef struct sqlite3_mutex sqlite3_mutex; + +/* +** CAPI3REF: OS Interface Object +** +** An instance of the sqlite3_vfs object defines the interface between +** the SQLite core and the underlying operating system. The "vfs" +** in the name of the object stands for "virtual file system". See +** the [VFS | VFS documentation] for further information. +** +** The value of the iVersion field is initially 1 but may be larger in +** future versions of SQLite. Additional fields may be appended to this +** object when the iVersion value is increased. Note that the structure +** of the sqlite3_vfs object changes in the transaction between +** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not +** modified. +** +** The szOsFile field is the size of the subclassed [sqlite3_file] +** structure used by this VFS. mxPathname is the maximum length of +** a pathname in this VFS. +** +** Registered sqlite3_vfs objects are kept on a linked list formed by +** the pNext pointer. The [sqlite3_vfs_register()] +** and [sqlite3_vfs_unregister()] interfaces manage this list +** in a thread-safe way. The [sqlite3_vfs_find()] interface +** searches the list. Neither the application code nor the VFS +** implementation should use the pNext pointer. +** +** The pNext field is the only field in the sqlite3_vfs +** structure that SQLite will ever modify. SQLite will only access +** or modify this field while holding a particular static mutex. +** The application should never modify anything within the sqlite3_vfs +** object once the object has been registered. +** +** The zName field holds the name of the VFS module. The name must +** be unique across all VFS modules. +** +** [[sqlite3_vfs.xOpen]] +** ^SQLite guarantees that the zFilename parameter to xOpen +** is either a NULL pointer or string obtained +** from xFullPathname() with an optional suffix added. +** ^If a suffix is added to the zFilename parameter, it will +** consist of a single "-" character followed by no more than +** 11 alphanumeric and/or "-" characters. +** ^SQLite further guarantees that +** the string will be valid and unchanged until xClose() is +** called. Because of the previous sentence, +** the [sqlite3_file] can safely store a pointer to the +** filename if it needs to remember the filename for some reason. +** If the zFilename parameter to xOpen is a NULL pointer then xOpen +** must invent its own temporary name for the file. ^Whenever the +** xFilename parameter is NULL it will also be the case that the +** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE]. +** +** The flags argument to xOpen() includes all bits set in +** the flags argument to [sqlite3_open_v2()]. Or if [sqlite3_open()] +** or [sqlite3_open16()] is used, then flags includes at least +** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. +** If xOpen() opens a file read-only then it sets *pOutFlags to +** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be set. +** +** ^(SQLite will also add one of the following flags to the xOpen() +** call, depending on the object being opened: +** +**
      +**
    • [SQLITE_OPEN_MAIN_DB] +**
    • [SQLITE_OPEN_MAIN_JOURNAL] +**
    • [SQLITE_OPEN_TEMP_DB] +**
    • [SQLITE_OPEN_TEMP_JOURNAL] +**
    • [SQLITE_OPEN_TRANSIENT_DB] +**
    • [SQLITE_OPEN_SUBJOURNAL] +**
    • [SQLITE_OPEN_MASTER_JOURNAL] +**
    • [SQLITE_OPEN_WAL] +**
    )^ +** +** The file I/O implementation can use the object type flags to +** change the way it deals with files. For example, an application +** that does not care about crash recovery or rollback might make +** the open of a journal file a no-op. Writes to this journal would +** also be no-ops, and any attempt to read the journal would return +** SQLITE_IOERR. Or the implementation might recognize that a database +** file will be doing page-aligned sector reads and writes in a random +** order and set up its I/O subsystem accordingly. +** +** SQLite might also add one of the following flags to the xOpen method: +** +**
      +**
    • [SQLITE_OPEN_DELETEONCLOSE] +**
    • [SQLITE_OPEN_EXCLUSIVE] +**
    +** +** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be +** deleted when it is closed. ^The [SQLITE_OPEN_DELETEONCLOSE] +** will be set for TEMP databases and their journals, transient +** databases, and subjournals. +** +** ^The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction +** with the [SQLITE_OPEN_CREATE] flag, which are both directly +** analogous to the O_EXCL and O_CREAT flags of the POSIX open() +** API. The SQLITE_OPEN_EXCLUSIVE flag, when paired with the +** SQLITE_OPEN_CREATE, is used to indicate that file should always +** be created, and that it is an error if it already exists. +** It is not used to indicate the file should be opened +** for exclusive access. +** +** ^At least szOsFile bytes of memory are allocated by SQLite +** to hold the [sqlite3_file] structure passed as the third +** argument to xOpen. The xOpen method does not have to +** allocate the structure; it should just fill it in. Note that +** the xOpen method must set the sqlite3_file.pMethods to either +** a valid [sqlite3_io_methods] object or to NULL. xOpen must do +** this even if the open fails. SQLite expects that the sqlite3_file.pMethods +** element will be valid after xOpen returns regardless of the success +** or failure of the xOpen call. +** +** [[sqlite3_vfs.xAccess]] +** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] +** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to +** test whether a file is readable and writable, or [SQLITE_ACCESS_READ] +** to test whether a file is at least readable. The file can be a +** directory. +** +** ^SQLite will always allocate at least mxPathname+1 bytes for the +** output buffer xFullPathname. The exact size of the output buffer +** is also passed as a parameter to both methods. If the output buffer +** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is +** handled as a fatal error by SQLite, vfs implementations should endeavor +** to prevent this by setting mxPathname to a sufficiently large value. +** +** The xRandomness(), xSleep(), xCurrentTime(), and xCurrentTimeInt64() +** interfaces are not strictly a part of the filesystem, but they are +** included in the VFS structure for completeness. +** The xRandomness() function attempts to return nBytes bytes +** of good-quality randomness into zOut. The return value is +** the actual number of bytes of randomness obtained. +** The xSleep() method causes the calling thread to sleep for at +** least the number of microseconds given. ^The xCurrentTime() +** method returns a Julian Day Number for the current date and time as +** a floating point value. +** ^The xCurrentTimeInt64() method returns, as an integer, the Julian +** Day Number multiplied by 86400000 (the number of milliseconds in +** a 24-hour day). +** ^SQLite will use the xCurrentTimeInt64() method to get the current +** date and time if that method is available (if iVersion is 2 or +** greater and the function pointer is not NULL) and will fall back +** to xCurrentTime() if xCurrentTimeInt64() is unavailable. +** +** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces +** are not used by the SQLite core. These optional interfaces are provided +** by some VFSes to facilitate testing of the VFS code. By overriding +** system calls with functions under its control, a test program can +** simulate faults and error conditions that would otherwise be difficult +** or impossible to induce. The set of system calls that can be overridden +** varies from one VFS to another, and from one version of the same VFS to the +** next. Applications that use these interfaces must be prepared for any +** or all of these interfaces to be NULL or for their behavior to change +** from one release to the next. Applications must not attempt to access +** any of these methods if the iVersion of the VFS is less than 3. +*/ +typedef struct sqlite3_vfs sqlite3_vfs; +typedef void (*sqlite3_syscall_ptr)(void); +struct sqlite3_vfs { + int iVersion; /* Structure version number (currently 3) */ + int szOsFile; /* Size of subclassed sqlite3_file */ + int mxPathname; /* Maximum file pathname length */ + sqlite3_vfs *pNext; /* Next registered VFS */ + const char *zName; /* Name of this virtual file system */ + void *pAppData; /* Pointer to application-specific data */ + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, + int flags, int *pOutFlags); + int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); + int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); + int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); + void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); + void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); + void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void); + void (*xDlClose)(sqlite3_vfs*, void*); + int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); + int (*xSleep)(sqlite3_vfs*, int microseconds); + int (*xCurrentTime)(sqlite3_vfs*, double*); + int (*xGetLastError)(sqlite3_vfs*, int, char *); + /* + ** The methods above are in version 1 of the sqlite_vfs object + ** definition. Those that follow are added in version 2 or later + */ + int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); + /* + ** The methods above are in versions 1 and 2 of the sqlite_vfs object. + ** Those below are for version 3 and greater. + */ + int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr); + sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName); + const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName); + /* + ** The methods above are in versions 1 through 3 of the sqlite_vfs object. + ** New fields may be appended in figure versions. The iVersion + ** value will increment whenever this happens. + */ +}; + +/* +** CAPI3REF: Flags for the xAccess VFS method +** +** These integer constants can be used as the third parameter to +** the xAccess method of an [sqlite3_vfs] object. They determine +** what kind of permissions the xAccess method is looking for. +** With SQLITE_ACCESS_EXISTS, the xAccess method +** simply checks whether the file exists. +** With SQLITE_ACCESS_READWRITE, the xAccess method +** checks whether the named directory is both readable and writable +** (in other words, if files can be added, removed, and renamed within +** the directory). +** The SQLITE_ACCESS_READWRITE constant is currently used only by the +** [temp_store_directory pragma], though this could change in a future +** release of SQLite. +** With SQLITE_ACCESS_READ, the xAccess method +** checks whether the file is readable. The SQLITE_ACCESS_READ constant is +** currently unused, though it might be used in a future release of +** SQLite. +*/ +#define SQLITE_ACCESS_EXISTS 0 +#define SQLITE_ACCESS_READWRITE 1 /* Used by PRAGMA temp_store_directory */ +#define SQLITE_ACCESS_READ 2 /* Unused */ + +/* +** CAPI3REF: Flags for the xShmLock VFS method +** +** These integer constants define the various locking operations +** allowed by the xShmLock method of [sqlite3_io_methods]. The +** following are the only legal combinations of flags to the +** xShmLock method: +** +**
      +**
    • SQLITE_SHM_LOCK | SQLITE_SHM_SHARED +**
    • SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE +**
    • SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED +**
    • SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE +**
    +** +** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as +** was given on the corresponding lock. +** +** The xShmLock method can transition between unlocked and SHARED or +** between unlocked and EXCLUSIVE. It cannot transition between SHARED +** and EXCLUSIVE. +*/ +#define SQLITE_SHM_UNLOCK 1 +#define SQLITE_SHM_LOCK 2 +#define SQLITE_SHM_SHARED 4 +#define SQLITE_SHM_EXCLUSIVE 8 + +/* +** CAPI3REF: Maximum xShmLock index +** +** The xShmLock method on [sqlite3_io_methods] may use values +** between 0 and this upper bound as its "offset" argument. +** The SQLite core will never attempt to acquire or release a +** lock outside of this range +*/ +#define SQLITE_SHM_NLOCK 8 + + +/* +** CAPI3REF: Initialize The SQLite Library +** +** ^The sqlite3_initialize() routine initializes the +** SQLite library. ^The sqlite3_shutdown() routine +** deallocates any resources that were allocated by sqlite3_initialize(). +** These routines are designed to aid in process initialization and +** shutdown on embedded systems. Workstation applications using +** SQLite normally do not need to invoke either of these routines. +** +** A call to sqlite3_initialize() is an "effective" call if it is +** the first time sqlite3_initialize() is invoked during the lifetime of +** the process, or if it is the first time sqlite3_initialize() is invoked +** following a call to sqlite3_shutdown(). ^(Only an effective call +** of sqlite3_initialize() does any initialization. All other calls +** are harmless no-ops.)^ +** +** A call to sqlite3_shutdown() is an "effective" call if it is the first +** call to sqlite3_shutdown() since the last sqlite3_initialize(). ^(Only +** an effective call to sqlite3_shutdown() does any deinitialization. +** All other valid calls to sqlite3_shutdown() are harmless no-ops.)^ +** +** The sqlite3_initialize() interface is threadsafe, but sqlite3_shutdown() +** is not. The sqlite3_shutdown() interface must only be called from a +** single thread. All open [database connections] must be closed and all +** other SQLite resources must be deallocated prior to invoking +** sqlite3_shutdown(). +** +** Among other things, ^sqlite3_initialize() will invoke +** sqlite3_os_init(). Similarly, ^sqlite3_shutdown() +** will invoke sqlite3_os_end(). +** +** ^The sqlite3_initialize() routine returns [SQLITE_OK] on success. +** ^If for some reason, sqlite3_initialize() is unable to initialize +** the library (perhaps it is unable to allocate a needed resource such +** as a mutex) it returns an [error code] other than [SQLITE_OK]. +** +** ^The sqlite3_initialize() routine is called internally by many other +** SQLite interfaces so that an application usually does not need to +** invoke sqlite3_initialize() directly. For example, [sqlite3_open()] +** calls sqlite3_initialize() so the SQLite library will be automatically +** initialized when [sqlite3_open()] is called if it has not be initialized +** already. ^However, if SQLite is compiled with the [SQLITE_OMIT_AUTOINIT] +** compile-time option, then the automatic calls to sqlite3_initialize() +** are omitted and the application must call sqlite3_initialize() directly +** prior to using any other SQLite interface. For maximum portability, +** it is recommended that applications always invoke sqlite3_initialize() +** directly prior to using any other SQLite interface. Future releases +** of SQLite may require this. In other words, the behavior exhibited +** when SQLite is compiled with [SQLITE_OMIT_AUTOINIT] might become the +** default behavior in some future release of SQLite. +** +** The sqlite3_os_init() routine does operating-system specific +** initialization of the SQLite library. The sqlite3_os_end() +** routine undoes the effect of sqlite3_os_init(). Typical tasks +** performed by these routines include allocation or deallocation +** of static resources, initialization of global variables, +** setting up a default [sqlite3_vfs] module, or setting up +** a default configuration using [sqlite3_config()]. +** +** The application should never invoke either sqlite3_os_init() +** or sqlite3_os_end() directly. The application should only invoke +** sqlite3_initialize() and sqlite3_shutdown(). The sqlite3_os_init() +** interface is called automatically by sqlite3_initialize() and +** sqlite3_os_end() is called by sqlite3_shutdown(). Appropriate +** implementations for sqlite3_os_init() and sqlite3_os_end() +** are built into SQLite when it is compiled for Unix, Windows, or OS/2. +** When [custom builds | built for other platforms] +** (using the [SQLITE_OS_OTHER=1] compile-time +** option) the application must supply a suitable implementation for +** sqlite3_os_init() and sqlite3_os_end(). An application-supplied +** implementation of sqlite3_os_init() or sqlite3_os_end() +** must return [SQLITE_OK] on success and some other [error code] upon +** failure. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void); +SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void); +SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void); +SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void); + +/* +** CAPI3REF: Configuring The SQLite Library +** +** The sqlite3_config() interface is used to make global configuration +** changes to SQLite in order to tune SQLite to the specific needs of +** the application. The default configuration is recommended for most +** applications and so this routine is usually not necessary. It is +** provided to support rare applications with unusual needs. +** +** The sqlite3_config() interface is not threadsafe. The application +** must insure that no other SQLite interfaces are invoked by other +** threads while sqlite3_config() is running. Furthermore, sqlite3_config() +** may only be invoked prior to library initialization using +** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()]. +** ^If sqlite3_config() is called after [sqlite3_initialize()] and before +** [sqlite3_shutdown()] then it will return SQLITE_MISUSE. +** Note, however, that ^sqlite3_config() can be called as part of the +** implementation of an application-defined [sqlite3_os_init()]. +** +** The first argument to sqlite3_config() is an integer +** [configuration option] that determines +** what property of SQLite is to be configured. Subsequent arguments +** vary depending on the [configuration option] +** in the first argument. +** +** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. +** ^If the option is unknown or SQLite is unable to set the option +** then this routine returns a non-zero [error code]. +*/ +SQLITE_API int SQLITE_CDECL sqlite3_config(int, ...); + +/* +** CAPI3REF: Configure database connections +** METHOD: sqlite3 +** +** The sqlite3_db_config() interface is used to make configuration +** changes to a [database connection]. The interface is similar to +** [sqlite3_config()] except that the changes apply to a single +** [database connection] (specified in the first argument). +** +** The second argument to sqlite3_db_config(D,V,...) is the +** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code +** that indicates what aspect of the [database connection] is being configured. +** Subsequent arguments vary depending on the configuration verb. +** +** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if +** the call is considered successful. +*/ +SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3*, int op, ...); + +/* +** CAPI3REF: Memory Allocation Routines +** +** An instance of this object defines the interface between SQLite +** and low-level memory allocation routines. +** +** This object is used in only one place in the SQLite interface. +** A pointer to an instance of this object is the argument to +** [sqlite3_config()] when the configuration option is +** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC]. +** By creating an instance of this object +** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC]) +** during configuration, an application can specify an alternative +** memory allocation subsystem for SQLite to use for all of its +** dynamic memory needs. +** +** Note that SQLite comes with several [built-in memory allocators] +** that are perfectly adequate for the overwhelming majority of applications +** and that this object is only useful to a tiny minority of applications +** with specialized memory allocation requirements. This object is +** also used during testing of SQLite in order to specify an alternative +** memory allocator that simulates memory out-of-memory conditions in +** order to verify that SQLite recovers gracefully from such +** conditions. +** +** The xMalloc, xRealloc, and xFree methods must work like the +** malloc(), realloc() and free() functions from the standard C library. +** ^SQLite guarantees that the second argument to +** xRealloc is always a value returned by a prior call to xRoundup. +** +** xSize should return the allocated size of a memory allocation +** previously obtained from xMalloc or xRealloc. The allocated size +** is always at least as big as the requested size but may be larger. +** +** The xRoundup method returns what would be the allocated size of +** a memory allocation given a particular requested size. Most memory +** allocators round up memory allocations at least to the next multiple +** of 8. Some allocators round up to a larger multiple or to a power of 2. +** Every memory allocation request coming in through [sqlite3_malloc()] +** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0, +** that causes the corresponding memory allocation to fail. +** +** The xInit method initializes the memory allocator. For example, +** it might allocate any require mutexes or initialize internal data +** structures. The xShutdown method is invoked (indirectly) by +** [sqlite3_shutdown()] and should deallocate any resources acquired +** by xInit. The pAppData pointer is used as the only parameter to +** xInit and xShutdown. +** +** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes +** the xInit method, so the xInit method need not be threadsafe. The +** xShutdown method is only called from [sqlite3_shutdown()] so it does +** not need to be threadsafe either. For all other methods, SQLite +** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the +** [SQLITE_CONFIG_MEMSTATUS] configuration option is turned on (which +** it is by default) and so the methods are automatically serialized. +** However, if [SQLITE_CONFIG_MEMSTATUS] is disabled, then the other +** methods must be threadsafe or else make their own arrangements for +** serialization. +** +** SQLite will never invoke xInit() more than once without an intervening +** call to xShutdown(). +*/ +typedef struct sqlite3_mem_methods sqlite3_mem_methods; +struct sqlite3_mem_methods { + void *(*xMalloc)(int); /* Memory allocation function */ + void (*xFree)(void*); /* Free a prior allocation */ + void *(*xRealloc)(void*,int); /* Resize an allocation */ + int (*xSize)(void*); /* Return the size of an allocation */ + int (*xRoundup)(int); /* Round up request size to allocation size */ + int (*xInit)(void*); /* Initialize the memory allocator */ + void (*xShutdown)(void*); /* Deinitialize the memory allocator */ + void *pAppData; /* Argument to xInit() and xShutdown() */ +}; + +/* +** CAPI3REF: Configuration Options +** KEYWORDS: {configuration option} +** +** These constants are the available integer configuration options that +** can be passed as the first argument to the [sqlite3_config()] interface. +** +** New configuration options may be added in future releases of SQLite. +** Existing configuration options might be discontinued. Applications +** should check the return code from [sqlite3_config()] to make sure that +** the call worked. The [sqlite3_config()] interface will return a +** non-zero [error code] if a discontinued or unsupported configuration option +** is invoked. +** +**
    +** [[SQLITE_CONFIG_SINGLETHREAD]]
    SQLITE_CONFIG_SINGLETHREAD
    +**
    There are no arguments to this option. ^This option sets the +** [threading mode] to Single-thread. In other words, it disables +** all mutexing and puts SQLite into a mode where it can only be used +** by a single thread. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to change the [threading mode] from its default +** value of Single-thread and so [sqlite3_config()] will return +** [SQLITE_ERROR] if called with the SQLITE_CONFIG_SINGLETHREAD +** configuration option.
    +** +** [[SQLITE_CONFIG_MULTITHREAD]]
    SQLITE_CONFIG_MULTITHREAD
    +**
    There are no arguments to this option. ^This option sets the +** [threading mode] to Multi-thread. In other words, it disables +** mutexing on [database connection] and [prepared statement] objects. +** The application is responsible for serializing access to +** [database connections] and [prepared statements]. But other mutexes +** are enabled so that SQLite will be safe to use in a multi-threaded +** environment as long as no two threads attempt to use the same +** [database connection] at the same time. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to set the Multi-thread [threading mode] and +** [sqlite3_config()] will return [SQLITE_ERROR] if called with the +** SQLITE_CONFIG_MULTITHREAD configuration option.
    +** +** [[SQLITE_CONFIG_SERIALIZED]]
    SQLITE_CONFIG_SERIALIZED
    +**
    There are no arguments to this option. ^This option sets the +** [threading mode] to Serialized. In other words, this option enables +** all mutexes including the recursive +** mutexes on [database connection] and [prepared statement] objects. +** In this mode (which is the default when SQLite is compiled with +** [SQLITE_THREADSAFE=1]) the SQLite library will itself serialize access +** to [database connections] and [prepared statements] so that the +** application is free to use the same [database connection] or the +** same [prepared statement] in different threads at the same time. +** ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to set the Serialized [threading mode] and +** [sqlite3_config()] will return [SQLITE_ERROR] if called with the +** SQLITE_CONFIG_SERIALIZED configuration option.
    +** +** [[SQLITE_CONFIG_MALLOC]]
    SQLITE_CONFIG_MALLOC
    +**
    ^(The SQLITE_CONFIG_MALLOC option takes a single argument which is +** a pointer to an instance of the [sqlite3_mem_methods] structure. +** The argument specifies +** alternative low-level memory allocation routines to be used in place of +** the memory allocation routines built into SQLite.)^ ^SQLite makes +** its own private copy of the content of the [sqlite3_mem_methods] structure +** before the [sqlite3_config()] call returns.
    +** +** [[SQLITE_CONFIG_GETMALLOC]]
    SQLITE_CONFIG_GETMALLOC
    +**
    ^(The SQLITE_CONFIG_GETMALLOC option takes a single argument which +** is a pointer to an instance of the [sqlite3_mem_methods] structure. +** The [sqlite3_mem_methods] +** structure is filled with the currently defined memory allocation routines.)^ +** This option can be used to overload the default memory allocation +** routines with a wrapper that simulations memory allocation failure or +** tracks memory usage, for example.
    +** +** [[SQLITE_CONFIG_MEMSTATUS]]
    SQLITE_CONFIG_MEMSTATUS
    +**
    ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int, +** interpreted as a boolean, which enables or disables the collection of +** memory allocation statistics. ^(When memory allocation statistics are +** disabled, the following SQLite interfaces become non-operational: +**
      +**
    • [sqlite3_memory_used()] +**
    • [sqlite3_memory_highwater()] +**
    • [sqlite3_soft_heap_limit64()] +**
    • [sqlite3_status64()] +**
    )^ +** ^Memory allocation statistics are enabled by default unless SQLite is +** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory +** allocation statistics are disabled by default. +**
    +** +** [[SQLITE_CONFIG_SCRATCH]]
    SQLITE_CONFIG_SCRATCH
    +**
    ^The SQLITE_CONFIG_SCRATCH option specifies a static memory buffer +** that SQLite can use for scratch memory. ^(There are three arguments +** to SQLITE_CONFIG_SCRATCH: A pointer an 8-byte +** aligned memory buffer from which the scratch allocations will be +** drawn, the size of each scratch allocation (sz), +** and the maximum number of scratch allocations (N).)^ +** The first argument must be a pointer to an 8-byte aligned buffer +** of at least sz*N bytes of memory. +** ^SQLite will not use more than one scratch buffers per thread. +** ^SQLite will never request a scratch buffer that is more than 6 +** times the database page size. +** ^If SQLite needs needs additional +** scratch memory beyond what is provided by this configuration option, then +** [sqlite3_malloc()] will be used to obtain the memory needed.

    +** ^When the application provides any amount of scratch memory using +** SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary large +** [sqlite3_malloc|heap allocations]. +** This can help [Robson proof|prevent memory allocation failures] due to heap +** fragmentation in low-memory embedded systems. +**

    +** +** [[SQLITE_CONFIG_PAGECACHE]]
    SQLITE_CONFIG_PAGECACHE
    +**
    ^The SQLITE_CONFIG_PAGECACHE option specifies a static memory buffer +** that SQLite can use for the database page cache with the default page +** cache implementation. +** This configuration should not be used if an application-define page +** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2] +** configuration option. +** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to +** 8-byte aligned +** memory, the size of each page buffer (sz), and the number of pages (N). +** The sz argument should be the size of the largest database page +** (a power of two between 512 and 65536) plus some extra bytes for each +** page header. ^The number of extra bytes needed by the page header +** can be determined using the [SQLITE_CONFIG_PCACHE_HDRSZ] option +** to [sqlite3_config()]. +** ^It is harmless, apart from the wasted memory, +** for the sz parameter to be larger than necessary. The first +** argument should pointer to an 8-byte aligned block of memory that +** is at least sz*N bytes of memory, otherwise subsequent behavior is +** undefined. +** ^SQLite will use the memory provided by the first argument to satisfy its +** memory needs for the first N pages that it adds to cache. ^If additional +** page cache memory is needed beyond what is provided by this option, then +** SQLite goes to [sqlite3_malloc()] for the additional storage space.
    +** +** [[SQLITE_CONFIG_HEAP]]
    SQLITE_CONFIG_HEAP
    +**
    ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer +** that SQLite will use for all of its dynamic memory allocation needs +** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and +** [SQLITE_CONFIG_PAGECACHE]. +** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled +** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns +** [SQLITE_ERROR] if invoked otherwise. +** ^There are three arguments to SQLITE_CONFIG_HEAP: +** An 8-byte aligned pointer to the memory, +** the number of bytes in the memory buffer, and the minimum allocation size. +** ^If the first pointer (the memory pointer) is NULL, then SQLite reverts +** to using its default memory allocator (the system malloc() implementation), +** undoing any prior invocation of [SQLITE_CONFIG_MALLOC]. ^If the +** memory pointer is not NULL then the alternative memory +** allocator is engaged to handle all of SQLites memory allocation needs. +** The first pointer (the memory pointer) must be aligned to an 8-byte +** boundary or subsequent behavior of SQLite will be undefined. +** The minimum allocation size is capped at 2**12. Reasonable values +** for the minimum allocation size are 2**5 through 2**8.
    +** +** [[SQLITE_CONFIG_MUTEX]]
    SQLITE_CONFIG_MUTEX
    +**
    ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a +** pointer to an instance of the [sqlite3_mutex_methods] structure. +** The argument specifies alternative low-level mutex routines to be used +** in place the mutex routines built into SQLite.)^ ^SQLite makes a copy of +** the content of the [sqlite3_mutex_methods] structure before the call to +** [sqlite3_config()] returns. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** the entire mutexing subsystem is omitted from the build and hence calls to +** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will +** return [SQLITE_ERROR].
    +** +** [[SQLITE_CONFIG_GETMUTEX]]
    SQLITE_CONFIG_GETMUTEX
    +**
    ^(The SQLITE_CONFIG_GETMUTEX option takes a single argument which +** is a pointer to an instance of the [sqlite3_mutex_methods] structure. The +** [sqlite3_mutex_methods] +** structure is filled with the currently defined mutex routines.)^ +** This option can be used to overload the default mutex allocation +** routines with a wrapper used to track mutex usage for performance +** profiling or testing, for example. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** the entire mutexing subsystem is omitted from the build and hence calls to +** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will +** return [SQLITE_ERROR].
    +** +** [[SQLITE_CONFIG_LOOKASIDE]]
    SQLITE_CONFIG_LOOKASIDE
    +**
    ^(The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine +** the default size of lookaside memory on each [database connection]. +** The first argument is the +** size of each lookaside buffer slot and the second is the number of +** slots allocated to each database connection.)^ ^(SQLITE_CONFIG_LOOKASIDE +** sets the default lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE] +** option to [sqlite3_db_config()] can be used to change the lookaside +** configuration on individual connections.)^
    +** +** [[SQLITE_CONFIG_PCACHE2]]
    SQLITE_CONFIG_PCACHE2
    +**
    ^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is +** a pointer to an [sqlite3_pcache_methods2] object. This object specifies +** the interface to a custom page cache implementation.)^ +** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.
    +** +** [[SQLITE_CONFIG_GETPCACHE2]]
    SQLITE_CONFIG_GETPCACHE2
    +**
    ^(The SQLITE_CONFIG_GETPCACHE2 option takes a single argument which +** is a pointer to an [sqlite3_pcache_methods2] object. SQLite copies of +** the current page cache implementation into that object.)^
    +** +** [[SQLITE_CONFIG_LOG]]
    SQLITE_CONFIG_LOG
    +**
    The SQLITE_CONFIG_LOG option is used to configure the SQLite +** global [error log]. +** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a +** function with a call signature of void(*)(void*,int,const char*), +** and a pointer to void. ^If the function pointer is not NULL, it is +** invoked by [sqlite3_log()] to process each logging event. ^If the +** function pointer is NULL, the [sqlite3_log()] interface becomes a no-op. +** ^The void pointer that is the second argument to SQLITE_CONFIG_LOG is +** passed through as the first parameter to the application-defined logger +** function whenever that function is invoked. ^The second parameter to +** the logger function is a copy of the first parameter to the corresponding +** [sqlite3_log()] call and is intended to be a [result code] or an +** [extended result code]. ^The third parameter passed to the logger is +** log message after formatting via [sqlite3_snprintf()]. +** The SQLite logging interface is not reentrant; the logger function +** supplied by the application must not invoke any SQLite interface. +** In a multi-threaded application, the application-defined logger +** function must be threadsafe.
    +** +** [[SQLITE_CONFIG_URI]]
    SQLITE_CONFIG_URI +**
    ^(The SQLITE_CONFIG_URI option takes a single argument of type int. +** If non-zero, then URI handling is globally enabled. If the parameter is zero, +** then URI handling is globally disabled.)^ ^If URI handling is globally +** enabled, all filenames passed to [sqlite3_open()], [sqlite3_open_v2()], +** [sqlite3_open16()] or +** specified as part of [ATTACH] commands are interpreted as URIs, regardless +** of whether or not the [SQLITE_OPEN_URI] flag is set when the database +** connection is opened. ^If it is globally disabled, filenames are +** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the +** database connection is opened. ^(By default, URI handling is globally +** disabled. The default value may be changed by compiling with the +** [SQLITE_USE_URI] symbol defined.)^ +** +** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]]
    SQLITE_CONFIG_COVERING_INDEX_SCAN +**
    ^The SQLITE_CONFIG_COVERING_INDEX_SCAN option takes a single integer +** argument which is interpreted as a boolean in order to enable or disable +** the use of covering indices for full table scans in the query optimizer. +** ^The default setting is determined +** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on" +** if that compile-time option is omitted. +** The ability to disable the use of covering indices for full table scans +** is because some incorrectly coded legacy applications might malfunction +** when the optimization is enabled. Providing the ability to +** disable the optimization allows the older, buggy application code to work +** without change even with newer versions of SQLite. +** +** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]] +**
    SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE +**
    These options are obsolete and should not be used by new code. +** They are retained for backwards compatibility but are now no-ops. +**
    +** +** [[SQLITE_CONFIG_SQLLOG]] +**
    SQLITE_CONFIG_SQLLOG +**
    This option is only available if sqlite is compiled with the +** [SQLITE_ENABLE_SQLLOG] pre-processor macro defined. The first argument should +** be a pointer to a function of type void(*)(void*,sqlite3*,const char*, int). +** The second should be of type (void*). The callback is invoked by the library +** in three separate circumstances, identified by the value passed as the +** fourth parameter. If the fourth parameter is 0, then the database connection +** passed as the second argument has just been opened. The third argument +** points to a buffer containing the name of the main database file. If the +** fourth parameter is 1, then the SQL statement that the third parameter +** points to has just been executed. Or, if the fourth parameter is 2, then +** the connection being passed as the second parameter is being closed. The +** third parameter is passed NULL In this case. An example of using this +** configuration option can be seen in the "test_sqllog.c" source file in +** the canonical SQLite source tree.
    +** +** [[SQLITE_CONFIG_MMAP_SIZE]] +**
    SQLITE_CONFIG_MMAP_SIZE +**
    ^SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values +** that are the default mmap size limit (the default setting for +** [PRAGMA mmap_size]) and the maximum allowed mmap size limit. +** ^The default setting can be overridden by each database connection using +** either the [PRAGMA mmap_size] command, or by using the +** [SQLITE_FCNTL_MMAP_SIZE] file control. ^(The maximum allowed mmap size +** will be silently truncated if necessary so that it does not exceed the +** compile-time maximum mmap size set by the +** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^ +** ^If either argument to this option is negative, then that argument is +** changed to its compile-time default. +** +** [[SQLITE_CONFIG_WIN32_HEAPSIZE]] +**
    SQLITE_CONFIG_WIN32_HEAPSIZE +**
    ^The SQLITE_CONFIG_WIN32_HEAPSIZE option is only available if SQLite is +** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro +** defined. ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value +** that specifies the maximum size of the created heap. +** +** [[SQLITE_CONFIG_PCACHE_HDRSZ]] +**
    SQLITE_CONFIG_PCACHE_HDRSZ +**
    ^The SQLITE_CONFIG_PCACHE_HDRSZ option takes a single parameter which +** is a pointer to an integer and writes into that integer the number of extra +** bytes per page required for each page in [SQLITE_CONFIG_PAGECACHE]. +** The amount of extra space required can change depending on the compiler, +** target platform, and SQLite version. +** +** [[SQLITE_CONFIG_PMASZ]] +**
    SQLITE_CONFIG_PMASZ +**
    ^The SQLITE_CONFIG_PMASZ option takes a single parameter which +** is an unsigned integer and sets the "Minimum PMA Size" for the multithreaded +** sorter to that integer. The default minimum PMA Size is set by the +** [SQLITE_SORTER_PMASZ] compile-time option. New threads are launched +** to help with sort operations when multithreaded sorting +** is enabled (using the [PRAGMA threads] command) and the amount of content +** to be sorted exceeds the page size times the minimum of the +** [PRAGMA cache_size] setting and this value. +**
    +*/ +#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ +#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ +#define SQLITE_CONFIG_SERIALIZED 3 /* nil */ +#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_SCRATCH 6 /* void*, int sz, int N */ +#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ +#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ +#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ +#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ +#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ +/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ +#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ +#define SQLITE_CONFIG_PCACHE 14 /* no-op */ +#define SQLITE_CONFIG_GETPCACHE 15 /* no-op */ +#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ +#define SQLITE_CONFIG_URI 17 /* int */ +#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */ +#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ +#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ +#define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */ +#define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */ +#define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */ + +/* +** CAPI3REF: Database Connection Configuration Options +** +** These constants are the available integer configuration options that +** can be passed as the second argument to the [sqlite3_db_config()] interface. +** +** New configuration options may be added in future releases of SQLite. +** Existing configuration options might be discontinued. Applications +** should check the return code from [sqlite3_db_config()] to make sure that +** the call worked. ^The [sqlite3_db_config()] interface will return a +** non-zero [error code] if a discontinued or unsupported configuration option +** is invoked. +** +**
    +**
    SQLITE_DBCONFIG_LOOKASIDE
    +**
    ^This option takes three additional arguments that determine the +** [lookaside memory allocator] configuration for the [database connection]. +** ^The first argument (the third parameter to [sqlite3_db_config()] is a +** pointer to a memory buffer to use for lookaside memory. +** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb +** may be NULL in which case SQLite will allocate the +** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the +** size of each lookaside buffer slot. ^The third argument is the number of +** slots. The size of the buffer in the first argument must be greater than +** or equal to the product of the second and third arguments. The buffer +** must be aligned to an 8-byte boundary. ^If the second argument to +** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally +** rounded down to the next smaller multiple of 8. ^(The lookaside memory +** configuration for a database connection can only be changed when that +** connection is not currently using lookaside memory, or in other words +** when the "current value" returned by +** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero. +** Any attempt to change the lookaside memory configuration when lookaside +** memory is in use leaves the configuration unchanged and returns +** [SQLITE_BUSY].)^
    +** +**
    SQLITE_DBCONFIG_ENABLE_FKEY
    +**
    ^This option is used to enable or disable the enforcement of +** [foreign key constraints]. There should be two additional arguments. +** The first argument is an integer which is 0 to disable FK enforcement, +** positive to enable FK enforcement or negative to leave FK enforcement +** unchanged. The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether FK enforcement is off or on +** following this call. The second parameter may be a NULL pointer, in +** which case the FK enforcement setting is not reported back.
    +** +**
    SQLITE_DBCONFIG_ENABLE_TRIGGER
    +**
    ^This option is used to enable or disable [CREATE TRIGGER | triggers]. +** There should be two additional arguments. +** The first argument is an integer which is 0 to disable triggers, +** positive to enable triggers or negative to leave the setting unchanged. +** The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether triggers are disabled or enabled +** following this call. The second parameter may be a NULL pointer, in +** which case the trigger setting is not reported back.
    +** +**
    +*/ +#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ +#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ +#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ + + +/* +** CAPI3REF: Enable Or Disable Extended Result Codes +** METHOD: sqlite3 +** +** ^The sqlite3_extended_result_codes() routine enables or disables the +** [extended result codes] feature of SQLite. ^The extended result +** codes are disabled by default for historical compatibility. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3*, int onoff); + +/* +** CAPI3REF: Last Insert Rowid +** METHOD: sqlite3 +** +** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables) +** has a unique 64-bit signed +** integer key called the [ROWID | "rowid"]. ^The rowid is always available +** as an undeclared column named ROWID, OID, or _ROWID_ as long as those +** names are not also used by explicitly declared columns. ^If +** the table has a column of type [INTEGER PRIMARY KEY] then that column +** is another alias for the rowid. +** +** ^The sqlite3_last_insert_rowid(D) interface returns the [rowid] of the +** most recent successful [INSERT] into a rowid table or [virtual table] +** on database connection D. +** ^Inserts into [WITHOUT ROWID] tables are not recorded. +** ^If no successful [INSERT]s into rowid tables +** have ever occurred on the database connection D, +** then sqlite3_last_insert_rowid(D) returns zero. +** +** ^(If an [INSERT] occurs within a trigger or within a [virtual table] +** method, then this routine will return the [rowid] of the inserted +** row as long as the trigger or virtual table method is running. +** But once the trigger or virtual table method ends, the value returned +** by this routine reverts to what it was before the trigger or virtual +** table method began.)^ +** +** ^An [INSERT] that fails due to a constraint violation is not a +** successful [INSERT] and does not change the value returned by this +** routine. ^Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK, +** and INSERT OR ABORT make no changes to the return value of this +** routine when their insertion fails. ^(When INSERT OR REPLACE +** encounters a constraint violation, it does not fail. The +** INSERT continues to completion after deleting rows that caused +** the constraint problem so INSERT OR REPLACE will always change +** the return value of this interface.)^ +** +** ^For the purposes of this routine, an [INSERT] is considered to +** be successful even if it is subsequently rolled back. +** +** This function is accessible to SQL statements via the +** [last_insert_rowid() SQL function]. +** +** If a separate thread performs a new [INSERT] on the same +** database connection while the [sqlite3_last_insert_rowid()] +** function is running and thus changes the last insert [rowid], +** then the value returned by [sqlite3_last_insert_rowid()] is +** unpredictable and might not equal either the old or the new +** last insert [rowid]. +*/ +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3*); + +/* +** CAPI3REF: Count The Number Of Rows Modified +** METHOD: sqlite3 +** +** ^This function returns the number of rows modified, inserted or +** deleted by the most recently completed INSERT, UPDATE or DELETE +** statement on the database connection specified by the only parameter. +** ^Executing any other type of SQL statement does not modify the value +** returned by this function. +** +** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are +** considered - auxiliary changes caused by [CREATE TRIGGER | triggers], +** [foreign key actions] or [REPLACE] constraint resolution are not counted. +** +** Changes to a view that are intercepted by +** [INSTEAD OF trigger | INSTEAD OF triggers] are not counted. ^The value +** returned by sqlite3_changes() immediately after an INSERT, UPDATE or +** DELETE statement run on a view is always zero. Only changes made to real +** tables are counted. +** +** Things are more complicated if the sqlite3_changes() function is +** executed while a trigger program is running. This may happen if the +** program uses the [changes() SQL function], or if some other callback +** function invokes sqlite3_changes() directly. Essentially: +** +**
      +**
    • ^(Before entering a trigger program the value returned by +** sqlite3_changes() function is saved. After the trigger program +** has finished, the original value is restored.)^ +** +**
    • ^(Within a trigger program each INSERT, UPDATE and DELETE +** statement sets the value returned by sqlite3_changes() +** upon completion as normal. Of course, this value will not include +** any changes performed by sub-triggers, as the sqlite3_changes() +** value will be saved and restored after each sub-trigger has run.)^ +**
    +** +** ^This means that if the changes() SQL function (or similar) is used +** by the first INSERT, UPDATE or DELETE statement within a trigger, it +** returns the value as set when the calling statement began executing. +** ^If it is used by the second or subsequent such statement within a trigger +** program, the value returned reflects the number of rows modified by the +** previous INSERT, UPDATE or DELETE statement within the same trigger. +** +** See also the [sqlite3_total_changes()] interface, the +** [count_changes pragma], and the [changes() SQL function]. +** +** If a separate thread makes changes on the same database connection +** while [sqlite3_changes()] is running then the value returned +** is unpredictable and not meaningful. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3*); + +/* +** CAPI3REF: Total Number Of Rows Modified +** METHOD: sqlite3 +** +** ^This function returns the total number of rows inserted, modified or +** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed +** since the database connection was opened, including those executed as +** part of trigger programs. ^Executing any other type of SQL statement +** does not affect the value returned by sqlite3_total_changes(). +** +** ^Changes made as part of [foreign key actions] are included in the +** count, but those made as part of REPLACE constraint resolution are +** not. ^Changes to a view that are intercepted by INSTEAD OF triggers +** are not counted. +** +** See also the [sqlite3_changes()] interface, the +** [count_changes pragma], and the [total_changes() SQL function]. +** +** If a separate thread makes changes on the same database connection +** while [sqlite3_total_changes()] is running then the value +** returned is unpredictable and not meaningful. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3*); + +/* +** CAPI3REF: Interrupt A Long-Running Query +** METHOD: sqlite3 +** +** ^This function causes any pending database operation to abort and +** return at its earliest opportunity. This routine is typically +** called in response to a user action such as pressing "Cancel" +** or Ctrl-C where the user wants a long query operation to halt +** immediately. +** +** ^It is safe to call this routine from a thread different from the +** thread that is currently running the database operation. But it +** is not safe to call this routine with a [database connection] that +** is closed or might close before sqlite3_interrupt() returns. +** +** ^If an SQL operation is very nearly finished at the time when +** sqlite3_interrupt() is called, then it might not have an opportunity +** to be interrupted and might continue to completion. +** +** ^An SQL operation that is interrupted will return [SQLITE_INTERRUPT]. +** ^If the interrupted SQL operation is an INSERT, UPDATE, or DELETE +** that is inside an explicit transaction, then the entire transaction +** will be rolled back automatically. +** +** ^The sqlite3_interrupt(D) call is in effect until all currently running +** SQL statements on [database connection] D complete. ^Any new SQL statements +** that are started after the sqlite3_interrupt() call and before the +** running statements reaches zero are interrupted as if they had been +** running prior to the sqlite3_interrupt() call. ^New SQL statements +** that are started after the running statement count reaches zero are +** not effected by the sqlite3_interrupt(). +** ^A call to sqlite3_interrupt(D) that occurs when there are no running +** SQL statements is a no-op and has no effect on SQL statements +** that are started after the sqlite3_interrupt() call returns. +** +** If the database connection closes while [sqlite3_interrupt()] +** is running then bad things will likely happen. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3*); + +/* +** CAPI3REF: Determine If An SQL Statement Is Complete +** +** These routines are useful during command-line input to determine if the +** currently entered text seems to form a complete SQL statement or +** if additional input is needed before sending the text into +** SQLite for parsing. ^These routines return 1 if the input string +** appears to be a complete SQL statement. ^A statement is judged to be +** complete if it ends with a semicolon token and is not a prefix of a +** well-formed CREATE TRIGGER statement. ^Semicolons that are embedded within +** string literals or quoted identifier names or comments are not +** independent tokens (they are part of the token in which they are +** embedded) and thus do not count as a statement terminator. ^Whitespace +** and comments that follow the final semicolon are ignored. +** +** ^These routines return 0 if the statement is incomplete. ^If a +** memory allocation fails, then SQLITE_NOMEM is returned. +** +** ^These routines do not parse the SQL statements thus +** will not detect syntactically incorrect SQL. +** +** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior +** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked +** automatically by sqlite3_complete16(). If that initialization fails, +** then the return value from sqlite3_complete16() will be non-zero +** regardless of whether or not the input SQL is complete.)^ +** +** The input to [sqlite3_complete()] must be a zero-terminated +** UTF-8 string. +** +** The input to [sqlite3_complete16()] must be a zero-terminated +** UTF-16 string in native byte order. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *sql); +SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *sql); + +/* +** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors +** KEYWORDS: {busy-handler callback} {busy handler} +** METHOD: sqlite3 +** +** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X +** that might be invoked with argument P whenever +** an attempt is made to access a database table associated with +** [database connection] D when another thread +** or process has the table locked. +** The sqlite3_busy_handler() interface is used to implement +** [sqlite3_busy_timeout()] and [PRAGMA busy_timeout]. +** +** ^If the busy callback is NULL, then [SQLITE_BUSY] +** is returned immediately upon encountering the lock. ^If the busy callback +** is not NULL, then the callback might be invoked with two arguments. +** +** ^The first argument to the busy handler is a copy of the void* pointer which +** is the third argument to sqlite3_busy_handler(). ^The second argument to +** the busy handler callback is the number of times that the busy handler has +** been invoked previously for the same locking event. ^If the +** busy callback returns 0, then no additional attempts are made to +** access the database and [SQLITE_BUSY] is returned +** to the application. +** ^If the callback returns non-zero, then another attempt +** is made to access the database and the cycle repeats. +** +** The presence of a busy handler does not guarantee that it will be invoked +** when there is lock contention. ^If SQLite determines that invoking the busy +** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY] +** to the application instead of invoking the +** busy handler. +** Consider a scenario where one process is holding a read lock that +** it is trying to promote to a reserved lock and +** a second process is holding a reserved lock that it is trying +** to promote to an exclusive lock. The first process cannot proceed +** because it is blocked by the second and the second process cannot +** proceed because it is blocked by the first. If both processes +** invoke the busy handlers, neither will make any progress. Therefore, +** SQLite returns [SQLITE_BUSY] for the first process, hoping that this +** will induce the first process to release its read lock and allow +** the second process to proceed. +** +** ^The default busy callback is NULL. +** +** ^(There can only be a single busy handler defined for each +** [database connection]. Setting a new busy handler clears any +** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()] +** or evaluating [PRAGMA busy_timeout=N] will change the +** busy handler and thus clear any previously set busy handler. +** +** The busy callback should not take any actions which modify the +** database connection that invoked the busy handler. In other words, +** the busy handler is not reentrant. Any such actions +** result in undefined behavior. +** +** A busy handler must not close the database connection +** or [prepared statement] that invoked the busy handler. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); + +/* +** CAPI3REF: Set A Busy Timeout +** METHOD: sqlite3 +** +** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps +** for a specified amount of time when a table is locked. ^The handler +** will sleep multiple times until at least "ms" milliseconds of sleeping +** have accumulated. ^After at least "ms" milliseconds of sleeping, +** the handler returns 0 which causes [sqlite3_step()] to return +** [SQLITE_BUSY]. +** +** ^Calling this routine with an argument less than or equal to zero +** turns off all busy handlers. +** +** ^(There can only be a single busy handler for a particular +** [database connection] at any given moment. If another busy handler +** was defined (using [sqlite3_busy_handler()]) prior to calling +** this routine, that other busy handler is cleared.)^ +** +** See also: [PRAGMA busy_timeout] +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3*, int ms); + +/* +** CAPI3REF: Convenience Routines For Running Queries +** METHOD: sqlite3 +** +** This is a legacy interface that is preserved for backwards compatibility. +** Use of this interface is not recommended. +** +** Definition: A result table is memory data structure created by the +** [sqlite3_get_table()] interface. A result table records the +** complete query results from one or more queries. +** +** The table conceptually has a number of rows and columns. But +** these numbers are not part of the result table itself. These +** numbers are obtained separately. Let N be the number of rows +** and M be the number of columns. +** +** A result table is an array of pointers to zero-terminated UTF-8 strings. +** There are (N+1)*M elements in the array. The first M pointers point +** to zero-terminated strings that contain the names of the columns. +** The remaining entries all point to query results. NULL values result +** in NULL pointers. All other values are in their UTF-8 zero-terminated +** string representation as returned by [sqlite3_column_text()]. +** +** A result table might consist of one or more memory allocations. +** It is not safe to pass a result table directly to [sqlite3_free()]. +** A result table should be deallocated using [sqlite3_free_table()]. +** +** ^(As an example of the result table format, suppose a query result +** is as follows: +** +**
    +**        Name        | Age
    +**        -----------------------
    +**        Alice       | 43
    +**        Bob         | 28
    +**        Cindy       | 21
    +** 
    +** +** There are two column (M==2) and three rows (N==3). Thus the +** result table has 8 entries. Suppose the result table is stored +** in an array names azResult. Then azResult holds this content: +** +**
    +**        azResult[0] = "Name";
    +**        azResult[1] = "Age";
    +**        azResult[2] = "Alice";
    +**        azResult[3] = "43";
    +**        azResult[4] = "Bob";
    +**        azResult[5] = "28";
    +**        azResult[6] = "Cindy";
    +**        azResult[7] = "21";
    +** 
    )^ +** +** ^The sqlite3_get_table() function evaluates one or more +** semicolon-separated SQL statements in the zero-terminated UTF-8 +** string of its 2nd parameter and returns a result table to the +** pointer given in its 3rd parameter. +** +** After the application has finished with the result from sqlite3_get_table(), +** it must pass the result table pointer to sqlite3_free_table() in order to +** release the memory that was malloced. Because of the way the +** [sqlite3_malloc()] happens within sqlite3_get_table(), the calling +** function must not try to call [sqlite3_free()] directly. Only +** [sqlite3_free_table()] is able to release the memory properly and safely. +** +** The sqlite3_get_table() interface is implemented as a wrapper around +** [sqlite3_exec()]. The sqlite3_get_table() routine does not have access +** to any internal data structures of SQLite. It uses only the public +** interface defined here. As a consequence, errors that occur in the +** wrapper layer outside of the internal [sqlite3_exec()] call are not +** reflected in subsequent calls to [sqlite3_errcode()] or +** [sqlite3_errmsg()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_get_table( + sqlite3 *db, /* An open database */ + const char *zSql, /* SQL to be evaluated */ + char ***pazResult, /* Results of the query */ + int *pnRow, /* Number of result rows written here */ + int *pnColumn, /* Number of result columns written here */ + char **pzErrmsg /* Error msg written here */ +); +SQLITE_API void SQLITE_STDCALL sqlite3_free_table(char **result); + +/* +** CAPI3REF: Formatted String Printing Functions +** +** These routines are work-alikes of the "printf()" family of functions +** from the standard C library. +** These routines understand most of the common K&R formatting options, +** plus some additional non-standard formats, detailed below. +** Note that some of the more obscure formatting options from recent +** C-library standards are omitted from this implementation. +** +** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their +** results into memory obtained from [sqlite3_malloc()]. +** The strings returned by these two routines should be +** released by [sqlite3_free()]. ^Both routines return a +** NULL pointer if [sqlite3_malloc()] is unable to allocate enough +** memory to hold the resulting string. +** +** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from +** the standard C library. The result is written into the +** buffer supplied as the second parameter whose size is given by +** the first parameter. Note that the order of the +** first two parameters is reversed from snprintf().)^ This is an +** historical accident that cannot be fixed without breaking +** backwards compatibility. ^(Note also that sqlite3_snprintf() +** returns a pointer to its buffer instead of the number of +** characters actually written into the buffer.)^ We admit that +** the number of characters written would be a more useful return +** value but we cannot change the implementation of sqlite3_snprintf() +** now without breaking compatibility. +** +** ^As long as the buffer size is greater than zero, sqlite3_snprintf() +** guarantees that the buffer is always zero-terminated. ^The first +** parameter "n" is the total size of the buffer, including space for +** the zero terminator. So the longest string that can be completely +** written will be n-1 characters. +** +** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf(). +** +** These routines all implement some additional formatting +** options that are useful for constructing SQL statements. +** All of the usual printf() formatting options apply. In addition, there +** is are "%q", "%Q", "%w" and "%z" options. +** +** ^(The %q option works like %s in that it substitutes a nul-terminated +** string from the argument list. But %q also doubles every '\'' character. +** %q is designed for use inside a string literal.)^ By doubling each '\'' +** character it escapes that character and allows it to be inserted into +** the string. +** +** For example, assume the string variable zText contains text as follows: +** +**
    +**  char *zText = "It's a happy day!";
    +** 
    +** +** One can use this text in an SQL statement as follows: +** +**
    +**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
    +**  sqlite3_exec(db, zSQL, 0, 0, 0);
    +**  sqlite3_free(zSQL);
    +** 
    +** +** 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 +** would have looked like this: +** +**
    +**  INSERT INTO table1 VALUES('It's a happy day!');
    +** 
    +** +** This second example is an SQL syntax error. As a general rule you should +** always use %q instead of %s when inserting text into a string literal. +** +** ^(The %Q option works like %q except it also adds single quotes around +** the outside of the total string. Additionally, if the parameter in the +** argument list is a NULL pointer, %Q substitutes the text "NULL" (without +** single quotes).)^ So, for example, one could say: +** +**
    +**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
    +**  sqlite3_exec(db, zSQL, 0, 0, 0);
    +**  sqlite3_free(zSQL);
    +** 
    +** +** The code above will render a correct SQL statement in the zSQL +** variable even if the zText variable is a NULL pointer. +** +** ^(The "%w" formatting option is like "%q" except that it expects to +** be contained within double-quotes instead of single quotes, and it +** escapes the double-quote character instead of the single-quote +** character.)^ The "%w" formatting option is intended for safely inserting +** table and column names into a constructed SQL statement. +** +** ^(The "%z" formatting option works like "%s" but with the +** addition that after the string has been read and copied into +** the result, [sqlite3_free()] is called on the input string.)^ +*/ +SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char*,...); +SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char*, va_list); +SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int,char*,const char*, ...); +SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int,char*,const char*, va_list); + +/* +** CAPI3REF: Memory Allocation Subsystem +** +** The SQLite core uses these three routines for all of its own +** internal memory allocation needs. "Core" in the previous sentence +** does not include operating-system specific VFS implementation. The +** Windows VFS uses native malloc() and free() for some operations. +** +** ^The sqlite3_malloc() routine returns a pointer to a block +** of memory at least N bytes in length, where N is the parameter. +** ^If sqlite3_malloc() is unable to obtain sufficient free +** memory, it returns a NULL pointer. ^If the parameter N to +** sqlite3_malloc() is zero or negative then sqlite3_malloc() returns +** a NULL pointer. +** +** ^The sqlite3_malloc64(N) routine works just like +** sqlite3_malloc(N) except that N is an unsigned 64-bit integer instead +** of a signed 32-bit integer. +** +** ^Calling sqlite3_free() with a pointer previously returned +** by sqlite3_malloc() or sqlite3_realloc() releases that memory so +** that it might be reused. ^The sqlite3_free() routine is +** a no-op if is called with a NULL pointer. Passing a NULL pointer +** to sqlite3_free() is harmless. After being freed, memory +** should neither be read nor written. Even reading previously freed +** memory might result in a segmentation fault or other severe error. +** Memory corruption, a segmentation fault, or other severe error +** might result if sqlite3_free() is called with a non-NULL pointer that +** was not obtained from sqlite3_malloc() or sqlite3_realloc(). +** +** ^The sqlite3_realloc(X,N) interface attempts to resize a +** prior memory allocation X to be at least N bytes. +** ^If the X parameter to sqlite3_realloc(X,N) +** is a NULL pointer then its behavior is identical to calling +** sqlite3_malloc(N). +** ^If the N parameter to sqlite3_realloc(X,N) is zero or +** negative then the behavior is exactly the same as calling +** sqlite3_free(X). +** ^sqlite3_realloc(X,N) returns a pointer to a memory allocation +** of at least N bytes in size or NULL if insufficient memory is available. +** ^If M is the size of the prior allocation, then min(N,M) bytes +** of the prior allocation are copied into the beginning of buffer returned +** by sqlite3_realloc(X,N) and the prior allocation is freed. +** ^If sqlite3_realloc(X,N) returns NULL and N is positive, then the +** prior allocation is not freed. +** +** ^The sqlite3_realloc64(X,N) interfaces works the same as +** sqlite3_realloc(X,N) except that N is a 64-bit unsigned integer instead +** of a 32-bit signed integer. +** +** ^If X is a memory allocation previously obtained from sqlite3_malloc(), +** sqlite3_malloc64(), sqlite3_realloc(), or sqlite3_realloc64(), then +** sqlite3_msize(X) returns the size of that memory allocation in bytes. +** ^The value returned by sqlite3_msize(X) might be larger than the number +** of bytes requested when X was allocated. ^If X is a NULL pointer then +** sqlite3_msize(X) returns zero. If X points to something that is not +** the beginning of memory allocation, or if it points to a formerly +** valid memory allocation that has now been freed, then the behavior +** of sqlite3_msize(X) is undefined and possibly harmful. +** +** ^The memory returned by sqlite3_malloc(), sqlite3_realloc(), +** sqlite3_malloc64(), and sqlite3_realloc64() +** is always aligned to at least an 8 byte boundary, or to a +** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time +** option is used. +** +** In SQLite version 3.5.0 and 3.5.1, it was possible to define +** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in +** implementation of these routines to be omitted. That capability +** is no longer provided. Only built-in memory allocators can be used. +** +** Prior to SQLite version 3.7.10, the Windows OS interface layer called +** the system malloc() and free() directly when converting +** filenames between the UTF-8 encoding used by SQLite +** and whatever filename encoding is used by the particular Windows +** installation. Memory allocation errors were detected, but +** they were reported back as [SQLITE_CANTOPEN] or +** [SQLITE_IOERR] rather than [SQLITE_NOMEM]. +** +** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()] +** must be either NULL or else pointers obtained from a prior +** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have +** not yet been released. +** +** The application must not read or write any part of +** a block of memory after it has been released using +** [sqlite3_free()] or [sqlite3_realloc()]. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int); +SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64); +SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void*, int); +SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void*, sqlite3_uint64); +SQLITE_API void SQLITE_STDCALL sqlite3_free(void*); +SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void*); + +/* +** CAPI3REF: Memory Allocator Statistics +** +** SQLite provides these two interfaces for reporting on the status +** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()] +** routines, which form the built-in memory allocation subsystem. +** +** ^The [sqlite3_memory_used()] routine returns the number of bytes +** of memory currently outstanding (malloced but not freed). +** ^The [sqlite3_memory_highwater()] routine returns the maximum +** value of [sqlite3_memory_used()] since the high-water mark +** was last reset. ^The values returned by [sqlite3_memory_used()] and +** [sqlite3_memory_highwater()] include any overhead +** added by SQLite in its implementation of [sqlite3_malloc()], +** but not overhead added by the any underlying system library +** routines that [sqlite3_malloc()] may call. +** +** ^The memory high-water mark is reset to the current value of +** [sqlite3_memory_used()] if and only if the parameter to +** [sqlite3_memory_highwater()] is true. ^The value returned +** by [sqlite3_memory_highwater(1)] is the high-water mark +** prior to the reset. +*/ +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void); +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag); + +/* +** CAPI3REF: Pseudo-Random Number Generator +** +** SQLite contains a high-quality pseudo-random number generator (PRNG) used to +** select random [ROWID | ROWIDs] when inserting new records into a table that +** already uses the largest possible [ROWID]. The PRNG is also used for +** the build-in random() and randomblob() SQL functions. This interface allows +** applications to access the same PRNG for other purposes. +** +** ^A call to this routine stores N bytes of randomness into buffer P. +** ^The P parameter can be a NULL pointer. +** +** ^If this routine has not been previously called or if the previous +** call had N less than one or a NULL pointer for P, then the PRNG is +** seeded using randomness obtained from the xRandomness method of +** the default [sqlite3_vfs] object. +** ^If the previous call to this routine had an N of 1 or more and a +** non-NULL P then the pseudo-randomness is generated +** internally and without recourse to the [sqlite3_vfs] xRandomness +** method. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *P); + +/* +** CAPI3REF: Compile-Time Authorization Callbacks +** METHOD: sqlite3 +** +** ^This routine registers an authorizer callback with a particular +** [database connection], supplied in the first argument. +** ^The authorizer callback is invoked as SQL statements are being compiled +** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], +** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. ^At various +** points during the compilation process, as logic is being created +** to perform various actions, the authorizer callback is invoked to +** see if those actions are allowed. ^The authorizer callback should +** return [SQLITE_OK] to allow the action, [SQLITE_IGNORE] to disallow the +** specific action but allow the SQL statement to continue to be +** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be +** rejected with an error. ^If the authorizer callback returns +** any value other than [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY] +** then the [sqlite3_prepare_v2()] or equivalent call that triggered +** the authorizer will fail with an error message. +** +** When the callback returns [SQLITE_OK], that means the operation +** requested is ok. ^When the callback returns [SQLITE_DENY], the +** [sqlite3_prepare_v2()] or equivalent call that triggered the +** authorizer will fail with an error message explaining that +** access is denied. +** +** ^The first parameter to the authorizer callback is a copy of the third +** parameter to the sqlite3_set_authorizer() interface. ^The second parameter +** to the callback is an integer [SQLITE_COPY | action code] that specifies +** the particular action to be authorized. ^The third through sixth parameters +** to the callback are zero-terminated strings that contain additional +** details about the action to be authorized. +** +** ^If the action code is [SQLITE_READ] +** and the callback returns [SQLITE_IGNORE] then the +** [prepared statement] statement is constructed to substitute +** a NULL value in place of the table column that would have +** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE] +** return can be used to deny an untrusted user access to individual +** columns of a table. +** ^If the action code is [SQLITE_DELETE] and the callback returns +** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the +** [truncate optimization] is disabled and all rows are deleted individually. +** +** An authorizer is used when [sqlite3_prepare | preparing] +** SQL statements from an untrusted source, to ensure that the SQL statements +** do not try to access data they are not allowed to see, or that they do not +** try to execute malicious statements that damage the database. For +** example, an application may allow a user to enter arbitrary +** SQL queries for evaluation by a database. But the application does +** not want the user to be able to make arbitrary changes to the +** database. An authorizer could then be put in place while the +** user-entered SQL is being [sqlite3_prepare | prepared] that +** disallows everything except [SELECT] statements. +** +** Applications that need to process SQL from untrusted sources +** might also consider lowering resource limits using [sqlite3_limit()] +** and limiting database size using the [max_page_count] [PRAGMA] +** in addition to using an authorizer. +** +** ^(Only a single authorizer can be in place on a database connection +** at a time. Each call to sqlite3_set_authorizer overrides the +** previous call.)^ ^Disable the authorizer by installing a NULL callback. +** The authorizer is disabled by default. +** +** The authorizer callback must not do anything that will modify +** the database connection that invoked the authorizer callback. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +** ^When [sqlite3_prepare_v2()] is used to prepare a statement, the +** statement might be re-prepared during [sqlite3_step()] due to a +** schema change. Hence, the application should ensure that the +** correct authorizer callback remains in place during the [sqlite3_step()]. +** +** ^Note that the authorizer callback is invoked only during +** [sqlite3_prepare()] or its variants. Authorization is not +** performed during statement evaluation in [sqlite3_step()], unless +** as stated in the previous paragraph, sqlite3_step() invokes +** sqlite3_prepare_v2() to reprepare a statement after a schema change. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer( + sqlite3*, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pUserData +); + +/* +** CAPI3REF: Authorizer Return Codes +** +** The [sqlite3_set_authorizer | authorizer callback function] must +** return either [SQLITE_OK] or one of these two constants in order +** to signal SQLite whether or not the action is permitted. See the +** [sqlite3_set_authorizer | authorizer documentation] for additional +** information. +** +** Note that SQLITE_IGNORE is also used as a [conflict resolution mode] +** returned from the [sqlite3_vtab_on_conflict()] interface. +*/ +#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 */ + +/* +** CAPI3REF: Authorizer Action Codes +** +** The [sqlite3_set_authorizer()] interface registers a callback function +** that is invoked to authorize certain SQL statement actions. The +** second parameter to the callback is an integer code that specifies +** what action is being authorized. These are the integer action codes that +** the authorizer callback may be passed. +** +** These action code values signify what kind of operation is to be +** authorized. The 3rd and 4th parameters to the authorization +** callback function will be parameters or NULL depending on which of these +** codes is used as the second parameter. ^(The 5th parameter to the +** authorizer callback is the name of the database ("main", "temp", +** etc.) if applicable.)^ ^The 6th parameter to the authorizer callback +** is the name of the inner-most trigger or view that is responsible for +** the access attempt or NULL if this access attempt is directly from +** top-level SQL code. +*/ +/******************************************* 3rd ************ 4th ***********/ +#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ +#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */ +#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */ +#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */ +#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */ +#define SQLITE_CREATE_VIEW 8 /* View Name NULL */ +#define SQLITE_DELETE 9 /* Table Name NULL */ +#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */ +#define SQLITE_DROP_TABLE 11 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */ +#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */ +#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */ +#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */ +#define SQLITE_DROP_VIEW 17 /* View Name NULL */ +#define SQLITE_INSERT 18 /* Table Name NULL */ +#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */ +#define SQLITE_READ 20 /* Table Name Column Name */ +#define SQLITE_SELECT 21 /* NULL NULL */ +#define SQLITE_TRANSACTION 22 /* Operation 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 */ +#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */ +#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ +#define SQLITE_FUNCTION 31 /* NULL Function Name */ +#define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */ +#define SQLITE_COPY 0 /* No longer used */ +#define SQLITE_RECURSIVE 33 /* NULL NULL */ + +/* +** CAPI3REF: Tracing And Profiling Functions +** METHOD: sqlite3 +** +** These routines register callback functions that can be used for +** tracing and profiling the execution of SQL statements. +** +** ^The callback function registered by sqlite3_trace() is invoked at +** various times when an SQL statement is being run by [sqlite3_step()]. +** ^The sqlite3_trace() callback is invoked with a UTF-8 rendering of the +** SQL statement text as the statement first begins executing. +** ^(Additional sqlite3_trace() callbacks might occur +** as each triggered subprogram is entered. The callbacks for triggers +** contain a UTF-8 SQL comment that identifies the trigger.)^ +** +** The [SQLITE_TRACE_SIZE_LIMIT] compile-time option can be used to limit +** the length of [bound parameter] expansion in the output of sqlite3_trace(). +** +** ^The callback function registered by sqlite3_profile() is invoked +** as each SQL statement finishes. ^The profile callback contains +** the original statement text and an estimate of wall-clock time +** of how long that statement took to run. ^The profile callback +** time is in units of nanoseconds, however the current implementation +** is only capable of millisecond resolution so the six least significant +** digits in the time are meaningless. Future versions of SQLite +** might provide greater resolution on the profiler callback. The +** sqlite3_profile() function is considered experimental and is +** subject to change in future versions of SQLite. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); +SQLITE_API SQLITE_EXPERIMENTAL void *SQLITE_STDCALL sqlite3_profile(sqlite3*, + void(*xProfile)(void*,const char*,sqlite3_uint64), void*); + +/* +** CAPI3REF: Query Progress Callbacks +** METHOD: sqlite3 +** +** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback +** function X to be invoked periodically during long running calls to +** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for +** database connection D. An example use for this +** interface is to keep a GUI updated during a large query. +** +** ^The parameter P is passed through as the only parameter to the +** callback function X. ^The parameter N is the approximate number of +** [virtual machine instructions] that are evaluated between successive +** invocations of the callback X. ^If N is less than one then the progress +** handler is disabled. +** +** ^Only a single progress handler may be defined at one time per +** [database connection]; setting a new progress handler cancels the +** old one. ^Setting parameter X to NULL disables the progress handler. +** ^The progress handler is also disabled by setting N to a value less +** than 1. +** +** ^If the progress callback returns non-zero, the operation is +** interrupted. This feature can be used to implement a +** "Cancel" button on a GUI progress dialog box. +** +** The progress handler callback must not do anything that will modify +** the database connection that invoked the progress handler. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); + +/* +** CAPI3REF: Opening A New Database Connection +** CONSTRUCTOR: sqlite3 +** +** ^These routines open an SQLite database file as specified by the +** filename argument. ^The filename argument is interpreted as UTF-8 for +** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte +** order for sqlite3_open16(). ^(A [database connection] handle is usually +** returned in *ppDb, even if an error occurs. The only exception is that +** if SQLite is unable to allocate memory to hold the [sqlite3] object, +** a NULL will be written into *ppDb instead of a pointer to the [sqlite3] +** object.)^ ^(If the database is opened (and/or created) successfully, then +** [SQLITE_OK] is returned. Otherwise an [error code] is returned.)^ ^The +** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain +** an English language description of the error following a failure of any +** of the sqlite3_open() routines. +** +** ^The default encoding will be UTF-8 for databases created using +** sqlite3_open() or sqlite3_open_v2(). ^The default encoding for databases +** created using sqlite3_open16() will be UTF-16 in the native byte order. +** +** Whether or not an error occurs when it is opened, resources +** associated with the [database connection] handle should be released by +** passing it to [sqlite3_close()] when it is no longer required. +** +** The sqlite3_open_v2() interface works like sqlite3_open() +** except that it accepts two additional parameters for additional control +** over the new database connection. ^(The flags parameter to +** sqlite3_open_v2() can take one of +** the following three values, optionally combined with the +** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE], +** [SQLITE_OPEN_PRIVATECACHE], and/or [SQLITE_OPEN_URI] flags:)^ +** +**
    +** ^(
    [SQLITE_OPEN_READONLY]
    +**
    The database is opened in read-only mode. If the database does not +** already exist, an error is returned.
    )^ +** +** ^(
    [SQLITE_OPEN_READWRITE]
    +**
    The database is opened for reading and writing if possible, or reading +** only if the file is write protected by the operating system. In either +** case the database must already exist, otherwise an error is returned.
    )^ +** +** ^(
    [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]
    +**
    The database is opened for reading and writing, and is created if +** it does not already exist. This is the behavior that is always used for +** sqlite3_open() and sqlite3_open16().
    )^ +**
    +** +** If the 3rd parameter to sqlite3_open_v2() is not one of the +** combinations shown above optionally combined with other +** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits] +** then the behavior is undefined. +** +** ^If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection +** opens in the multi-thread [threading mode] as long as the single-thread +** mode has not been set at compile-time or start-time. ^If the +** [SQLITE_OPEN_FULLMUTEX] flag is set then the database connection opens +** in the serialized [threading mode] unless single-thread was +** previously selected at compile-time or start-time. +** ^The [SQLITE_OPEN_SHAREDCACHE] flag causes the database connection to be +** eligible to use [shared cache mode], regardless of whether or not shared +** cache is enabled using [sqlite3_enable_shared_cache()]. ^The +** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not +** participate in [shared cache mode] even if it is enabled. +** +** ^The fourth parameter to sqlite3_open_v2() is the name of the +** [sqlite3_vfs] object that defines the operating system interface that +** the new database connection should use. ^If the fourth parameter is +** a NULL pointer then the default [sqlite3_vfs] object is used. +** +** ^If the filename is ":memory:", then a private, temporary in-memory database +** is created for the connection. ^This in-memory database will vanish when +** the database connection is closed. Future versions of SQLite might +** make use of additional special filenames that begin with the ":" character. +** It is recommended that when a database filename actually does begin with +** a ":" character you should prefix the filename with a pathname such as +** "./" to avoid ambiguity. +** +** ^If the filename is an empty string, then a private, temporary +** on-disk database will be created. ^This private database will be +** automatically deleted as soon as the database connection is closed. +** +** [[URI filenames in sqlite3_open()]]

    URI Filenames

    +** +** ^If [URI filename] interpretation is enabled, and the filename argument +** begins with "file:", then the filename is interpreted as a URI. ^URI +** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is +** set in the fourth argument to sqlite3_open_v2(), or if it has +** been enabled globally using the [SQLITE_CONFIG_URI] option with the +** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option. +** As of SQLite version 3.7.7, URI filename interpretation is turned off +** by default, but future releases of SQLite might enable URI filename +** interpretation by default. See "[URI filenames]" for additional +** information. +** +** URI filenames are parsed according to RFC 3986. ^If the URI contains an +** authority, then it must be either an empty string or the string +** "localhost". ^If the authority is not an empty string or "localhost", an +** error is returned to the caller. ^The fragment component of a URI, if +** present, is ignored. +** +** ^SQLite uses the path component of the URI as the name of the disk file +** which contains the database. ^If the path begins with a '/' character, +** then it is interpreted as an absolute path. ^If the path does not begin +** with a '/' (meaning that the authority section is omitted from the URI) +** then the path is interpreted as a relative path. +** ^(On windows, the first component of an absolute path +** is a drive specification (e.g. "C:").)^ +** +** [[core URI query parameters]] +** The query component of a URI may contain parameters that are interpreted +** either by SQLite itself, or by a [VFS | custom VFS implementation]. +** SQLite and its built-in [VFSes] interpret the +** following query parameters: +** +**
      +**
    • vfs: ^The "vfs" parameter may be used to specify the name of +** a VFS object that provides the operating system interface that should +** be used to access the database file on disk. ^If this option is set to +** an empty string the default VFS object is used. ^Specifying an unknown +** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is +** present, then the VFS specified by the option takes precedence over +** the value passed as the fourth parameter to sqlite3_open_v2(). +** +**
    • mode: ^(The mode parameter may be set to either "ro", "rw", +** "rwc", or "memory". Attempting to set it to any other value is +** an error)^. +** ^If "ro" is specified, then the database is opened for read-only +** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the +** third argument to sqlite3_open_v2(). ^If the mode option is set to +** "rw", then the database is opened for read-write (but not create) +** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had +** been set. ^Value "rwc" is equivalent to setting both +** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If the mode option is +** set to "memory" then a pure [in-memory database] that never reads +** or writes from disk is used. ^It is an error to specify a value for +** the mode parameter that is less restrictive than that specified by +** the flags passed in the third parameter to sqlite3_open_v2(). +** +**
    • cache: ^The cache parameter may be set to either "shared" or +** "private". ^Setting it to "shared" is equivalent to setting the +** SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to +** sqlite3_open_v2(). ^Setting the cache parameter to "private" is +** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. +** ^If sqlite3_open_v2() is used and the "cache" parameter is present in +** a URI filename, its value overrides any behavior requested by setting +** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag. +** +**
    • psow: ^The psow parameter indicates whether or not the +** [powersafe overwrite] property does or does not apply to the +** storage media on which the database file resides. +** +**
    • nolock: ^The nolock parameter is a boolean query parameter +** which if set disables file locking in rollback journal modes. This +** is useful for accessing a database on a filesystem that does not +** support locking. Caution: Database corruption might result if two +** or more processes write to the same database and any one of those +** processes uses nolock=1. +** +**
    • immutable: ^The immutable parameter is a boolean query +** parameter that indicates that the database file is stored on +** read-only media. ^When immutable is set, SQLite assumes that the +** database file cannot be changed, even by a process with higher +** privilege, and so the database is opened read-only and all locking +** and change detection is disabled. Caution: Setting the immutable +** property on a database file that does in fact change can result +** in incorrect query results and/or [SQLITE_CORRUPT] errors. +** See also: [SQLITE_IOCAP_IMMUTABLE]. +** +**
    +** +** ^Specifying an unknown parameter in the query component of a URI is not an +** error. Future versions of SQLite might understand additional query +** parameters. See "[query parameters with special meaning to SQLite]" for +** additional information. +** +** [[URI filename examples]]

    URI filename examples

    +** +** +**
    URI filenames Results +**
    file:data.db +** Open the file "data.db" in the current directory. +**
    file:/home/fred/data.db
    +** file:///home/fred/data.db
    +** file://localhost/home/fred/data.db
    +** Open the database file "/home/fred/data.db". +**
    file://darkstar/home/fred/data.db +** An error. "darkstar" is not a recognized authority. +**
    +** file:///C:/Documents%20and%20Settings/fred/Desktop/data.db +** Windows only: Open the file "data.db" on fred's desktop on drive +** C:. Note that the %20 escaping in this example is not strictly +** necessary - space characters can be used literally +** in URI filenames. +**
    file:data.db?mode=ro&cache=private +** Open file "data.db" in the current directory for read-only access. +** Regardless of whether or not shared-cache mode is enabled by +** default, use a private cache. +**
    file:/home/fred/data.db?vfs=unix-dotfile +** Open file "/home/fred/data.db". Use the special VFS "unix-dotfile" +** that uses dot-files in place of posix advisory locking. +**
    file:data.db?mode=readonly +** An error. "readonly" is not a valid option for the "mode" parameter. +**
    +** +** ^URI hexadecimal escape sequences (%HH) are supported within the path and +** query components of a URI. A hexadecimal escape sequence consists of a +** percent sign - "%" - followed by exactly two hexadecimal digits +** specifying an octet value. ^Before the path or query components of a +** URI filename are interpreted, they are encoded using UTF-8 and all +** hexadecimal escape sequences replaced by a single byte containing the +** corresponding octet. If this process generates an invalid UTF-8 encoding, +** the results are undefined. +** +** Note to Windows users: The encoding used for the filename argument +** of sqlite3_open() and sqlite3_open_v2() must be UTF-8, not whatever +** codepage is currently defined. Filenames containing international +** characters must be converted to UTF-8 prior to passing them into +** sqlite3_open() or sqlite3_open_v2(). +** +** Note to Windows Runtime users: The temporary directory must be set +** prior to calling sqlite3_open() or sqlite3_open_v2(). Otherwise, various +** features that require the use of temporary files may fail. +** +** See also: [sqlite3_temp_directory] +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_open( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +SQLITE_API int SQLITE_STDCALL sqlite3_open16( + const void *filename, /* Database filename (UTF-16) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +SQLITE_API int SQLITE_STDCALL sqlite3_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs /* Name of VFS module to use */ +); + +/* +** CAPI3REF: Obtain Values For URI Parameters +** +** These are utility routines, useful to VFS implementations, that check +** to see if a database file was a URI that contained a specific query +** parameter, and if so obtains the value of that query parameter. +** +** If F is the database filename pointer passed into the xOpen() method of +** a VFS implementation when the flags parameter to xOpen() has one or +** more of the [SQLITE_OPEN_URI] or [SQLITE_OPEN_MAIN_DB] bits set and +** P is the name of the query parameter, then +** sqlite3_uri_parameter(F,P) returns the value of the P +** parameter if it exists or a NULL pointer if P does not appear as a +** query parameter on F. If P is a query parameter of F +** has no explicit value, then sqlite3_uri_parameter(F,P) returns +** a pointer to an empty string. +** +** The sqlite3_uri_boolean(F,P,B) routine assumes that P is a boolean +** parameter and returns true (1) or false (0) according to the value +** of P. The sqlite3_uri_boolean(F,P,B) routine returns true (1) if the +** value of query parameter P is one of "yes", "true", or "on" in any +** case or if the value begins with a non-zero number. The +** sqlite3_uri_boolean(F,P,B) routines returns false (0) if the value of +** query parameter P is one of "no", "false", or "off" in any case or +** if the value begins with a numeric zero. If P is not a query +** parameter on F or if the value of P is does not match any of the +** above, then sqlite3_uri_boolean(F,P,B) returns (B!=0). +** +** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a +** 64-bit signed integer and returns that integer, or D if P does not +** exist. If the value of P is something other than an integer, then +** zero is returned. +** +** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and +** sqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and +** is not a database file pathname pointer that SQLite passed into the xOpen +** VFS method, then the behavior of this routine is undefined and probably +** undesirable. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam); +SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64(const char*, const char*, sqlite3_int64); + + +/* +** CAPI3REF: Error Codes And Messages +** METHOD: sqlite3 +** +** ^If the most recent sqlite3_* API call associated with +** [database connection] D failed, then the sqlite3_errcode(D) interface +** returns the numeric [result code] or [extended result code] for that +** API call. +** If the most recent API call was successful, +** then the return value from sqlite3_errcode() is undefined. +** ^The sqlite3_extended_errcode() +** interface is the same except that it always returns the +** [extended result code] even when extended result codes are +** disabled. +** +** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language +** text that describes the error, as either UTF-8 or UTF-16 respectively. +** ^(Memory to hold the error message string is managed internally. +** The application does not need to worry about freeing the result. +** However, the error string might be overwritten or deallocated by +** subsequent calls to other SQLite interface functions.)^ +** +** ^The sqlite3_errstr() interface returns the English-language text +** that describes the [result code], as UTF-8. +** ^(Memory to hold the error message string is managed internally +** and must not be freed by the application)^. +** +** When the serialized [threading mode] is in use, it might be the +** case that a second error occurs on a separate thread in between +** the time of the first error and the call to these interfaces. +** When that happens, the second error will be reported since these +** interfaces always report the most recent result. To avoid +** this, each thread can obtain exclusive use of the [database connection] D +** by invoking [sqlite3_mutex_enter]([sqlite3_db_mutex](D)) before beginning +** to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after +** all calls to the interfaces listed here are completed. +** +** If an interface fails with SQLITE_MISUSE, that means the interface +** was invoked incorrectly by the application. In that case, the +** error code and message may or may not be set. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db); +SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db); +SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3*); +SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3*); +SQLITE_API const char *SQLITE_STDCALL sqlite3_errstr(int); + +/* +** CAPI3REF: Prepared Statement Object +** KEYWORDS: {prepared statement} {prepared statements} +** +** An instance of this object represents a single SQL statement that +** has been compiled into binary form and is ready to be evaluated. +** +** Think of each SQL statement as a separate computer program. The +** original SQL text is source code. A prepared statement object +** is the compiled object code. All SQL must be converted into a +** prepared statement before it can be run. +** +** The life-cycle of a prepared statement object usually goes like this: +** +**
      +**
    1. Create the prepared statement object using [sqlite3_prepare_v2()]. +**
    2. Bind values to [parameters] using the sqlite3_bind_*() +** interfaces. +**
    3. Run the SQL by calling [sqlite3_step()] one or more times. +**
    4. Reset the prepared statement using [sqlite3_reset()] then go back +** to step 2. Do this zero or more times. +**
    5. Destroy the object using [sqlite3_finalize()]. +**
    +*/ +typedef struct sqlite3_stmt sqlite3_stmt; + +/* +** CAPI3REF: Run-time Limits +** METHOD: sqlite3 +** +** ^(This interface allows the size of various constructs to be limited +** on a connection by connection basis. The first parameter is the +** [database connection] whose limit is to be set or queried. The +** second parameter is one of the [limit categories] that define a +** class of constructs to be size limited. The third parameter is the +** new limit for that construct.)^ +** +** ^If the new limit is a negative number, the limit is unchanged. +** ^(For each limit category SQLITE_LIMIT_NAME there is a +** [limits | hard upper bound] +** set at compile-time by a C preprocessor macro called +** [limits | SQLITE_MAX_NAME]. +** (The "_LIMIT_" in the name is changed to "_MAX_".))^ +** ^Attempts to increase a limit above its hard upper bound are +** silently truncated to the hard upper bound. +** +** ^Regardless of whether or not the limit was changed, the +** [sqlite3_limit()] interface returns the prior value of the limit. +** ^Hence, to find the current value of a limit without changing it, +** simply invoke this interface with the third parameter set to -1. +** +** Run-time limits are intended for use in applications that manage +** both their own internal database and also databases that are controlled +** by untrusted external sources. An example application might be a +** web browser that has its own databases for storing history and +** separate databases controlled by JavaScript applications downloaded +** off the Internet. The internal databases can be given the +** large, default limits. Databases managed by external sources can +** be given much smaller limits designed to prevent a denial of service +** attack. Developers might also want to use the [sqlite3_set_authorizer()] +** interface to further control untrusted SQL. The size of the database +** created by an untrusted script can be contained using the +** [max_page_count] [PRAGMA]. +** +** New run-time limit categories may be added in future releases. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal); + +/* +** CAPI3REF: Run-Time Limit Categories +** KEYWORDS: {limit category} {*limit categories} +** +** These constants define various performance limits +** that can be lowered at run-time using [sqlite3_limit()]. +** The synopsis of the meanings of the various limits is shown below. +** Additional information is available at [limits | Limits in SQLite]. +** +**
    +** [[SQLITE_LIMIT_LENGTH]] ^(
    SQLITE_LIMIT_LENGTH
    +**
    The maximum size of any string or BLOB or table row, in bytes.
    )^ +** +** [[SQLITE_LIMIT_SQL_LENGTH]] ^(
    SQLITE_LIMIT_SQL_LENGTH
    +**
    The maximum length of an SQL statement, in bytes.
    )^ +** +** [[SQLITE_LIMIT_COLUMN]] ^(
    SQLITE_LIMIT_COLUMN
    +**
    The maximum number of columns in a table definition or in the +** result set of a [SELECT] or the maximum number of columns in an index +** or in an ORDER BY or GROUP BY clause.
    )^ +** +** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(
    SQLITE_LIMIT_EXPR_DEPTH
    +**
    The maximum depth of the parse tree on any expression.
    )^ +** +** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(
    SQLITE_LIMIT_COMPOUND_SELECT
    +**
    The maximum number of terms in a compound SELECT statement.
    )^ +** +** [[SQLITE_LIMIT_VDBE_OP]] ^(
    SQLITE_LIMIT_VDBE_OP
    +**
    The maximum number of instructions in a virtual machine program +** used to implement an SQL statement. This limit is not currently +** enforced, though that might be added in some future release of +** SQLite.
    )^ +** +** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(
    SQLITE_LIMIT_FUNCTION_ARG
    +**
    The maximum number of arguments on a function.
    )^ +** +** [[SQLITE_LIMIT_ATTACHED]] ^(
    SQLITE_LIMIT_ATTACHED
    +**
    The maximum number of [ATTACH | attached databases].)^
    +** +** [[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]] +** ^(
    SQLITE_LIMIT_LIKE_PATTERN_LENGTH
    +**
    The maximum length of the pattern argument to the [LIKE] or +** [GLOB] operators.
    )^ +** +** [[SQLITE_LIMIT_VARIABLE_NUMBER]] +** ^(
    SQLITE_LIMIT_VARIABLE_NUMBER
    +**
    The maximum index number of any [parameter] in an SQL statement.)^ +** +** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(
    SQLITE_LIMIT_TRIGGER_DEPTH
    +**
    The maximum depth of recursion for triggers.
    )^ +** +** [[SQLITE_LIMIT_WORKER_THREADS]] ^(
    SQLITE_LIMIT_WORKER_THREADS
    +**
    The maximum number of auxiliary worker threads that a single +** [prepared statement] may start.
    )^ +**
    +*/ +#define SQLITE_LIMIT_LENGTH 0 +#define SQLITE_LIMIT_SQL_LENGTH 1 +#define SQLITE_LIMIT_COLUMN 2 +#define SQLITE_LIMIT_EXPR_DEPTH 3 +#define SQLITE_LIMIT_COMPOUND_SELECT 4 +#define SQLITE_LIMIT_VDBE_OP 5 +#define SQLITE_LIMIT_FUNCTION_ARG 6 +#define SQLITE_LIMIT_ATTACHED 7 +#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8 +#define SQLITE_LIMIT_VARIABLE_NUMBER 9 +#define SQLITE_LIMIT_TRIGGER_DEPTH 10 +#define SQLITE_LIMIT_WORKER_THREADS 11 + +/* +** CAPI3REF: Compiling An SQL Statement +** KEYWORDS: {SQL statement compiler} +** METHOD: sqlite3 +** CONSTRUCTOR: sqlite3_stmt +** +** To execute an SQL query, it must first be compiled into a byte-code +** program using one of these routines. +** +** The first argument, "db", is a [database connection] obtained from a +** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or +** [sqlite3_open16()]. The database connection must not have been closed. +** +** The second argument, "zSql", is the statement to be compiled, encoded +** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2() +** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2() +** use UTF-16. +** +** ^If the nByte argument is negative, then zSql is read up to the +** first zero terminator. ^If nByte is positive, then it is the +** number of bytes read from zSql. ^If nByte is zero, then no prepared +** statement is generated. +** If the caller knows that the supplied string is nul-terminated, then +** there is a small performance advantage to passing an nByte parameter that +** is the number of bytes in the input string including +** the nul-terminator. +** +** ^If pzTail is not NULL then *pzTail is made to point to the first byte +** past the end of the first SQL statement in zSql. These routines only +** compile the first statement in zSql, so *pzTail is left pointing to +** what remains uncompiled. +** +** ^*ppStmt is left pointing to a compiled [prepared statement] that can be +** executed using [sqlite3_step()]. ^If there is an error, *ppStmt is set +** to NULL. ^If the input text contains no SQL (if the input is an empty +** string or a comment) then *ppStmt is set to NULL. +** The calling procedure is responsible for deleting the compiled +** SQL statement using [sqlite3_finalize()] after it has finished with it. +** ppStmt may not be NULL. +** +** ^On success, the sqlite3_prepare() family of routines return [SQLITE_OK]; +** otherwise an [error code] is returned. +** +** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are +** recommended for all new programs. The two older interfaces are retained +** for backwards compatibility, but their use is discouraged. +** ^In the "v2" interfaces, the prepared statement +** that is returned (the [sqlite3_stmt] object) contains a copy of the +** original SQL text. This causes the [sqlite3_step()] interface to +** behave differently in three ways: +** +**
      +**
    1. +** ^If the database schema changes, instead of returning [SQLITE_SCHEMA] as it +** always used to do, [sqlite3_step()] will automatically recompile the SQL +** statement and try to run it again. As many as [SQLITE_MAX_SCHEMA_RETRY] +** retries will occur before sqlite3_step() gives up and returns an error. +**
    2. +** +**
    3. +** ^When an error occurs, [sqlite3_step()] will return one of the detailed +** [error codes] or [extended error codes]. ^The legacy behavior was that +** [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code +** and the application would have to make a second call to [sqlite3_reset()] +** in order to find the underlying cause of the problem. With the "v2" prepare +** interfaces, the underlying reason for the error is returned immediately. +**
    4. +** +**
    5. +** ^If the specific value bound to [parameter | host parameter] in the +** WHERE clause might influence the choice of query plan for a statement, +** then the statement will be automatically recompiled, as if there had been +** a schema change, on the first [sqlite3_step()] call following any change +** to the [sqlite3_bind_text | bindings] of that [parameter]. +** ^The specific value of WHERE-clause [parameter] might influence the +** choice of query plan if the parameter is the left-hand side of a [LIKE] +** or [GLOB] operator or if the parameter is compared to an indexed column +** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled. +**
    6. +**
    +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_prepare( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int SQLITE_STDCALL sqlite3_prepare16( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); + +/* +** CAPI3REF: Retrieving Statement SQL +** METHOD: sqlite3_stmt +** +** ^This interface can be used to retrieve a saved copy of the original +** SQL text used to create a [prepared statement] if that statement was +** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()]. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Determine If An SQL Statement Writes The Database +** METHOD: sqlite3_stmt +** +** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if +** and only if the [prepared statement] X makes no direct changes to +** the content of the database file. +** +** Note that [application-defined SQL functions] or +** [virtual tables] might change the database indirectly as a side effect. +** ^(For example, if an application defines a function "eval()" that +** calls [sqlite3_exec()], then the following SQL statement would +** change the database file through side-effects: +** +**
    +**    SELECT eval('DELETE FROM t1') FROM t2;
    +** 
    +** +** But because the [SELECT] statement does not change the database file +** directly, sqlite3_stmt_readonly() would still return true.)^ +** +** ^Transaction control statements such as [BEGIN], [COMMIT], [ROLLBACK], +** [SAVEPOINT], and [RELEASE] cause sqlite3_stmt_readonly() to return true, +** since the statements themselves do not actually modify the database but +** rather they control the timing of when other statements modify the +** database. ^The [ATTACH] and [DETACH] statements also cause +** sqlite3_stmt_readonly() to return true since, while those statements +** change the configuration of a database connection, they do not make +** changes to the content of the database files on disk. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Determine If A Prepared Statement Has Been Reset +** METHOD: sqlite3_stmt +** +** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the +** [prepared statement] S has been stepped at least once using +** [sqlite3_step(S)] but has not run to completion and/or has not +** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S) +** interface returns false if S is a NULL pointer. If S is not a +** NULL pointer and is not a pointer to a valid [prepared statement] +** object, then the behavior is undefined and probably undesirable. +** +** This interface can be used in combination [sqlite3_next_stmt()] +** to locate all prepared statements associated with a database +** connection that are in need of being reset. This can be used, +** for example, in diagnostic routines to search for prepared +** statements that are holding a transaction open. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt*); + +/* +** CAPI3REF: Dynamically Typed Value Object +** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value} +** +** SQLite uses the sqlite3_value object to represent all values +** that can be stored in a database table. SQLite uses dynamic typing +** for the values it stores. ^Values stored in sqlite3_value objects +** can be integers, floating point values, strings, BLOBs, or NULL. +** +** An sqlite3_value object may be either "protected" or "unprotected". +** Some interfaces require a protected sqlite3_value. Other interfaces +** will accept either a protected or an unprotected sqlite3_value. +** Every interface that accepts sqlite3_value arguments specifies +** whether or not it requires a protected sqlite3_value. +** +** The terms "protected" and "unprotected" refer to whether or not +** a mutex is held. An internal mutex is held for a protected +** sqlite3_value object but no mutex is held for an unprotected +** sqlite3_value object. If SQLite is compiled to be single-threaded +** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0) +** or if SQLite is run in one of reduced mutex modes +** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD] +** then there is no distinction between protected and unprotected +** sqlite3_value objects and they can be used interchangeably. However, +** for maximum code portability it is recommended that applications +** still make the distinction between protected and unprotected +** sqlite3_value objects even when not strictly required. +** +** ^The sqlite3_value objects that are passed as parameters into the +** implementation of [application-defined SQL functions] are protected. +** ^The sqlite3_value object returned by +** [sqlite3_column_value()] is unprotected. +** Unprotected sqlite3_value objects may only be used with +** [sqlite3_result_value()] and [sqlite3_bind_value()]. +** The [sqlite3_value_blob | sqlite3_value_type()] family of +** interfaces require protected sqlite3_value objects. +*/ +typedef struct Mem sqlite3_value; + +/* +** CAPI3REF: SQL Function Context Object +** +** The context in which an SQL function executes is stored in an +** sqlite3_context object. ^A pointer to an sqlite3_context object +** is always first parameter to [application-defined SQL functions]. +** The application-defined SQL function implementation will pass this +** pointer through into calls to [sqlite3_result_int | sqlite3_result()], +** [sqlite3_aggregate_context()], [sqlite3_user_data()], +** [sqlite3_context_db_handle()], [sqlite3_get_auxdata()], +** and/or [sqlite3_set_auxdata()]. +*/ +typedef struct sqlite3_context sqlite3_context; + +/* +** CAPI3REF: Binding Values To Prepared Statements +** KEYWORDS: {host parameter} {host parameters} {host parameter name} +** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} +** METHOD: sqlite3_stmt +** +** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, +** literals may be replaced by a [parameter] that matches one of following +** templates: +** +**
      +**
    • ? +**
    • ?NNN +**
    • :VVV +**
    • @VVV +**
    • $VVV +**
    +** +** In the templates above, NNN represents an integer literal, +** and VVV represents an alphanumeric identifier.)^ ^The values of these +** parameters (also called "host parameter names" or "SQL parameters") +** can be set using the sqlite3_bind_*() routines defined here. +** +** ^The first argument to the sqlite3_bind_*() routines is always +** a pointer to the [sqlite3_stmt] object returned from +** [sqlite3_prepare_v2()] or its variants. +** +** ^The second argument is the index of the SQL parameter to be set. +** ^The leftmost SQL parameter has an index of 1. ^When the same named +** SQL parameter is used more than once, second and subsequent +** occurrences have the same index as the first occurrence. +** ^The index for named parameters can be looked up using the +** [sqlite3_bind_parameter_index()] API if desired. ^The index +** for "?NNN" parameters is the value of NNN. +** ^The NNN value must be between 1 and the [sqlite3_limit()] +** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999). +** +** ^The third argument is the value to bind to the parameter. +** ^If the third parameter to sqlite3_bind_text() or sqlite3_bind_text16() +** or sqlite3_bind_blob() is a NULL pointer then the fourth parameter +** is ignored and the end result is the same as sqlite3_bind_null(). +** +** ^(In those routines that have a fourth argument, its value is the +** number of bytes in the parameter. To be clear: the value is the +** number of bytes in the value, not the number of characters.)^ +** ^If the fourth parameter to sqlite3_bind_text() or sqlite3_bind_text16() +** is negative, then the length of the string is +** the number of bytes up to the first zero terminator. +** If the fourth parameter to sqlite3_bind_blob() is negative, then +** the behavior is undefined. +** If a non-negative fourth parameter is provided to sqlite3_bind_text() +** or sqlite3_bind_text16() or sqlite3_bind_text64() then +** that parameter must be the byte offset +** where the NUL terminator would occur assuming the string were NUL +** terminated. If any NUL characters occur at byte offsets less than +** the value of the fourth parameter then the resulting string value will +** contain embedded NULs. The result of expressions involving strings +** with embedded NULs is undefined. +** +** ^The fifth argument to the BLOB and string binding interfaces +** is a destructor used to dispose of the BLOB or +** string after SQLite has finished with it. ^The destructor is called +** to dispose of the BLOB or string even if the call to bind API fails. +** ^If the fifth argument is +** the special value [SQLITE_STATIC], then SQLite assumes that the +** information is in static, unmanaged space and does not need to be freed. +** ^If the fifth argument has the value [SQLITE_TRANSIENT], then +** SQLite makes its own private copy of the data immediately, before +** the sqlite3_bind_*() routine returns. +** +** ^The sixth argument to sqlite3_bind_text64() must be one of +** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE] +** to specify the encoding of the text in the third parameter. If +** the sixth argument to sqlite3_bind_text64() is not one of the +** allowed values shown above, or if the text encoding is different +** from the encoding specified by the sixth parameter, then the behavior +** is undefined. +** +** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that +** is filled with zeroes. ^A zeroblob uses a fixed amount of memory +** (just an integer to hold its size) while it is being processed. +** Zeroblobs are intended to serve as placeholders for BLOBs whose +** content is later written using +** [sqlite3_blob_open | incremental BLOB I/O] routines. +** ^A negative value for the zeroblob results in a zero-length BLOB. +** +** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer +** for the [prepared statement] or with a prepared statement for which +** [sqlite3_step()] has been called more recently than [sqlite3_reset()], +** then the call will return [SQLITE_MISUSE]. If any sqlite3_bind_() +** routine is passed a [prepared statement] that has been finalized, the +** result is undefined and probably harmful. +** +** ^Bindings are not cleared by the [sqlite3_reset()] routine. +** ^Unbound parameters are interpreted as NULL. +** +** ^The sqlite3_bind_* routines return [SQLITE_OK] on success or an +** [error code] if anything goes wrong. +** ^[SQLITE_TOOBIG] might be returned if the size of a string or BLOB +** exceeds limits imposed by [sqlite3_limit]([SQLITE_LIMIT_LENGTH]) or +** [SQLITE_MAX_LENGTH]. +** ^[SQLITE_RANGE] is returned if the parameter +** index is out of range. ^[SQLITE_NOMEM] is returned if malloc() fails. +** +** See also: [sqlite3_bind_parameter_count()], +** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64, + void(*)(void*)); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt*, int, double); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt*, int, int); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt*, int); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*)); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, + void(*)(void*), unsigned char encoding); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); + +/* +** CAPI3REF: Number Of SQL Parameters +** METHOD: sqlite3_stmt +** +** ^This routine can be used to find the number of [SQL parameters] +** in a [prepared statement]. SQL parameters are tokens of the +** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as +** placeholders for values that are [sqlite3_bind_blob | bound] +** to the parameters at a later time. +** +** ^(This routine actually returns the index of the largest (rightmost) +** parameter. For all forms except ?NNN, this will correspond to the +** number of unique parameters. If parameters of the ?NNN form are used, +** there may be gaps in the list.)^ +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_name()], and +** [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt*); + +/* +** CAPI3REF: Name Of A Host Parameter +** METHOD: sqlite3_stmt +** +** ^The sqlite3_bind_parameter_name(P,N) interface returns +** the name of the N-th [SQL parameter] in the [prepared statement] P. +** ^(SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA" +** have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA" +** respectively. +** In other words, the initial ":" or "$" or "@" or "?" +** is included as part of the name.)^ +** ^Parameters of the form "?" without a following integer have no name +** and are referred to as "nameless" or "anonymous parameters". +** +** ^The first host parameter has an index of 1, not 0. +** +** ^If the value N is out of range or if the N-th parameter is +** nameless, then NULL is returned. ^The returned string is +** always in UTF-8 encoding even if the named parameter was +** originally specified as UTF-16 in [sqlite3_prepare16()] or +** [sqlite3_prepare16_v2()]. +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_count()], and +** [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt*, int); + +/* +** CAPI3REF: Index Of A Parameter With A Given Name +** METHOD: sqlite3_stmt +** +** ^Return the index of an SQL parameter given its name. ^The +** index value returned is suitable for use as the second +** parameter to [sqlite3_bind_blob|sqlite3_bind()]. ^A zero +** is returned if no matching parameter is found. ^The parameter +** name must be given in UTF-8 even if the original statement +** was prepared from UTF-16 text using [sqlite3_prepare16_v2()]. +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_count()], and +** [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); + +/* +** CAPI3REF: Reset All Bindings On A Prepared Statement +** METHOD: sqlite3_stmt +** +** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset +** the [sqlite3_bind_blob | bindings] on a [prepared statement]. +** ^Use this routine to reset all host parameters to NULL. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt*); + +/* +** CAPI3REF: Number Of Columns In A Result Set +** METHOD: sqlite3_stmt +** +** ^Return the number of columns in the result set returned by the +** [prepared statement]. ^This routine returns 0 if pStmt is an SQL +** statement that does not return data (for example an [UPDATE]). +** +** See also: [sqlite3_data_count()] +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Column Names In A Result Set +** METHOD: sqlite3_stmt +** +** ^These routines return the name assigned to a particular column +** in the result set of a [SELECT] statement. ^The sqlite3_column_name() +** interface returns a pointer to a zero-terminated UTF-8 string +** and sqlite3_column_name16() returns a pointer to a zero-terminated +** UTF-16 string. ^The first parameter is the [prepared statement] +** that implements the [SELECT] statement. ^The second parameter is the +** column number. ^The leftmost column is number 0. +** +** ^The returned string pointer is valid until either the [prepared statement] +** is destroyed by [sqlite3_finalize()] or until the statement is automatically +** reprepared by the first call to [sqlite3_step()] for a particular run +** or until the next call to +** sqlite3_column_name() or sqlite3_column_name16() on the same column. +** +** ^If sqlite3_malloc() fails during the processing of either routine +** (for example during a conversion from UTF-8 to UTF-16) then a +** NULL pointer is returned. +** +** ^The name of a result column is the value of the "AS" clause for +** that column, if there is an AS clause. If there is no AS clause +** then the name of the column is unspecified and may change from +** one release of SQLite to the next. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_name(sqlite3_stmt*, int N); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt*, int N); + +/* +** CAPI3REF: Source Of Data In A Query Result +** METHOD: sqlite3_stmt +** +** ^These routines provide a means to determine the database, table, and +** table column that is the origin of a particular result column in +** [SELECT] statement. +** ^The name of the database or table or column can be returned as +** either a UTF-8 or UTF-16 string. ^The _database_ routines return +** the database name, the _table_ routines return the table name, and +** the origin_ routines return the column name. +** ^The returned string is valid until the [prepared statement] is destroyed +** using [sqlite3_finalize()] or until the statement is automatically +** reprepared by the first call to [sqlite3_step()] for a particular run +** or until the same information is requested +** again in a different encoding. +** +** ^The names returned are the original un-aliased names of the +** database, table, and column. +** +** ^The first argument to these interfaces is a [prepared statement]. +** ^These functions return information about the Nth result column returned by +** the statement, where N is the second function argument. +** ^The left-most column is column 0 for these routines. +** +** ^If the Nth column returned by the statement is an expression or +** subquery and is not a column value, then all of these functions return +** NULL. ^These routine might also return NULL if a memory allocation error +** occurs. ^Otherwise, they return the name of the attached database, table, +** or column that query result column was extracted from. +** +** ^As with all other SQLite APIs, those whose names end with "16" return +** UTF-16 encoded strings and the other functions return UTF-8. +** +** ^These APIs are only available if the library was compiled with the +** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol. +** +** If two or more threads call one or more of these routines against the same +** prepared statement and column at the same time then the results are +** undefined. +** +** If two or more threads call one or more +** [sqlite3_column_database_name | column metadata interfaces] +** for the same [prepared statement] and result column +** at the same time then the results are undefined. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt*,int); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt*,int); +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt*,int); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt*,int); +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt*,int); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Declared Datatype Of A Query Result +** METHOD: sqlite3_stmt +** +** ^(The first parameter is a [prepared statement]. +** If this statement is a [SELECT] statement and the Nth column of the +** returned result set of that [SELECT] is a table column (not an +** expression or subquery) then the declared type of the table +** column is returned.)^ ^If the Nth column of the result set is an +** expression or subquery, then a NULL pointer is returned. +** ^The returned string is always UTF-8 encoded. +** +** ^(For example, given the database schema: +** +** CREATE TABLE t1(c1 VARIANT); +** +** and the following statement to be compiled: +** +** SELECT c1 + 1, c1 FROM t1; +** +** this routine would return the string "VARIANT" for the second result +** column (i==1), and a NULL pointer for the first result column (i==0).)^ +** +** ^SQLite uses dynamic run-time typing. ^So just because a column +** is declared to contain a particular type does not mean that the +** data stored in that column is of the declared type. SQLite is +** strongly typed, but the typing is dynamic not static. ^Type +** is associated with individual values, not with the containers +** used to hold those values. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt*,int); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Evaluate An SQL Statement +** METHOD: sqlite3_stmt +** +** After a [prepared statement] has been prepared using either +** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy +** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function +** must be called one or more times to evaluate the statement. +** +** The details of the behavior of the sqlite3_step() interface depend +** on whether the statement was prepared using the newer "v2" interface +** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy +** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the +** new "v2" interface is recommended for new applications but the legacy +** interface will continue to be supported. +** +** ^In the legacy interface, the return value will be either [SQLITE_BUSY], +** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE]. +** ^With the "v2" interface, any of the other [result codes] or +** [extended result codes] might be returned as well. +** +** ^[SQLITE_BUSY] means that the database engine was unable to acquire the +** database locks it needs to do its job. ^If the statement is a [COMMIT] +** or occurs outside of an explicit transaction, then you can retry the +** statement. If the statement is not a [COMMIT] and occurs within an +** explicit transaction then you should rollback the transaction before +** continuing. +** +** ^[SQLITE_DONE] means that the statement has finished executing +** successfully. sqlite3_step() should not be called again on this virtual +** machine without first calling [sqlite3_reset()] to reset the virtual +** machine back to its initial state. +** +** ^If the SQL statement being executed returns any data, then [SQLITE_ROW] +** is returned each time a new row of data is ready for processing by the +** caller. The values may be accessed using the [column access functions]. +** sqlite3_step() is called again to retrieve the next row of data. +** +** ^[SQLITE_ERROR] means that a run-time error (such as a constraint +** violation) has occurred. sqlite3_step() should not be called again on +** the VM. More information may be found by calling [sqlite3_errmsg()]. +** ^With the legacy interface, a more specific error code (for example, +** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth) +** can be obtained by calling [sqlite3_reset()] on the +** [prepared statement]. ^In the "v2" interface, +** the more specific error code is returned directly by sqlite3_step(). +** +** [SQLITE_MISUSE] means that the this routine was called inappropriately. +** Perhaps it was called on a [prepared statement] that has +** already been [sqlite3_finalize | finalized] or on one that had +** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could +** be the case that the same database connection is being used by two or +** more threads at the same moment in time. +** +** For all versions of SQLite up to and including 3.6.23.1, a call to +** [sqlite3_reset()] was required after sqlite3_step() returned anything +** other than [SQLITE_ROW] before any subsequent invocation of +** sqlite3_step(). Failure to reset the prepared statement using +** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from +** sqlite3_step(). But after version 3.6.23.1, sqlite3_step() began +** calling [sqlite3_reset()] automatically in this circumstance rather +** than returning [SQLITE_MISUSE]. This is not considered a compatibility +** break because any application that ever receives an SQLITE_MISUSE error +** is broken by definition. The [SQLITE_OMIT_AUTORESET] compile-time option +** can be used to restore the legacy behavior. +** +** Goofy Interface Alert: In the legacy interface, the sqlite3_step() +** API always returns a generic error code, [SQLITE_ERROR], following any +** error other than [SQLITE_BUSY] and [SQLITE_MISUSE]. You must call +** [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the +** specific [error codes] that better describes the error. +** We admit that this is a goofy design. The problem has been fixed +** with the "v2" interface. If you prepare all of your SQL statements +** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead +** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces, +** then the more specific [error codes] are returned directly +** by sqlite3_step(). The use of the "v2" interface is recommended. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt*); + +/* +** CAPI3REF: Number of columns in a result set +** METHOD: sqlite3_stmt +** +** ^The sqlite3_data_count(P) interface returns the number of columns in the +** current row of the result set of [prepared statement] P. +** ^If prepared statement P does not have results ready to return +** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of +** interfaces) then sqlite3_data_count(P) returns 0. +** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer. +** ^The sqlite3_data_count(P) routine returns 0 if the previous call to +** [sqlite3_step](P) returned [SQLITE_DONE]. ^The sqlite3_data_count(P) +** will return non-zero if previous call to [sqlite3_step](P) returned +** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum] +** where it always returns zero since each step of that multi-step +** pragma returns 0 columns of data. +** +** See also: [sqlite3_column_count()] +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Fundamental Datatypes +** KEYWORDS: SQLITE_TEXT +** +** ^(Every value in SQLite has one of five fundamental datatypes: +** +**
      +**
    • 64-bit signed integer +**
    • 64-bit IEEE floating point number +**
    • string +**
    • BLOB +**
    • NULL +**
    )^ +** +** These constants are codes for each of those types. +** +** Note that the SQLITE_TEXT constant was also used in SQLite version 2 +** for a completely different meaning. Software that links against both +** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT, not +** SQLITE_TEXT. +*/ +#define SQLITE_INTEGER 1 +#define SQLITE_FLOAT 2 +#define SQLITE_BLOB 4 +#define SQLITE_NULL 5 +#ifdef SQLITE_TEXT +# undef SQLITE_TEXT +#else +# define SQLITE_TEXT 3 +#endif +#define SQLITE3_TEXT 3 + +/* +** CAPI3REF: Result Values From A Query +** KEYWORDS: {column access functions} +** METHOD: sqlite3_stmt +** +** These routines form the "result set" interface. +** +** ^These routines return information about a single column of the current +** result row of a query. ^In every case the first argument is a pointer +** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*] +** that was returned from [sqlite3_prepare_v2()] or one of its variants) +** and the second argument is the index of the column for which information +** should be returned. ^The leftmost column of the result set has the index 0. +** ^The number of columns in the result can be determined using +** [sqlite3_column_count()]. +** +** If the SQL statement does not currently point to a valid row, or if the +** column index is out of range, the result is undefined. +** These routines may only be called when the most recent call to +** [sqlite3_step()] has returned [SQLITE_ROW] and neither +** [sqlite3_reset()] nor [sqlite3_finalize()] have been called subsequently. +** If any of these routines are called after [sqlite3_reset()] or +** [sqlite3_finalize()] or after [sqlite3_step()] has returned +** something other than [SQLITE_ROW], the results are undefined. +** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()] +** are called from a different thread while any of these routines +** are pending, then the results are undefined. +** +** ^The sqlite3_column_type() routine returns the +** [SQLITE_INTEGER | datatype code] for the initial data type +** of the result column. ^The returned value is one of [SQLITE_INTEGER], +** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value +** returned by sqlite3_column_type() is only meaningful if no type +** conversions have occurred as described below. After a type conversion, +** the value returned by sqlite3_column_type() is undefined. Future +** versions of SQLite may change the behavior of sqlite3_column_type() +** following a type conversion. +** +** ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() +** routine returns the number of bytes in that BLOB or string. +** ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts +** the string to UTF-8 and then returns the number of bytes. +** ^If the result is a numeric value then sqlite3_column_bytes() uses +** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns +** the number of bytes in that string. +** ^If the result is NULL, then sqlite3_column_bytes() returns zero. +** +** ^If the result is a BLOB or UTF-16 string then the sqlite3_column_bytes16() +** routine returns the number of bytes in that BLOB or string. +** ^If the result is a UTF-8 string, then sqlite3_column_bytes16() converts +** the string to UTF-16 and then returns the number of bytes. +** ^If the result is a numeric value then sqlite3_column_bytes16() uses +** [sqlite3_snprintf()] to convert that value to a UTF-16 string and returns +** the number of bytes in that string. +** ^If the result is NULL, then sqlite3_column_bytes16() returns zero. +** +** ^The values returned by [sqlite3_column_bytes()] and +** [sqlite3_column_bytes16()] do not include the zero terminators at the end +** of the string. ^For clarity: the values returned by +** [sqlite3_column_bytes()] and [sqlite3_column_bytes16()] are the number of +** bytes in the string, not the number of characters. +** +** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(), +** even empty strings, are always zero-terminated. ^The return +** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer. +** +** ^The object returned by [sqlite3_column_value()] is an +** [unprotected sqlite3_value] object. An unprotected sqlite3_value object +** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()]. +** If the [unprotected sqlite3_value] object returned by +** [sqlite3_column_value()] is used in any other way, including calls +** to routines like [sqlite3_value_int()], [sqlite3_value_text()], +** or [sqlite3_value_bytes()], then the behavior is undefined. +** +** These routines attempt to convert the value where appropriate. ^For +** example, if the internal representation is FLOAT and a text result +** is requested, [sqlite3_snprintf()] is used internally to perform the +** conversion automatically. ^(The following table details the conversions +** that are applied: +** +**
    +** +**
    Internal
    Type
    Requested
    Type
    Conversion +** +**
    NULL INTEGER Result is 0 +**
    NULL FLOAT Result is 0.0 +**
    NULL TEXT Result is a NULL pointer +**
    NULL BLOB Result is a NULL pointer +**
    INTEGER FLOAT Convert from integer to float +**
    INTEGER TEXT ASCII rendering of the integer +**
    INTEGER BLOB Same as INTEGER->TEXT +**
    FLOAT INTEGER [CAST] to INTEGER +**
    FLOAT TEXT ASCII rendering of the float +**
    FLOAT BLOB [CAST] to BLOB +**
    TEXT INTEGER [CAST] to INTEGER +**
    TEXT FLOAT [CAST] to REAL +**
    TEXT BLOB No change +**
    BLOB INTEGER [CAST] to INTEGER +**
    BLOB FLOAT [CAST] to REAL +**
    BLOB TEXT Add a zero terminator if needed +**
    +**
    )^ +** +** The table above makes reference to standard C library functions atoi() +** and atof(). SQLite does not really use these functions. It has its +** own equivalent internal routines. The atoi() and atof() names are +** used in the table for brevity and because they are familiar to most +** C programmers. +** +** Note that when type conversions occur, pointers returned by prior +** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or +** sqlite3_column_text16() may be invalidated. +** Type conversions and pointer invalidations might occur +** in the following cases: +** +**
      +**
    • The initial content is a BLOB and sqlite3_column_text() or +** sqlite3_column_text16() is called. A zero-terminator might +** need to be added to the string.
    • +**
    • The initial content is UTF-8 text and sqlite3_column_bytes16() or +** sqlite3_column_text16() is called. The content must be converted +** to UTF-16.
    • +**
    • The initial content is UTF-16 text and sqlite3_column_bytes() or +** sqlite3_column_text() is called. The content must be converted +** to UTF-8.
    • +**
    +** +** ^Conversions between UTF-16be and UTF-16le are always done in place and do +** not invalidate a prior pointer, though of course the content of the buffer +** that the prior pointer references will have been modified. Other kinds +** of conversion are done in place when it is possible, but sometimes they +** are not possible and in those cases prior pointers are invalidated. +** +** The safest and easiest to remember policy is to invoke these routines +** in one of the following ways: +** +**
      +**
    • sqlite3_column_text() followed by sqlite3_column_bytes()
    • +**
    • sqlite3_column_blob() followed by sqlite3_column_bytes()
    • +**
    • sqlite3_column_text16() followed by sqlite3_column_bytes16()
    • +**
    +** +** In other words, you should call sqlite3_column_text(), +** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result +** into the desired format, then invoke sqlite3_column_bytes() or +** sqlite3_column_bytes16() to find the size of the result. Do not mix calls +** to sqlite3_column_text() or sqlite3_column_blob() with calls to +** sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16() +** with calls to sqlite3_column_bytes(). +** +** ^The pointers returned are valid until a type conversion occurs as +** described above, or until [sqlite3_step()] or [sqlite3_reset()] or +** [sqlite3_finalize()] is called. ^The memory space used to hold strings +** and BLOBs is freed automatically. Do not pass the pointers returned +** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into +** [sqlite3_free()]. +** +** ^(If a memory allocation error occurs during the evaluation of any +** of these routines, a default value is returned. The default value +** is either the integer 0, the floating point number 0.0, or a NULL +** pointer. Subsequent calls to [sqlite3_errcode()] will return +** [SQLITE_NOMEM].)^ +*/ +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt*, int iCol); +SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt*, int iCol); +SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt*, int iCol); +SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_column_int64(sqlite3_stmt*, int iCol); +SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt*, int iCol); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_text16(sqlite3_stmt*, int iCol); +SQLITE_API int SQLITE_STDCALL sqlite3_column_type(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt*, int iCol); + +/* +** CAPI3REF: Destroy A Prepared Statement Object +** DESTRUCTOR: sqlite3_stmt +** +** ^The sqlite3_finalize() function is called to delete a [prepared statement]. +** ^If the most recent evaluation of the statement encountered no errors +** or if the statement is never been evaluated, then sqlite3_finalize() returns +** SQLITE_OK. ^If the most recent evaluation of statement S failed, then +** sqlite3_finalize(S) returns the appropriate [error code] or +** [extended error code]. +** +** ^The sqlite3_finalize(S) routine can be called at any point during +** the life cycle of [prepared statement] S: +** before statement S is ever evaluated, after +** one or more calls to [sqlite3_reset()], or after any call +** to [sqlite3_step()] regardless of whether or not the statement has +** completed execution. +** +** ^Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op. +** +** The application must finalize every [prepared statement] in order to avoid +** resource leaks. It is a grievous error for the application to try to use +** a prepared statement after it has been finalized. Any use of a prepared +** statement after it has been finalized can result in undefined and +** undesirable behavior such as segfaults and heap corruption. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Reset A Prepared Statement Object +** METHOD: sqlite3_stmt +** +** The sqlite3_reset() function is called to reset a [prepared statement] +** object back to its initial state, ready to be re-executed. +** ^Any SQL statement variables that had values bound to them using +** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values. +** Use [sqlite3_clear_bindings()] to reset the bindings. +** +** ^The [sqlite3_reset(S)] interface resets the [prepared statement] S +** back to the beginning of its program. +** +** ^If the most recent call to [sqlite3_step(S)] for the +** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE], +** or if [sqlite3_step(S)] has never before been called on S, +** then [sqlite3_reset(S)] returns [SQLITE_OK]. +** +** ^If the most recent call to [sqlite3_step(S)] for the +** [prepared statement] S indicated an error, then +** [sqlite3_reset(S)] returns an appropriate [error code]. +** +** ^The [sqlite3_reset(S)] interface does not change the values +** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Create Or Redefine SQL Functions +** KEYWORDS: {function creation routines} +** KEYWORDS: {application-defined SQL function} +** KEYWORDS: {application-defined SQL functions} +** METHOD: sqlite3 +** +** ^These functions (collectively known as "function creation routines") +** are used to add SQL functions or aggregates or to redefine the behavior +** of existing SQL functions or aggregates. The only differences between +** these routines are the text encoding expected for +** the second parameter (the name of the function being created) +** and the presence or absence of a destructor callback for +** the application data pointer. +** +** ^The first parameter is the [database connection] to which the SQL +** function is to be added. ^If an application uses more than one database +** connection then application-defined SQL functions must be added +** to each database connection separately. +** +** ^The second parameter is the name of the SQL function to be created or +** redefined. ^The length of the name is limited to 255 bytes in a UTF-8 +** representation, exclusive of the zero-terminator. ^Note that the name +** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes. +** ^Any attempt to create a function with a longer name +** will result in [SQLITE_MISUSE] being returned. +** +** ^The third parameter (nArg) +** is the number of arguments that the SQL function or +** aggregate takes. ^If this parameter is -1, then the SQL function or +** aggregate may take any number of arguments between 0 and the limit +** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]). If the third +** parameter is less than -1 or greater than 127 then the behavior is +** undefined. +** +** ^The fourth parameter, eTextRep, specifies what +** [SQLITE_UTF8 | text encoding] this SQL function prefers for +** its parameters. The application should set this parameter to +** [SQLITE_UTF16LE] if the function implementation invokes +** [sqlite3_value_text16le()] on an input, or [SQLITE_UTF16BE] if the +** implementation invokes [sqlite3_value_text16be()] on an input, or +** [SQLITE_UTF16] if [sqlite3_value_text16()] is used, or [SQLITE_UTF8] +** otherwise. ^The same SQL function may be registered multiple times using +** different preferred text encodings, with different implementations for +** each encoding. +** ^When multiple implementations of the same function are available, SQLite +** will pick the one that involves the least amount of data conversion. +** +** ^The fourth parameter may optionally be ORed with [SQLITE_DETERMINISTIC] +** to signal that the function will always return the same result given +** the same inputs within a single SQL statement. Most SQL functions are +** deterministic. The built-in [random()] SQL function is an example of a +** function that is not deterministic. The SQLite query planner is able to +** perform additional optimizations on deterministic functions, so use +** of the [SQLITE_DETERMINISTIC] flag is recommended where possible. +** +** ^(The fifth parameter is an arbitrary pointer. The implementation of the +** function can gain access to this pointer using [sqlite3_user_data()].)^ +** +** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are +** pointers to C-language functions that implement the SQL function or +** aggregate. ^A scalar SQL function requires an implementation of the xFunc +** callback only; NULL pointers must be passed as the xStep and xFinal +** parameters. ^An aggregate SQL function requires an implementation of xStep +** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing +** SQL function or aggregate, pass NULL pointers for all three function +** callbacks. +** +** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL, +** then it is destructor for the application data pointer. +** The destructor is invoked when the function is deleted, either by being +** overloaded or when the database connection closes.)^ +** ^The destructor is also invoked if the call to +** sqlite3_create_function_v2() fails. +** ^When the destructor callback of the tenth parameter is invoked, it +** is passed a single argument which is a copy of the application data +** pointer which was the fifth parameter to sqlite3_create_function_v2(). +** +** ^It is permitted to register multiple implementations of the same +** functions with the same name but with either differing numbers of +** arguments or differing preferred text encodings. ^SQLite will use +** the implementation that most closely matches the way in which the +** SQL function is used. ^A function implementation with a non-negative +** nArg parameter is a better match than a function implementation with +** a negative nArg. ^A function where the preferred text encoding +** matches the database encoding is a better +** match than a function where the encoding is different. +** ^A function where the encoding difference is between UTF16le and UTF16be +** is a closer match than a function where the encoding difference is +** between UTF8 and UTF16. +** +** ^Built-in functions may be overloaded by new application-defined functions. +** +** ^An application-defined function is permitted to call other +** SQLite interfaces. However, such calls must not +** close the database connection nor finalize or reset the prepared +** statement in which the function is running. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_create_function( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +SQLITE_API int SQLITE_STDCALL sqlite3_create_function16( + sqlite3 *db, + const void *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void(*xDestroy)(void*) +); + +/* +** CAPI3REF: Text Encodings +** +** These constant define integer codes that represent the various +** text encodings supported by SQLite. +*/ +#define SQLITE_UTF8 1 /* IMP: R-37514-35566 */ +#define SQLITE_UTF16LE 2 /* IMP: R-03371-37637 */ +#define SQLITE_UTF16BE 3 /* IMP: R-51971-34154 */ +#define SQLITE_UTF16 4 /* Use native byte order */ +#define SQLITE_ANY 5 /* Deprecated */ +#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ + +/* +** CAPI3REF: Function Flags +** +** These constants may be ORed together with the +** [SQLITE_UTF8 | preferred text encoding] as the fourth argument +** to [sqlite3_create_function()], [sqlite3_create_function16()], or +** [sqlite3_create_function_v2()]. +*/ +#define SQLITE_DETERMINISTIC 0x800 + +/* +** CAPI3REF: Deprecated Functions +** DEPRECATED +** +** These functions are [deprecated]. In order to maintain +** backwards compatibility with older code, these functions continue +** to be supported. However, new applications should avoid +** the use of these functions. To encourage programmers to avoid +** these functions, we will not explain what they do. +*/ +#ifndef SQLITE_OMIT_DEPRECATED +SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context*); +SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_global_recover(void); +SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_thread_cleanup(void); +SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), + void*,sqlite3_int64); +#endif + +/* +** CAPI3REF: Obtaining SQL Function Parameter Values +** METHOD: sqlite3_value +** +** The C-language implementation of SQL functions and aggregates uses +** this set of interface routines to access the parameter values on +** the function or aggregate. +** +** The xFunc (for scalar functions) or xStep (for aggregates) parameters +** to [sqlite3_create_function()] and [sqlite3_create_function16()] +** define callbacks that implement the SQL functions and aggregates. +** The 3rd parameter to these callbacks is an array of pointers to +** [protected sqlite3_value] objects. There is one [sqlite3_value] object for +** each parameter to the SQL function. These routines are used to +** extract values from the [sqlite3_value] objects. +** +** These routines work only with [protected sqlite3_value] objects. +** Any attempt to use these routines on an [unprotected sqlite3_value] +** object results in undefined behavior. +** +** ^These routines work just like the corresponding [column access functions] +** except that these routines take a single [protected sqlite3_value] object +** pointer instead of a [sqlite3_stmt*] pointer and an integer column number. +** +** ^The sqlite3_value_text16() interface extracts a UTF-16 string +** in the native byte-order of the host machine. ^The +** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces +** extract UTF-16 strings as big-endian and little-endian respectively. +** +** ^(The sqlite3_value_numeric_type() interface attempts to apply +** numeric affinity to the value. This means that an attempt is +** made to convert the value to an integer or floating point. If +** such a conversion is possible without loss of information (in other +** words, if the value is a string that looks like a number) +** then the conversion is performed. Otherwise no conversion occurs. +** The [SQLITE_INTEGER | datatype] after conversion is returned.)^ +** +** Please pay particular attention to the fact that the pointer returned +** from [sqlite3_value_blob()], [sqlite3_value_text()], or +** [sqlite3_value_text16()] can be invalidated by a subsequent call to +** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], +** or [sqlite3_value_text16()]. +** +** These routines must be called from the same thread as +** the SQL function that supplied the [sqlite3_value*] parameters. +*/ +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value*); +SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value*); +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value*); +SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value*); +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value*); +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value*); +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*); + +/* +** CAPI3REF: Obtain Aggregate Function Context +** METHOD: sqlite3_context +** +** Implementations of aggregate SQL functions use this +** routine to allocate memory for storing their state. +** +** ^The first time the sqlite3_aggregate_context(C,N) routine is called +** for a particular aggregate function, SQLite +** allocates N of memory, zeroes out that memory, and returns a pointer +** to the new memory. ^On second and subsequent calls to +** sqlite3_aggregate_context() for the same aggregate function instance, +** the same buffer is returned. Sqlite3_aggregate_context() is normally +** called once for each invocation of the xStep callback and then one +** last time when the xFinal callback is invoked. ^(When no rows match +** an aggregate query, the xStep() callback of the aggregate function +** implementation is never called and xFinal() is called exactly once. +** In those cases, sqlite3_aggregate_context() might be called for the +** first time from within xFinal().)^ +** +** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer +** when first called if N is less than or equal to zero or if a memory +** allocate error occurs. +** +** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is +** determined by the N parameter on first successful call. Changing the +** value of N in subsequent call to sqlite3_aggregate_context() within +** the same aggregate function instance will not resize the memory +** allocation.)^ Within the xFinal callback, it is customary to set +** N=0 in calls to sqlite3_aggregate_context(C,N) so that no +** pointless memory allocations occur. +** +** ^SQLite automatically frees the memory allocated by +** sqlite3_aggregate_context() when the aggregate query concludes. +** +** The first parameter must be a copy of the +** [sqlite3_context | SQL function context] that is the first parameter +** to the xStep or xFinal callback routine that implements the aggregate +** function. +** +** This routine must be called from the same thread in which +** the aggregate SQL function is running. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context*, int nBytes); + +/* +** CAPI3REF: User Data For Functions +** METHOD: sqlite3_context +** +** ^The sqlite3_user_data() interface returns a copy of +** the pointer that was the pUserData parameter (the 5th parameter) +** of the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines that originally +** registered the application defined function. +** +** This routine must be called from the same thread in which +** the application-defined function is running. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context*); + +/* +** CAPI3REF: Database Connection For Functions +** METHOD: sqlite3_context +** +** ^The sqlite3_context_db_handle() interface returns a copy of +** the pointer to the [database connection] (the 1st parameter) +** of the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines that originally +** registered the application defined function. +*/ +SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context*); + +/* +** CAPI3REF: Function Auxiliary Data +** METHOD: sqlite3_context +** +** These functions may be used by (non-aggregate) SQL functions to +** associate metadata with argument values. If the same value is passed to +** multiple invocations of the same SQL function during query execution, under +** some circumstances the associated metadata may be preserved. An example +** of where this might be useful is in a regular-expression matching +** function. The compiled version of the regular expression can be stored as +** metadata associated with the pattern string. +** Then as long as the pattern string remains the same, +** the compiled regular expression can be reused on multiple +** invocations of the same function. +** +** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata +** associated by the sqlite3_set_auxdata() function with the Nth argument +** value to the application-defined function. ^If there is no metadata +** associated with the function argument, this sqlite3_get_auxdata() interface +** returns a NULL pointer. +** +** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th +** argument of the application-defined function. ^Subsequent +** calls to sqlite3_get_auxdata(C,N) return P from the most recent +** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or +** NULL if the metadata has been discarded. +** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL, +** SQLite will invoke the destructor function X with parameter P exactly +** once, when the metadata is discarded. +** SQLite is free to discard the metadata at any time, including:
      +**
    • when the corresponding function parameter changes, or +**
    • when [sqlite3_reset()] or [sqlite3_finalize()] is called for the +** SQL statement, or +**
    • when sqlite3_set_auxdata() is invoked again on the same parameter, or +**
    • during the original sqlite3_set_auxdata() call when a memory +** allocation error occurs.
    )^ +** +** Note the last bullet in particular. The destructor X in +** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the +** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata() +** should be called near the end of the function implementation and the +** function implementation should not make any use of P after +** sqlite3_set_auxdata() has been called. +** +** ^(In practice, metadata is preserved between function calls for +** function parameters that are compile-time constants, including literal +** values and [parameters] and expressions composed from the same.)^ +** +** These routines must be called from the same thread in which +** the SQL function is running. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context*, int N); +SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); + + +/* +** CAPI3REF: Constants Defining Special Destructor Behavior +** +** These are special values for the destructor that is passed in as the +** final argument to routines like [sqlite3_result_blob()]. ^If the destructor +** argument is SQLITE_STATIC, it means that the content pointer is constant +** and will never change. It does not need to be destroyed. ^The +** SQLITE_TRANSIENT value means that the content will likely change in +** the near future and that SQLite should make its own private copy of +** the content before returning. +** +** The typedef is necessary to work around problems in certain +** C++ compilers. +*/ +typedef void (*sqlite3_destructor_type)(void*); +#define SQLITE_STATIC ((sqlite3_destructor_type)0) +#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) + +/* +** CAPI3REF: Setting The Result Of An SQL Function +** METHOD: sqlite3_context +** +** These routines are used by the xFunc or xFinal callbacks that +** implement SQL functions and aggregates. See +** [sqlite3_create_function()] and [sqlite3_create_function16()] +** for additional information. +** +** These functions work very much like the [parameter binding] family of +** functions used to bind values to host parameters in prepared statements. +** Refer to the [SQL parameter] documentation for additional information. +** +** ^The sqlite3_result_blob() interface sets the result from +** an application-defined function to be the BLOB whose content is pointed +** to by the second parameter and which is N bytes long where N is the +** third parameter. +** +** ^The sqlite3_result_zeroblob() interfaces set the result of +** the application-defined function to be a BLOB containing all zero +** bytes and N bytes in size, where N is the value of the 2nd parameter. +** +** ^The sqlite3_result_double() interface sets the result from +** an application-defined function to be a floating point value specified +** by its 2nd argument. +** +** ^The sqlite3_result_error() and sqlite3_result_error16() functions +** cause the implemented SQL function to throw an exception. +** ^SQLite uses the string pointed to by the +** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16() +** as the text of an error message. ^SQLite interprets the error +** message string from sqlite3_result_error() as UTF-8. ^SQLite +** interprets the string from sqlite3_result_error16() as UTF-16 in native +** byte order. ^If the third parameter to sqlite3_result_error() +** or sqlite3_result_error16() is negative then SQLite takes as the error +** message all text up through the first zero character. +** ^If the third parameter to sqlite3_result_error() or +** sqlite3_result_error16() is non-negative then SQLite takes that many +** bytes (not characters) from the 2nd parameter as the error message. +** ^The sqlite3_result_error() and sqlite3_result_error16() +** routines make a private copy of the error message text before +** they return. Hence, the calling function can deallocate or +** modify the text after they return without harm. +** ^The sqlite3_result_error_code() function changes the error code +** returned by SQLite as a result of an error in a function. ^By default, +** the error code is SQLITE_ERROR. ^A subsequent call to sqlite3_result_error() +** or sqlite3_result_error16() resets the error code to SQLITE_ERROR. +** +** ^The sqlite3_result_error_toobig() interface causes SQLite to throw an +** error indicating that a string or BLOB is too long to represent. +** +** ^The sqlite3_result_error_nomem() interface causes SQLite to throw an +** error indicating that a memory allocation failed. +** +** ^The sqlite3_result_int() interface sets the return value +** of the application-defined function to be the 32-bit signed integer +** value given in the 2nd argument. +** ^The sqlite3_result_int64() interface sets the return value +** of the application-defined function to be the 64-bit signed integer +** value given in the 2nd argument. +** +** ^The sqlite3_result_null() interface sets the return value +** of the application-defined function to be NULL. +** +** ^The sqlite3_result_text(), sqlite3_result_text16(), +** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces +** set the return value of the application-defined function to be +** a text string which is represented as UTF-8, UTF-16 native byte order, +** UTF-16 little endian, or UTF-16 big endian, respectively. +** ^The sqlite3_result_text64() interface sets the return value of an +** application-defined function to be a text string in an encoding +** specified by the fifth (and last) parameter, which must be one +** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]. +** ^SQLite takes the text result from the application from +** the 2nd parameter of the sqlite3_result_text* interfaces. +** ^If the 3rd parameter to the sqlite3_result_text* interfaces +** is negative, then SQLite takes result text from the 2nd parameter +** through the first zero character. +** ^If the 3rd parameter to the sqlite3_result_text* interfaces +** is non-negative, then as many bytes (not characters) of the text +** pointed to by the 2nd parameter are taken as the application-defined +** function result. If the 3rd parameter is non-negative, then it +** must be the byte offset into the string where the NUL terminator would +** appear if the string where NUL terminated. If any NUL characters occur +** in the string at a byte offset that is less than the value of the 3rd +** parameter, then the resulting string will contain embedded NULs and the +** result of expressions operating on strings with embedded NULs is undefined. +** ^If the 4th parameter to the sqlite3_result_text* interfaces +** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that +** function as the destructor on the text or BLOB result when it has +** finished using that result. +** ^If the 4th parameter to the sqlite3_result_text* interfaces or to +** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite +** assumes that the text or BLOB result is in constant space and does not +** copy the content of the parameter nor call a destructor on the content +** when it has finished using that result. +** ^If the 4th parameter to the sqlite3_result_text* interfaces +** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT +** then SQLite makes a copy of the result into space obtained from +** from [sqlite3_malloc()] before it returns. +** +** ^The sqlite3_result_value() interface sets the result of +** the application-defined function to be a copy the +** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The +** sqlite3_result_value() interface makes a copy of the [sqlite3_value] +** so that the [sqlite3_value] specified in the parameter may change or +** be deallocated after sqlite3_result_value() returns without harm. +** ^A [protected sqlite3_value] object may always be used where an +** [unprotected sqlite3_value] object is required, so either +** kind of [sqlite3_value] object can be used with this interface. +** +** If these routines are called from within the different thread +** than the one containing the application-defined function that received +** the [sqlite3_context] pointer, the results are undefined. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64(sqlite3_context*,const void*, + sqlite3_uint64,void(*)(void*)); +SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context*, double); +SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context*, const char*, int); +SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context*, const void*, int); +SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context*); +SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context*); +SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context*, int); +SQLITE_API void SQLITE_STDCALL sqlite3_result_int(sqlite3_context*, int); +SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context*, sqlite3_int64); +SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context*); +SQLITE_API void SQLITE_STDCALL sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64, + void(*)(void*), unsigned char encoding); +SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context*, sqlite3_value*); +SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context*, int n); + +/* +** CAPI3REF: Define New Collating Sequences +** METHOD: sqlite3 +** +** ^These functions add, remove, or modify a [collation] associated +** with the [database connection] specified as the first argument. +** +** ^The name of the collation is a UTF-8 string +** for sqlite3_create_collation() and sqlite3_create_collation_v2() +** and a UTF-16 string in native byte order for sqlite3_create_collation16(). +** ^Collation names that compare equal according to [sqlite3_strnicmp()] are +** considered to be the same name. +** +** ^(The third argument (eTextRep) must be one of the constants: +**
      +**
    • [SQLITE_UTF8], +**
    • [SQLITE_UTF16LE], +**
    • [SQLITE_UTF16BE], +**
    • [SQLITE_UTF16], or +**
    • [SQLITE_UTF16_ALIGNED]. +**
    )^ +** ^The eTextRep argument determines the encoding of strings passed +** to the collating function callback, xCallback. +** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep +** force strings to be UTF16 with native byte order. +** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin +** on an even byte address. +** +** ^The fourth argument, pArg, is an application data pointer that is passed +** through as the first argument to the collating function callback. +** +** ^The fifth argument, xCallback, is a pointer to the collating function. +** ^Multiple collating functions can be registered using the same name but +** with different eTextRep parameters and SQLite will use whichever +** function requires the least amount of data transformation. +** ^If the xCallback argument is NULL then the collating function is +** deleted. ^When all collating functions having the same name are deleted, +** that collation is no longer usable. +** +** ^The collating function callback is invoked with a copy of the pArg +** application data pointer and with two strings in the encoding specified +** by the eTextRep argument. The collating function must return an +** integer that is negative, zero, or positive +** if the first string is less than, equal to, or greater than the second, +** respectively. A collating function must always return the same answer +** given the same inputs. If two or more collating functions are registered +** to the same collation name (using different eTextRep values) then all +** must give an equivalent answer when invoked with equivalent strings. +** The collating function must obey the following properties for all +** strings A, B, and C: +** +**
      +**
    1. If A==B then B==A. +**
    2. If A==B and B==C then A==C. +**
    3. If A<B THEN B>A. +**
    4. If A<B and B<C then A<C. +**
    +** +** If a collating function fails any of the above constraints and that +** collating function is registered and used, then the behavior of SQLite +** is undefined. +** +** ^The sqlite3_create_collation_v2() works like sqlite3_create_collation() +** with the addition that the xDestroy callback is invoked on pArg when +** the collating function is deleted. +** ^Collating functions are deleted when they are overridden by later +** calls to the collation creation functions or when the +** [database connection] is closed using [sqlite3_close()]. +** +** ^The xDestroy callback is not called if the +** sqlite3_create_collation_v2() function fails. Applications that invoke +** sqlite3_create_collation_v2() with a non-NULL xDestroy argument should +** check the return code and dispose of the application data pointer +** themselves rather than expecting SQLite to deal with it for them. +** This is different from every other SQLite interface. The inconsistency +** is unfortunate but cannot be changed without breaking backwards +** compatibility. +** +** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_create_collation( + sqlite3*, + const char *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*) +); +SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2( + sqlite3*, + const char *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDestroy)(void*) +); +SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16( + sqlite3*, + const void *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*) +); + +/* +** CAPI3REF: Collation Needed Callbacks +** METHOD: sqlite3 +** +** ^To avoid having to register all collation sequences before a database +** can be used, a single callback function may be registered with the +** [database connection] to be invoked whenever an undefined collation +** sequence is required. +** +** ^If the function is registered using the sqlite3_collation_needed() API, +** then it is passed the names of undefined collation sequences as strings +** encoded in UTF-8. ^If sqlite3_collation_needed16() is used, +** the names are passed as UTF-16 in machine native byte order. +** ^A call to either function replaces the existing collation-needed callback. +** +** ^(When the callback is invoked, the first argument passed is a copy +** of the second argument to sqlite3_collation_needed() or +** sqlite3_collation_needed16(). The second argument is the database +** connection. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE], +** or [SQLITE_UTF16LE], indicating the most desirable form of the collation +** sequence function required. The fourth parameter is the name of the +** required collation sequence.)^ +** +** The callback function should register the desired collation using +** [sqlite3_create_collation()], [sqlite3_create_collation16()], or +** [sqlite3_create_collation_v2()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const char*) +); +SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const void*) +); + +#ifdef SQLITE_HAS_CODEC +/* +** Specify the key for an encrypted database. This routine should be +** called right after sqlite3_open(). +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_key( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The key */ +); +SQLITE_API int SQLITE_STDCALL sqlite3_key_v2( + sqlite3 *db, /* Database to be rekeyed */ + const char *zDbName, /* Name of the database */ + const void *pKey, int nKey /* The key */ +); + +/* +** Change the key on an open database. If the current database is not +** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the +** database is decrypted. +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_rekey( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The new key */ +); +SQLITE_API int SQLITE_STDCALL sqlite3_rekey_v2( + sqlite3 *db, /* Database to be rekeyed */ + const char *zDbName, /* Name of the database */ + const void *pKey, int nKey /* The new key */ +); + +/* +** Specify the activation key for a SEE database. Unless +** activated, none of the SEE routines will work. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_activate_see( + const char *zPassPhrase /* Activation phrase */ +); +#endif + +#ifdef SQLITE_ENABLE_CEROD +/* +** Specify the activation key for a CEROD database. Unless +** activated, none of the CEROD routines will work. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_activate_cerod( + const char *zPassPhrase /* Activation phrase */ +); +#endif + +/* +** CAPI3REF: Suspend Execution For A Short Time +** +** The sqlite3_sleep() function causes the current thread to suspend execution +** for at least a number of milliseconds specified in its parameter. +** +** If the operating system does not support sleep requests with +** millisecond time resolution, then the time will be rounded up to +** the nearest second. The number of milliseconds of sleep actually +** requested from the operating system is returned. +** +** ^SQLite implements this interface by calling the xSleep() +** method of the default [sqlite3_vfs] object. If the xSleep() method +** of the default VFS is not implemented correctly, or not implemented at +** all, then the behavior of sqlite3_sleep() may deviate from the description +** in the previous paragraphs. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int); + +/* +** CAPI3REF: Name Of The Folder Holding Temporary Files +** +** ^(If this global variable is made to point to a string which is +** the name of a folder (a.k.a. directory), then all temporary files +** created by SQLite when using a built-in [sqlite3_vfs | VFS] +** will be placed in that directory.)^ ^If this variable +** is a NULL pointer, then SQLite performs a search for an appropriate +** temporary file directory. +** +** Applications are strongly discouraged from using this global variable. +** It is required to set a temporary folder on Windows Runtime (WinRT). +** But for all other platforms, it is highly recommended that applications +** neither read nor write this variable. This global variable is a relic +** that exists for backwards compatibility of legacy applications and should +** be avoided in new projects. +** +** It is not safe to read or modify this variable in more than one +** thread at a time. It is not safe to read or modify this variable +** if a [database connection] is being used at the same time in a separate +** thread. +** It is intended that this variable be set once +** as part of process initialization and before any SQLite interface +** routines have been called and that this variable remain unchanged +** thereafter. +** +** ^The [temp_store_directory pragma] may modify this variable and cause +** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore, +** the [temp_store_directory pragma] always assumes that any string +** that this variable points to is held in memory obtained from +** [sqlite3_malloc] and the pragma may attempt to free that memory +** using [sqlite3_free]. +** Hence, if this variable is modified directly, either it should be +** made NULL or made to point to memory obtained from [sqlite3_malloc] +** or else the use of the [temp_store_directory pragma] should be avoided. +** Except when requested by the [temp_store_directory pragma], SQLite +** does not free the memory that sqlite3_temp_directory points to. If +** the application wants that memory to be freed, it must do +** so itself, taking care to only do so after all [database connection] +** objects have been destroyed. +** +** Note to Windows Runtime users: The temporary directory must be set +** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various +** features that require the use of temporary files may fail. Here is an +** example of how to do this using C++ with the Windows Runtime: +** +**
    +** LPCWSTR zPath = Windows::Storage::ApplicationData::Current->
    +**       TemporaryFolder->Path->Data();
    +** char zPathBuf[MAX_PATH + 1];
    +** memset(zPathBuf, 0, sizeof(zPathBuf));
    +** WideCharToMultiByte(CP_UTF8, 0, zPath, -1, zPathBuf, sizeof(zPathBuf),
    +**       NULL, NULL);
    +** sqlite3_temp_directory = sqlite3_mprintf("%s", zPathBuf);
    +** 
    +*/ +SQLITE_API char *sqlite3_temp_directory; + +/* +** CAPI3REF: Name Of The Folder Holding Database Files +** +** ^(If this global variable is made to point to a string which is +** the name of a folder (a.k.a. directory), then all database files +** specified with a relative pathname and created or accessed by +** SQLite when using a built-in windows [sqlite3_vfs | VFS] will be assumed +** to be relative to that directory.)^ ^If this variable is a NULL +** pointer, then SQLite assumes that all database files specified +** with a relative pathname are relative to the current directory +** for the process. Only the windows VFS makes use of this global +** variable; it is ignored by the unix VFS. +** +** Changing the value of this variable while a database connection is +** open can result in a corrupt database. +** +** It is not safe to read or modify this variable in more than one +** thread at a time. It is not safe to read or modify this variable +** if a [database connection] is being used at the same time in a separate +** thread. +** It is intended that this variable be set once +** as part of process initialization and before any SQLite interface +** routines have been called and that this variable remain unchanged +** thereafter. +** +** ^The [data_store_directory pragma] may modify this variable and cause +** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore, +** the [data_store_directory pragma] always assumes that any string +** that this variable points to is held in memory obtained from +** [sqlite3_malloc] and the pragma may attempt to free that memory +** using [sqlite3_free]. +** Hence, if this variable is modified directly, either it should be +** made NULL or made to point to memory obtained from [sqlite3_malloc] +** or else the use of the [data_store_directory pragma] should be avoided. +*/ +SQLITE_API char *sqlite3_data_directory; + +/* +** CAPI3REF: Test For Auto-Commit Mode +** KEYWORDS: {autocommit mode} +** METHOD: sqlite3 +** +** ^The sqlite3_get_autocommit() interface returns non-zero or +** zero if the given database connection is or is not in autocommit mode, +** respectively. ^Autocommit mode is on by default. +** ^Autocommit mode is disabled by a [BEGIN] statement. +** ^Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK]. +** +** If certain kinds of errors occur on a statement within a multi-statement +** transaction (errors including [SQLITE_FULL], [SQLITE_IOERR], +** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the +** transaction might be rolled back automatically. The only way to +** find out whether SQLite automatically rolled back the transaction after +** an error is to use this function. +** +** If another thread changes the autocommit status of the database +** connection while this routine is running, then the return value +** is undefined. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3*); + +/* +** CAPI3REF: Find The Database Handle Of A Prepared Statement +** METHOD: sqlite3_stmt +** +** ^The sqlite3_db_handle interface returns the [database connection] handle +** to which a [prepared statement] belongs. ^The [database connection] +** returned by sqlite3_db_handle is the same [database connection] +** that was the first argument +** to the [sqlite3_prepare_v2()] call (or its variants) that was used to +** create the statement in the first place. +*/ +SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt*); + +/* +** CAPI3REF: Return The Filename For A Database Connection +** METHOD: sqlite3 +** +** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename +** associated with database N of connection D. ^The main database file +** has the name "main". If there is no attached database N on the database +** connection D, or if database N is a temporary or in-memory database, then +** a NULL pointer is returned. +** +** ^The filename returned by this function is the output of the +** xFullPathname method of the [VFS]. ^In other words, the filename +** will be an absolute pathname, even if the filename used +** to open the database originally was a URI or relative pathname. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *zDbName); + +/* +** CAPI3REF: Determine if a database is read-only +** METHOD: sqlite3 +** +** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N +** of connection D is read-only, 0 if it is read/write, or -1 if N is not +** the name of a database on connection D. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbName); + +/* +** CAPI3REF: Find the next prepared statement +** METHOD: sqlite3 +** +** ^This interface returns a pointer to the next [prepared statement] after +** pStmt associated with the [database connection] pDb. ^If pStmt is NULL +** then this interface returns a pointer to the first prepared statement +** associated with the database connection pDb. ^If no prepared statement +** satisfies the conditions of this routine, it returns NULL. +** +** The [database connection] pointer D in a call to +** [sqlite3_next_stmt(D,S)] must refer to an open database +** connection and in particular must not be a NULL pointer. +*/ +SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Commit And Rollback Notification Callbacks +** METHOD: sqlite3 +** +** ^The sqlite3_commit_hook() interface registers a callback +** function to be invoked whenever a transaction is [COMMIT | committed]. +** ^Any callback set by a previous call to sqlite3_commit_hook() +** for the same database connection is overridden. +** ^The sqlite3_rollback_hook() interface registers a callback +** function to be invoked whenever a transaction is [ROLLBACK | rolled back]. +** ^Any callback set by a previous call to sqlite3_rollback_hook() +** for the same database connection is overridden. +** ^The pArg argument is passed through to the callback. +** ^If the callback on a commit hook function returns non-zero, +** then the commit is converted into a rollback. +** +** ^The sqlite3_commit_hook(D,C,P) and sqlite3_rollback_hook(D,C,P) functions +** return the P argument from the previous call of the same function +** on the same [database connection] D, or NULL for +** the first call for each function on D. +** +** The commit and rollback hook callbacks are not reentrant. +** The callback implementation must not do anything that will modify +** the database connection that invoked the callback. Any actions +** to modify the database connection must be deferred until after the +** completion of the [sqlite3_step()] call that triggered the commit +** or rollback hook in the first place. +** Note that running any other SQL statements, including SELECT statements, +** or merely calling [sqlite3_prepare_v2()] and [sqlite3_step()] will modify +** the database connections for the meaning of "modify" in this paragraph. +** +** ^Registering a NULL function disables the callback. +** +** ^When the commit hook callback routine returns zero, the [COMMIT] +** operation is allowed to continue normally. ^If the commit hook +** returns non-zero, then the [COMMIT] is converted into a [ROLLBACK]. +** ^The rollback hook is invoked on a rollback that results from a commit +** hook returning non-zero, just as it would be with any other rollback. +** +** ^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 rollback callback is not invoked if a transaction is +** automatically rolled back because the database connection is closed. +** +** See also the [sqlite3_update_hook()] interface. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); +SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); + +/* +** CAPI3REF: Data Change Notification Callbacks +** METHOD: sqlite3 +** +** ^The sqlite3_update_hook() interface registers a callback function +** with the [database connection] identified by the first argument +** to be invoked whenever a row is updated, inserted or deleted in +** a rowid table. +** ^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 in a rowid table. +** ^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).)^ +** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified. +** +** ^In the current implementation, the update hook +** is not invoked when duplication rows are deleted because of an +** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook +** invoked when rows are deleted using the [truncate optimization]. +** The exceptions defined in this paragraph might change in a future +** release of SQLite. +** +** The update hook implementation must not do anything that will modify +** the database connection that invoked the update hook. Any actions +** to modify the database connection must be deferred until after the +** completion of the [sqlite3_step()] call that triggered the update hook. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +** ^The sqlite3_update_hook(D,C,P) function +** returns the P argument from the previous call +** on the same [database connection] D, or NULL for +** the first call on D. +** +** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()] +** interfaces. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook( + sqlite3*, + void(*)(void *,int ,char const *,char const *,sqlite3_int64), + void* +); + +/* +** CAPI3REF: Enable Or Disable Shared Pager Cache +** +** ^(This routine enables or disables the sharing of the database cache +** and schema data structures between [database connection | connections] +** to the same database. Sharing is enabled if the argument is true +** and disabled if the argument is false.)^ +** +** ^Cache sharing is enabled and disabled for an entire process. +** This is a change as of SQLite version 3.5.0. In prior versions of SQLite, +** sharing was enabled or disabled for each thread separately. +** +** ^(The cache sharing mode set by this interface effects all subsequent +** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()]. +** Existing database connections continue use the sharing mode +** that was in effect at the time they were opened.)^ +** +** ^(This routine returns [SQLITE_OK] if shared cache was enabled or disabled +** successfully. An [error code] is returned otherwise.)^ +** +** ^Shared cache is disabled by default. But this might change in +** future releases of SQLite. Applications that care about shared +** cache setting should set it explicitly. +** +** Note: This method is disabled on MacOS X 10.7 and iOS version 5.0 +** and will always return SQLITE_MISUSE. On those systems, +** shared cache mode should be enabled per-database connection via +** [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE]. +** +** This interface is threadsafe on processors where writing a +** 32-bit integer is atomic. +** +** See Also: [SQLite Shared-Cache Mode] +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int); + +/* +** CAPI3REF: Attempt To Free Heap Memory +** +** ^The sqlite3_release_memory() interface attempts to free N bytes +** of heap memory by deallocating non-essential memory allocations +** held by the database library. Memory used to cache database +** pages to improve performance is an example of non-essential memory. +** ^sqlite3_release_memory() returns the number of bytes actually freed, +** which might be more or less than the amount requested. +** ^The sqlite3_release_memory() routine is a no-op returning zero +** if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT]. +** +** See also: [sqlite3_db_release_memory()] +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int); + +/* +** CAPI3REF: Free Memory Used By A Database Connection +** METHOD: sqlite3 +** +** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap +** memory as possible from database connection D. Unlike the +** [sqlite3_release_memory()] interface, this interface is in effect even +** when the [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is +** omitted. +** +** See also: [sqlite3_release_memory()] +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3*); + +/* +** CAPI3REF: Impose A Limit On Heap Size +** +** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the +** soft limit on the amount of heap memory that may be allocated by SQLite. +** ^SQLite strives to keep heap memory utilization below the soft heap +** limit by reducing the number of pages held in the page cache +** as heap memory usages approaches the limit. +** ^The soft heap limit is "soft" because even though SQLite strives to stay +** below the limit, it will exceed the limit rather than generate +** an [SQLITE_NOMEM] error. In other words, the soft heap limit +** is advisory only. +** +** ^The return value from sqlite3_soft_heap_limit64() is the size of +** the soft heap limit prior to the call, or negative in the case of an +** error. ^If the argument N is negative +** then no change is made to the soft heap limit. Hence, the current +** size of the soft heap limit can be determined by invoking +** sqlite3_soft_heap_limit64() with a negative argument. +** +** ^If the argument N is zero then the soft heap limit is disabled. +** +** ^(The soft heap limit is not enforced in the current implementation +** if one or more of following conditions are true: +** +**
      +**
    • The soft heap limit is set to zero. +**
    • Memory accounting is disabled using a combination of the +** [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and +** the [SQLITE_DEFAULT_MEMSTATUS] compile-time option. +**
    • An alternative page cache implementation is specified using +** [sqlite3_config]([SQLITE_CONFIG_PCACHE2],...). +**
    • The page cache allocates from its own memory pool supplied +** by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than +** from the heap. +**
    )^ +** +** Beginning with SQLite version 3.7.3, the soft heap limit is enforced +** regardless of whether or not the [SQLITE_ENABLE_MEMORY_MANAGEMENT] +** compile-time option is invoked. With [SQLITE_ENABLE_MEMORY_MANAGEMENT], +** the soft heap limit is enforced on every memory allocation. Without +** [SQLITE_ENABLE_MEMORY_MANAGEMENT], the soft heap limit is only enforced +** when memory is allocated by the page cache. Testing suggests that because +** the page cache is the predominate memory user in SQLite, most +** applications will achieve adequate soft heap limit enforcement without +** the use of [SQLITE_ENABLE_MEMORY_MANAGEMENT]. +** +** The circumstances under which SQLite will enforce the soft heap limit may +** changes in future releases of SQLite. +*/ +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 N); + +/* +** CAPI3REF: Deprecated Soft Heap Limit Interface +** DEPRECATED +** +** This is a deprecated version of the [sqlite3_soft_heap_limit64()] +** interface. This routine is provided for historical compatibility +** only. All new applications should use the +** [sqlite3_soft_heap_limit64()] interface rather than this one. +*/ +SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_soft_heap_limit(int N); + + +/* +** CAPI3REF: Extract Metadata About A Column Of A Table +** METHOD: sqlite3 +** +** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns +** information about column C of table T in database D +** on [database connection] X.)^ ^The sqlite3_table_column_metadata() +** interface returns SQLITE_OK and fills in the non-NULL pointers in +** the final five arguments with appropriate values if the specified +** column exists. ^The sqlite3_table_column_metadata() interface returns +** SQLITE_ERROR and if the specified column does not exist. +** ^If the column-name parameter to sqlite3_table_column_metadata() is a +** NULL pointer, then this routine simply checks for the existance of the +** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it +** does not. +** +** ^The column is identified by the second, third and fourth parameters to +** this function. ^(The second parameter is either the name of the database +** (i.e. "main", "temp", or an attached database) containing the specified +** table or NULL.)^ ^If it is NULL, then all attached databases are searched +** for the table using the same algorithm used by the database engine to +** resolve unqualified table references. +** +** ^The third and fourth parameters to this function are the table and column +** name of the desired column, respectively. +** +** ^Metadata is returned by writing to the memory locations passed as the 5th +** and subsequent parameters to this function. ^Any of these arguments may be +** NULL, in which case the corresponding element of metadata is omitted. +** +** ^(
    +** +**
    Parameter Output
    Type
    Description +** +**
    5th const char* Data type +**
    6th const char* Name of default collation sequence +**
    7th int True if column has a NOT NULL constraint +**
    8th int True if column is part of the PRIMARY KEY +**
    9th int True if column is [AUTOINCREMENT] +**
    +**
    )^ +** +** ^The memory pointed to by the character pointers returned for the +** declaration type and collation sequence is valid until the next +** call to any SQLite API function. +** +** ^If the specified table is actually a view, an [error code] is returned. +** +** ^If the specified column is "rowid", "oid" or "_rowid_" and the table +** is not a [WITHOUT ROWID] table and an +** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output +** parameters are set for the explicitly declared column. ^(If there is no +** [INTEGER PRIMARY KEY] column, then the outputs +** for the [rowid] are set as follows: +** +**
    +**     data type: "INTEGER"
    +**     collation sequence: "BINARY"
    +**     not null: 0
    +**     primary key: 1
    +**     auto increment: 0
    +** 
    )^ +** +** ^This function causes all database schemas to be read from disk and +** parsed, if that has not already been done, and returns an error if +** any errors are encountered while loading the schema. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata( + sqlite3 *db, /* Connection handle */ + const char *zDbName, /* Database name or NULL */ + const char *zTableName, /* Table name */ + const char *zColumnName, /* Column name */ + char const **pzDataType, /* OUTPUT: Declared data type */ + char const **pzCollSeq, /* OUTPUT: Collation sequence name */ + int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ + int *pPrimaryKey, /* OUTPUT: True if column part of PK */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ +); + +/* +** CAPI3REF: Load An Extension +** METHOD: sqlite3 +** +** ^This interface loads an SQLite extension library from the named file. +** +** ^The sqlite3_load_extension() interface attempts to load an +** [SQLite extension] library contained in the file zFile. If +** the file cannot be loaded directly, attempts are made to load +** with various operating-system specific extensions added. +** So for example, if "samplelib" cannot be loaded, then names like +** "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might +** be tried also. +** +** ^The entry point is zProc. +** ^(zProc may be 0, in which case SQLite will try to come up with an +** entry point name on its own. It first tries "sqlite3_extension_init". +** If that does not work, it constructs a name "sqlite3_X_init" where the +** X is consists of the lower-case equivalent of all ASCII alphabetic +** characters in the filename from the last "/" to the first following +** "." and omitting any initial "lib".)^ +** ^The sqlite3_load_extension() interface returns +** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. +** ^If an error occurs and pzErrMsg is not 0, then the +** [sqlite3_load_extension()] interface shall attempt to +** fill *pzErrMsg with error message text stored in memory +** obtained from [sqlite3_malloc()]. The calling function +** should free this memory by calling [sqlite3_free()]. +** +** ^Extension loading must be enabled using +** [sqlite3_enable_load_extension()] prior to calling this API, +** otherwise an error will be returned. +** +** See also the [load_extension() SQL function]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Derived from zFile if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +); + +/* +** CAPI3REF: Enable Or Disable Extension Loading +** METHOD: sqlite3 +** +** ^So as not to open security holes in older applications that are +** unprepared to deal with [extension loading], and as a means of disabling +** [extension loading] while evaluating user-entered SQL, the following API +** is provided to turn the [sqlite3_load_extension()] mechanism on and off. +** +** ^Extension loading is off by default. +** ^Call the sqlite3_enable_load_extension() routine with onoff==1 +** to turn extension loading on and call it with onoff==0 to turn +** it back off again. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff); + +/* +** CAPI3REF: Automatically Load Statically Linked Extensions +** +** ^This interface causes the xEntryPoint() function to be invoked for +** each new [database connection] that is created. The idea here is that +** xEntryPoint() is the entry point for a statically linked [SQLite extension] +** that is to be automatically loaded into all new database connections. +** +** ^(Even though the function prototype shows that xEntryPoint() takes +** no arguments and returns void, SQLite invokes xEntryPoint() with three +** arguments and expects and integer result as if the signature of the +** entry point where as follows: +** +**
    +**    int xEntryPoint(
    +**      sqlite3 *db,
    +**      const char **pzErrMsg,
    +**      const struct sqlite3_api_routines *pThunk
    +**    );
    +** 
    )^ +** +** If the xEntryPoint routine encounters an error, it should make *pzErrMsg +** point to an appropriate error message (obtained from [sqlite3_mprintf()]) +** and return an appropriate [error code]. ^SQLite ensures that *pzErrMsg +** is NULL before calling the xEntryPoint(). ^SQLite will invoke +** [sqlite3_free()] on *pzErrMsg after xEntryPoint() returns. ^If any +** xEntryPoint() returns an error, the [sqlite3_open()], [sqlite3_open16()], +** or [sqlite3_open_v2()] call that provoked the xEntryPoint() will fail. +** +** ^Calling sqlite3_auto_extension(X) with an entry point X that is already +** on the list of automatic extensions is a harmless no-op. ^No entry point +** will be called more than once for each database connection that is opened. +** +** See also: [sqlite3_reset_auto_extension()] +** and [sqlite3_cancel_auto_extension()] +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xEntryPoint)(void)); + +/* +** CAPI3REF: Cancel Automatic Extension Loading +** +** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the +** initialization routine X that was registered using a prior call to +** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)] +** routine returns 1 if initialization routine X was successfully +** unregistered and it returns 0 if X was not on the list of initialization +** routines. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void (*xEntryPoint)(void)); + +/* +** CAPI3REF: Reset Automatic Extension Loading +** +** ^This interface disables all automatic extensions previously +** registered using [sqlite3_auto_extension()]. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void); + +/* +** The interface to the virtual-table mechanism is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + +/* +** Structures used by the virtual table interface +*/ +typedef struct sqlite3_vtab sqlite3_vtab; +typedef struct sqlite3_index_info sqlite3_index_info; +typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; +typedef struct sqlite3_module sqlite3_module; + +/* +** CAPI3REF: Virtual Table Object +** KEYWORDS: sqlite3_module {virtual table module} +** +** This structure, sometimes called a "virtual table module", +** defines the implementation of a [virtual tables]. +** This structure consists mostly of methods for the module. +** +** ^A virtual table module is created by filling in a persistent +** instance of this structure and passing a pointer to that instance +** to [sqlite3_create_module()] or [sqlite3_create_module_v2()]. +** ^The registration remains valid until it is replaced by a different +** module or until the [database connection] closes. The content +** of this structure must not change while it is registered with +** any database connection. +*/ +struct sqlite3_module { + int iVersion; + int (*xCreate)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xConnect)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); + int (*xDisconnect)(sqlite3_vtab *pVTab); + int (*xDestroy)(sqlite3_vtab *pVTab); + int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); + int (*xClose)(sqlite3_vtab_cursor*); + int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); + int (*xNext)(sqlite3_vtab_cursor*); + int (*xEof)(sqlite3_vtab_cursor*); + int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); + int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); + int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); + int (*xBegin)(sqlite3_vtab *pVTab); + int (*xSync)(sqlite3_vtab *pVTab); + int (*xCommit)(sqlite3_vtab *pVTab); + int (*xRollback)(sqlite3_vtab *pVTab); + int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg); + int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); + /* The methods above are in version 1 of the sqlite_module object. Those + ** below are for version 2 and greater. */ + int (*xSavepoint)(sqlite3_vtab *pVTab, int); + int (*xRelease)(sqlite3_vtab *pVTab, int); + int (*xRollbackTo)(sqlite3_vtab *pVTab, int); +}; + +/* +** CAPI3REF: Virtual Table Indexing Information +** KEYWORDS: sqlite3_index_info +** +** The sqlite3_index_info structure and its substructures is used as part +** of the [virtual table] interface to +** pass information into and receive the reply from the [xBestIndex] +** method of a [virtual table module]. The fields under **Inputs** are the +** inputs to xBestIndex and are read-only. xBestIndex inserts its +** results into the **Outputs** fields. +** +** ^(The aConstraint[] array records WHERE clause constraints of the form: +** +**
    column OP expr
    +** +** where OP is =, <, <=, >, or >=.)^ ^(The particular operator is +** stored in aConstraint[].op using one of the +** [SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_ values].)^ +** ^(The index of the column is stored in +** aConstraint[].iColumn.)^ ^(aConstraint[].usable is TRUE if the +** expr on the right-hand side can be evaluated (and thus the constraint +** is usable) and false if it cannot.)^ +** +** ^The optimizer automatically inverts terms of the form "expr OP column" +** and makes other simplifications to the WHERE clause in an attempt to +** get as many WHERE clause terms into the form shown above as possible. +** ^The aConstraint[] array only reports WHERE clause terms that are +** relevant to the particular virtual table being queried. +** +** ^Information about the ORDER BY clause is stored in aOrderBy[]. +** ^Each term of aOrderBy records a column of the ORDER BY clause. +** +** The [xBestIndex] method must fill aConstraintUsage[] with information +** about what parameters to pass to xFilter. ^If argvIndex>0 then +** the right-hand side of the corresponding aConstraint[] is evaluated +** and becomes the argvIndex-th entry in argv. ^(If aConstraintUsage[].omit +** is true, then the constraint is assumed to be fully handled by the +** virtual table and is not checked again by SQLite.)^ +** +** ^The idxNum and idxPtr values are recorded and passed into the +** [xFilter] method. +** ^[sqlite3_free()] is used to free idxPtr if and only if +** needToFreeIdxPtr is true. +** +** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in +** the correct order to satisfy the ORDER BY clause so that no separate +** sorting step is required. +** +** ^The estimatedCost value is an estimate of the cost of a particular +** strategy. A cost of N indicates that the cost of the strategy is similar +** to a linear scan of an SQLite table with N rows. A cost of log(N) +** indicates that the expense of the operation is similar to that of a +** binary search on a unique indexed field of an SQLite table with N rows. +** +** ^The estimatedRows value is an estimate of the number of rows that +** will be returned by the strategy. +** +** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info +** structure for SQLite version 3.8.2. If a virtual table extension is +** used with an SQLite version earlier than 3.8.2, the results of attempting +** to read or write the estimatedRows field are undefined (but are likely +** to included crashing the application). The estimatedRows field should +** therefore only be used if [sqlite3_libversion_number()] returns a +** value greater than or equal to 3008002. +*/ +struct sqlite3_index_info { + /* Inputs */ + int nConstraint; /* Number of entries in aConstraint */ + struct sqlite3_index_constraint { + int iColumn; /* Column on left-hand side of constraint */ + unsigned char op; /* Constraint operator */ + unsigned char usable; /* True if this constraint is usable */ + int iTermOffset; /* Used internally - xBestIndex should ignore */ + } *aConstraint; /* Table of WHERE clause constraints */ + int nOrderBy; /* Number of terms in the ORDER BY clause */ + struct sqlite3_index_orderby { + int iColumn; /* Column number */ + unsigned char desc; /* True for DESC. False for ASC. */ + } *aOrderBy; /* The ORDER BY clause */ + /* Outputs */ + struct sqlite3_index_constraint_usage { + int argvIndex; /* if >0, constraint is part of argv to xFilter */ + unsigned char omit; /* Do not code a test for this constraint */ + } *aConstraintUsage; + int idxNum; /* Number used to identify the index */ + char *idxStr; /* String, possibly obtained from sqlite3_malloc */ + int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ + int orderByConsumed; /* True if output is already ordered */ + double estimatedCost; /* Estimated cost of using this index */ + /* Fields below are only available in SQLite 3.8.2 and later */ + sqlite3_int64 estimatedRows; /* Estimated number of rows returned */ +}; + +/* +** CAPI3REF: Virtual Table Constraint Operator Codes +** +** These macros defined the allowed values for the +** [sqlite3_index_info].aConstraint[].op field. Each value represents +** an operator that is part of a constraint term in the wHERE clause of +** a query that uses a [virtual table]. +*/ +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 + +/* +** CAPI3REF: Register A Virtual Table Implementation +** METHOD: sqlite3 +** +** ^These routines are used to register a new [virtual table module] name. +** ^Module names must be registered before +** creating a new [virtual table] using the module and before using a +** preexisting [virtual table] for the module. +** +** ^The module name is registered on the [database connection] specified +** by the first parameter. ^The name of the module is given by the +** second parameter. ^The third parameter is a pointer to +** the implementation of the [virtual table module]. ^The fourth +** parameter is an arbitrary client data pointer that is passed through +** into the [xCreate] and [xConnect] methods of the virtual table module +** when a new virtual table is be being created or reinitialized. +** +** ^The sqlite3_create_module_v2() interface has a fifth parameter which +** is a pointer to a destructor for the pClientData. ^SQLite will +** invoke the destructor function (if it is not NULL) when SQLite +** no longer needs the pClientData pointer. ^The destructor will also +** be invoked if the call to sqlite3_create_module_v2() fails. +** ^The sqlite3_create_module() +** interface is equivalent to sqlite3_create_module_v2() with a NULL +** destructor. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_create_module( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *p, /* Methods for the module */ + void *pClientData /* Client data for xCreate/xConnect */ +); +SQLITE_API int SQLITE_STDCALL sqlite3_create_module_v2( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *p, /* Methods for the module */ + void *pClientData, /* Client data for xCreate/xConnect */ + void(*xDestroy)(void*) /* Module destructor function */ +); + +/* +** CAPI3REF: Virtual Table Instance Object +** KEYWORDS: sqlite3_vtab +** +** Every [virtual table module] implementation uses a subclass +** of this object to describe a particular instance +** of the [virtual table]. Each subclass will +** be tailored to the specific needs of the module implementation. +** The purpose of this superclass is to define certain fields that are +** common to all module implementations. +** +** ^Virtual tables methods can set an error message by assigning a +** string obtained from [sqlite3_mprintf()] to zErrMsg. The method should +** take care that any prior string is freed by a call to [sqlite3_free()] +** prior to assigning a new string to zErrMsg. ^After the error message +** is delivered up to the client application, the string will be automatically +** freed by sqlite3_free() and the zErrMsg field will be zeroed. +*/ +struct sqlite3_vtab { + const sqlite3_module *pModule; /* The module for this virtual table */ + int nRef; /* Number of open cursors */ + char *zErrMsg; /* Error message from sqlite3_mprintf() */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** CAPI3REF: Virtual Table Cursor Object +** KEYWORDS: sqlite3_vtab_cursor {virtual table cursor} +** +** Every [virtual table module] implementation uses a subclass of the +** following structure to describe cursors that point into the +** [virtual table] and are used +** to loop through the virtual table. Cursors are created using the +** [sqlite3_module.xOpen | xOpen] method of the module and are destroyed +** by the [sqlite3_module.xClose | xClose] method. Cursors are used +** by the [xFilter], [xNext], [xEof], [xColumn], and [xRowid] methods +** of the module. Each module implementation will define +** the content of a cursor structure to suit its own needs. +** +** This superclass exists in order to define fields of the cursor that +** are common to all implementations. +*/ +struct sqlite3_vtab_cursor { + sqlite3_vtab *pVtab; /* Virtual table of this cursor */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** CAPI3REF: Declare The Schema Of A Virtual Table +** +** ^The [xCreate] and [xConnect] methods of a +** [virtual table module] call this interface +** to declare the format (the names and datatypes of the columns) of +** the virtual tables they implement. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3*, const char *zSQL); + +/* +** CAPI3REF: Overload A Function For A Virtual Table +** METHOD: sqlite3 +** +** ^(Virtual tables can provide alternative implementations of functions +** using the [xFindFunction] method of the [virtual table module]. +** But global versions of those functions +** must exist in order to be overloaded.)^ +** +** ^(This API makes sure a global version of a function with a particular +** name and number of parameters exists. If no such function exists +** before this API is called, a new function is created.)^ ^The implementation +** of the new function always causes an exception to be thrown. So +** the new function is not good for anything by itself. Its only +** purpose is to be a placeholder function that can be overloaded +** by a [virtual table]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); + +/* +** The interface to the virtual-table mechanism defined above (back up +** to a comment remarkably similar to this one) is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + +/* +** CAPI3REF: A Handle To An Open BLOB +** KEYWORDS: {BLOB handle} {BLOB handles} +** +** An instance of this object represents an open BLOB on which +** [sqlite3_blob_open | incremental BLOB I/O] can be performed. +** ^Objects of this type are created by [sqlite3_blob_open()] +** and destroyed by [sqlite3_blob_close()]. +** ^The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces +** can be used to read or write small subsections of the BLOB. +** ^The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes. +*/ +typedef struct sqlite3_blob sqlite3_blob; + +/* +** CAPI3REF: Open A BLOB For Incremental I/O +** METHOD: sqlite3 +** CONSTRUCTOR: sqlite3_blob +** +** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located +** in row iRow, column zColumn, table zTable in database zDb; +** in other words, the same BLOB that would be selected by: +** +**
    +**     SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
    +** 
    )^ +** +** ^(Parameter zDb is not the filename that contains the database, but +** rather the symbolic name of the database. For attached databases, this is +** the name that appears after the AS keyword in the [ATTACH] statement. +** For the main database file, the database name is "main". For TEMP +** tables, the database name is "temp".)^ +** +** ^If the flags parameter is non-zero, then the BLOB is opened for read +** and write access. ^If the flags parameter is zero, the BLOB is opened for +** read-only access. +** +** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored +** in *ppBlob. Otherwise an [error code] is returned and, unless the error +** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided +** the API is not misused, it is always safe to call [sqlite3_blob_close()] +** on *ppBlob after this function it returns. +** +** This function fails with SQLITE_ERROR if any of the following are true: +**
      +**
    • ^(Database zDb does not exist)^, +**
    • ^(Table zTable does not exist within database zDb)^, +**
    • ^(Table zTable is a WITHOUT ROWID table)^, +**
    • ^(Column zColumn does not exist)^, +**
    • ^(Row iRow is not present in the table)^, +**
    • ^(The specified column of row iRow contains a value that is not +** a TEXT or BLOB value)^, +**
    • ^(Column zColumn is part of an index, PRIMARY KEY or UNIQUE +** constraint and the blob is being opened for read/write access)^, +**
    • ^([foreign key constraints | Foreign key constraints] are enabled, +** column zColumn is part of a [child key] definition and the blob is +** being opened for read/write access)^. +**
    +** +** ^Unless it returns SQLITE_MISUSE, this function sets the +** [database connection] error code and message accessible via +** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. +** +** +** ^(If the row that a BLOB handle points to is modified by an +** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects +** then the BLOB handle is marked as "expired". +** This is true if any column of the row is changed, even a column +** other than the one the BLOB handle is open on.)^ +** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for +** an expired BLOB handle fail with a return code of [SQLITE_ABORT]. +** ^(Changes written into a BLOB prior to the BLOB expiring are not +** rolled back by the expiration of the BLOB. Such changes will eventually +** commit if the transaction continues to completion.)^ +** +** ^Use the [sqlite3_blob_bytes()] interface to determine the size of +** the opened blob. ^The size of a blob may not be changed by this +** interface. Use the [UPDATE] SQL command to change the size of a +** blob. +** +** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces +** and the built-in [zeroblob] SQL function may be used to create a +** zero-filled blob to read or write using the incremental-blob interface. +** +** To avoid a resource leak, every open [BLOB handle] should eventually +** be released by a call to [sqlite3_blob_close()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_blob_open( + sqlite3*, + const char *zDb, + const char *zTable, + const char *zColumn, + sqlite3_int64 iRow, + int flags, + sqlite3_blob **ppBlob +); + +/* +** CAPI3REF: Move a BLOB Handle to a New Row +** METHOD: sqlite3_blob +** +** ^This function is used to move an existing blob handle so that it points +** to a different row of the same database table. ^The new row is identified +** by the rowid value passed as the second argument. Only the row can be +** changed. ^The database, table and column on which the blob handle is open +** remain the same. Moving an existing blob handle to a new row can be +** faster than closing the existing handle and opening a new one. +** +** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] - +** it must exist and there must be either a blob or text value stored in +** the nominated column.)^ ^If the new row is not present in the table, or if +** it does not contain a blob or text value, or if another error occurs, an +** SQLite error code is returned and the blob handle is considered aborted. +** ^All subsequent calls to [sqlite3_blob_read()], [sqlite3_blob_write()] or +** [sqlite3_blob_reopen()] on an aborted blob handle immediately return +** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle +** always returns zero. +** +** ^This function sets the database handle error code and message. +*/ +SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); + +/* +** CAPI3REF: Close A BLOB Handle +** DESTRUCTOR: sqlite3_blob +** +** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed +** unconditionally. Even if this routine returns an error code, the +** handle is still closed.)^ +** +** ^If the blob handle being closed was opened for read-write access, and if +** the database is in auto-commit mode and there are no other open read-write +** blob handles or active write statements, the current transaction is +** committed. ^If an error occurs while committing the transaction, an error +** code is returned and the transaction rolled back. +** +** Calling this function with an argument that is not a NULL pointer or an +** open blob handle results in undefined behaviour. ^Calling this routine +** with a null pointer (such as would be returned by a failed call to +** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function +** is passed a valid open blob handle, the values returned by the +** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *); + +/* +** CAPI3REF: Return The Size Of An Open BLOB +** METHOD: sqlite3_blob +** +** ^Returns the size in bytes of the BLOB accessible via the +** successfully opened [BLOB handle] in its only argument. ^The +** incremental blob I/O routines can only read or overwriting existing +** blob content; they cannot change the size of a blob. +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *); + +/* +** CAPI3REF: Read Data From A BLOB Incrementally +** METHOD: sqlite3_blob +** +** ^(This function is used to read data from an open [BLOB handle] into a +** caller-supplied buffer. N bytes of data are copied into buffer Z +** from the open BLOB, starting at offset iOffset.)^ +** +** ^If offset iOffset is less than N bytes from the end of the BLOB, +** [SQLITE_ERROR] is returned and no data is read. ^If N or iOffset is +** less than zero, [SQLITE_ERROR] is returned and no data is read. +** ^The size of the blob (and hence the maximum value of N+iOffset) +** can be determined using the [sqlite3_blob_bytes()] interface. +** +** ^An attempt to read from an expired [BLOB handle] fails with an +** error code of [SQLITE_ABORT]. +** +** ^(On success, sqlite3_blob_read() returns SQLITE_OK. +** Otherwise, an [error code] or an [extended error code] is returned.)^ +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +** +** See also: [sqlite3_blob_write()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); + +/* +** CAPI3REF: Write Data Into A BLOB Incrementally +** METHOD: sqlite3_blob +** +** ^(This function is used to write data into an open [BLOB handle] from a +** caller-supplied buffer. N bytes of data are copied from the buffer Z +** into the open BLOB, starting at offset iOffset.)^ +** +** ^(On success, sqlite3_blob_write() returns SQLITE_OK. +** Otherwise, an [error code] or an [extended error code] is returned.)^ +** ^Unless SQLITE_MISUSE is returned, this function sets the +** [database connection] error code and message accessible via +** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. +** +** ^If the [BLOB handle] passed as the first argument was not opened for +** writing (the flags parameter to [sqlite3_blob_open()] was zero), +** this function returns [SQLITE_READONLY]. +** +** This function may only modify the contents of the BLOB; it is +** not possible to increase the size of a BLOB using this API. +** ^If offset iOffset is less than N bytes from the end of the BLOB, +** [SQLITE_ERROR] is returned and no data is written. The size of the +** BLOB (and hence the maximum value of N+iOffset) can be determined +** using the [sqlite3_blob_bytes()] interface. ^If N or iOffset are less +** than zero [SQLITE_ERROR] is returned and no data is written. +** +** ^An attempt to write to an expired [BLOB handle] fails with an +** error code of [SQLITE_ABORT]. ^Writes to the BLOB that occurred +** before the [BLOB handle] expired are not rolled back by the +** expiration of the handle, though of course those changes might +** have been overwritten by the statement that expired the BLOB handle +** or by other independent statements. +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +** +** See also: [sqlite3_blob_read()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); + +/* +** CAPI3REF: Virtual File System Objects +** +** A virtual filesystem (VFS) is an [sqlite3_vfs] object +** that SQLite uses to interact +** with the underlying operating system. Most SQLite builds come with a +** single default VFS that is appropriate for the host computer. +** New VFSes can be registered and existing VFSes can be unregistered. +** The following interfaces are provided. +** +** ^The sqlite3_vfs_find() interface returns a pointer to a VFS given its name. +** ^Names are case sensitive. +** ^Names are zero-terminated UTF-8 strings. +** ^If there is no match, a NULL pointer is returned. +** ^If zVfsName is NULL then the default VFS is returned. +** +** ^New VFSes are registered with sqlite3_vfs_register(). +** ^Each new VFS becomes the default VFS if the makeDflt flag is set. +** ^The same VFS can be registered multiple times without injury. +** ^To make an existing VFS into the default VFS, register it again +** with the makeDflt flag set. If two different VFSes with the +** same name are registered, the behavior is undefined. If a +** VFS is registered with a name that is NULL or an empty string, +** then the behavior is undefined. +** +** ^Unregister a VFS with the sqlite3_vfs_unregister() interface. +** ^(If the default VFS is unregistered, another VFS is chosen as +** the default. The choice for the new VFS is arbitrary.)^ +*/ +SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfsName); +SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); +SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs*); + +/* +** CAPI3REF: Mutexes +** +** The SQLite core uses these routines for thread +** synchronization. Though they are intended for internal +** use by SQLite, code that links against SQLite is +** permitted to use any of these routines. +** +** The SQLite source code contains multiple implementations +** of these mutex routines. An appropriate implementation +** is selected automatically at compile-time. The following +** implementations are available in the SQLite core: +** +**
      +**
    • SQLITE_MUTEX_PTHREADS +**
    • SQLITE_MUTEX_W32 +**
    • SQLITE_MUTEX_NOOP +**
    +** +** The SQLITE_MUTEX_NOOP implementation is a set of routines +** that does no real locking and is appropriate for use in +** a single-threaded application. The SQLITE_MUTEX_PTHREADS and +** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix +** and Windows. +** +** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor +** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex +** implementation is included with the library. In this case the +** application must supply a custom mutex implementation using the +** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function +** before calling sqlite3_initialize() or any other public sqlite3_ +** function that calls sqlite3_initialize(). +** +** ^The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() +** routine returns NULL if it is unable to allocate the requested +** mutex. The argument to sqlite3_mutex_alloc() must one of these +** integer constants: +** +**
      +**
    • SQLITE_MUTEX_FAST +**
    • SQLITE_MUTEX_RECURSIVE +**
    • SQLITE_MUTEX_STATIC_MASTER +**
    • SQLITE_MUTEX_STATIC_MEM +**
    • SQLITE_MUTEX_STATIC_OPEN +**
    • SQLITE_MUTEX_STATIC_PRNG +**
    • SQLITE_MUTEX_STATIC_LRU +**
    • SQLITE_MUTEX_STATIC_PMEM +**
    • SQLITE_MUTEX_STATIC_APP1 +**
    • SQLITE_MUTEX_STATIC_APP2 +**
    • SQLITE_MUTEX_STATIC_APP3 +**
    +** +** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) +** cause sqlite3_mutex_alloc() to create +** a new mutex. ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** ^The other allowed parameters to sqlite3_mutex_alloc() (anything other +** than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return +** a pointer to a static preexisting mutex. ^Nine static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. ^For the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +** +** ^The sqlite3_mutex_free() routine deallocates a previously +** allocated dynamic mutex. Attempting to deallocate a static +** mutex results in undefined behavior. +** +** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. ^If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. ^The sqlite3_mutex_try() interface returns [SQLITE_OK] +** upon successful entry. ^(Mutexes created using +** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread. +** In such cases, the +** mutex must be exited an equal number of times before another thread +** can enter.)^ If the same thread tries to enter any mutex other +** than an SQLITE_MUTEX_RECURSIVE more than once, the behavior is undefined. +** +** ^(Some systems (for example, Windows 95) do not support the operation +** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() +** will always return SQLITE_BUSY. The SQLite core only ever uses +** sqlite3_mutex_try() as an optimization so this is acceptable +** behavior.)^ +** +** ^The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered by the +** calling thread or is not currently allocated. +** +** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or +** sqlite3_mutex_leave() is a NULL pointer, then all three routines +** behave as no-ops. +** +** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. +*/ +SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int); +SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex*); +SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex*); +SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex*); +SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Methods Object +** +** An instance of this structure defines the low-level routines +** used to allocate and use mutexes. +** +** Usually, the default mutex implementations provided by SQLite are +** sufficient, however the application has the option of substituting a custom +** implementation for specialized deployments or systems for which SQLite +** does not provide a suitable implementation. In this case, the application +** creates and populates an instance of this structure to pass +** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option. +** Additionally, an instance of this structure can be used as an +** output variable when querying the system for the current mutex +** implementation, using the [SQLITE_CONFIG_GETMUTEX] option. +** +** ^The xMutexInit method defined by this structure is invoked as +** part of system initialization by the sqlite3_initialize() function. +** ^The xMutexInit routine is called by SQLite exactly once for each +** effective call to [sqlite3_initialize()]. +** +** ^The xMutexEnd method defined by this structure is invoked as +** part of system shutdown by the sqlite3_shutdown() function. The +** implementation of this method is expected to release all outstanding +** resources obtained by the mutex methods implementation, especially +** those obtained by the xMutexInit method. ^The xMutexEnd() +** interface is invoked exactly once for each call to [sqlite3_shutdown()]. +** +** ^(The remaining seven methods defined by this structure (xMutexAlloc, +** xMutexFree, xMutexEnter, xMutexTry, xMutexLeave, xMutexHeld and +** xMutexNotheld) implement the following interfaces (respectively): +** +**
      +**
    • [sqlite3_mutex_alloc()]
    • +**
    • [sqlite3_mutex_free()]
    • +**
    • [sqlite3_mutex_enter()]
    • +**
    • [sqlite3_mutex_try()]
    • +**
    • [sqlite3_mutex_leave()]
    • +**
    • [sqlite3_mutex_held()]
    • +**
    • [sqlite3_mutex_notheld()]
    • +**
    )^ +** +** The only difference is that the public sqlite3_XXX functions enumerated +** above silently ignore any invocations that pass a NULL pointer instead +** of a valid mutex handle. The implementations of the methods defined +** by this structure are not required to handle this case, the results +** of passing a NULL pointer instead of a valid mutex handle are undefined +** (i.e. it is acceptable to provide an implementation that segfaults if +** it is passed a NULL pointer). +** +** The xMutexInit() method must be threadsafe. It must be harmless to +** invoke xMutexInit() multiple times within the same process and without +** intervening calls to xMutexEnd(). Second and subsequent calls to +** xMutexInit() must be no-ops. +** +** xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()] +** and its associates). Similarly, xMutexAlloc() must not use SQLite memory +** allocation for a static mutex. ^However xMutexAlloc() may use SQLite +** memory allocation for a fast or recursive mutex. +** +** ^SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is +** called, but only if the prior call to xMutexInit returned SQLITE_OK. +** If xMutexInit fails in any way, it is expected to clean up after itself +** prior to returning. +*/ +typedef struct sqlite3_mutex_methods sqlite3_mutex_methods; +struct sqlite3_mutex_methods { + int (*xMutexInit)(void); + int (*xMutexEnd)(void); + sqlite3_mutex *(*xMutexAlloc)(int); + void (*xMutexFree)(sqlite3_mutex *); + void (*xMutexEnter)(sqlite3_mutex *); + int (*xMutexTry)(sqlite3_mutex *); + void (*xMutexLeave)(sqlite3_mutex *); + int (*xMutexHeld)(sqlite3_mutex *); + int (*xMutexNotheld)(sqlite3_mutex *); +}; + +/* +** CAPI3REF: Mutex Verification Routines +** +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines +** are intended for use inside assert() statements. The SQLite core +** never uses these routines except inside an assert() and applications +** are advised to follow the lead of the core. The SQLite core only +** provides implementations for these routines when it is compiled +** with the SQLITE_DEBUG flag. External mutex implementations +** are only required to provide these routines if SQLITE_DEBUG is +** defined and if NDEBUG is not defined. +** +** These routines should return true if the mutex in their argument +** is held or not held, respectively, by the calling thread. +** +** The implementation is not required to provide versions of these +** routines that actually work. If the implementation does not provide working +** versions of these routines, it should at least provide stubs that always +** return true so that one does not get spurious assertion failures. +** +** If the argument to sqlite3_mutex_held() is a NULL pointer then +** the routine should return 1. This seems counter-intuitive since +** clearly the mutex cannot be held if it does not exist. But +** the reason the mutex does not exist is because the build is not +** using mutexes. And we do not want the assert() containing the +** call to sqlite3_mutex_held() to fail, so a non-zero return is +** the appropriate thing to do. The sqlite3_mutex_notheld() +** interface should also return 1 when given a NULL pointer. +*/ +#ifndef NDEBUG +SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex*); +SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex*); +#endif + +/* +** CAPI3REF: Mutex Types +** +** The [sqlite3_mutex_alloc()] interface takes a single argument +** which is one of these integer constants. +** +** The set of static mutexes may change from one SQLite release to the +** next. Applications that override the built-in mutex logic must be +** prepared to accommodate additional static mutexes. +*/ +#define SQLITE_MUTEX_FAST 0 +#define SQLITE_MUTEX_RECURSIVE 1 +#define SQLITE_MUTEX_STATIC_MASTER 2 +#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ +#define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */ +#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ +#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ +#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ +#define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */ +#define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ +#define SQLITE_MUTEX_STATIC_APP1 8 /* For use by application */ +#define SQLITE_MUTEX_STATIC_APP2 9 /* For use by application */ +#define SQLITE_MUTEX_STATIC_APP3 10 /* For use by application */ + +/* +** CAPI3REF: Retrieve the mutex for a database connection +** METHOD: sqlite3 +** +** ^This interface returns a pointer the [sqlite3_mutex] object that +** serializes access to the [database connection] given in the argument +** when the [threading mode] is Serialized. +** ^If the [threading mode] is Single-thread or Multi-thread then this +** routine returns a NULL pointer. +*/ +SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3*); + +/* +** CAPI3REF: Low-Level Control Of Database Files +** METHOD: sqlite3 +** +** ^The [sqlite3_file_control()] interface makes a direct call to the +** xFileControl method for the [sqlite3_io_methods] object associated +** with a particular database identified by the second argument. ^The +** name of the database is "main" for the main database or "temp" for the +** TEMP database, or the name that appears after the AS keyword for +** databases that are added using the [ATTACH] SQL command. +** ^A NULL pointer can be used in place of "main" to refer to the +** main database file. +** ^The third and fourth parameters to this routine +** are passed directly through to the second and third parameters of +** the xFileControl method. ^The return value of the xFileControl +** method becomes the return value of this routine. +** +** ^The SQLITE_FCNTL_FILE_POINTER value for the op parameter causes +** a pointer to the underlying [sqlite3_file] object to be written into +** the space pointed to by the 4th parameter. ^The SQLITE_FCNTL_FILE_POINTER +** case is a short-circuit path which does not actually invoke the +** underlying sqlite3_io_methods.xFileControl method. +** +** ^If the second parameter (zDbName) does not match the name of any +** open database file, then SQLITE_ERROR is returned. ^This error +** code is not remembered and will not be recalled by [sqlite3_errcode()] +** or [sqlite3_errmsg()]. The underlying xFileControl method might +** also return SQLITE_ERROR. There is no way to distinguish between +** an incorrect zDbName and an SQLITE_ERROR return from the underlying +** xFileControl method. +** +** See also: [SQLITE_FCNTL_LOCKSTATE] +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); + +/* +** CAPI3REF: Testing Interface +** +** ^The sqlite3_test_control() interface is used to read out internal +** state of SQLite and to inject faults into SQLite for testing +** purposes. ^The first parameter is an operation code that determines +** the number, meaning, and operation of all subsequent parameters. +** +** This interface is not for use by applications. It exists solely +** for verifying the correct operation of the SQLite library. Depending +** on how the SQLite library is compiled, this interface might not exist. +** +** The details of the operation codes, their meanings, the parameters +** they take, and what they do are all subject to change without notice. +** Unlike most of the SQLite API, this function is not guaranteed to +** operate consistently from one release to the next. +*/ +SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...); + +/* +** CAPI3REF: Testing Interface Operation Codes +** +** These constants are the valid operation code parameters used +** as the first argument to [sqlite3_test_control()]. +** +** These parameters and their meanings are subject to change +** without notice. These values are for testing purposes only. +** Applications should not use any of these parameters or the +** [sqlite3_test_control()] interface. +*/ +#define SQLITE_TESTCTRL_FIRST 5 +#define SQLITE_TESTCTRL_PRNG_SAVE 5 +#define SQLITE_TESTCTRL_PRNG_RESTORE 6 +#define SQLITE_TESTCTRL_PRNG_RESET 7 +#define SQLITE_TESTCTRL_BITVEC_TEST 8 +#define SQLITE_TESTCTRL_FAULT_INSTALL 9 +#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10 +#define SQLITE_TESTCTRL_PENDING_BYTE 11 +#define SQLITE_TESTCTRL_ASSERT 12 +#define SQLITE_TESTCTRL_ALWAYS 13 +#define SQLITE_TESTCTRL_RESERVE 14 +#define SQLITE_TESTCTRL_OPTIMIZATIONS 15 +#define SQLITE_TESTCTRL_ISKEYWORD 16 +#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 +#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 +#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */ +#define SQLITE_TESTCTRL_NEVER_CORRUPT 20 +#define SQLITE_TESTCTRL_VDBE_COVERAGE 21 +#define SQLITE_TESTCTRL_BYTEORDER 22 +#define SQLITE_TESTCTRL_ISINIT 23 +#define SQLITE_TESTCTRL_SORTER_MMAP 24 +#define SQLITE_TESTCTRL_IMPOSTER 25 +#define SQLITE_TESTCTRL_LAST 25 + +/* +** CAPI3REF: SQLite Runtime Status +** +** ^These interfaces are used to retrieve runtime status information +** about the performance of SQLite, and optionally to reset various +** highwater marks. ^The first argument is an integer code for +** the specific parameter to measure. ^(Recognized integer codes +** are of the form [status parameters | SQLITE_STATUS_...].)^ +** ^The current value of the parameter is returned into *pCurrent. +** ^The highest recorded value is returned in *pHighwater. ^If the +** resetFlag is true, then the highest record value is reset after +** *pHighwater is written. ^(Some parameters do not record the highest +** value. For those parameters +** nothing is written into *pHighwater and the resetFlag is ignored.)^ +** ^(Other parameters record only the highwater mark and not the current +** value. For these latter parameters nothing is written into *pCurrent.)^ +** +** ^The sqlite3_status() and sqlite3_status64() routines return +** SQLITE_OK on success and a non-zero [error code] on failure. +** +** If either the current value or the highwater mark is too large to +** be represented by a 32-bit integer, then the values returned by +** sqlite3_status() are undefined. +** +** See also: [sqlite3_db_status()] +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); +SQLITE_API int SQLITE_STDCALL sqlite3_status64( + int op, + sqlite3_int64 *pCurrent, + sqlite3_int64 *pHighwater, + int resetFlag +); + + +/* +** CAPI3REF: Status Parameters +** KEYWORDS: {status parameters} +** +** These integer constants designate various run-time status parameters +** that can be returned by [sqlite3_status()]. +** +**
    +** [[SQLITE_STATUS_MEMORY_USED]] ^(
    SQLITE_STATUS_MEMORY_USED
    +**
    This parameter is the current amount of memory checked out +** using [sqlite3_malloc()], either directly or indirectly. The +** figure includes calls made to [sqlite3_malloc()] by the application +** and internal memory usage by the SQLite library. Scratch memory +** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache +** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in +** this parameter. The amount returned is the sum of the allocation +** sizes as reported by the xSize method in [sqlite3_mem_methods].
    )^ +** +** [[SQLITE_STATUS_MALLOC_SIZE]] ^(
    SQLITE_STATUS_MALLOC_SIZE
    +**
    This parameter records the largest memory allocation request +** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their +** internal equivalents). Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.
    )^ +** +** [[SQLITE_STATUS_MALLOC_COUNT]] ^(
    SQLITE_STATUS_MALLOC_COUNT
    +**
    This parameter records the number of separate memory allocations +** currently checked out.
    )^ +** +** [[SQLITE_STATUS_PAGECACHE_USED]] ^(
    SQLITE_STATUS_PAGECACHE_USED
    +**
    This parameter returns the number of pages used out of the +** [pagecache memory allocator] that was configured using +** [SQLITE_CONFIG_PAGECACHE]. The +** value returned is in pages, not in bytes.
    )^ +** +** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]] +** ^(
    SQLITE_STATUS_PAGECACHE_OVERFLOW
    +**
    This parameter returns the number of bytes of page cache +** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] +** buffer and where forced to overflow to [sqlite3_malloc()]. The +** returned value includes allocations that overflowed because they +** where too large (they were larger than the "sz" parameter to +** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because +** no space was left in the page cache.
    )^ +** +** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(
    SQLITE_STATUS_PAGECACHE_SIZE
    +**
    This parameter records the largest memory allocation request +** handed to [pagecache memory allocator]. Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.
    )^ +** +** [[SQLITE_STATUS_SCRATCH_USED]] ^(
    SQLITE_STATUS_SCRATCH_USED
    +**
    This parameter returns the number of allocations used out of the +** [scratch memory allocator] configured using +** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not +** in bytes. Since a single thread may only have one scratch allocation +** outstanding at time, this parameter also reports the number of threads +** using scratch memory at the same time.
    )^ +** +** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(
    SQLITE_STATUS_SCRATCH_OVERFLOW
    +**
    This parameter returns the number of bytes of scratch memory +** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH] +** buffer and where forced to overflow to [sqlite3_malloc()]. The values +** returned include overflows because the requested allocation was too +** larger (that is, because the requested allocation was larger than the +** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer +** slots were available. +**
    )^ +** +** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(
    SQLITE_STATUS_SCRATCH_SIZE
    +**
    This parameter records the largest memory allocation request +** handed to [scratch memory allocator]. Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.
    )^ +** +** [[SQLITE_STATUS_PARSER_STACK]] ^(
    SQLITE_STATUS_PARSER_STACK
    +**
    This parameter records the deepest parser stack. It is only +** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].
    )^ +**
    +** +** New status parameters may be added from time to time. +*/ +#define SQLITE_STATUS_MEMORY_USED 0 +#define SQLITE_STATUS_PAGECACHE_USED 1 +#define SQLITE_STATUS_PAGECACHE_OVERFLOW 2 +#define SQLITE_STATUS_SCRATCH_USED 3 +#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 +#define SQLITE_STATUS_MALLOC_SIZE 5 +#define SQLITE_STATUS_PARSER_STACK 6 +#define SQLITE_STATUS_PAGECACHE_SIZE 7 +#define SQLITE_STATUS_SCRATCH_SIZE 8 +#define SQLITE_STATUS_MALLOC_COUNT 9 + +/* +** CAPI3REF: Database Connection Status +** METHOD: sqlite3 +** +** ^This interface is used to retrieve runtime status information +** about a single [database connection]. ^The first argument is the +** database connection object to be interrogated. ^The second argument +** is an integer constant, taken from the set of +** [SQLITE_DBSTATUS options], that +** determines the parameter to interrogate. The set of +** [SQLITE_DBSTATUS options] is likely +** to grow in future releases of SQLite. +** +** ^The current value of the requested parameter is written into *pCur +** and the highest instantaneous value is written into *pHiwtr. ^If +** the resetFlg is true, then the highest instantaneous value is +** reset back down to the current value. +** +** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a +** non-zero [error code] on failure. +** +** See also: [sqlite3_status()] and [sqlite3_stmt_status()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); + +/* +** CAPI3REF: Status Parameters for database connections +** KEYWORDS: {SQLITE_DBSTATUS options} +** +** These constants are the available integer "verbs" that can be passed as +** the second argument to the [sqlite3_db_status()] interface. +** +** New verbs may be added in future releases of SQLite. Existing verbs +** might be discontinued. Applications should check the return code from +** [sqlite3_db_status()] to make sure that the call worked. +** The [sqlite3_db_status()] interface will return a non-zero error code +** if a discontinued or unsupported verb is invoked. +** +**
    +** [[SQLITE_DBSTATUS_LOOKASIDE_USED]] ^(
    SQLITE_DBSTATUS_LOOKASIDE_USED
    +**
    This parameter returns the number of lookaside memory slots currently +** checked out.
    )^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(
    SQLITE_DBSTATUS_LOOKASIDE_HIT
    +**
    This parameter returns the number malloc attempts that were +** satisfied using lookaside memory. Only the high-water value is meaningful; +** the current value is always zero.)^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]] +** ^(
    SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE
    +**
    This parameter returns the number malloc attempts that might have +** been satisfied using lookaside memory but failed due to the amount of +** memory requested being larger than the lookaside slot size. +** Only the high-water value is meaningful; +** the current value is always zero.)^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]] +** ^(
    SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL
    +**
    This parameter returns the number malloc attempts that might have +** been satisfied using lookaside memory but failed due to all lookaside +** memory already being in use. +** Only the high-water value is meaningful; +** the current value is always zero.)^ +** +** [[SQLITE_DBSTATUS_CACHE_USED]] ^(
    SQLITE_DBSTATUS_CACHE_USED
    +**
    This parameter returns the approximate number of bytes of heap +** memory used by all pager caches associated with the database connection.)^ +** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. +** +** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(
    SQLITE_DBSTATUS_SCHEMA_USED
    +**
    This parameter returns the approximate number of bytes of heap +** memory used to store the schema for all databases associated +** with the connection - main, temp, and any [ATTACH]-ed databases.)^ +** ^The full amount of memory used by the schemas is reported, even if the +** schema memory is shared with other database connections due to +** [shared cache mode] being enabled. +** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0. +** +** [[SQLITE_DBSTATUS_STMT_USED]] ^(
    SQLITE_DBSTATUS_STMT_USED
    +**
    This parameter returns the approximate number of bytes of heap +** and lookaside memory used by all prepared statements associated with +** the database connection.)^ +** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0. +**
    +** +** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(
    SQLITE_DBSTATUS_CACHE_HIT
    +**
    This parameter returns the number of pager cache hits that have +** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT +** is always 0. +**
    +** +** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(
    SQLITE_DBSTATUS_CACHE_MISS
    +**
    This parameter returns the number of pager cache misses that have +** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS +** is always 0. +**
    +** +** [[SQLITE_DBSTATUS_CACHE_WRITE]] ^(
    SQLITE_DBSTATUS_CACHE_WRITE
    +**
    This parameter returns the number of dirty cache entries that have +** been written to disk. Specifically, the number of pages written to the +** wal file in wal mode databases, or the number of pages written to the +** database file in rollback mode databases. Any pages written as part of +** transaction rollback or database recovery operations are not included. +** If an IO or other error occurs while writing a page to disk, the effect +** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The +** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. +**
    +** +** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(
    SQLITE_DBSTATUS_DEFERRED_FKS
    +**
    This parameter returns zero for the current value if and only if +** all foreign key constraints (deferred or immediate) have been +** resolved.)^ ^The highwater mark is always 0. +**
    +**
    +*/ +#define SQLITE_DBSTATUS_LOOKASIDE_USED 0 +#define SQLITE_DBSTATUS_CACHE_USED 1 +#define SQLITE_DBSTATUS_SCHEMA_USED 2 +#define SQLITE_DBSTATUS_STMT_USED 3 +#define SQLITE_DBSTATUS_LOOKASIDE_HIT 4 +#define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5 +#define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6 +#define SQLITE_DBSTATUS_CACHE_HIT 7 +#define SQLITE_DBSTATUS_CACHE_MISS 8 +#define SQLITE_DBSTATUS_CACHE_WRITE 9 +#define SQLITE_DBSTATUS_DEFERRED_FKS 10 +#define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */ + + +/* +** CAPI3REF: Prepared Statement Status +** METHOD: sqlite3_stmt +** +** ^(Each prepared statement maintains various +** [SQLITE_STMTSTATUS counters] that measure the number +** of times it has performed specific operations.)^ These counters can +** be used to monitor the performance characteristics of the prepared +** statements. For example, if the number of table steps greatly exceeds +** the number of table searches or result rows, that would tend to indicate +** that the prepared statement is using a full table scan rather than +** an index. +** +** ^(This interface is used to retrieve and reset counter values from +** a [prepared statement]. The first argument is the prepared statement +** object to be interrogated. The second argument +** is an integer code for a specific [SQLITE_STMTSTATUS counter] +** to be interrogated.)^ +** ^The current value of the requested counter is returned. +** ^If the resetFlg is true, then the counter is reset to zero after this +** interface call returns. +** +** See also: [sqlite3_status()] and [sqlite3_db_status()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); + +/* +** CAPI3REF: Status Parameters for prepared statements +** KEYWORDS: {SQLITE_STMTSTATUS counter} {SQLITE_STMTSTATUS counters} +** +** These preprocessor macros define integer codes that name counter +** values associated with the [sqlite3_stmt_status()] interface. +** The meanings of the various counters are as follows: +** +**
    +** [[SQLITE_STMTSTATUS_FULLSCAN_STEP]]
    SQLITE_STMTSTATUS_FULLSCAN_STEP
    +**
    ^This is the number of times that SQLite has stepped forward in +** a table as part of a full table scan. Large numbers for this counter +** may indicate opportunities for performance improvement through +** careful use of indices.
    +** +** [[SQLITE_STMTSTATUS_SORT]]
    SQLITE_STMTSTATUS_SORT
    +**
    ^This is the number of sort operations that have occurred. +** A non-zero value in this counter may indicate an opportunity to +** improvement performance through careful use of indices.
    +** +** [[SQLITE_STMTSTATUS_AUTOINDEX]]
    SQLITE_STMTSTATUS_AUTOINDEX
    +**
    ^This is the number of rows inserted into transient indices that +** were created automatically in order to help joins run faster. +** A non-zero value in this counter may indicate an opportunity to +** improvement performance by adding permanent indices that do not +** need to be reinitialized each time the statement is run.
    +** +** [[SQLITE_STMTSTATUS_VM_STEP]]
    SQLITE_STMTSTATUS_VM_STEP
    +**
    ^This is the number of virtual machine operations executed +** by the prepared statement if that number is less than or equal +** to 2147483647. The number of virtual machine operations can be +** used as a proxy for the total work done by the prepared statement. +** If the number of virtual machine operations exceeds 2147483647 +** then the value returned by this statement status code is undefined. +**
    +**
    +*/ +#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1 +#define SQLITE_STMTSTATUS_SORT 2 +#define SQLITE_STMTSTATUS_AUTOINDEX 3 +#define SQLITE_STMTSTATUS_VM_STEP 4 + +/* +** CAPI3REF: Custom Page Cache Object +** +** The sqlite3_pcache type is opaque. It is implemented by +** the pluggable module. The SQLite core has no knowledge of +** its size or internal structure and never deals with the +** sqlite3_pcache object except by holding and passing pointers +** to the object. +** +** See [sqlite3_pcache_methods2] for additional information. +*/ +typedef struct sqlite3_pcache sqlite3_pcache; + +/* +** CAPI3REF: Custom Page Cache Object +** +** The sqlite3_pcache_page object represents a single page in the +** page cache. The page cache will allocate instances of this +** object. Various methods of the page cache use pointers to instances +** of this object as parameters or as their return value. +** +** See [sqlite3_pcache_methods2] for additional information. +*/ +typedef struct sqlite3_pcache_page sqlite3_pcache_page; +struct sqlite3_pcache_page { + void *pBuf; /* The content of the page */ + void *pExtra; /* Extra information associated with the page */ +}; + +/* +** CAPI3REF: Application Defined Page Cache. +** KEYWORDS: {page cache} +** +** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE2], ...) interface can +** register an alternative page cache implementation by passing in an +** instance of the sqlite3_pcache_methods2 structure.)^ +** In many applications, most of the heap memory allocated by +** SQLite is used for the page cache. +** By implementing a +** custom page cache using this API, an application can better control +** the amount of memory consumed by SQLite, the way in which +** that memory is allocated and released, and the policies used to +** determine exactly which parts of a database file are cached and for +** how long. +** +** The alternative page cache mechanism is an +** extreme measure that is only needed by the most demanding applications. +** The built-in page cache is recommended for most uses. +** +** ^(The contents of the sqlite3_pcache_methods2 structure are copied to an +** internal buffer by SQLite within the call to [sqlite3_config]. Hence +** the application may discard the parameter after the call to +** [sqlite3_config()] returns.)^ +** +** [[the xInit() page cache method]] +** ^(The xInit() method is called once for each effective +** call to [sqlite3_initialize()])^ +** (usually only once during the lifetime of the process). ^(The xInit() +** method is passed a copy of the sqlite3_pcache_methods2.pArg value.)^ +** The intent of the xInit() method is to set up global data structures +** required by the custom page cache implementation. +** ^(If the xInit() method is NULL, then the +** built-in default page cache is used instead of the application defined +** page cache.)^ +** +** [[the xShutdown() page cache method]] +** ^The xShutdown() method is called by [sqlite3_shutdown()]. +** It can be used to clean up +** any outstanding resources before process shutdown, if required. +** ^The xShutdown() method may be NULL. +** +** ^SQLite automatically serializes calls to the xInit method, +** so the xInit method need not be threadsafe. ^The +** xShutdown method is only called from [sqlite3_shutdown()] so it does +** not need to be threadsafe either. All other methods must be threadsafe +** in multithreaded applications. +** +** ^SQLite will never invoke xInit() more than once without an intervening +** call to xShutdown(). +** +** [[the xCreate() page cache methods]] +** ^SQLite invokes the xCreate() method to construct a new cache instance. +** SQLite will typically create one cache instance for each open database file, +** though this is not guaranteed. ^The +** first parameter, szPage, is the size in bytes of the pages that must +** be allocated by the cache. ^szPage will always a power of two. ^The +** second parameter szExtra is a number of bytes of extra storage +** associated with each page cache entry. ^The szExtra parameter will +** a number less than 250. SQLite will use the +** extra szExtra bytes on each page to store metadata about the underlying +** database page on disk. The value passed into szExtra depends +** on the SQLite version, the target platform, and how SQLite was compiled. +** ^The third argument to xCreate(), bPurgeable, is true if the cache being +** created will be used to cache database pages of a file stored on disk, or +** false if it is used for an in-memory database. The cache implementation +** does not have to do anything special based with the value of bPurgeable; +** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will +** never invoke xUnpin() except to deliberately delete a page. +** ^In other words, calls to xUnpin() on a cache with bPurgeable set to +** false will always have the "discard" flag set to true. +** ^Hence, a cache created with bPurgeable false will +** never contain any unpinned pages. +** +** [[the xCachesize() page cache method]] +** ^(The xCachesize() method may be called at any time by SQLite to set the +** suggested maximum cache-size (number of pages stored by) the cache +** instance passed as the first argument. This is the value configured using +** the SQLite "[PRAGMA cache_size]" command.)^ As with the bPurgeable +** parameter, the implementation is not required to do anything with this +** value; it is advisory only. +** +** [[the xPagecount() page cache methods]] +** The xPagecount() method must return the number of pages currently +** stored in the cache, both pinned and unpinned. +** +** [[the xFetch() page cache methods]] +** The xFetch() method locates a page in the cache and returns a pointer to +** an sqlite3_pcache_page object associated with that page, or a NULL pointer. +** The pBuf element of the returned sqlite3_pcache_page object will be a +** pointer to a buffer of szPage bytes used to store the content of a +** single database page. The pExtra element of sqlite3_pcache_page will be +** a pointer to the szExtra bytes of extra storage that SQLite has requested +** for each entry in the page cache. +** +** The page to be fetched is determined by the key. ^The minimum key value +** is 1. After it has been retrieved using xFetch, the page is considered +** to be "pinned". +** +** If the requested page is already in the page cache, then the page cache +** implementation must return a pointer to the page buffer with its content +** intact. If the requested page is not already in the cache, then the +** cache implementation should use the value of the createFlag +** parameter to help it determined what action to take: +** +** +**
    createFlag Behavior when page is not already in cache +**
    0 Do not allocate a new page. Return NULL. +**
    1 Allocate a new page if it easy and convenient to do so. +** Otherwise return NULL. +**
    2 Make every effort to allocate a new page. Only return +** NULL if allocating a new page is effectively impossible. +**
    +** +** ^(SQLite will normally invoke xFetch() with a createFlag of 0 or 1. SQLite +** will only use a createFlag of 2 after a prior call with a createFlag of 1 +** failed.)^ In between the to xFetch() calls, SQLite may +** attempt to unpin one or more cache pages by spilling the content of +** pinned pages to disk and synching the operating system disk cache. +** +** [[the xUnpin() page cache method]] +** ^xUnpin() is called by SQLite with a pointer to a currently pinned page +** as its second argument. If the third parameter, discard, is non-zero, +** then the page must be evicted from the cache. +** ^If the discard parameter is +** zero, then the page may be discarded or retained at the discretion of +** page cache implementation. ^The page cache implementation +** may choose to evict unpinned pages at any time. +** +** The cache must not perform any reference counting. A single +** call to xUnpin() unpins the page regardless of the number of prior calls +** to xFetch(). +** +** [[the xRekey() page cache methods]] +** The xRekey() method is used to change the key value associated with the +** page passed as the second argument. If the cache +** previously contains an entry associated with newKey, it must be +** discarded. ^Any prior cache entry associated with newKey is guaranteed not +** to be pinned. +** +** When SQLite calls the xTruncate() method, the cache must discard all +** existing cache entries with page numbers (keys) greater than or equal +** to the value of the iLimit parameter passed to xTruncate(). If any +** of these pages are pinned, they are implicitly unpinned, meaning that +** they can be safely discarded. +** +** [[the xDestroy() page cache method]] +** ^The xDestroy() method is used to delete a cache allocated by xCreate(). +** All resources associated with the specified cache should be freed. ^After +** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*] +** handle invalid, and will not use it with any other sqlite3_pcache_methods2 +** functions. +** +** [[the xShrink() page cache method]] +** ^SQLite invokes the xShrink() method when it wants the page cache to +** free up as much of heap memory as possible. The page cache implementation +** is not obligated to free any memory, but well-behaved implementations should +** do their best. +*/ +typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2; +struct sqlite3_pcache_methods2 { + int iVersion; + void *pArg; + int (*xInit)(void*); + void (*xShutdown)(void*); + sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard); + void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, + unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); + void (*xShrink)(sqlite3_pcache*); +}; + +/* +** This is the obsolete pcache_methods object that has now been replaced +** by sqlite3_pcache_methods2. This object is not used by SQLite. It is +** retained in the header file for backwards compatibility only. +*/ +typedef struct sqlite3_pcache_methods sqlite3_pcache_methods; +struct sqlite3_pcache_methods { + void *pArg; + int (*xInit)(void*); + void (*xShutdown)(void*); + sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + void *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, void*, int discard); + void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); +}; + + +/* +** CAPI3REF: Online Backup Object +** +** The sqlite3_backup object records state information about an ongoing +** online backup operation. ^The sqlite3_backup object is created by +** a call to [sqlite3_backup_init()] and is destroyed by a call to +** [sqlite3_backup_finish()]. +** +** See Also: [Using the SQLite Online Backup API] +*/ +typedef struct sqlite3_backup sqlite3_backup; + +/* +** CAPI3REF: Online Backup API. +** +** The backup API copies the content of one database into another. +** It is useful either for creating backups of databases or +** for copying in-memory databases to or from persistent files. +** +** See Also: [Using the SQLite Online Backup API] +** +** ^SQLite holds a write transaction open on the destination database file +** for the duration of the backup operation. +** ^The source database is read-locked only while it is being read; +** it is not locked continuously for the entire backup operation. +** ^Thus, the backup may be performed on a live source database without +** preventing other database connections from +** reading or writing to the source database while the backup is underway. +** +** ^(To perform a backup operation: +**
      +**
    1. sqlite3_backup_init() is called once to initialize the +** backup, +**
    2. sqlite3_backup_step() is called one or more times to transfer +** the data between the two databases, and finally +**
    3. sqlite3_backup_finish() is called to release all resources +** associated with the backup operation. +**
    )^ +** There should be exactly one call to sqlite3_backup_finish() for each +** successful call to sqlite3_backup_init(). +** +** [[sqlite3_backup_init()]] sqlite3_backup_init() +** +** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the +** [database connection] associated with the destination database +** and the database name, respectively. +** ^The database name is "main" for the main database, "temp" for the +** temporary database, or the name specified after the AS keyword in +** an [ATTACH] statement for an attached database. +** ^The S and M arguments passed to +** sqlite3_backup_init(D,N,S,M) identify the [database connection] +** and database name of the source database, respectively. +** ^The source and destination [database connections] (parameters S and D) +** must be different or else sqlite3_backup_init(D,N,S,M) will fail with +** an error. +** +** ^A call to sqlite3_backup_init() will fail, returning SQLITE_ERROR, if +** there is already a read or read-write transaction open on the +** destination database. +** +** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is +** returned and an error code and error message are stored in the +** destination [database connection] D. +** ^The error code and message for the failed call to sqlite3_backup_init() +** can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or +** [sqlite3_errmsg16()] functions. +** ^A successful call to sqlite3_backup_init() returns a pointer to an +** [sqlite3_backup] object. +** ^The [sqlite3_backup] object may be used with the sqlite3_backup_step() and +** sqlite3_backup_finish() functions to perform the specified backup +** operation. +** +** [[sqlite3_backup_step()]] sqlite3_backup_step() +** +** ^Function sqlite3_backup_step(B,N) will copy up to N pages between +** the source and destination databases specified by [sqlite3_backup] object B. +** ^If N is negative, all remaining source pages are copied. +** ^If sqlite3_backup_step(B,N) successfully copies N pages and there +** are still more pages to be copied, then the function returns [SQLITE_OK]. +** ^If sqlite3_backup_step(B,N) successfully finishes copying all pages +** from source to destination, then it returns [SQLITE_DONE]. +** ^If an error occurs while running sqlite3_backup_step(B,N), +** then an [error code] is returned. ^As well as [SQLITE_OK] and +** [SQLITE_DONE], a call to sqlite3_backup_step() may return [SQLITE_READONLY], +** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an +** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code. +** +** ^(The sqlite3_backup_step() might return [SQLITE_READONLY] if +**
      +**
    1. the destination database was opened read-only, or +**
    2. the destination database is using write-ahead-log journaling +** and the destination and source page sizes differ, or +**
    3. the destination database is an in-memory database and the +** destination and source page sizes differ. +**
    )^ +** +** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then +** the [sqlite3_busy_handler | busy-handler function] +** is invoked (if one is specified). ^If the +** busy-handler returns non-zero before the lock is available, then +** [SQLITE_BUSY] is returned to the caller. ^In this case the call to +** sqlite3_backup_step() can be retried later. ^If the source +** [database connection] +** is being used to write to the source database when sqlite3_backup_step() +** is called, then [SQLITE_LOCKED] is returned immediately. ^Again, in this +** case the call to sqlite3_backup_step() can be retried later on. ^(If +** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or +** [SQLITE_READONLY] is returned, then +** there is no point in retrying the call to sqlite3_backup_step(). These +** errors are considered fatal.)^ The application must accept +** that the backup operation has failed and pass the backup operation handle +** to the sqlite3_backup_finish() to release associated resources. +** +** ^The first call to sqlite3_backup_step() obtains an exclusive lock +** on the destination file. ^The exclusive lock is not released until either +** sqlite3_backup_finish() is called or the backup operation is complete +** and sqlite3_backup_step() returns [SQLITE_DONE]. ^Every call to +** sqlite3_backup_step() obtains a [shared lock] on the source database that +** lasts for the duration of the sqlite3_backup_step() call. +** ^Because the source database is not locked between calls to +** sqlite3_backup_step(), the source database may be modified mid-way +** through the backup process. ^If the source database is modified by an +** external process or via a database connection other than the one being +** used by the backup operation, then the backup will be automatically +** restarted by the next call to sqlite3_backup_step(). ^If the source +** database is modified by the using the same database connection as is used +** by the backup operation, then the backup database is automatically +** updated at the same time. +** +** [[sqlite3_backup_finish()]] sqlite3_backup_finish() +** +** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the +** application wishes to abandon the backup operation, the application +** should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish(). +** ^The sqlite3_backup_finish() interfaces releases all +** resources associated with the [sqlite3_backup] object. +** ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any +** active write-transaction on the destination database is rolled back. +** The [sqlite3_backup] object is invalid +** and may not be used following a call to sqlite3_backup_finish(). +** +** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no +** sqlite3_backup_step() errors occurred, regardless or whether or not +** sqlite3_backup_step() completed. +** ^If an out-of-memory condition or IO error occurred during any prior +** sqlite3_backup_step() call on the same [sqlite3_backup] object, then +** sqlite3_backup_finish() returns the corresponding [error code]. +** +** ^A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from sqlite3_backup_step() +** is not a permanent error and does not affect the return value of +** sqlite3_backup_finish(). +** +** [[sqlite3_backup_remaining()]] [[sqlite3_backup_pagecount()]] +** sqlite3_backup_remaining() and sqlite3_backup_pagecount() +** +** ^The sqlite3_backup_remaining() routine returns the number of pages still +** to be backed up at the conclusion of the most recent sqlite3_backup_step(). +** ^The sqlite3_backup_pagecount() routine returns the total number of pages +** in the source database at the conclusion of the most recent +** sqlite3_backup_step(). +** ^(The values returned by these functions are only updated by +** sqlite3_backup_step(). If the source database is modified in a way that +** changes the size of the source database or the number of pages remaining, +** those changes are not reflected in the output of sqlite3_backup_pagecount() +** and sqlite3_backup_remaining() until after the next +** sqlite3_backup_step().)^ +** +** Concurrent Usage of Database Handles +** +** ^The source [database connection] may be used by the application for other +** purposes while a backup operation is underway or being initialized. +** ^If SQLite is compiled and configured to support threadsafe database +** connections, then the source database connection may be used concurrently +** from within other threads. +** +** However, the application must guarantee that the destination +** [database connection] is not passed to any other API (by any thread) after +** sqlite3_backup_init() is called and before the corresponding call to +** sqlite3_backup_finish(). SQLite does not currently check to see +** if the application incorrectly accesses the destination [database connection] +** and so no error code is reported, but the operations may malfunction +** nevertheless. Use of the destination database connection while a +** backup is in progress might also also cause a mutex deadlock. +** +** If running in [shared cache mode], the application must +** guarantee that the shared cache used by the destination database +** is not accessed while the backup is running. In practice this means +** that the application must guarantee that the disk file being +** backed up to is not accessed by any connection within the process, +** not just the specific connection that was passed to sqlite3_backup_init(). +** +** The [sqlite3_backup] object itself is partially threadsafe. Multiple +** threads may safely make multiple concurrent calls to sqlite3_backup_step(). +** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount() +** APIs are not strictly speaking threadsafe. If they are invoked at the +** same time as another thread is invoking sqlite3_backup_step() it is +** possible that they return invalid values. +*/ +SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init( + sqlite3 *pDest, /* Destination database handle */ + const char *zDestName, /* Destination database name */ + sqlite3 *pSource, /* Source database handle */ + const char *zSourceName /* Source database name */ +); +SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage); +SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p); +SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p); +SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p); + +/* +** CAPI3REF: Unlock Notification +** METHOD: sqlite3 +** +** ^When running in shared-cache mode, a database operation may fail with +** an [SQLITE_LOCKED] error if the required locks on the shared-cache or +** individual tables within the shared-cache cannot be obtained. See +** [SQLite Shared-Cache Mode] for a description of shared-cache locking. +** ^This API may be used to register a callback that SQLite will invoke +** when the connection currently holding the required lock relinquishes it. +** ^This API is only available if the library was compiled with the +** [SQLITE_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined. +** +** See Also: [Using the SQLite Unlock Notification Feature]. +** +** ^Shared-cache locks are released when a database connection concludes +** its current transaction, either by committing it or rolling it back. +** +** ^When a connection (known as the blocked connection) fails to obtain a +** shared-cache lock and SQLITE_LOCKED is returned to the caller, the +** identity of the database connection (the blocking connection) that +** has locked the required resource is stored internally. ^After an +** application receives an SQLITE_LOCKED error, it may call the +** sqlite3_unlock_notify() method with the blocked connection handle as +** the first argument to register for a callback that will be invoked +** when the blocking connections current transaction is concluded. ^The +** callback is invoked from within the [sqlite3_step] or [sqlite3_close] +** call that concludes the blocking connections transaction. +** +** ^(If sqlite3_unlock_notify() is called in a multi-threaded application, +** there is a chance that the blocking connection will have already +** concluded its transaction by the time sqlite3_unlock_notify() is invoked. +** If this happens, then the specified callback is invoked immediately, +** from within the call to sqlite3_unlock_notify().)^ +** +** ^If the blocked connection is attempting to obtain a write-lock on a +** shared-cache table, and more than one other connection currently holds +** a read-lock on the same table, then SQLite arbitrarily selects one of +** the other connections to use as the blocking connection. +** +** ^(There may be at most one unlock-notify callback registered by a +** blocked connection. If sqlite3_unlock_notify() is called when the +** blocked connection already has a registered unlock-notify callback, +** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is +** called with a NULL pointer as its second argument, then any existing +** unlock-notify callback is canceled. ^The blocked connections +** unlock-notify callback may also be canceled by closing the blocked +** connection using [sqlite3_close()]. +** +** The unlock-notify callback is not reentrant. If an application invokes +** any sqlite3_xxx API functions from within an unlock-notify callback, a +** crash or deadlock may be the result. +** +** ^Unless deadlock is detected (see below), sqlite3_unlock_notify() always +** returns SQLITE_OK. +** +** Callback Invocation Details +** +** When an unlock-notify callback is registered, the application provides a +** single void* pointer that is passed to the callback when it is invoked. +** However, the signature of the callback function allows SQLite to pass +** it an array of void* context pointers. The first argument passed to +** an unlock-notify callback is a pointer to an array of void* pointers, +** and the second is the number of entries in the array. +** +** When a blocking connections transaction is concluded, there may be +** more than one blocked connection that has registered for an unlock-notify +** callback. ^If two or more such blocked connections have specified the +** same callback function, then instead of invoking the callback function +** multiple times, it is invoked once with the set of void* context pointers +** specified by the blocked connections bundled together into an array. +** This gives the application an opportunity to prioritize any actions +** related to the set of unblocked database connections. +** +** Deadlock Detection +** +** Assuming that after registering for an unlock-notify callback a +** database waits for the callback to be issued before taking any further +** action (a reasonable assumption), then using this API may cause the +** application to deadlock. For example, if connection X is waiting for +** connection Y's transaction to be concluded, and similarly connection +** Y is waiting on connection X's transaction, then neither connection +** will proceed and the system may remain deadlocked indefinitely. +** +** To avoid this scenario, the sqlite3_unlock_notify() performs deadlock +** detection. ^If a given call to sqlite3_unlock_notify() would put the +** system in a deadlocked state, then SQLITE_LOCKED is returned and no +** unlock-notify callback is registered. The system is said to be in +** a deadlocked state if connection A has registered for an unlock-notify +** callback on the conclusion of connection B's transaction, and connection +** B has itself registered for an unlock-notify callback when connection +** A's transaction is concluded. ^Indirect deadlock is also detected, so +** the system is also considered to be deadlocked if connection B has +** registered for an unlock-notify callback on the conclusion of connection +** C's transaction, where connection C is waiting on connection A. ^Any +** number of levels of indirection are allowed. +** +** The "DROP TABLE" Exception +** +** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost +** always appropriate to call sqlite3_unlock_notify(). There is however, +** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement, +** SQLite checks if there are any currently executing SELECT statements +** that belong to the same connection. If there are, SQLITE_LOCKED is +** returned. In this case there is no "blocking connection", so invoking +** sqlite3_unlock_notify() results in the unlock-notify callback being +** invoked immediately. If the application then re-attempts the "DROP TABLE" +** or "DROP INDEX" query, an infinite loop might be the result. +** +** One way around this problem is to check the extended error code returned +** by an sqlite3_step() call. ^(If there is a blocking connection, then the +** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in +** the special "DROP TABLE/INDEX" case, the extended error code is just +** SQLITE_LOCKED.)^ +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify( + sqlite3 *pBlocked, /* Waiting connection */ + void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */ + void *pNotifyArg /* Argument to pass to xNotify */ +); + + +/* +** CAPI3REF: String Comparison +** +** ^The [sqlite3_stricmp()] and [sqlite3_strnicmp()] APIs allow applications +** and extensions to compare the contents of two buffers containing UTF-8 +** strings in a case-independent fashion, using the same definition of "case +** independence" that SQLite uses internally when comparing identifiers. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *, const char *); +SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *, const char *, int); + +/* +** CAPI3REF: String Globbing +* +** ^The [sqlite3_strglob(P,X)] interface returns zero if string X matches +** the glob pattern P, and it returns non-zero if string X does not match +** the glob pattern P. ^The definition of glob pattern matching used in +** [sqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the +** SQL dialect used by SQLite. ^The sqlite3_strglob(P,X) function is case +** sensitive. +** +** Note that this routine returns zero on a match and non-zero if the strings +** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlob, const char *zStr); + +/* +** CAPI3REF: Error Logging Interface +** +** ^The [sqlite3_log()] interface writes a message into the [error log] +** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()]. +** ^If logging is enabled, the zFormat string and subsequent arguments are +** used with [sqlite3_snprintf()] to generate the final output string. +** +** The sqlite3_log() interface is intended for use by extensions such as +** virtual tables, collating functions, and SQL functions. While there is +** nothing to prevent an application from calling sqlite3_log(), doing so +** is considered bad form. +** +** The zFormat string must not be NULL. +** +** To avoid deadlocks and other threading problems, the sqlite3_log() routine +** will not use dynamically allocated memory. The log message is stored in +** a fixed-length buffer on the stack. If the log message is longer than +** a few hundred characters, it will be truncated to the length of the +** buffer. +*/ +SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...); + +/* +** CAPI3REF: Write-Ahead Log Commit Hook +** METHOD: sqlite3 +** +** ^The [sqlite3_wal_hook()] function is used to register a callback that +** is invoked each time data is committed to a database in wal mode. +** +** ^(The callback is invoked by SQLite after the commit has taken place and +** the associated write-lock on the database released)^, so the implementation +** may read, write or [checkpoint] the database as required. +** +** ^The first parameter passed to the callback function when it is invoked +** is a copy of the third parameter passed to sqlite3_wal_hook() when +** registering the callback. ^The second is a copy of the database handle. +** ^The third parameter is the name of the database that was written to - +** either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter +** is the number of pages currently in the write-ahead log file, +** including those that were just committed. +** +** The callback function should normally return [SQLITE_OK]. ^If an error +** code is returned, that error will propagate back up through the +** SQLite code base to cause the statement that provoked the callback +** to report an error, though the commit will have still occurred. If the +** callback returns [SQLITE_ROW] or [SQLITE_DONE], or if it returns a value +** that does not correspond to any valid SQLite error code, the results +** are undefined. +** +** A single database handle may have at most a single write-ahead log callback +** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any +** previously registered write-ahead log callback. ^Note that the +** [sqlite3_wal_autocheckpoint()] interface and the +** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will +** those overwrite any prior [sqlite3_wal_hook()] settings. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook( + sqlite3*, + int(*)(void *,sqlite3*,const char*,int), + void* +); + +/* +** CAPI3REF: Configure an auto-checkpoint +** METHOD: sqlite3 +** +** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around +** [sqlite3_wal_hook()] that causes any database on [database connection] D +** to automatically [checkpoint] +** after committing a transaction if there are N or +** more frames in the [write-ahead log] file. ^Passing zero or +** a negative value as the nFrame parameter disables automatic +** checkpoints entirely. +** +** ^The callback registered by this function replaces any existing callback +** registered using [sqlite3_wal_hook()]. ^Likewise, registering a callback +** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism +** configured by this function. +** +** ^The [wal_autocheckpoint pragma] can be used to invoke this interface +** from SQL. +** +** ^Checkpoints initiated by this mechanism are +** [sqlite3_wal_checkpoint_v2|PASSIVE]. +** +** ^Every new [database connection] defaults to having the auto-checkpoint +** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] +** pages. The use of this interface +** is only necessary if the default setting is found to be suboptimal +** for a particular application. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int N); + +/* +** CAPI3REF: Checkpoint a database +** METHOD: sqlite3 +** +** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to +** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^ +** +** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the +** [write-ahead log] for database X on [database connection] D to be +** transferred into the database file and for the write-ahead log to +** be reset. See the [checkpointing] documentation for addition +** information. +** +** This interface used to be the only way to cause a checkpoint to +** occur. But then the newer and more powerful [sqlite3_wal_checkpoint_v2()] +** interface was added. This interface is retained for backwards +** compatibility and as a convenience for applications that need to manually +** start a callback but which do not need the full power (and corresponding +** complication) of [sqlite3_wal_checkpoint_v2()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); + +/* +** CAPI3REF: Checkpoint a database +** METHOD: sqlite3 +** +** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint +** operation on database X of [database connection] D in mode M. Status +** information is written back into integers pointed to by L and C.)^ +** ^(The M parameter must be a valid [checkpoint mode]:)^ +** +**
    +**
    SQLITE_CHECKPOINT_PASSIVE
    +** ^Checkpoint as many frames as possible without waiting for any database +** readers or writers to finish, then sync the database file if all frames +** in the log were checkpointed. ^The [busy-handler callback] +** is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode. +** ^On the other hand, passive mode might leave the checkpoint unfinished +** if there are concurrent readers or writers. +** +**
    SQLITE_CHECKPOINT_FULL
    +** ^This mode blocks (it invokes the +** [sqlite3_busy_handler|busy-handler callback]) until there is no +** database writer and all readers are reading from the most recent database +** snapshot. ^It then checkpoints all frames in the log file and syncs the +** database file. ^This mode blocks new database writers while it is pending, +** but new database readers are allowed to continue unimpeded. +** +**
    SQLITE_CHECKPOINT_RESTART
    +** ^This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition +** that after checkpointing the log file it blocks (calls the +** [busy-handler callback]) +** until all readers are reading from the database file only. ^This ensures +** that the next writer will restart the log file from the beginning. +** ^Like SQLITE_CHECKPOINT_FULL, this mode blocks new +** database writer attempts while it is pending, but does not impede readers. +** +**
    SQLITE_CHECKPOINT_TRUNCATE
    +** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the +** addition that it also truncates the log file to zero bytes just prior +** to a successful return. +**
    +** +** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in +** the log file or to -1 if the checkpoint could not run because +** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not +** NULL,then *pnCkpt is set to the total number of checkpointed frames in the +** log file (including any that were already checkpointed before the function +** was called) or to -1 if the checkpoint could not run due to an error or +** because the database is not in WAL mode. ^Note that upon successful +** completion of an SQLITE_CHECKPOINT_TRUNCATE, the log file will have been +** truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero. +** +** ^All calls obtain an exclusive "checkpoint" lock on the database file. ^If +** any other process is running a checkpoint operation at the same time, the +** lock cannot be obtained and SQLITE_BUSY is returned. ^Even if there is a +** busy-handler configured, it will not be invoked in this case. +** +** ^The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the +** exclusive "writer" lock on the database file. ^If the writer lock cannot be +** obtained immediately, and a busy-handler is configured, it is invoked and +** the writer lock retried until either the busy-handler returns 0 or the lock +** is successfully obtained. ^The busy-handler is also invoked while waiting for +** database readers as described above. ^If the busy-handler returns 0 before +** the writer lock is obtained or while waiting for database readers, the +** checkpoint operation proceeds from that point in the same way as +** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible +** without blocking any further. ^SQLITE_BUSY is returned in this case. +** +** ^If parameter zDb is NULL or points to a zero length string, then the +** specified operation is attempted on all WAL databases [attached] to +** [database connection] db. In this case the +** values written to output parameters *pnLog and *pnCkpt are undefined. ^If +** an SQLITE_BUSY error is encountered when processing one or more of the +** attached WAL databases, the operation is still attempted on any remaining +** attached databases and SQLITE_BUSY is returned at the end. ^If any other +** error occurs while processing an attached database, processing is abandoned +** and the error code is returned to the caller immediately. ^If no error +** (SQLITE_BUSY or otherwise) is encountered while processing the attached +** databases, SQLITE_OK is returned. +** +** ^If database zDb is the name of an attached database that is not in WAL +** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. ^If +** zDb is not NULL (or a zero length string) and is not the name of any +** attached database, SQLITE_ERROR is returned to the caller. +** +** ^Unless it returns SQLITE_MISUSE, +** the sqlite3_wal_checkpoint_v2() interface +** sets the error information that is queried by +** [sqlite3_errcode()] and [sqlite3_errmsg()]. +** +** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface +** from SQL. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Name of attached database (or NULL) */ + int eMode, /* SQLITE_CHECKPOINT_* value */ + int *pnLog, /* OUT: Size of WAL log in frames */ + int *pnCkpt /* OUT: Total number of frames checkpointed */ +); + +/* +** CAPI3REF: Checkpoint Mode Values +** KEYWORDS: {checkpoint mode} +** +** These constants define all valid values for the "checkpoint mode" passed +** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface. +** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the +** meaning of each of these checkpoint modes. +*/ +#define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */ +#define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */ +#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for for readers */ +#define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */ + +/* +** CAPI3REF: Virtual Table Interface Configuration +** +** This function may be called by either the [xConnect] or [xCreate] method +** of a [virtual table] implementation to configure +** various facets of the virtual table interface. +** +** If this interface is invoked outside the context of an xConnect or +** xCreate virtual table method then the behavior is undefined. +** +** At present, there is only one option that may be configured using +** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options +** may be added in the future. +*/ +SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3*, int op, ...); + +/* +** CAPI3REF: Virtual Table Configuration Options +** +** These macros define the various options to the +** [sqlite3_vtab_config()] interface that [virtual table] implementations +** can use to customize and optimize their behavior. +** +**
    +**
    SQLITE_VTAB_CONSTRAINT_SUPPORT +**
    Calls of the form +** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported, +** where X is an integer. If X is zero, then the [virtual table] whose +** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not +** support constraints. In this configuration (which is the default) if +** a call to the [xUpdate] method returns [SQLITE_CONSTRAINT], then the entire +** statement is rolled back as if [ON CONFLICT | OR ABORT] had been +** specified as part of the users SQL statement, regardless of the actual +** ON CONFLICT mode specified. +** +** If X is non-zero, then the virtual table implementation guarantees +** that if [xUpdate] returns [SQLITE_CONSTRAINT], it will do so before +** any modifications to internal or persistent data structures have been made. +** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite +** is able to roll back a statement or database transaction, and abandon +** or continue processing the current SQL statement as appropriate. +** If the ON CONFLICT mode is REPLACE and the [xUpdate] method returns +** [SQLITE_CONSTRAINT], SQLite handles this as if the ON CONFLICT mode +** had been ABORT. +** +** Virtual table implementations that are required to handle OR REPLACE +** must do so within the [xUpdate] method. If a call to the +** [sqlite3_vtab_on_conflict()] function indicates that the current ON +** CONFLICT policy is REPLACE, the virtual table implementation should +** silently replace the appropriate rows within the xUpdate callback and +** return SQLITE_OK. Or, if this is not possible, it may return +** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT +** constraint handling. +**
    +*/ +#define SQLITE_VTAB_CONSTRAINT_SUPPORT 1 + +/* +** CAPI3REF: Determine The Virtual Table Conflict Policy +** +** This function may only be called from within a call to the [xUpdate] method +** of a [virtual table] implementation for an INSERT or UPDATE operation. ^The +** value returned is one of [SQLITE_ROLLBACK], [SQLITE_IGNORE], [SQLITE_FAIL], +** [SQLITE_ABORT], or [SQLITE_REPLACE], according to the [ON CONFLICT] mode +** of the SQL statement that triggered the call to the [xUpdate] method of the +** [virtual table]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *); + +/* +** CAPI3REF: Conflict resolution modes +** KEYWORDS: {conflict resolution mode} +** +** These constants are returned by [sqlite3_vtab_on_conflict()] to +** inform a [virtual table] implementation what the [ON CONFLICT] mode +** is for the SQL statement being evaluated. +** +** Note that the [SQLITE_IGNORE] constant is also used as a potential +** return value from the [sqlite3_set_authorizer()] callback and that +** [SQLITE_ABORT] is also a [result code]. +*/ +#define SQLITE_ROLLBACK 1 +/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */ +#define SQLITE_FAIL 3 +/* #define SQLITE_ABORT 4 // Also an error code */ +#define SQLITE_REPLACE 5 + +/* +** CAPI3REF: Prepared Statement Scan Status Opcodes +** KEYWORDS: {scanstatus options} +** +** The following constants can be used for the T parameter to the +** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a +** different metric for sqlite3_stmt_scanstatus() to return. +** +** When the value returned to V is a string, space to hold that string is +** managed by the prepared statement S and will be automatically freed when +** S is finalized. +** +**
    +** [[SQLITE_SCANSTAT_NLOOP]]
    SQLITE_SCANSTAT_NLOOP
    +**
    ^The [sqlite3_int64] variable pointed to by the T parameter will be +** set to the total number of times that the X-th loop has run.
    +** +** [[SQLITE_SCANSTAT_NVISIT]]
    SQLITE_SCANSTAT_NVISIT
    +**
    ^The [sqlite3_int64] variable pointed to by the T parameter will be set +** to the total number of rows examined by all iterations of the X-th loop.
    +** +** [[SQLITE_SCANSTAT_EST]]
    SQLITE_SCANSTAT_EST
    +**
    ^The "double" variable pointed to by the T parameter will be set to the +** query planner's estimate for the average number of rows output from each +** iteration of the X-th loop. If the query planner's estimates was accurate, +** then this value will approximate the quotient NVISIT/NLOOP and the +** product of this value for all prior loops with the same SELECTID will +** be the NLOOP value for the current loop. +** +** [[SQLITE_SCANSTAT_NAME]]
    SQLITE_SCANSTAT_NAME
    +**
    ^The "const char *" variable pointed to by the T parameter will be set +** to a zero-terminated UTF-8 string containing the name of the index or table +** used for the X-th loop. +** +** [[SQLITE_SCANSTAT_EXPLAIN]]
    SQLITE_SCANSTAT_EXPLAIN
    +**
    ^The "const char *" variable pointed to by the T parameter will be set +** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] +** description for the X-th loop. +** +** [[SQLITE_SCANSTAT_SELECTID]]
    SQLITE_SCANSTAT_SELECT
    +**
    ^The "int" variable pointed to by the T parameter will be set to the +** "select-id" for the X-th loop. The select-id identifies which query or +** subquery the loop is part of. The main query has a select-id of zero. +** The select-id is the same value as is output in the first column +** of an [EXPLAIN QUERY PLAN] query. +**
    +*/ +#define SQLITE_SCANSTAT_NLOOP 0 +#define SQLITE_SCANSTAT_NVISIT 1 +#define SQLITE_SCANSTAT_EST 2 +#define SQLITE_SCANSTAT_NAME 3 +#define SQLITE_SCANSTAT_EXPLAIN 4 +#define SQLITE_SCANSTAT_SELECTID 5 + +/* +** CAPI3REF: Prepared Statement Scan Status +** METHOD: sqlite3_stmt +** +** This interface returns information about the predicted and measured +** performance for pStmt. Advanced applications can use this +** interface to compare the predicted and the measured performance and +** issue warnings and/or rerun [ANALYZE] if discrepancies are found. +** +** Since this interface is expected to be rarely used, it is only +** available if SQLite is compiled using the [SQLITE_ENABLE_STMT_SCANSTATUS] +** compile-time option. +** +** The "iScanStatusOp" parameter determines which status information to return. +** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior +** of this interface is undefined. +** ^The requested measurement is written into a variable pointed to by +** the "pOut" parameter. +** Parameter "idx" identifies the specific loop to retrieve statistics for. +** Loops are numbered starting from zero. ^If idx is out of range - less than +** zero or greater than or equal to the total number of loops used to implement +** the statement - a non-zero value is returned and the variable that pOut +** points to is unchanged. +** +** ^Statistics might not be available for all loops in all statements. ^In cases +** where there exist loops with no available statistics, this function behaves +** as if the loop did not exist - it returns non-zero and leave the variable +** that pOut points to unchanged. +** +** See also: [sqlite3_stmt_scanstatus_reset()] +*/ +SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_stmt_scanstatus( + sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ + int idx, /* Index of loop to report on */ + int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ + void *pOut /* Result written here */ +); + +/* +** CAPI3REF: Zero Scan-Status Counters +** METHOD: sqlite3_stmt +** +** ^Zero all [sqlite3_stmt_scanstatus()] related event counters. +** +** This API is only available if the library is built with pre-processor +** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined. +*/ +SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); + + +/* +** 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 + +#if 0 +} /* End of the 'extern "C"' block */ +#endif +#endif /* _SQLITE3_H_ */ + +/* +** 2010 August 30 +** +** 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. +** +************************************************************************* +*/ + +#ifndef _SQLITE3RTREE_H_ +#define _SQLITE3RTREE_H_ + + +#if 0 +extern "C" { +#endif + +typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry; +typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info; + +/* The double-precision datatype used by RTree depends on the +** SQLITE_RTREE_INT_ONLY compile-time option. +*/ +#ifdef SQLITE_RTREE_INT_ONLY + typedef sqlite3_int64 sqlite3_rtree_dbl; +#else + typedef double sqlite3_rtree_dbl; +#endif + +/* +** Register a geometry callback named zGeom that can be used as part of an +** R-Tree geometry query as follows: +** +** SELECT ... FROM WHERE MATCH $zGeom(... params ...) +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback( + sqlite3 *db, + const char *zGeom, + int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*), + void *pContext +); + + +/* +** A pointer to a structure of the following type is passed as the first +** argument to callbacks registered using rtree_geometry_callback(). +*/ +struct sqlite3_rtree_geometry { + void *pContext; /* Copy of pContext passed to s_r_g_c() */ + int nParam; /* Size of array aParam[] */ + sqlite3_rtree_dbl *aParam; /* Parameters passed to SQL geom function */ + void *pUser; /* Callback implementation user data */ + void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */ +}; + +/* +** Register a 2nd-generation geometry callback named zScore that can be +** used as part of an R-Tree geometry query as follows: +** +** SELECT ... FROM WHERE MATCH $zQueryFunc(... params ...) +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback( + sqlite3 *db, + const char *zQueryFunc, + int (*xQueryFunc)(sqlite3_rtree_query_info*), + void *pContext, + void (*xDestructor)(void*) +); + + +/* +** A pointer to a structure of the following type is passed as the +** argument to scored geometry callback registered using +** sqlite3_rtree_query_callback(). +** +** Note that the first 5 fields of this structure are identical to +** sqlite3_rtree_geometry. This structure is a subclass of +** sqlite3_rtree_geometry. +*/ +struct sqlite3_rtree_query_info { + void *pContext; /* pContext from when function registered */ + int nParam; /* Number of function parameters */ + sqlite3_rtree_dbl *aParam; /* value of function parameters */ + void *pUser; /* callback can use this, if desired */ + void (*xDelUser)(void*); /* function to free pUser */ + sqlite3_rtree_dbl *aCoord; /* Coordinates of node or entry to check */ + unsigned int *anQueue; /* Number of pending entries in the queue */ + int nCoord; /* Number of coordinates */ + int iLevel; /* Level of current node or entry */ + int mxLevel; /* The largest iLevel value in the tree */ + sqlite3_int64 iRowid; /* Rowid for current entry */ + sqlite3_rtree_dbl rParentScore; /* Score of parent node */ + int eParentWithin; /* Visibility of parent node */ + int eWithin; /* OUT: Visiblity */ + sqlite3_rtree_dbl rScore; /* OUT: Write the score here */ +}; + +/* +** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin. +*/ +#define NOT_WITHIN 0 /* Object completely outside of query region */ +#define PARTLY_WITHIN 1 /* Object partially overlaps query region */ +#define FULLY_WITHIN 2 /* Object fully contained within query region */ + + +#if 0 +} /* end of the 'extern "C"' block */ +#endif + +#endif /* ifndef _SQLITE3RTREE_H_ */ + + +/************** End of sqlite3.h *********************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ + +/* +** Include the configuration header output by 'configure' if we're using the +** autoconf-based build +*/ +#ifdef _HAVE_SQLITE_CONFIG_H +#include "config.h" +#endif + +/************** Include sqliteLimit.h in the middle of sqliteInt.h ***********/ +/************** Begin file sqliteLimit.h *************************************/ +/* +** 2007 May 7 +** +** 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 defines various limits of what SQLite can process. +*/ + +/* +** The maximum length of a TEXT or BLOB in bytes. This also +** limits the size of a row in a table or index. +** +** The hard limit is the ability of a 32-bit signed integer +** to count the size: 2^31-1 or 2147483647. +*/ +#ifndef SQLITE_MAX_LENGTH +# define SQLITE_MAX_LENGTH 1000000000 +#endif + +/* +** This is the maximum number of +** +** * Columns in a table +** * Columns in an index +** * Columns in a view +** * Terms in the SET clause of an UPDATE statement +** * Terms in the result set of a SELECT statement +** * Terms in the GROUP BY or ORDER BY clauses of a SELECT statement. +** * Terms in the VALUES clause of an INSERT statement +** +** The hard upper limit here is 32676. Most database people will +** tell you that in a well-normalized database, you usually should +** not have more than a dozen or so columns in any table. And if +** that is the case, there is no point in having more than a few +** dozen values in any of the other situations described above. +*/ +#ifndef SQLITE_MAX_COLUMN +# define SQLITE_MAX_COLUMN 2000 +#endif + +/* +** The maximum length of a single SQL statement in bytes. +** +** It used to be the case that setting this value to zero would +** turn the limit off. That is no longer true. It is not possible +** to turn this limit off. +*/ +#ifndef SQLITE_MAX_SQL_LENGTH +# define SQLITE_MAX_SQL_LENGTH 1000000000 +#endif + +/* +** The maximum depth of an expression tree. This is limited to +** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might +** want to place more severe limits on the complexity of an +** expression. +** +** A value of 0 used to mean that the limit was not enforced. +** But that is no longer true. The limit is now strictly enforced +** at all times. +*/ +#ifndef SQLITE_MAX_EXPR_DEPTH +# define SQLITE_MAX_EXPR_DEPTH 1000 +#endif + +/* +** The maximum number of terms in a compound SELECT statement. +** The code generator for compound SELECT statements does one +** level of recursion for each term. A stack overflow can result +** if the number of terms is too large. In practice, most SQL +** never has more than 3 or 4 terms. Use a value of 0 to disable +** any limit on the number of terms in a compount SELECT. +*/ +#ifndef SQLITE_MAX_COMPOUND_SELECT +# define SQLITE_MAX_COMPOUND_SELECT 500 +#endif + +/* +** The maximum number of opcodes in a VDBE program. +** Not currently enforced. +*/ +#ifndef SQLITE_MAX_VDBE_OP +# define SQLITE_MAX_VDBE_OP 25000 +#endif + +/* +** The maximum number of arguments to an SQL function. +*/ +#ifndef SQLITE_MAX_FUNCTION_ARG +# define SQLITE_MAX_FUNCTION_ARG 127 +#endif + +/* +** The suggested maximum number of in-memory pages to use for +** the main database table and for temporary tables. +** +** IMPLEMENTATION-OF: R-31093-59126 The default suggested cache size +** is 2000 pages. +** IMPLEMENTATION-OF: R-48205-43578 The default suggested cache size can be +** altered using the SQLITE_DEFAULT_CACHE_SIZE compile-time options. +*/ +#ifndef SQLITE_DEFAULT_CACHE_SIZE +# define SQLITE_DEFAULT_CACHE_SIZE 2000 +#endif + +/* +** The default number of frames to accumulate in the log file before +** checkpointing the database in WAL mode. +*/ +#ifndef SQLITE_DEFAULT_WAL_AUTOCHECKPOINT +# define SQLITE_DEFAULT_WAL_AUTOCHECKPOINT 1000 +#endif + +/* +** The maximum number of attached databases. This must be between 0 +** and 62. The upper bound on 62 is because a 64-bit integer bitmap +** is used internally to track attached databases. +*/ +#ifndef SQLITE_MAX_ATTACHED +# define SQLITE_MAX_ATTACHED 10 +#endif + + +/* +** The maximum value of a ?nnn wildcard that the parser will accept. +*/ +#ifndef SQLITE_MAX_VARIABLE_NUMBER +# define SQLITE_MAX_VARIABLE_NUMBER 999 +#endif + +/* Maximum page size. The upper bound on this value is 65536. This a limit +** imposed by the use of 16-bit offsets within each page. +** +** Earlier versions of SQLite allowed the user to change this value at +** compile time. This is no longer permitted, on the grounds that it creates +** a library that is technically incompatible with an SQLite library +** compiled with a different limit. If a process operating on a database +** with a page-size of 65536 bytes crashes, then an instance of SQLite +** compiled with the default page-size limit will not be able to rollback +** the aborted transaction. This could lead to database corruption. +*/ +#ifdef SQLITE_MAX_PAGE_SIZE +# undef SQLITE_MAX_PAGE_SIZE +#endif +#define SQLITE_MAX_PAGE_SIZE 65536 + + +/* +** The default size of a database page. +*/ +#ifndef SQLITE_DEFAULT_PAGE_SIZE +# define SQLITE_DEFAULT_PAGE_SIZE 1024 +#endif +#if SQLITE_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE +# undef SQLITE_DEFAULT_PAGE_SIZE +# define SQLITE_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE +#endif + +/* +** Ordinarily, if no value is explicitly provided, SQLite creates databases +** with page size SQLITE_DEFAULT_PAGE_SIZE. However, based on certain +** device characteristics (sector-size and atomic write() support), +** SQLite may choose a larger value. This constant is the maximum value +** SQLite will choose on its own. +*/ +#ifndef SQLITE_MAX_DEFAULT_PAGE_SIZE +# define SQLITE_MAX_DEFAULT_PAGE_SIZE 8192 +#endif +#if SQLITE_MAX_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE +# undef SQLITE_MAX_DEFAULT_PAGE_SIZE +# define SQLITE_MAX_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE +#endif + + +/* +** Maximum number of pages in one database file. +** +** This is really just the default value for the max_page_count pragma. +** This value can be lowered (or raised) at run-time using that the +** max_page_count macro. +*/ +#ifndef SQLITE_MAX_PAGE_COUNT +# define SQLITE_MAX_PAGE_COUNT 1073741823 +#endif + +/* +** Maximum length (in bytes) of the pattern in a LIKE or GLOB +** operator. +*/ +#ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH +# define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000 +#endif + +/* +** Maximum depth of recursion for triggers. +** +** A value of 1 means that a trigger program will not be able to itself +** fire any triggers. A value of 0 means that no trigger programs at all +** may be executed. +*/ +#ifndef SQLITE_MAX_TRIGGER_DEPTH +# define SQLITE_MAX_TRIGGER_DEPTH 1000 +#endif + +/************** End of sqliteLimit.h *****************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ + +/* Disable nuisance warnings on Borland compilers */ +#if defined(__BORLANDC__) +#pragma warn -rch /* unreachable code */ +#pragma warn -ccc /* Condition is always true or false */ +#pragma warn -aus /* Assigned value is never used */ +#pragma warn -csu /* Comparing signed and unsigned */ +#pragma warn -spa /* Suspicious pointer arithmetic */ +#endif + +/* +** Include standard header files as necessary +*/ +#ifdef HAVE_STDINT_H +#include +#endif +#ifdef HAVE_INTTYPES_H +#include +#endif + +/* +** The following macros are used to cast pointers to integers and +** integers to pointers. The way you do this varies from one compiler +** to the next, so we have developed the following set of #if statements +** to generate appropriate macros for a wide range of compilers. +** +** The correct "ANSI" way to do this is to use the intptr_t type. +** Unfortunately, that typedef is not available on all compilers, or +** if it is available, it requires an #include of specific headers +** that vary from one machine to the next. +** +** Ticket #3860: The llvm-gcc-4.2 compiler from Apple chokes on +** the ((void*)&((char*)0)[X]) construct. But MSVC chokes on ((void*)(X)). +** So we have to define the macros in different ways depending on the +** compiler. +*/ +#if defined(__PTRDIFF_TYPE__) /* This case should work for GCC */ +# define SQLITE_INT_TO_PTR(X) ((void*)(__PTRDIFF_TYPE__)(X)) +# define SQLITE_PTR_TO_INT(X) ((int)(__PTRDIFF_TYPE__)(X)) +#elif !defined(__GNUC__) /* Works for compilers other than LLVM */ +# define SQLITE_INT_TO_PTR(X) ((void*)&((char*)0)[X]) +# define SQLITE_PTR_TO_INT(X) ((int)(((char*)X)-(char*)0)) +#elif defined(HAVE_STDINT_H) /* Use this case if we have ANSI headers */ +# define SQLITE_INT_TO_PTR(X) ((void*)(intptr_t)(X)) +# define SQLITE_PTR_TO_INT(X) ((int)(intptr_t)(X)) +#else /* Generates a warning - but it always works */ +# define SQLITE_INT_TO_PTR(X) ((void*)(X)) +# define SQLITE_PTR_TO_INT(X) ((int)(X)) +#endif + +/* +** A macro to hint to the compiler that a function should not be +** inlined. +*/ +#if defined(__GNUC__) +# define SQLITE_NOINLINE __attribute__((noinline)) +#elif defined(_MSC_VER) && _MSC_VER>=1310 +# define SQLITE_NOINLINE __declspec(noinline) +#else +# define SQLITE_NOINLINE +#endif + +/* +** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. +** 0 means mutexes are permanently disable and the library is never +** threadsafe. 1 means the library is serialized which is the highest +** level of threadsafety. 2 means the library is multithreaded - multiple +** threads can use SQLite as long as no two threads try to use the same +** database connection at the same time. +** +** Older versions of SQLite used an optional THREADSAFE macro. +** We support that for legacy. +*/ +#if !defined(SQLITE_THREADSAFE) +# if defined(THREADSAFE) +# define SQLITE_THREADSAFE THREADSAFE +# else +# define SQLITE_THREADSAFE 1 /* IMP: R-07272-22309 */ +# endif +#endif + +/* +** Powersafe overwrite is on by default. But can be turned off using +** the -DSQLITE_POWERSAFE_OVERWRITE=0 command-line option. +*/ +#ifndef SQLITE_POWERSAFE_OVERWRITE +# define SQLITE_POWERSAFE_OVERWRITE 1 +#endif + +/* +** EVIDENCE-OF: R-25715-37072 Memory allocation statistics are enabled by +** default unless SQLite is compiled with SQLITE_DEFAULT_MEMSTATUS=0 in +** which case memory allocation statistics are disabled by default. +*/ +#if !defined(SQLITE_DEFAULT_MEMSTATUS) +# define SQLITE_DEFAULT_MEMSTATUS 1 +#endif + +/* +** Exactly one of the following macros must be defined in order to +** specify which memory allocation subsystem to use. +** +** SQLITE_SYSTEM_MALLOC // Use normal system malloc() +** SQLITE_WIN32_MALLOC // Use Win32 native heap API +** SQLITE_ZERO_MALLOC // Use a stub allocator that always fails +** SQLITE_MEMDEBUG // Debugging version of system malloc() +** +** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the +** assert() macro is enabled, each call into the Win32 native heap subsystem +** will cause HeapValidate to be called. If heap validation should fail, an +** assertion will be triggered. +** +** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as +** the default. +*/ +#if defined(SQLITE_SYSTEM_MALLOC) \ + + defined(SQLITE_WIN32_MALLOC) \ + + defined(SQLITE_ZERO_MALLOC) \ + + defined(SQLITE_MEMDEBUG)>1 +# error "Two or more of the following compile-time configuration options\ + are defined but at most one is allowed:\ + SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG,\ + SQLITE_ZERO_MALLOC" +#endif +#if defined(SQLITE_SYSTEM_MALLOC) \ + + defined(SQLITE_WIN32_MALLOC) \ + + defined(SQLITE_ZERO_MALLOC) \ + + defined(SQLITE_MEMDEBUG)==0 +# define SQLITE_SYSTEM_MALLOC 1 +#endif + +/* +** If SQLITE_MALLOC_SOFT_LIMIT is not zero, then try to keep the +** sizes of memory allocations below this value where possible. +*/ +#if !defined(SQLITE_MALLOC_SOFT_LIMIT) +# define SQLITE_MALLOC_SOFT_LIMIT 1024 +#endif + +/* +** We need to define _XOPEN_SOURCE as follows in order to enable +** recursive mutexes on most Unix systems and fchmod() on OpenBSD. +** But _XOPEN_SOURCE define causes problems for Mac OS X, so omit +** it. +*/ +#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__) +# define _XOPEN_SOURCE 600 +#endif + +/* +** NDEBUG and SQLITE_DEBUG are opposites. It should always be true that +** defined(NDEBUG)==!defined(SQLITE_DEBUG). If this is not currently true, +** make it true by defining or undefining NDEBUG. +** +** Setting NDEBUG makes the code smaller and faster by disabling the +** assert() statements in the code. So we want the default action +** to be for NDEBUG to be set and NDEBUG to be undefined only if SQLITE_DEBUG +** is set. Thus NDEBUG becomes an opt-in rather than an opt-out +** feature. +*/ +#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) +# define NDEBUG 1 +#endif +#if defined(NDEBUG) && defined(SQLITE_DEBUG) +# undef NDEBUG +#endif + +/* +** Enable SQLITE_ENABLE_EXPLAIN_COMMENTS if SQLITE_DEBUG is turned on. +*/ +#if !defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) && defined(SQLITE_DEBUG) +# define SQLITE_ENABLE_EXPLAIN_COMMENTS 1 +#endif + +/* +** The testcase() macro is used to aid in coverage testing. When +** doing coverage testing, the condition inside the argument to +** testcase() must be evaluated both true and false in order to +** get full branch coverage. The testcase() macro is inserted +** to help ensure adequate test coverage in places where simple +** condition/decision coverage is inadequate. For example, testcase() +** can be used to make sure boundary values are tested. For +** bitmask tests, testcase() can be used to make sure each bit +** is significant and used at least once. On switch statements +** where multiple cases go to the same block of code, testcase() +** can insure that all cases are evaluated. +** +*/ +#ifdef SQLITE_COVERAGE_TEST +SQLITE_PRIVATE void sqlite3Coverage(int); +# define testcase(X) if( X ){ sqlite3Coverage(__LINE__); } +#else +# define testcase(X) +#endif + +/* +** The TESTONLY macro is used to enclose variable declarations or +** other bits of code that are needed to support the arguments +** within testcase() and assert() macros. +*/ +#if !defined(NDEBUG) || defined(SQLITE_COVERAGE_TEST) +# define TESTONLY(X) X +#else +# define TESTONLY(X) +#endif + +/* +** Sometimes we need a small amount of code such as a variable initialization +** to setup for a later assert() statement. We do not want this code to +** appear when assert() is disabled. The following macro is therefore +** used to contain that setup code. The "VVA" acronym stands for +** "Verification, Validation, and Accreditation". In other words, the +** code within VVA_ONLY() will only run during verification processes. +*/ +#ifndef NDEBUG +# define VVA_ONLY(X) X +#else +# define VVA_ONLY(X) +#endif + +/* +** The ALWAYS and NEVER macros surround boolean expressions which +** are intended to always be true or false, respectively. Such +** expressions could be omitted from the code completely. But they +** are included in a few cases in order to enhance the resilience +** of SQLite to unexpected behavior - to make the code "self-healing" +** or "ductile" rather than being "brittle" and crashing at the first +** hint of unplanned behavior. +** +** In other words, ALWAYS and NEVER are added for defensive code. +** +** When doing coverage testing ALWAYS and NEVER are hard-coded to +** be true and false so that the unreachable code they specify will +** not be counted as untested code. +*/ +#if defined(SQLITE_COVERAGE_TEST) +# define ALWAYS(X) (1) +# define NEVER(X) (0) +#elif !defined(NDEBUG) +# define ALWAYS(X) ((X)?1:(assert(0),0)) +# define NEVER(X) ((X)?(assert(0),1):0) +#else +# define ALWAYS(X) (X) +# define NEVER(X) (X) +#endif + +/* +** Declarations used for tracing the operating system interfaces. +*/ +#if defined(SQLITE_FORCE_OS_TRACE) || defined(SQLITE_TEST) || \ + (defined(SQLITE_DEBUG) && SQLITE_OS_WIN) + extern int sqlite3OSTrace; +# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X +# define SQLITE_HAVE_OS_TRACE +#else +# define OSTRACE(X) +# undef SQLITE_HAVE_OS_TRACE +#endif + +/* +** Is the sqlite3ErrName() function needed in the build? Currently, +** it is needed by "mutex_w32.c" (when debugging), "os_win.c" (when +** OSTRACE is enabled), and by several "test*.c" files (which are +** compiled using SQLITE_TEST). +*/ +#if defined(SQLITE_HAVE_OS_TRACE) || defined(SQLITE_TEST) || \ + (defined(SQLITE_DEBUG) && SQLITE_OS_WIN) +# define SQLITE_NEED_ERR_NAME +#else +# undef SQLITE_NEED_ERR_NAME +#endif + +/* +** Return true (non-zero) if the input is an integer that is too large +** to fit in 32-bits. This macro is used inside of various testcase() +** macros to verify that we have tested SQLite for large-file support. +*/ +#define IS_BIG_INT(X) (((X)&~(i64)0xffffffff)!=0) + +/* +** The macro unlikely() is a hint that surrounds a boolean +** expression that is usually false. Macro likely() surrounds +** a boolean expression that is usually true. These hints could, +** in theory, be used by the compiler to generate better code, but +** currently they are just comments for human readers. +*/ +#define likely(X) (X) +#define unlikely(X) (X) + +/************** Include hash.h in the middle of sqliteInt.h ******************/ +/************** Begin file hash.h ********************************************/ +/* +** 2001 September 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 is the header file for the generic hash-table implementation +** used in SQLite. +*/ +#ifndef _SQLITE_HASH_H_ +#define _SQLITE_HASH_H_ + +/* Forward declarations of structures. */ +typedef struct Hash Hash; +typedef struct HashElem HashElem; + +/* A complete hash table is an instance of the following structure. +** The internals of this structure are intended to be opaque -- client +** code should not attempt to access or modify the fields of this structure +** directly. Change this structure only by using the routines below. +** However, some of the "procedures" and "functions" for modifying and +** accessing this structure are really macros, so we can't really make +** this structure opaque. +** +** All elements of the hash table are on a single doubly-linked list. +** Hash.first points to the head of this list. +** +** There are Hash.htsize buckets. Each bucket points to a spot in +** the global doubly-linked list. The contents of the bucket are the +** element pointed to plus the next _ht.count-1 elements in the list. +** +** Hash.htsize and Hash.ht may be zero. In that case lookup is done +** by a linear search of the global list. For small tables, the +** Hash.ht table is never allocated because if there are few elements +** in the table, it is faster to do a linear search than to manage +** the hash table. +*/ +struct Hash { + unsigned int htsize; /* Number of buckets in the hash table */ + unsigned int count; /* Number of entries in this table */ + HashElem *first; /* The first element of the array */ + struct _ht { /* the hash table */ + int count; /* Number of entries with this hash */ + HashElem *chain; /* Pointer to first entry with this hash */ + } *ht; +}; + +/* Each element in the hash table is an instance of the following +** structure. All elements are stored on a single doubly-linked list. +** +** Again, this structure is intended to be opaque, but it can't really +** be opaque because it is used by macros. +*/ +struct HashElem { + HashElem *next, *prev; /* Next and previous elements in the table */ + void *data; /* Data associated with this element */ + const char *pKey; /* Key associated with this element */ +}; + +/* +** Access routines. To delete, insert a NULL pointer. +*/ +SQLITE_PRIVATE void sqlite3HashInit(Hash*); +SQLITE_PRIVATE void *sqlite3HashInsert(Hash*, const char *pKey, void *pData); +SQLITE_PRIVATE void *sqlite3HashFind(const Hash*, const char *pKey); +SQLITE_PRIVATE void sqlite3HashClear(Hash*); + +/* +** Macros for looping over all elements of a hash table. The idiom is +** like this: +** +** Hash h; +** HashElem *p; +** ... +** for(p=sqliteHashFirst(&h); p; p=sqliteHashNext(p)){ +** SomeStructure *pData = sqliteHashData(p); +** // do something with pData +** } +*/ +#define sqliteHashFirst(H) ((H)->first) +#define sqliteHashNext(E) ((E)->next) +#define sqliteHashData(E) ((E)->data) +/* #define sqliteHashKey(E) ((E)->pKey) // NOT USED */ +/* #define sqliteHashKeysize(E) ((E)->nKey) // NOT USED */ + +/* +** Number of entries in a hash table +*/ +/* #define sqliteHashCount(H) ((H)->count) // NOT USED */ + +#endif /* _SQLITE_HASH_H_ */ + +/************** End of hash.h ************************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ +/************** Include parse.h in the middle of sqliteInt.h *****************/ +/************** Begin file parse.h *******************************************/ +#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_SAVEPOINT 13 +#define TK_RELEASE 14 +#define TK_TO 15 +#define TK_TABLE 16 +#define TK_CREATE 17 +#define TK_IF 18 +#define TK_NOT 19 +#define TK_EXISTS 20 +#define TK_TEMP 21 +#define TK_LP 22 +#define TK_RP 23 +#define TK_AS 24 +#define TK_WITHOUT 25 +#define TK_COMMA 26 +#define TK_ID 27 +#define TK_INDEXED 28 +#define TK_ABORT 29 +#define TK_ACTION 30 +#define TK_AFTER 31 +#define TK_ANALYZE 32 +#define TK_ASC 33 +#define TK_ATTACH 34 +#define TK_BEFORE 35 +#define TK_BY 36 +#define TK_CASCADE 37 +#define TK_CAST 38 +#define TK_COLUMNKW 39 +#define TK_CONFLICT 40 +#define TK_DATABASE 41 +#define TK_DESC 42 +#define TK_DETACH 43 +#define TK_EACH 44 +#define TK_FAIL 45 +#define TK_FOR 46 +#define TK_IGNORE 47 +#define TK_INITIALLY 48 +#define TK_INSTEAD 49 +#define TK_LIKE_KW 50 +#define TK_MATCH 51 +#define TK_NO 52 +#define TK_KEY 53 +#define TK_OF 54 +#define TK_OFFSET 55 +#define TK_PRAGMA 56 +#define TK_RAISE 57 +#define TK_RECURSIVE 58 +#define TK_REPLACE 59 +#define TK_RESTRICT 60 +#define TK_ROW 61 +#define TK_TRIGGER 62 +#define TK_VACUUM 63 +#define TK_VIEW 64 +#define TK_VIRTUAL 65 +#define TK_WITH 66 +#define TK_REINDEX 67 +#define TK_RENAME 68 +#define TK_CTIME_KW 69 +#define TK_ANY 70 +#define TK_OR 71 +#define TK_AND 72 +#define TK_IS 73 +#define TK_BETWEEN 74 +#define TK_IN 75 +#define TK_ISNULL 76 +#define TK_NOTNULL 77 +#define TK_NE 78 +#define TK_EQ 79 +#define TK_GT 80 +#define TK_LE 81 +#define TK_LT 82 +#define TK_GE 83 +#define TK_ESCAPE 84 +#define TK_BITAND 85 +#define TK_BITOR 86 +#define TK_LSHIFT 87 +#define TK_RSHIFT 88 +#define TK_PLUS 89 +#define TK_MINUS 90 +#define TK_STAR 91 +#define TK_SLASH 92 +#define TK_REM 93 +#define TK_CONCAT 94 +#define TK_COLLATE 95 +#define TK_BITNOT 96 +#define TK_STRING 97 +#define TK_JOIN_KW 98 +#define TK_CONSTRAINT 99 +#define TK_DEFAULT 100 +#define TK_NULL 101 +#define TK_PRIMARY 102 +#define TK_UNIQUE 103 +#define TK_CHECK 104 +#define TK_REFERENCES 105 +#define TK_AUTOINCR 106 +#define TK_ON 107 +#define TK_INSERT 108 +#define TK_DELETE 109 +#define TK_UPDATE 110 +#define TK_SET 111 +#define TK_DEFERRABLE 112 +#define TK_FOREIGN 113 +#define TK_DROP 114 +#define TK_UNION 115 +#define TK_ALL 116 +#define TK_EXCEPT 117 +#define TK_INTERSECT 118 +#define TK_SELECT 119 +#define TK_VALUES 120 +#define TK_DISTINCT 121 +#define TK_DOT 122 +#define TK_FROM 123 +#define TK_JOIN 124 +#define TK_USING 125 +#define TK_ORDER 126 +#define TK_GROUP 127 +#define TK_HAVING 128 +#define TK_LIMIT 129 +#define TK_WHERE 130 +#define TK_INTO 131 +#define TK_INTEGER 132 +#define TK_FLOAT 133 +#define TK_BLOB 134 +#define TK_VARIABLE 135 +#define TK_CASE 136 +#define TK_WHEN 137 +#define TK_THEN 138 +#define TK_ELSE 139 +#define TK_INDEX 140 +#define TK_ALTER 141 +#define TK_ADD 142 +#define TK_TO_TEXT 143 +#define TK_TO_BLOB 144 +#define TK_TO_NUMERIC 145 +#define TK_TO_INT 146 +#define TK_TO_REAL 147 +#define TK_ISNOT 148 +#define TK_END_OF_FILE 149 +#define TK_ILLEGAL 150 +#define TK_SPACE 151 +#define TK_UNCLOSED_STRING 152 +#define TK_FUNCTION 153 +#define TK_COLUMN 154 +#define TK_AGG_FUNCTION 155 +#define TK_AGG_COLUMN 156 +#define TK_UMINUS 157 +#define TK_UPLUS 158 +#define TK_REGISTER 159 + +/************** End of parse.h ***********************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ +#include +#include +#include +#include +#include + +/* +** 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 float sqlite_int64 +# define LONGDOUBLE_TYPE sqlite_int64 +# ifndef SQLITE_BIG_DBL +# define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50) +# endif +# define SQLITE_OMIT_DATETIME_FUNCS 1 +# define SQLITE_OMIT_TRACE 1 +# undef SQLITE_MIXED_ENDIAN_64BIT_FLOAT +# undef SQLITE_HAVE_ISNAN +#endif +#ifndef SQLITE_BIG_DBL +# define SQLITE_BIG_DBL (1e99) +#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 + +/* +** 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 + +/* +** Determine whether triggers are recursive by default. This can be +** changed at run-time using a pragma. +*/ +#ifndef SQLITE_DEFAULT_RECURSIVE_TRIGGERS +# define SQLITE_DEFAULT_RECURSIVE_TRIGGERS 0 +#endif + +/* +** Provide a default value for SQLITE_TEMP_STORE in case it is not specified +** on the command-line +*/ +#ifndef SQLITE_TEMP_STORE +# define SQLITE_TEMP_STORE 1 +# define SQLITE_TEMP_STORE_xc 1 /* Exclude from ctime.c */ +#endif + +/* +** If no value has been provided for SQLITE_MAX_WORKER_THREADS, or if +** SQLITE_TEMP_STORE is set to 3 (never use temporary files), set it +** to zero. +*/ +#if SQLITE_TEMP_STORE==3 || SQLITE_THREADSAFE==0 +# undef SQLITE_MAX_WORKER_THREADS +# define SQLITE_MAX_WORKER_THREADS 0 +#endif +#ifndef SQLITE_MAX_WORKER_THREADS +# define SQLITE_MAX_WORKER_THREADS 8 +#endif +#ifndef SQLITE_DEFAULT_WORKER_THREADS +# define SQLITE_DEFAULT_WORKER_THREADS 0 +#endif +#if SQLITE_DEFAULT_WORKER_THREADS>SQLITE_MAX_WORKER_THREADS +# undef SQLITE_MAX_WORKER_THREADS +# define SQLITE_MAX_WORKER_THREADS SQLITE_DEFAULT_WORKER_THREADS +#endif + + +/* +** GCC does not define the offsetof() macro so we'll have to do it +** ourselves. +*/ +#ifndef offsetof +#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD)) +#endif + +/* +** Macros to compute minimum and maximum of two numbers. +*/ +#define MIN(A,B) ((A)<(B)?(A):(B)) +#define MAX(A,B) ((A)>(B)?(A):(B)) + +/* +** Swap two objects of type TYPE. +*/ +#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;} + +/* +** Check to see if this machine uses EBCDIC. (Yes, believe it or +** not, there are still machines out there that use EBCDIC.) +*/ +#if 'A' == '\301' +# define SQLITE_EBCDIC 1 +#else +# define SQLITE_ASCII 1 +#endif + +/* +** Integers of known sizes. These typedefs might change for architectures +** where the sizes very. Preprocessor macros are available so that the +** types can be conveniently redefined at compile-type. Like this: +** +** cc '-DUINTPTR_TYPE=long long int' ... +*/ +#ifndef UINT32_TYPE +# ifdef HAVE_UINT32_T +# define UINT32_TYPE uint32_t +# else +# define UINT32_TYPE unsigned int +# endif +#endif +#ifndef UINT16_TYPE +# ifdef HAVE_UINT16_T +# define UINT16_TYPE uint16_t +# else +# define UINT16_TYPE unsigned short int +# endif +#endif +#ifndef INT16_TYPE +# ifdef HAVE_INT16_T +# define INT16_TYPE int16_t +# else +# define INT16_TYPE short int +# endif +#endif +#ifndef UINT8_TYPE +# ifdef HAVE_UINT8_T +# define UINT8_TYPE uint8_t +# else +# define UINT8_TYPE unsigned char +# endif +#endif +#ifndef INT8_TYPE +# ifdef HAVE_INT8_T +# define INT8_TYPE int8_t +# else +# define INT8_TYPE signed char +# endif +#endif +#ifndef LONGDOUBLE_TYPE +# define LONGDOUBLE_TYPE long double +#endif +typedef sqlite_int64 i64; /* 8-byte signed integer */ +typedef sqlite_uint64 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 INT8_TYPE i8; /* 1-byte signed integer */ + +/* +** SQLITE_MAX_U32 is a u64 constant that is the maximum u64 value +** that can be stored in a u32 without loss of data. The value +** is 0x00000000ffffffff. But because of quirks of some compilers, we +** have to specify the value in the less intuitive manner shown: +*/ +#define SQLITE_MAX_U32 ((((u64)1)<<32)-1) + +/* +** The datatype used to store estimates of the number of rows in a +** table or index. This is an unsigned integer type. For 99.9% of +** the world, a 32-bit integer is sufficient. But a 64-bit integer +** can be used at compile-time if desired. +*/ +#ifdef SQLITE_64BIT_STATS + typedef u64 tRowcnt; /* 64-bit only if requested at compile-time */ +#else + typedef u32 tRowcnt; /* 32-bit is the default */ +#endif + +/* +** Estimated quantities used for query planning are stored as 16-bit +** logarithms. For quantity X, the value stored is 10*log2(X). This +** gives a possible range of values of approximately 1.0e986 to 1e-986. +** But the allowed values are "grainy". Not every value is representable. +** For example, quantities 16 and 17 are both represented by a LogEst +** of 40. However, since LogEst quantities are suppose to be estimates, +** not exact values, this imprecision is not a problem. +** +** "LogEst" is short for "Logarithmic Estimate". +** +** Examples: +** 1 -> 0 20 -> 43 10000 -> 132 +** 2 -> 10 25 -> 46 25000 -> 146 +** 3 -> 16 100 -> 66 1000000 -> 199 +** 4 -> 20 1000 -> 99 1048576 -> 200 +** 10 -> 33 1024 -> 100 4294967296 -> 320 +** +** The LogEst can be negative to indicate fractional values. +** Examples: +** +** 0.5 -> -10 0.1 -> -33 0.0625 -> -40 +*/ +typedef INT16_TYPE LogEst; + +/* +** Set the SQLITE_PTRSIZE macro to the number of bytes in a pointer +*/ +#ifndef SQLITE_PTRSIZE +# if defined(__SIZEOF_POINTER__) +# define SQLITE_PTRSIZE __SIZEOF_POINTER__ +# elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(_M_ARM) || defined(__arm__) || defined(__x86) +# define SQLITE_PTRSIZE 4 +# else +# define SQLITE_PTRSIZE 8 +# endif +#endif + +/* +** Macros to determine whether the machine is big or little endian, +** and whether or not that determination is run-time or compile-time. +** +** For best performance, an attempt is made to guess at the byte-order +** using C-preprocessor macros. If that is unsuccessful, or if +** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined +** at run-time. +*/ +#ifdef SQLITE_AMALGAMATION +SQLITE_PRIVATE const int sqlite3one = 1; +#else +SQLITE_PRIVATE const int sqlite3one; +#endif +#if (defined(i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ + defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ + defined(__arm__)) && !defined(SQLITE_RUNTIME_BYTEORDER) +# define SQLITE_BYTEORDER 1234 +# define SQLITE_BIGENDIAN 0 +# define SQLITE_LITTLEENDIAN 1 +# define SQLITE_UTF16NATIVE SQLITE_UTF16LE +#endif +#if (defined(sparc) || defined(__ppc__)) \ + && !defined(SQLITE_RUNTIME_BYTEORDER) +# define SQLITE_BYTEORDER 4321 +# define SQLITE_BIGENDIAN 1 +# define SQLITE_LITTLEENDIAN 0 +# define SQLITE_UTF16NATIVE SQLITE_UTF16BE +#endif +#if !defined(SQLITE_BYTEORDER) +# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */ +# define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0) +# define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1) +# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE) +#endif + +/* +** Constants for the largest and smallest possible 64-bit signed integers. +** These macros are designed to work correctly on both 32-bit and 64-bit +** compilers. +*/ +#define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) +#define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) + +/* +** 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) + +/* +** Round down to the nearest multiple of 8 +*/ +#define ROUNDDOWN8(x) ((x)&~7) + +/* +** Assert that the pointer X is aligned to an 8-byte boundary. This +** macro is used only within assert() to verify that the code gets +** all alignment restrictions correct. +** +** Except, if SQLITE_4_BYTE_ALIGNED_MALLOC is defined, then the +** underlying malloc() implementation might return us 4-byte aligned +** pointers. In that case, only verify 4-byte alignment. +*/ +#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC +# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&3)==0) +#else +# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&7)==0) +#endif + +/* +** Disable MMAP on platforms where it is known to not work +*/ +#if defined(__OpenBSD__) || defined(__QNXNTO__) +# undef SQLITE_MAX_MMAP_SIZE +# define SQLITE_MAX_MMAP_SIZE 0 +#endif + +/* +** Default maximum size of memory used by memory-mapped I/O in the VFS +*/ +#ifdef __APPLE__ +# include +# if TARGET_OS_IPHONE +# undef SQLITE_MAX_MMAP_SIZE +# define SQLITE_MAX_MMAP_SIZE 0 +# endif +#endif +#ifndef SQLITE_MAX_MMAP_SIZE +# if defined(__linux__) \ + || defined(_WIN32) \ + || (defined(__APPLE__) && defined(__MACH__)) \ + || defined(__sun) +# define SQLITE_MAX_MMAP_SIZE 0x7fff0000 /* 2147418112 */ +# else +# define SQLITE_MAX_MMAP_SIZE 0 +# endif +# define SQLITE_MAX_MMAP_SIZE_xc 1 /* exclude from ctime.c */ +#endif + +/* +** The default MMAP_SIZE is zero on all platforms. Or, even if a larger +** default MMAP_SIZE is specified at compile-time, make sure that it does +** not exceed the maximum mmap size. +*/ +#ifndef SQLITE_DEFAULT_MMAP_SIZE +# define SQLITE_DEFAULT_MMAP_SIZE 0 +# define SQLITE_DEFAULT_MMAP_SIZE_xc 1 /* Exclude from ctime.c */ +#endif +#if SQLITE_DEFAULT_MMAP_SIZE>SQLITE_MAX_MMAP_SIZE +# undef SQLITE_DEFAULT_MMAP_SIZE +# define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE +#endif + +/* +** Only one of SQLITE_ENABLE_STAT3 or SQLITE_ENABLE_STAT4 can be defined. +** Priority is given to SQLITE_ENABLE_STAT4. If either are defined, also +** define SQLITE_ENABLE_STAT3_OR_STAT4 +*/ +#ifdef SQLITE_ENABLE_STAT4 +# undef SQLITE_ENABLE_STAT3 +# define SQLITE_ENABLE_STAT3_OR_STAT4 1 +#elif SQLITE_ENABLE_STAT3 +# define SQLITE_ENABLE_STAT3_OR_STAT4 1 +#elif SQLITE_ENABLE_STAT3_OR_STAT4 +# undef SQLITE_ENABLE_STAT3_OR_STAT4 +#endif + +/* +** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not +** the Select query generator tracing logic is turned on. +*/ +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_SELECTTRACE) +# define SELECTTRACE_ENABLED 1 +#else +# define SELECTTRACE_ENABLED 0 +#endif + +/* +** An instance of the following structure is used to store the busy-handler +** callback for a given sqlite handle. +** +** The sqlite.busyHandler member of the sqlite struct contains the busy +** callback for the database handle. Each pager opened via the sqlite +** 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 */ +}; + +/* +** 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) ((int)(sizeof(X)/sizeof(X[0]))) + +/* +** Determine if the argument is a power of two +*/ +#define IsPowerOfTwo(X) (((X)&((X)-1))==0) + +/* +** The following value as a destructor means to use sqlite3DbFree(). +** The sqlite3DbFree() routine requires two parameters instead of the +** one parameter that destructors normally want. So we have to introduce +** this magic value that the code knows to handle differently. Any +** pointer will work here as long as it is distinct from SQLITE_STATIC +** and SQLITE_TRANSIENT. +*/ +#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3MallocSize) + +/* +** When SQLITE_OMIT_WSD is defined, it means that the target platform does +** not support Writable Static Data (WSD) such as global and static variables. +** All variables must either be on the stack or dynamically allocated from +** the heap. When WSD is unsupported, the variable declarations scattered +** throughout the SQLite code must become constants instead. The SQLITE_WSD +** macro is used for this purpose. And instead of referencing the variable +** directly, we use its constant as a key to lookup the run-time allocated +** buffer that holds real variable. The constant is also the initializer +** for the run-time allocated buffer. +** +** In the usual case where WSD is supported, the SQLITE_WSD and GLOBAL +** macros become no-ops and have zero performance impact. +*/ +#ifdef SQLITE_OMIT_WSD + #define SQLITE_WSD const + #define GLOBAL(t,v) (*(t*)sqlite3_wsd_find((void*)&(v), sizeof(v))) + #define sqlite3GlobalConfig GLOBAL(struct Sqlite3Config, sqlite3Config) +SQLITE_API int SQLITE_STDCALL sqlite3_wsd_init(int N, int J); +SQLITE_API void *SQLITE_STDCALL sqlite3_wsd_find(void *K, int L); +#else + #define SQLITE_WSD + #define GLOBAL(t,v) v + #define sqlite3GlobalConfig sqlite3Config +#endif + +/* +** The following macros are used to suppress compiler warnings and to +** make it clear to human readers when a function parameter is deliberately +** left unused within the body of a function. This usually happens when +** a function is called via a function pointer. For example the +** implementation of an SQL aggregate step callback may not use the +** parameter indicating the number of arguments passed to the aggregate, +** if it knows that this is enforced elsewhere. +** +** When a function parameter is not used at all within the body of a function, +** it is generally named "NotUsed" or "NotUsed2" to make things even clearer. +** However, these macros may also be used to suppress warnings related to +** parameters that may or may not be used depending on compilation options. +** For example those parameters only used in assert() statements. In these +** cases the parameters are named as per the usual conventions. +*/ +#define UNUSED_PARAMETER(x) (void)(x) +#define UNUSED_PARAMETER2(x,y) UNUSED_PARAMETER(x),UNUSED_PARAMETER(y) + +/* +** Forward references to structures +*/ +typedef struct AggInfo AggInfo; +typedef struct AuthContext AuthContext; +typedef struct AutoincInfo AutoincInfo; +typedef struct Bitvec Bitvec; +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 ExprSpan ExprSpan; +typedef struct FKey FKey; +typedef struct FuncDestructor FuncDestructor; +typedef struct FuncDef FuncDef; +typedef struct FuncDefHash FuncDefHash; +typedef struct IdList IdList; +typedef struct Index Index; +typedef struct IndexSample IndexSample; +typedef struct KeyClass KeyClass; +typedef struct KeyInfo KeyInfo; +typedef struct Lookaside Lookaside; +typedef struct LookasideSlot LookasideSlot; +typedef struct Module Module; +typedef struct NameContext NameContext; +typedef struct Parse Parse; +typedef struct PrintfArguments PrintfArguments; +typedef struct RowSet RowSet; +typedef struct Savepoint Savepoint; +typedef struct Select Select; +typedef struct SQLiteThread SQLiteThread; +typedef struct SelectDest SelectDest; +typedef struct SrcList SrcList; +typedef struct StrAccum StrAccum; +typedef struct Table Table; +typedef struct TableLock TableLock; +typedef struct Token Token; +typedef struct TreeView TreeView; +typedef struct Trigger Trigger; +typedef struct TriggerPrg TriggerPrg; +typedef struct TriggerStep TriggerStep; +typedef struct UnpackedRecord UnpackedRecord; +typedef struct VTable VTable; +typedef struct VtabCtx VtabCtx; +typedef struct Walker Walker; +typedef struct WhereInfo WhereInfo; +typedef struct With With; + +/* +** Defer sourcing vdbe.h and btree.h until after the "u8" and +** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque +** pointer types (i.e. FuncDef) defined above. +*/ +/************** Include btree.h in the middle of sqliteInt.h *****************/ +/************** Begin file btree.h *******************************************/ +/* +** 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. +** +************************************************************************* +** 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. +*/ +#ifndef _BTREE_H_ +#define _BTREE_H_ + +/* TODO: This definition is just included so other modules compile. It +** needs to be revisited. +*/ +#define SQLITE_N_BTREE_META 16 + +/* +** If defined as non-zero, auto-vacuum is enabled by default. Otherwise +** it must be turned on for each database using "PRAGMA auto_vacuum = 1". +*/ +#ifndef SQLITE_DEFAULT_AUTOVACUUM + #define SQLITE_DEFAULT_AUTOVACUUM 0 +#endif + +#define BTREE_AUTOVACUUM_NONE 0 /* Do not do auto-vacuum */ +#define BTREE_AUTOVACUUM_FULL 1 /* Do full auto-vacuum */ +#define BTREE_AUTOVACUUM_INCR 2 /* Incremental vacuum */ + +/* +** Forward declarations of structure +*/ +typedef struct Btree Btree; +typedef struct BtCursor BtCursor; +typedef struct BtShared BtShared; + + +SQLITE_PRIVATE int sqlite3BtreeOpen( + sqlite3_vfs *pVfs, /* VFS to use with this b-tree */ + const char *zFilename, /* Name of database file to open */ + sqlite3 *db, /* Associated database connection */ + Btree **ppBtree, /* Return open Btree* here */ + int flags, /* Flags */ + int vfsFlags /* Flags passed through to VFS open */ +); + +/* 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 create or use a rollback journal */ +#define BTREE_MEMORY 2 /* This is an in-memory DB */ +#define BTREE_SINGLE 4 /* The file contains at most 1 b-tree */ +#define BTREE_UNORDERED 8 /* Use of a hash implementation is OK */ + +SQLITE_PRIVATE int sqlite3BtreeClose(Btree*); +SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int); +#if SQLITE_MAX_MMAP_SIZE>0 +SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64); +#endif +SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags(Btree*,unsigned); +SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*); +SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix); +SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*); +SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int); +SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree*); +SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree*,int); +SQLITE_PRIVATE int sqlite3BtreeGetOptimalReserve(Btree*); +SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p); +SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int); +SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *); +SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int); +SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster); +SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*, int); +SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*); +SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*,int,int); +SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree*,int); +SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree*, int*, int flags); +SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree*); +SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree*); +SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree*); +SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *, int, void(*)(void *)); +SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *pBtree); +SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock); +SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *, int, int); + +SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *); +SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *); +SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *, Btree *); + +SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *); + +/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR +** of the flags shown below. +** +** Every SQLite table must have either BTREE_INTKEY or BTREE_BLOBKEY set. +** With BTREE_INTKEY, the table key is a 64-bit integer and arbitrary data +** is stored in the leaves. (BTREE_INTKEY is used for SQL tables.) With +** BTREE_BLOBKEY, the key is an arbitrary BLOB and no content is stored +** anywhere - the key is the content. (BTREE_BLOBKEY is used for SQL +** indices.) +*/ +#define BTREE_INTKEY 1 /* Table has only 64-bit signed integer keys */ +#define BTREE_BLOBKEY 2 /* Table has keys only - no data */ + +SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*); +SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, int*); +SQLITE_PRIVATE int sqlite3BtreeClearTableOfCursor(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree*, int, int); + +SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue); +SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value); + +SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p); + +/* +** The second parameter to sqlite3BtreeGetMeta or sqlite3BtreeUpdateMeta +** should be one of the following values. The integer values are assigned +** to constants so that the offset of the corresponding field in an +** SQLite database header may be found using the following formula: +** +** offset = 36 + (idx * 4) +** +** For example, the free-page-count field is located at byte offset 36 of +** the database file header. The incr-vacuum-flag field is located at +** byte offset 64 (== 36+4*7). +** +** The BTREE_DATA_VERSION value is not really a value stored in the header. +** It is a read-only number computed by the pager. But we merge it with +** the header value access routines since its access pattern is the same. +** Call it a "virtual meta value". +*/ +#define BTREE_FREE_PAGE_COUNT 0 +#define BTREE_SCHEMA_VERSION 1 +#define BTREE_FILE_FORMAT 2 +#define BTREE_DEFAULT_CACHE_SIZE 3 +#define BTREE_LARGEST_ROOT_PAGE 4 +#define BTREE_TEXT_ENCODING 5 +#define BTREE_USER_VERSION 6 +#define BTREE_INCR_VACUUM 7 +#define BTREE_APPLICATION_ID 8 +#define BTREE_DATA_VERSION 15 /* A virtual meta-value */ + +/* +** Values that may be OR'd together to form the second argument of an +** sqlite3BtreeCursorHints() call. +** +** The BTREE_BULKLOAD flag is set on index cursors when the index is going +** to be filled with content that is already in sorted order. +** +** The BTREE_SEEK_EQ flag is set on cursors that will get OP_SeekGE or +** OP_SeekLE opcodes for a range search, but where the range of entries +** selected will all have the same key. In other words, the cursor will +** be used only for equality key searches. +** +*/ +#define BTREE_BULKLOAD 0x00000001 /* Used to full index in sorted order */ +#define BTREE_SEEK_EQ 0x00000002 /* EQ seeks only - no range seeks */ + +SQLITE_PRIVATE int sqlite3BtreeCursor( + Btree*, /* BTree containing table to open */ + int iTable, /* Index of root page */ + int wrFlag, /* 1 for writing. 0 for read-only */ + struct KeyInfo*, /* First argument to compare function */ + BtCursor *pCursor /* Space to write cursor structure */ +); +SQLITE_PRIVATE int sqlite3BtreeCursorSize(void); +SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*); + +SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( + BtCursor*, + UnpackedRecord *pUnKey, + i64 intKey, + int bias, + int *pRes +); +SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor*, int*); +SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey, + const void *pData, int nData, + int nZero, int bias, int seekResult); +SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes); +SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes); +SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int *pRes); +SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int *pRes); +SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor*, i64 *pSize); +SQLITE_PRIVATE int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*); +SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor*, u32 *pAmt); +SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor*, u32 *pAmt); +SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor*, u32 *pSize); +SQLITE_PRIVATE int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*); + +SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*); +SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*); + +SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); +SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *); +SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *); +SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion); +SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask); +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask); +#endif +SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *pBt); +SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void); + +#ifndef NDEBUG +SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*); +#endif + +#ifndef SQLITE_OMIT_BTREECOUNT +SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *, i64 *); +#endif + +#ifdef SQLITE_TEST +SQLITE_PRIVATE int sqlite3BtreeCursorInfo(BtCursor*, int*, int); +SQLITE_PRIVATE void sqlite3BtreeCursorList(Btree*); +#endif + +#ifndef SQLITE_OMIT_WAL +SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree*, int, int *, int *); +#endif + +/* +** If we are not using shared cache, then there is no need to +** use mutexes to access the BtShared structures. So make the +** Enter and Leave procedures no-ops. +*/ +#ifndef SQLITE_OMIT_SHARED_CACHE +SQLITE_PRIVATE void sqlite3BtreeEnter(Btree*); +SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3*); +#else +# define sqlite3BtreeEnter(X) +# define sqlite3BtreeEnterAll(X) +#endif + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE +SQLITE_PRIVATE int sqlite3BtreeSharable(Btree*); +SQLITE_PRIVATE void sqlite3BtreeLeave(Btree*); +SQLITE_PRIVATE void sqlite3BtreeEnterCursor(BtCursor*); +SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor*); +SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3*); +#ifndef NDEBUG + /* These routines are used inside assert() statements only. */ +SQLITE_PRIVATE int sqlite3BtreeHoldsMutex(Btree*); +SQLITE_PRIVATE int sqlite3BtreeHoldsAllMutexes(sqlite3*); +SQLITE_PRIVATE int sqlite3SchemaMutexHeld(sqlite3*,int,Schema*); +#endif +#else + +# define sqlite3BtreeSharable(X) 0 +# define sqlite3BtreeLeave(X) +# define sqlite3BtreeEnterCursor(X) +# define sqlite3BtreeLeaveCursor(X) +# define sqlite3BtreeLeaveAll(X) + +# define sqlite3BtreeHoldsMutex(X) 1 +# define sqlite3BtreeHoldsAllMutexes(X) 1 +# define sqlite3SchemaMutexHeld(X,Y,Z) 1 +#endif + + +#endif /* _BTREE_H_ */ + +/************** End of btree.h ***********************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ +/************** Include vdbe.h in the middle of sqliteInt.h ******************/ +/************** Begin file vdbe.h ********************************************/ +/* +** 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. +** +************************************************************************* +** 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. +*/ +#ifndef _SQLITE_VDBE_H_ +#define _SQLITE_VDBE_H_ +/* #include */ + +/* +** A single VDBE is an opaque structure named "Vdbe". Only routines +** in the source file sqliteVdbe.c are allowed to see the insides +** of this structure. +*/ +typedef struct Vdbe Vdbe; + +/* +** The names of the following types declared in vdbeInt.h are required +** for the VdbeOp definition. +*/ +typedef struct Mem Mem; +typedef struct SubProgram SubProgram; + +/* +** A single instruction of the virtual machine has an opcode +** and as many as three operands. The instruction is recorded +** as an instance of the following structure: +*/ +struct VdbeOp { + u8 opcode; /* What operation to perform */ + signed char p4type; /* One of the P4_xxx constants for p4 */ + u8 opflags; /* Mask of the OPFLG_* flags in opcodes.h */ + u8 p5; /* Fifth parameter is an unsigned character */ + int p1; /* First operand */ + int p2; /* Second parameter (often the jump destination) */ + int p3; /* The third parameter */ + union { /* fourth parameter */ + int i; /* Integer value if p4type==P4_INT32 */ + void *p; /* Generic pointer */ + char *z; /* Pointer to data for string (char array) types */ + i64 *pI64; /* Used when p4type is P4_INT64 */ + double *pReal; /* Used when p4type is P4_REAL */ + FuncDef *pFunc; /* Used when p4type is P4_FUNCDEF */ + CollSeq *pColl; /* Used when p4type is P4_COLLSEQ */ + Mem *pMem; /* Used when p4type is P4_MEM */ + VTable *pVtab; /* Used when p4type is P4_VTAB */ + KeyInfo *pKeyInfo; /* Used when p4type is P4_KEYINFO */ + int *ai; /* Used when p4type is P4_INTARRAY */ + SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */ + int (*xAdvance)(BtCursor *, int *); + } p4; +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + char *zComment; /* Comment to improve readability */ +#endif +#ifdef VDBE_PROFILE + u32 cnt; /* Number of times this instruction was executed */ + u64 cycles; /* Total time spent executing this instruction */ +#endif +#ifdef SQLITE_VDBE_COVERAGE + int iSrcLine; /* Source-code line that generated this opcode */ +#endif +}; +typedef struct VdbeOp VdbeOp; + + +/* +** A sub-routine used to implement a trigger program. +*/ +struct SubProgram { + VdbeOp *aOp; /* Array of opcodes for sub-program */ + int nOp; /* Elements in aOp[] */ + int nMem; /* Number of memory cells required */ + int nCsr; /* Number of cursors required */ + int nOnce; /* Number of OP_Once instructions */ + void *token; /* id that may be used to recursive triggers */ + SubProgram *pNext; /* Next sub-program already visited */ +}; + +/* +** A smaller version of VdbeOp used for the VdbeAddOpList() function because +** it takes up less space. +*/ +struct VdbeOpList { + u8 opcode; /* What operation to perform */ + signed char p1; /* First operand */ + signed char p2; /* Second parameter (often the jump destination) */ + signed char p3; /* Third parameter */ +}; +typedef struct VdbeOpList VdbeOpList; + +/* +** Allowed values of VdbeOp.p4type +*/ +#define P4_NOTUSED 0 /* The P4 parameter is not used */ +#define P4_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */ +#define P4_STATIC (-2) /* Pointer to a static string */ +#define P4_COLLSEQ (-4) /* P4 is a pointer to a CollSeq structure */ +#define P4_FUNCDEF (-5) /* P4 is a pointer to a FuncDef structure */ +#define P4_KEYINFO (-6) /* P4 is a pointer to a KeyInfo structure */ +#define P4_MEM (-8) /* P4 is a pointer to a Mem* structure */ +#define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */ +#define P4_VTAB (-10) /* P4 is a pointer to an sqlite3_vtab structure */ +#define P4_MPRINTF (-11) /* P4 is a string obtained from sqlite3_mprintf() */ +#define P4_REAL (-12) /* P4 is a 64-bit floating point value */ +#define P4_INT64 (-13) /* P4 is a 64-bit signed integer */ +#define P4_INT32 (-14) /* P4 is a 32-bit signed integer */ +#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */ +#define P4_SUBPROGRAM (-18) /* P4 is a pointer to a SubProgram structure */ +#define P4_ADVANCE (-19) /* P4 is a pointer to BtreeNext() or BtreePrev() */ + +/* Error message codes for OP_Halt */ +#define P5_ConstraintNotNull 1 +#define P5_ConstraintUnique 2 +#define P5_ConstraintCheck 3 +#define P5_ConstraintFK 4 + +/* +** The Vdbe.aColName array contains 5n Mem structures, where n is the +** number of columns of data returned by the statement. +*/ +#define COLNAME_NAME 0 +#define COLNAME_DECLTYPE 1 +#define COLNAME_DATABASE 2 +#define COLNAME_TABLE 3 +#define COLNAME_COLUMN 4 +#ifdef SQLITE_ENABLE_COLUMN_METADATA +# define COLNAME_N 5 /* Number of COLNAME_xxx symbols */ +#else +# ifdef SQLITE_OMIT_DECLTYPE +# define COLNAME_N 1 /* Store only the name */ +# else +# define COLNAME_N 2 /* Store the name and decltype */ +# endif +#endif + +/* +** 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. +*/ +#define ADDR(X) (-1-(X)) + +/* +** The makefile scans the vdbe.c source file and creates the "opcodes.h" +** header file that defines a number for each opcode used by the VDBE. +*/ +/************** Include opcodes.h in the middle of vdbe.h ********************/ +/************** Begin file opcodes.h *****************************************/ +/* Automatically generated. Do not edit */ +/* See the mkopcodeh.awk script for details */ +#define OP_Function 1 /* synopsis: r[P3]=func(r[P2@P5]) */ +#define OP_Savepoint 2 +#define OP_AutoCommit 3 +#define OP_Transaction 4 +#define OP_SorterNext 5 +#define OP_PrevIfOpen 6 +#define OP_NextIfOpen 7 +#define OP_Prev 8 +#define OP_Next 9 +#define OP_AggStep 10 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_Checkpoint 11 +#define OP_JournalMode 12 +#define OP_Vacuum 13 +#define OP_VFilter 14 /* synopsis: iplan=r[P3] zplan='P4' */ +#define OP_VUpdate 15 /* synopsis: data=r[P3@P2] */ +#define OP_Goto 16 +#define OP_Gosub 17 +#define OP_Return 18 +#define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */ +#define OP_InitCoroutine 20 +#define OP_EndCoroutine 21 +#define OP_Yield 22 +#define OP_HaltIfNull 23 /* synopsis: if r[P3]=null halt */ +#define OP_Halt 24 +#define OP_Integer 25 /* synopsis: r[P2]=P1 */ +#define OP_Int64 26 /* synopsis: r[P2]=P4 */ +#define OP_String 27 /* synopsis: r[P2]='P4' (len=P1) */ +#define OP_Null 28 /* synopsis: r[P2..P3]=NULL */ +#define OP_SoftNull 29 /* synopsis: r[P1]=NULL */ +#define OP_Blob 30 /* synopsis: r[P2]=P4 (len=P1) */ +#define OP_Variable 31 /* synopsis: r[P2]=parameter(P1,P4) */ +#define OP_Move 32 /* synopsis: r[P2@P3]=r[P1@P3] */ +#define OP_Copy 33 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ +#define OP_SCopy 34 /* synopsis: r[P2]=r[P1] */ +#define OP_ResultRow 35 /* synopsis: output=r[P1@P2] */ +#define OP_CollSeq 36 +#define OP_AddImm 37 /* synopsis: r[P1]=r[P1]+P2 */ +#define OP_MustBeInt 38 +#define OP_RealAffinity 39 +#define OP_Cast 40 /* synopsis: affinity(r[P1]) */ +#define OP_Permutation 41 +#define OP_Compare 42 /* synopsis: r[P1@P3] <-> r[P2@P3] */ +#define OP_Jump 43 +#define OP_Once 44 +#define OP_If 45 +#define OP_IfNot 46 +#define OP_Column 47 /* synopsis: r[P3]=PX */ +#define OP_Affinity 48 /* synopsis: affinity(r[P1@P2]) */ +#define OP_MakeRecord 49 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ +#define OP_Count 50 /* synopsis: r[P2]=count() */ +#define OP_ReadCookie 51 +#define OP_SetCookie 52 +#define OP_ReopenIdx 53 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenRead 54 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenWrite 55 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenAutoindex 56 /* synopsis: nColumn=P2 */ +#define OP_OpenEphemeral 57 /* synopsis: nColumn=P2 */ +#define OP_SorterOpen 58 +#define OP_SequenceTest 59 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ +#define OP_OpenPseudo 60 /* synopsis: P3 columns in r[P2] */ +#define OP_Close 61 +#define OP_SeekLT 62 /* synopsis: key=r[P3@P4] */ +#define OP_SeekLE 63 /* synopsis: key=r[P3@P4] */ +#define OP_SeekGE 64 /* synopsis: key=r[P3@P4] */ +#define OP_SeekGT 65 /* synopsis: key=r[P3@P4] */ +#define OP_Seek 66 /* synopsis: intkey=r[P2] */ +#define OP_NoConflict 67 /* synopsis: key=r[P3@P4] */ +#define OP_NotFound 68 /* synopsis: key=r[P3@P4] */ +#define OP_Found 69 /* synopsis: key=r[P3@P4] */ +#define OP_NotExists 70 /* synopsis: intkey=r[P3] */ +#define OP_Or 71 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ +#define OP_And 72 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ +#define OP_Sequence 73 /* synopsis: r[P2]=cursor[P1].ctr++ */ +#define OP_NewRowid 74 /* synopsis: r[P2]=rowid */ +#define OP_Insert 75 /* synopsis: intkey=r[P3] data=r[P2] */ +#define OP_IsNull 76 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ +#define OP_NotNull 77 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ +#define OP_Ne 78 /* same as TK_NE, synopsis: if r[P1]!=r[P3] goto P2 */ +#define OP_Eq 79 /* same as TK_EQ, synopsis: if r[P1]==r[P3] goto P2 */ +#define OP_Gt 80 /* same as TK_GT, synopsis: if r[P1]>r[P3] goto P2 */ +#define OP_Le 81 /* same as TK_LE, synopsis: if r[P1]<=r[P3] goto P2 */ +#define OP_Lt 82 /* same as TK_LT, synopsis: if r[P1]=r[P3] goto P2 */ +#define OP_InsertInt 84 /* synopsis: intkey=P3 data=r[P2] */ +#define OP_BitAnd 85 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ +#define OP_BitOr 86 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ +#define OP_ShiftLeft 87 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */ +#define OP_Add 89 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ +#define OP_Subtract 90 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ +#define OP_Multiply 91 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ +#define OP_Divide 92 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ +#define OP_Remainder 93 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ +#define OP_Concat 94 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ +#define OP_Delete 95 +#define OP_BitNot 96 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */ +#define OP_String8 97 /* same as TK_STRING, synopsis: r[P2]='P4' */ +#define OP_ResetCount 98 +#define OP_SorterCompare 99 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ +#define OP_SorterData 100 /* synopsis: r[P2]=data */ +#define OP_RowKey 101 /* synopsis: r[P2]=key */ +#define OP_RowData 102 /* synopsis: r[P2]=data */ +#define OP_Rowid 103 /* synopsis: r[P2]=rowid */ +#define OP_NullRow 104 +#define OP_Last 105 +#define OP_SorterSort 106 +#define OP_Sort 107 +#define OP_Rewind 108 +#define OP_SorterInsert 109 +#define OP_IdxInsert 110 /* synopsis: key=r[P2] */ +#define OP_IdxDelete 111 /* synopsis: key=r[P2@P3] */ +#define OP_IdxRowid 112 /* synopsis: r[P2]=rowid */ +#define OP_IdxLE 113 /* synopsis: key=r[P3@P4] */ +#define OP_IdxGT 114 /* synopsis: key=r[P3@P4] */ +#define OP_IdxLT 115 /* synopsis: key=r[P3@P4] */ +#define OP_IdxGE 116 /* synopsis: key=r[P3@P4] */ +#define OP_Destroy 117 +#define OP_Clear 118 +#define OP_ResetSorter 119 +#define OP_CreateIndex 120 /* synopsis: r[P2]=root iDb=P1 */ +#define OP_CreateTable 121 /* synopsis: r[P2]=root iDb=P1 */ +#define OP_ParseSchema 122 +#define OP_LoadAnalysis 123 +#define OP_DropTable 124 +#define OP_DropIndex 125 +#define OP_DropTrigger 126 +#define OP_IntegrityCk 127 +#define OP_RowSetAdd 128 /* synopsis: rowset(P1)=r[P2] */ +#define OP_RowSetRead 129 /* synopsis: r[P3]=rowset(P1) */ +#define OP_RowSetTest 130 /* synopsis: if r[P3] in rowset(P1) goto P2 */ +#define OP_Program 131 +#define OP_Param 132 +#define OP_Real 133 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ +#define OP_FkCounter 134 /* synopsis: fkctr[P1]+=P2 */ +#define OP_FkIfZero 135 /* synopsis: if fkctr[P1]==0 goto P2 */ +#define OP_MemMax 136 /* synopsis: r[P1]=max(r[P1],r[P2]) */ +#define OP_IfPos 137 /* synopsis: if r[P1]>0 goto P2 */ +#define OP_IfNeg 138 /* synopsis: r[P1]+=P3, if r[P1]<0 goto P2 */ +#define OP_IfNotZero 139 /* synopsis: if r[P1]!=0 then r[P1]+=P3, goto P2 */ +#define OP_DecrJumpZero 140 /* synopsis: if (--r[P1])==0 goto P2 */ +#define OP_JumpZeroIncr 141 /* synopsis: if (r[P1]++)==0 ) goto P2 */ +#define OP_AggFinal 142 /* synopsis: accum=r[P1] N=P2 */ +#define OP_IncrVacuum 143 +#define OP_Expire 144 +#define OP_TableLock 145 /* synopsis: iDb=P1 root=P2 write=P3 */ +#define OP_VBegin 146 +#define OP_VCreate 147 +#define OP_VDestroy 148 +#define OP_VOpen 149 +#define OP_VColumn 150 /* synopsis: r[P3]=vcolumn(P2) */ +#define OP_VNext 151 +#define OP_VRename 152 +#define OP_Pagecount 153 +#define OP_MaxPgcnt 154 +#define OP_Init 155 /* synopsis: Start at P2 */ +#define OP_Noop 156 +#define OP_Explain 157 + + +/* Properties such as "out2" or "jump" that are specified in +** comments following the "case" for each opcode in the vdbe.c +** are encoded into bitvectors as follows: +*/ +#define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */ +#define OPFLG_IN1 0x0002 /* in1: P1 is an input */ +#define OPFLG_IN2 0x0004 /* in2: P2 is an input */ +#define OPFLG_IN3 0x0008 /* in3: P3 is an input */ +#define OPFLG_OUT2 0x0010 /* out2: P2 is an output */ +#define OPFLG_OUT3 0x0020 /* out3: P3 is an output */ +#define OPFLG_INITIALIZER {\ +/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,\ +/* 8 */ 0x01, 0x01, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\ +/* 16 */ 0x01, 0x01, 0x02, 0x12, 0x01, 0x02, 0x03, 0x08,\ +/* 24 */ 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10,\ +/* 32 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x03, 0x02,\ +/* 40 */ 0x02, 0x00, 0x00, 0x01, 0x01, 0x03, 0x03, 0x00,\ +/* 48 */ 0x00, 0x00, 0x10, 0x10, 0x08, 0x00, 0x00, 0x00,\ +/* 56 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09,\ +/* 64 */ 0x09, 0x09, 0x04, 0x09, 0x09, 0x09, 0x09, 0x26,\ +/* 72 */ 0x26, 0x10, 0x10, 0x00, 0x03, 0x03, 0x0b, 0x0b,\ +/* 80 */ 0x0b, 0x0b, 0x0b, 0x0b, 0x00, 0x26, 0x26, 0x26,\ +/* 88 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00,\ +/* 96 */ 0x12, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\ +/* 104 */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x04, 0x04, 0x00,\ +/* 112 */ 0x10, 0x01, 0x01, 0x01, 0x01, 0x10, 0x00, 0x00,\ +/* 120 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 128 */ 0x06, 0x23, 0x0b, 0x01, 0x10, 0x10, 0x00, 0x01,\ +/* 136 */ 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x01,\ +/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,\ +/* 152 */ 0x00, 0x10, 0x10, 0x01, 0x00, 0x00,} + +/************** End of opcodes.h *********************************************/ +/************** Continuing where we left off in vdbe.h ***********************/ + +/* +** Prototypes for the VDBE interface. See comments on the implementation +** for a description of what each of these routines does. +*/ +SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse*); +SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe*,int); +SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe*,int,int); +SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe*,int,int,int); +SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int); +SQLITE_PRIVATE int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int); +SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int); +SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno); +SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); +SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1); +SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2); +SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3); +SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u8 P5); +SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr); +SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe*, int addr); +SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op); +SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N); +SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse*, Index*); +SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int); +SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); +SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3*,Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*); +SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int); +SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*); +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *, int); +#endif +SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe*); +SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int); +SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*)); +SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*); +SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int); +SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*); +SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*); +SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8); +SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int); +#ifndef SQLITE_OMIT_TRACE +SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); +#endif +SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); + +SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); +SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); +SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int); +SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **); + +typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); +SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*); + +#ifndef SQLITE_OMIT_TRIGGER +SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); +#endif + +/* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on +** each VDBE opcode. +** +** Use the SQLITE_ENABLE_MODULE_COMMENTS macro to see some extra no-op +** comments in VDBE programs that show key decision points in the code +** generator. +*/ +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS +SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe*, const char*, ...); +# define VdbeComment(X) sqlite3VdbeComment X +SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe*, const char*, ...); +# define VdbeNoopComment(X) sqlite3VdbeNoopComment X +# ifdef SQLITE_ENABLE_MODULE_COMMENTS +# define VdbeModuleComment(X) sqlite3VdbeNoopComment X +# else +# define VdbeModuleComment(X) +# endif +#else +# define VdbeComment(X) +# define VdbeNoopComment(X) +# define VdbeModuleComment(X) +#endif + +/* +** The VdbeCoverage macros are used to set a coverage testing point +** for VDBE branch instructions. The coverage testing points are line +** numbers in the sqlite3.c source file. VDBE branch coverage testing +** only works with an amalagmation build. That's ok since a VDBE branch +** coverage build designed for testing the test suite only. No application +** should ever ship with VDBE branch coverage measuring turned on. +** +** VdbeCoverage(v) // Mark the previously coded instruction +** // as a branch +** +** VdbeCoverageIf(v, conditional) // Mark previous if conditional true +** +** VdbeCoverageAlwaysTaken(v) // Previous branch is always taken +** +** VdbeCoverageNeverTaken(v) // Previous branch is never taken +** +** Every VDBE branch operation must be tagged with one of the macros above. +** If not, then when "make test" is run with -DSQLITE_VDBE_COVERAGE and +** -DSQLITE_DEBUG then an ALWAYS() will fail in the vdbeTakeBranch() +** routine in vdbe.c, alerting the developer to the missed tag. +*/ +#ifdef SQLITE_VDBE_COVERAGE +SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe*,int); +# define VdbeCoverage(v) sqlite3VdbeSetLineNumber(v,__LINE__) +# define VdbeCoverageIf(v,x) if(x)sqlite3VdbeSetLineNumber(v,__LINE__) +# define VdbeCoverageAlwaysTaken(v) sqlite3VdbeSetLineNumber(v,2); +# define VdbeCoverageNeverTaken(v) sqlite3VdbeSetLineNumber(v,1); +# define VDBE_OFFSET_LINENO(x) (__LINE__+x) +#else +# define VdbeCoverage(v) +# define VdbeCoverageIf(v,x) +# define VdbeCoverageAlwaysTaken(v) +# define VdbeCoverageNeverTaken(v) +# define VDBE_OFFSET_LINENO(x) 0 +#endif + +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS +SQLITE_PRIVATE void sqlite3VdbeScanStatus(Vdbe*, int, int, int, LogEst, const char*); +#else +# define sqlite3VdbeScanStatus(a,b,c,d,e) +#endif + +#endif + +/************** End of vdbe.h ************************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ +/************** Include pager.h in the middle of sqliteInt.h *****************/ +/************** Begin file pager.h *******************************************/ +/* +** 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. +** +************************************************************************* +** 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. +*/ + +#ifndef _PAGER_H_ +#define _PAGER_H_ + +/* +** Default maximum size for persistent journal files. A negative +** value means no limit. This value may be overridden using the +** sqlite3PagerJournalSizeLimit() API. See also "PRAGMA journal_size_limit". +*/ +#ifndef SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT + #define SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT -1 +#endif + +/* +** The type used to represent a page number. The first page in a file +** is called page 1. 0 is used to represent "not a page". +*/ +typedef u32 Pgno; + +/* +** Each open file is managed by a separate instance of the "Pager" structure. +*/ +typedef struct Pager Pager; + +/* +** Handle type for pages. +*/ +typedef struct PgHdr DbPage; + +/* +** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is +** reserved for working around a windows/posix incompatibility). It is +** used in the journal to signify that the remainder of the journal file +** is devoted to storing a master journal name - there are no more pages to +** roll back. See comments for function writeMasterJournal() in pager.c +** for details. +*/ +#define PAGER_MJ_PGNO(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1)) + +/* +** Allowed values for the flags parameter to sqlite3PagerOpen(). +** +** NOTE: These values must match the corresponding BTREE_ values in btree.h. +*/ +#define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */ +#define PAGER_MEMORY 0x0002 /* In-memory database */ + +/* +** Valid values for the second argument to sqlite3PagerLockingMode(). +*/ +#define PAGER_LOCKINGMODE_QUERY -1 +#define PAGER_LOCKINGMODE_NORMAL 0 +#define PAGER_LOCKINGMODE_EXCLUSIVE 1 + +/* +** Numeric constants that encode the journalmode. +*/ +#define PAGER_JOURNALMODE_QUERY (-1) /* Query the value of journalmode */ +#define PAGER_JOURNALMODE_DELETE 0 /* Commit by deleting journal file */ +#define PAGER_JOURNALMODE_PERSIST 1 /* Commit by zeroing journal header */ +#define PAGER_JOURNALMODE_OFF 2 /* Journal omitted. */ +#define PAGER_JOURNALMODE_TRUNCATE 3 /* Commit by truncating journal */ +#define PAGER_JOURNALMODE_MEMORY 4 /* In-memory journal file */ +#define PAGER_JOURNALMODE_WAL 5 /* Use write-ahead logging */ + +/* +** Flags that make up the mask passed to sqlite3PagerAcquire(). +*/ +#define PAGER_GET_NOCONTENT 0x01 /* Do not load data from disk */ +#define PAGER_GET_READONLY 0x02 /* Read-only page is acceptable */ + +/* +** Flags for sqlite3PagerSetFlags() +*/ +#define PAGER_SYNCHRONOUS_OFF 0x01 /* PRAGMA synchronous=OFF */ +#define PAGER_SYNCHRONOUS_NORMAL 0x02 /* PRAGMA synchronous=NORMAL */ +#define PAGER_SYNCHRONOUS_FULL 0x03 /* PRAGMA synchronous=FULL */ +#define PAGER_SYNCHRONOUS_MASK 0x03 /* Mask for three values above */ +#define PAGER_FULLFSYNC 0x04 /* PRAGMA fullfsync=ON */ +#define PAGER_CKPT_FULLFSYNC 0x08 /* PRAGMA checkpoint_fullfsync=ON */ +#define PAGER_CACHESPILL 0x10 /* PRAGMA cache_spill=ON */ +#define PAGER_FLAGS_MASK 0x1c /* All above except SYNCHRONOUS */ + +/* +** The remainder of this file contains the declarations of the functions +** that make up the Pager sub-system API. See source code comments for +** a detailed description of each routine. +*/ + +/* Open and close a Pager connection. */ +SQLITE_PRIVATE int sqlite3PagerOpen( + sqlite3_vfs*, + Pager **ppPager, + const char*, + int, + int, + int, + void(*)(DbPage*) +); +SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager); +SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*); + +/* Functions used to configure a Pager object. */ +SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *); +SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u32*, int); +SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int); +SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int); +SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64); +SQLITE_PRIVATE void sqlite3PagerShrink(Pager*); +SQLITE_PRIVATE void sqlite3PagerSetFlags(Pager*,unsigned); +SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int); +SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *, int); +SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager*); +SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager*); +SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *, i64); +SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager*); + +/* Functions used to obtain and release page references. */ +SQLITE_PRIVATE int sqlite3PagerAcquire(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag); +#define sqlite3PagerGet(A,B,C) sqlite3PagerAcquire(A,B,C,0) +SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno); +SQLITE_PRIVATE void sqlite3PagerRef(DbPage*); +SQLITE_PRIVATE void sqlite3PagerUnref(DbPage*); +SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage*); + +/* Operations on page references. */ +SQLITE_PRIVATE int sqlite3PagerWrite(DbPage*); +SQLITE_PRIVATE void sqlite3PagerDontWrite(DbPage*); +SQLITE_PRIVATE int sqlite3PagerMovepage(Pager*,DbPage*,Pgno,int); +SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage*); +SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *); +SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *); + +/* Functions used to manage pager transactions and savepoints. */ +SQLITE_PRIVATE void sqlite3PagerPagecount(Pager*, int*); +SQLITE_PRIVATE int sqlite3PagerBegin(Pager*, int exFlag, int); +SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, int); +SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager*); +SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager, const char *zMaster); +SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager*); +SQLITE_PRIVATE int sqlite3PagerRollback(Pager*); +SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int n); +SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint); +SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager); + +#ifndef SQLITE_OMIT_WAL +SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*); +SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager); +SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager); +SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen); +SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager); +#endif + +#ifdef SQLITE_ENABLE_ZIPVFS +SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager); +#endif + +/* Functions used to query pager state and configuration. */ +SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*); +SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager*); +SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*); +SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*); +SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*, int); +SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager*); +SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*); +SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*); +SQLITE_PRIVATE int sqlite3PagerNosync(Pager*); +SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*); +SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*); +SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *); +SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *); +SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *); + +/* Functions used to truncate the database file. */ +SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno); + +SQLITE_PRIVATE void sqlite3PagerRekey(DbPage*, Pgno, u16); + +#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL) +SQLITE_PRIVATE void *sqlite3PagerCodec(DbPage *); +#endif + +/* Functions to support testing and debugging. */ +#if !defined(NDEBUG) || defined(SQLITE_TEST) +SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage*); +SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage*); +#endif +#ifdef SQLITE_TEST +SQLITE_PRIVATE int *sqlite3PagerStats(Pager*); +SQLITE_PRIVATE void sqlite3PagerRefdump(Pager*); + void disable_simulated_io_errors(void); + void enable_simulated_io_errors(void); +#else +# define disable_simulated_io_errors() +# define enable_simulated_io_errors() +#endif + +#endif /* _PAGER_H_ */ + +/************** End of pager.h ***********************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ +/************** Include pcache.h in the middle of sqliteInt.h ****************/ +/************** Begin file pcache.h ******************************************/ +/* +** 2008 August 05 +** +** 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 the interface that the sqlite page cache +** subsystem. +*/ + +#ifndef _PCACHE_H_ + +typedef struct PgHdr PgHdr; +typedef struct PCache PCache; + +/* +** Every page in the cache is controlled by an instance of the following +** structure. +*/ +struct PgHdr { + sqlite3_pcache_page *pPage; /* Pcache object page handle */ + void *pData; /* Page data */ + void *pExtra; /* Extra content */ + PgHdr *pDirty; /* Transient list of dirty pages */ + Pager *pPager; /* The pager this page is part of */ + Pgno pgno; /* Page number for this page */ +#ifdef SQLITE_CHECK_PAGES + u32 pageHash; /* Hash of page content */ +#endif + u16 flags; /* PGHDR flags defined below */ + + /********************************************************************** + ** Elements above are public. All that follows is private to pcache.c + ** and should not be accessed by other modules. + */ + i16 nRef; /* Number of users of this page */ + PCache *pCache; /* Cache that owns this page */ + + PgHdr *pDirtyNext; /* Next element in list of dirty pages */ + PgHdr *pDirtyPrev; /* Previous element in list of dirty pages */ +}; + +/* Bit values for PgHdr.flags */ +#define PGHDR_DIRTY 0x002 /* Page has changed */ +#define PGHDR_NEED_SYNC 0x004 /* Fsync the rollback journal before + ** writing this page to the database */ +#define PGHDR_NEED_READ 0x008 /* Content is unread */ +#define PGHDR_REUSE_UNLIKELY 0x010 /* A hint that reuse is unlikely */ +#define PGHDR_DONT_WRITE 0x020 /* Do not write content to disk */ + +#define PGHDR_MMAP 0x040 /* This is an mmap page object */ + +/* Initialize and shutdown the page cache subsystem */ +SQLITE_PRIVATE int sqlite3PcacheInitialize(void); +SQLITE_PRIVATE void sqlite3PcacheShutdown(void); + +/* Page cache buffer management: +** These routines implement SQLITE_CONFIG_PAGECACHE. +*/ +SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *, int sz, int n); + +/* Create a new pager cache. +** Under memory stress, invoke xStress to try to make pages clean. +** Only clean and unpinned pages can be reclaimed. +*/ +SQLITE_PRIVATE int sqlite3PcacheOpen( + int szPage, /* Size of every page */ + int szExtra, /* Extra space associated with each page */ + int bPurgeable, /* True if pages are on backing store */ + int (*xStress)(void*, PgHdr*), /* Call to try to make pages clean */ + void *pStress, /* Argument to xStress */ + PCache *pToInit /* Preallocated space for the PCache */ +); + +/* Modify the page-size after the cache has been created. */ +SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *, int); + +/* Return the size in bytes of a PCache object. Used to preallocate +** storage space. +*/ +SQLITE_PRIVATE int sqlite3PcacheSize(void); + +/* One release per successful fetch. Page is pinned until released. +** Reference counted. +*/ +SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch(PCache*, Pgno, int createFlag); +SQLITE_PRIVATE int sqlite3PcacheFetchStress(PCache*, Pgno, sqlite3_pcache_page**); +SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish(PCache*, Pgno, sqlite3_pcache_page *pPage); +SQLITE_PRIVATE void sqlite3PcacheRelease(PgHdr*); + +SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr*); /* Remove page from cache */ +SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr*); /* Make sure page is marked dirty */ +SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr*); /* Mark a single page as clean */ +SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache*); /* Mark all dirty list pages as clean */ + +/* Change a page number. Used by incr-vacuum. */ +SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr*, Pgno); + +/* Remove all pages with pgno>x. Reset the cache if x==0 */ +SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache*, Pgno x); + +/* Get a list of all dirty pages in the cache, sorted by page number */ +SQLITE_PRIVATE PgHdr *sqlite3PcacheDirtyList(PCache*); + +/* Reset and close the cache object */ +SQLITE_PRIVATE void sqlite3PcacheClose(PCache*); + +/* Clear flags from pages of the page cache */ +SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *); + +/* Discard the contents of the cache */ +SQLITE_PRIVATE void sqlite3PcacheClear(PCache*); + +/* Return the total number of outstanding page references */ +SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache*); + +/* Increment the reference count of an existing page */ +SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr*); + +SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr*); + +/* Return the total number of pages stored in the cache */ +SQLITE_PRIVATE int sqlite3PcachePagecount(PCache*); + +#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) +/* Iterate through all dirty pages currently stored in the cache. This +** interface is only available if SQLITE_CHECK_PAGES is defined when the +** library is built. +*/ +SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)); +#endif + +/* Set and get the suggested cache-size for the specified pager-cache. +** +** If no global maximum is configured, then the system attempts to limit +** the total number of pages cached by purgeable pager-caches to the sum +** of the suggested cache-sizes. +*/ +SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *, int); +#ifdef SQLITE_TEST +SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *); +#endif + +/* Free up as much memory as possible from the page cache */ +SQLITE_PRIVATE void sqlite3PcacheShrink(PCache*); + +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT +/* Try to return memory used by the pcache module to the main memory heap */ +SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int); +#endif + +#ifdef SQLITE_TEST +SQLITE_PRIVATE void sqlite3PcacheStats(int*,int*,int*,int*); +#endif + +SQLITE_PRIVATE void sqlite3PCacheSetDefault(void); + +/* Return the header size */ +SQLITE_PRIVATE int sqlite3HeaderSizePcache(void); +SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void); + +#endif /* _PCACHE_H_ */ + +/************** End of pcache.h **********************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ + +/************** Include os.h in the middle of sqliteInt.h ********************/ +/************** Begin file os.h **********************************************/ +/* +** 2001 September 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 header file (together with is companion C source-code file +** "os.c") attempt to abstract the underlying operating system so that +** the SQLite library will work on both POSIX and windows systems. +** +** This header file is #include-ed by sqliteInt.h and thus ends up +** being included by every source file. +*/ +#ifndef _SQLITE_OS_H_ +#define _SQLITE_OS_H_ + +/* +** Attempt to automatically detect the operating system and setup the +** necessary pre-processor macros for it. +*/ +/************** Include os_setup.h in the middle of os.h *********************/ +/************** Begin file os_setup.h ****************************************/ +/* +** 2013 November 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 pre-processor directives related to operating system +** detection and/or setup. +*/ +#ifndef _OS_SETUP_H_ +#define _OS_SETUP_H_ + +/* +** Figure out if we are dealing with Unix, Windows, or some other operating +** system. +** +** After the following block of preprocess macros, all of SQLITE_OS_UNIX, +** SQLITE_OS_WIN, and SQLITE_OS_OTHER will defined to either 1 or 0. One of +** the three will be 1. The other two will be 0. +*/ +#if defined(SQLITE_OS_OTHER) +# if SQLITE_OS_OTHER==1 +# undef SQLITE_OS_UNIX +# define SQLITE_OS_UNIX 0 +# undef SQLITE_OS_WIN +# define SQLITE_OS_WIN 0 +# else +# undef SQLITE_OS_OTHER +# endif +#endif +#if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER) +# define SQLITE_OS_OTHER 0 +# ifndef SQLITE_OS_WIN +# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \ + defined(__MINGW32__) || defined(__BORLANDC__) +# define SQLITE_OS_WIN 1 +# define SQLITE_OS_UNIX 0 +# else +# define SQLITE_OS_WIN 0 +# define SQLITE_OS_UNIX 1 +# endif +# else +# define SQLITE_OS_UNIX 0 +# endif +#else +# ifndef SQLITE_OS_WIN +# define SQLITE_OS_WIN 0 +# endif +#endif + +#endif /* _OS_SETUP_H_ */ + +/************** End of os_setup.h ********************************************/ +/************** Continuing where we left off in os.h *************************/ + +/* If the SET_FULLSYNC macro is not defined above, then make it +** a no-op +*/ +#ifndef SET_FULLSYNC +# define SET_FULLSYNC(x,y) +#endif + +/* +** The default size of a disk sector +*/ +#ifndef SQLITE_DEFAULT_SECTOR_SIZE +# define SQLITE_DEFAULT_SECTOR_SIZE 4096 +#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 -DSQLITE_TEMP_FILE_PREFIX=myprefix_ on the compiler command line. +** +** 2006-10-31: The default prefix used to be "sqlite_". But then +** Mcafee started using SQLite in their anti-virus product and it +** started putting files with the "sqlite" name in the c:/temp folder. +** This annoyed many windows users. Those users would then do a +** Google search for "sqlite", find the telephone numbers of the +** developers and call to wake them up at night and complain. +** For this reason, the default name prefix is changed to be "sqlite" +** spelled backwards. So the temp files are still identified, but +** anybody smart enough to figure out the code is also likely smart +** enough to know that calling the developer will not help get rid +** of the file. +*/ +#ifndef SQLITE_TEMP_FILE_PREFIX +# define SQLITE_TEMP_FILE_PREFIX "etilqs_" +#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. +** PENDING: A single process may hold a PENDING lock on a file at +** any one time. Existing SHARED locks may persist, but no new +** SHARED locks may be obtained by other processes. +** EXCLUSIVE: An EXCLUSIVE lock precludes all other locks. +** +** PENDING_LOCK may not be passed directly to sqlite3OsLock(). Instead, a +** process that requests an EXCLUSIVE lock may actually obtain a PENDING +** lock. This can be upgraded to an EXCLUSIVE lock by a subsequent call to +** sqlite3OsLock(). +*/ +#define NO_LOCK 0 +#define SHARED_LOCK 1 +#define RESERVED_LOCK 2 +#define PENDING_LOCK 3 +#define EXCLUSIVE_LOCK 4 + +/* +** File Locking Notes: (Mostly about windows but also some info for Unix) +** +** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because +** those functions are not available. So we use only LockFile() and +** UnlockFile(). +** +** LockFile() prevents not just writing but also reading by other processes. +** A SHARED_LOCK is obtained by locking a single randomly-chosen +** byte out of a specific range of bytes. The lock byte is obtained at +** random so two separate readers can probably access the file at the +** same time, unless they are unlucky and choose the same lock byte. +** An EXCLUSIVE_LOCK is obtained by locking all bytes in the range. +** There can only be one writer. A RESERVED_LOCK is obtained by locking +** a single byte of the file that is designated as the reserved lock byte. +** A PENDING_LOCK is obtained by locking a designated byte different from +** the RESERVED_LOCK byte. +** +** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available, +** which means we can use reader/writer locks. When reader/writer locks +** are used, the lock is placed on the same range of bytes that is used +** for probabilistic locking in Win95/98/ME. Hence, the locking scheme +** will support two or more Win95 readers or two or more WinNT readers. +** But a single Win95 reader will lock out all WinNT readers and a single +** 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. +** +** The same locking strategy and +** byte ranges are used for Unix. This leaves open the possibility 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 +** actual data in the bytes used for locking. The pager never allocates +** the pages involved in locking therefore. SHARED_SIZE is selected so +** that all locks will fit on a single page even at the minimum page size. +** PENDING_BYTE defines the beginning of the locks. By default PENDING_BYTE +** is set high so that we don't have to allocate an unused page except +** for very large databases. But one should test the page skipping logic +** by setting PENDING_BYTE low and running the entire regression suite. +** +** 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. +** +*/ +#ifdef SQLITE_OMIT_WSD +# define PENDING_BYTE (0x40000000) +#else +# define PENDING_BYTE sqlite3PendingByte +#endif +#define RESERVED_BYTE (PENDING_BYTE+1) +#define SHARED_FIRST (PENDING_BYTE+2) +#define SHARED_SIZE 510 + +/* +** Wrapper around OS specific sqlite3_os_init() function. +*/ +SQLITE_PRIVATE int sqlite3OsInit(void); + +/* +** Functions for accessing sqlite3_file methods +*/ +SQLITE_PRIVATE int sqlite3OsClose(sqlite3_file*); +SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset); +SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset); +SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file*, i64 size); +SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file*, int); +SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file*, i64 *pSize); +SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file*, int); +SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file*, int); +SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut); +SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file*,int,void*); +SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file*,int,void*); +#define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0 +SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id); +SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id); +SQLITE_PRIVATE int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **); +SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int, int, int); +SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id); +SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int); +SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64, int, void **); +SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *, i64, void *); + + +/* +** Functions for accessing sqlite3_vfs methods +*/ +SQLITE_PRIVATE int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *); +SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *, const char *, int); +SQLITE_PRIVATE int sqlite3OsAccess(sqlite3_vfs *, const char *, int, int *pResOut); +SQLITE_PRIVATE int sqlite3OsFullPathname(sqlite3_vfs *, const char *, int, char *); +#ifndef SQLITE_OMIT_LOAD_EXTENSION +SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *, const char *); +SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *, int, char *); +SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void); +SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *); +#endif /* SQLITE_OMIT_LOAD_EXTENSION */ +SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *); +SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int); +SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*); + +/* +** Convenience functions for opening and closing files using +** sqlite3_malloc() to obtain space for the file-handle structure. +*/ +SQLITE_PRIVATE int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*); +SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *); + +#endif /* _SQLITE_OS_H_ */ + +/************** End of os.h **************************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ +/************** Include mutex.h in the middle of sqliteInt.h *****************/ +/************** Begin file mutex.h *******************************************/ +/* +** 2007 August 28 +** +** 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 common header for all mutex implementations. +** The sqliteInt.h header #includes this file so that it is available +** to all source files. We break it out in an effort to keep the code +** better organized. +** +** NOTE: source files should *not* #include this header file directly. +** Source files should #include the sqliteInt.h file and let that file +** include this one indirectly. +*/ + + +/* +** Figure out what version of the code to use. The choices are +** +** SQLITE_MUTEX_OMIT No mutex logic. Not even stubs. The +** mutexes implementation cannot be overridden +** at start-time. +** +** SQLITE_MUTEX_NOOP For single-threaded applications. No +** mutual exclusion is provided. But this +** implementation can be overridden at +** start-time. +** +** SQLITE_MUTEX_PTHREADS For multi-threaded applications on Unix. +** +** SQLITE_MUTEX_W32 For multi-threaded applications on Win32. +*/ +#if !SQLITE_THREADSAFE +# define SQLITE_MUTEX_OMIT +#endif +#if SQLITE_THREADSAFE && !defined(SQLITE_MUTEX_NOOP) +# if SQLITE_OS_UNIX +# define SQLITE_MUTEX_PTHREADS +# elif SQLITE_OS_WIN +# define SQLITE_MUTEX_W32 +# else +# define SQLITE_MUTEX_NOOP +# endif +#endif + +#ifdef SQLITE_MUTEX_OMIT +/* +** If this is a no-op implementation, implement everything as macros. +*/ +#define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8) +#define sqlite3_mutex_free(X) +#define sqlite3_mutex_enter(X) +#define sqlite3_mutex_try(X) SQLITE_OK +#define sqlite3_mutex_leave(X) +#define sqlite3_mutex_held(X) ((void)(X),1) +#define sqlite3_mutex_notheld(X) ((void)(X),1) +#define sqlite3MutexAlloc(X) ((sqlite3_mutex*)8) +#define sqlite3MutexInit() SQLITE_OK +#define sqlite3MutexEnd() +#define MUTEX_LOGIC(X) +#else +#define MUTEX_LOGIC(X) X +#endif /* defined(SQLITE_MUTEX_OMIT) */ + +/************** End of mutex.h ***********************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ + + +/* +** 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 safety_level; /* How aggressive at syncing data to disk */ + Schema *pSchema; /* Pointer to database schema (possibly shared) */ +}; + +/* +** An instance of the following structure stores a database schema. +** +** Most Schema objects are associated with a Btree. The exception is +** the Schema for the TEMP databaes (sqlite3.aDb[1]) which is free-standing. +** In shared cache mode, a single Schema object can be shared by multiple +** Btrees that refer to the same underlying BtShared object. +** +** Schema objects are automatically deallocated when the last Btree that +** references them is destroyed. The TEMP Schema is manually freed by +** sqlite3_close(). +* +** A thread must be holding a mutex on the corresponding Btree in order +** to access Schema content. This implies that the thread must also be +** holding a mutex on the sqlite3 connection pointer that owns the Btree. +** For a TEMP Schema, only the connection mutex is required. +*/ +struct Schema { + int schema_cookie; /* Database schema version number for this file */ + int iGeneration; /* Generation counter. Incremented with each change */ + Hash tblHash; /* All tables indexed by name */ + Hash idxHash; /* All (named) indices indexed by name */ + Hash trigHash; /* All triggers indexed by name */ + Hash fkeyHash; /* All foreign keys by referenced table name */ + 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 schemaFlags; /* 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.pSchema->flags field. +*/ +#define DbHasProperty(D,I,P) (((D)->aDb[I].pSchema->schemaFlags&(P))==(P)) +#define DbHasAnyProperty(D,I,P) (((D)->aDb[I].pSchema->schemaFlags&(P))!=0) +#define DbSetProperty(D,I,P) (D)->aDb[I].pSchema->schemaFlags|=(P) +#define DbClearProperty(D,I,P) (D)->aDb[I].pSchema->schemaFlags&=~(P) + +/* +** Allowed values for the DB.pSchema->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) */ + +/* +** The number of different kinds of things that can be limited +** using the sqlite3_limit() interface. +*/ +#define SQLITE_N_LIMIT (SQLITE_LIMIT_WORKER_THREADS+1) + +/* +** Lookaside malloc is a set of fixed-size buffers that can be used +** to satisfy small transient memory allocation requests for objects +** associated with a particular database connection. The use of +** lookaside malloc provides a significant performance enhancement +** (approx 10%) by avoiding numerous malloc/free requests while parsing +** SQL statements. +** +** The Lookaside structure holds configuration information about the +** lookaside malloc subsystem. Each available memory allocation in +** the lookaside subsystem is stored on a linked list of LookasideSlot +** objects. +** +** Lookaside allocations are only allowed for objects that are associated +** with a particular database connection. Hence, schema information cannot +** be stored in lookaside because in shared cache mode the schema information +** is shared by multiple database connections. Therefore, while parsing +** schema information, the Lookaside.bEnabled flag is cleared so that +** lookaside allocations are not used to construct the schema objects. +*/ +struct Lookaside { + u16 sz; /* Size of each buffer in bytes */ + u8 bEnabled; /* False to disable new lookaside allocations */ + u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */ + int nOut; /* Number of buffers currently checked out */ + int mxOut; /* Highwater mark for nOut */ + int anStat[3]; /* 0: hits. 1: size misses. 2: full misses */ + LookasideSlot *pFree; /* List of available buffers */ + void *pStart; /* First byte of available memory space */ + void *pEnd; /* First byte past end of available space */ +}; +struct LookasideSlot { + LookasideSlot *pNext; /* Next buffer in the list of free buffers */ +}; + +/* +** A hash table for function definitions. +** +** Hash each FuncDef structure into one of the FuncDefHash.a[] slots. +** Collisions are on the FuncDef.pHash chain. +*/ +struct FuncDefHash { + FuncDef *a[23]; /* Hash table for functions */ +}; + +#ifdef SQLITE_USER_AUTHENTICATION +/* +** Information held in the "sqlite3" database connection object and used +** to manage user authentication. +*/ +typedef struct sqlite3_userauth sqlite3_userauth; +struct sqlite3_userauth { + u8 authLevel; /* Current authentication level */ + int nAuthPW; /* Size of the zAuthPW in bytes */ + char *zAuthPW; /* Password used to authenticate */ + char *zAuthUser; /* User name used to authenticate */ +}; + +/* Allowed values for sqlite3_userauth.authLevel */ +#define UAUTH_Unknown 0 /* Authentication not yet checked */ +#define UAUTH_Fail 1 /* User authentication failed */ +#define UAUTH_User 2 /* Authenticated as a normal user */ +#define UAUTH_Admin 3 /* Authenticated as an administrator */ + +/* Functions used only by user authorization logic */ +SQLITE_PRIVATE int sqlite3UserAuthTable(const char*); +SQLITE_PRIVATE int sqlite3UserAuthCheckLogin(sqlite3*,const char*,u8*); +SQLITE_PRIVATE void sqlite3UserAuthInit(sqlite3*); +SQLITE_PRIVATE void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**); + +#endif /* SQLITE_USER_AUTHENTICATION */ + +/* +** typedef for the authorization callback function. +*/ +#ifdef SQLITE_USER_AUTHENTICATION + typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*, + const char*, const char*); +#else + typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*, + const char*); +#endif + + +/* +** Each database connection is an instance of the following structure. +*/ +struct sqlite3 { + sqlite3_vfs *pVfs; /* OS Interface */ + struct Vdbe *pVdbe; /* List of active virtual machines */ + CollSeq *pDfltColl; /* The default collating sequence (BINARY) */ + sqlite3_mutex *mutex; /* Connection mutex */ + Db *aDb; /* All backends */ + int nDb; /* Number of backends currently in use */ + int flags; /* Miscellaneous flags. See below */ + i64 lastRowid; /* ROWID of most recent insert (see above) */ + i64 szMmap; /* Default mmap_size setting */ + unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ + int errCode; /* Most recent error code (SQLITE_*) */ + int errMask; /* & result codes with this before returning */ + u16 dbOptFlags; /* Flags to enable/disable optimizations */ + u8 enc; /* Text encoding */ + u8 autoCommit; /* The auto-commit flag. */ + u8 temp_store; /* 1: file 2: memory 0: default */ + u8 mallocFailed; /* True if we have seen a malloc failure */ + u8 dfltLockMode; /* Default locking-mode for attached dbs */ + signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */ + u8 suppressErr; /* Do not issue error messages if true */ + u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */ + u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */ + int nextPagesize; /* Pagesize after VACUUM if >0 */ + u32 magic; /* Magic number for detect library misuse */ + int nChange; /* Value returned by sqlite3_changes() */ + int nTotalChange; /* Value returned by sqlite3_total_changes() */ + int aLimit[SQLITE_N_LIMIT]; /* Limits */ + int nMaxSorterMmap; /* Maximum size of regions mapped by sorter */ + struct sqlite3InitInfo { /* Information used during initialization */ + int newTnum; /* Rootpage of table being initialized */ + u8 iDb; /* Which db file is being initialized */ + u8 busy; /* TRUE if currently initializing */ + u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */ + u8 imposterTable; /* Building an imposter table */ + } init; + int nVdbeActive; /* Number of VDBEs currently running */ + int nVdbeRead; /* Number of active VDBEs that read or write */ + int nVdbeWrite; /* Number of active VDBEs that read and write */ + int nVdbeExec; /* Number of nested calls to VdbeExec() */ + int nVDestroy; /* Number of active OP_VDestroy operations */ + int nExtension; /* Number of loaded extensions */ + void **aExtension; /* Array of shared library handles */ + 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); +#ifndef SQLITE_OMIT_WAL + int (*xWalCallback)(void *, sqlite3 *, const char *, int); + void *pWalArg; +#endif + 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 */ + union { + volatile int isInterrupted; /* True if sqlite3_interrupt has been called */ + double notUsed1; /* Spacer */ + } u1; + Lookaside lookaside; /* Lookaside malloc configuration */ +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth; /* 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 */ + unsigned nProgressOps; /* Number of opcodes for progress callback */ +#endif +#ifndef SQLITE_OMIT_VIRTUALTABLE + int nVTrans; /* Allocated size of aVTrans */ + Hash aModule; /* populated by sqlite3_create_module() */ + VtabCtx *pVtabCtx; /* Context for active vtab connect/create */ + VTable **aVTrans; /* Virtual tables with open transactions */ + VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */ +#endif + FuncDefHash aFunc; /* Hash table of connection functions */ + Hash aCollSeq; /* All collating sequences */ + BusyHandler busyHandler; /* Busy callback */ + Db aDbStatic[2]; /* Static space for the 2 default backends */ + Savepoint *pSavepoint; /* List of active savepoints */ + int busyTimeout; /* Busy handler timeout, in msec */ + int nSavepoint; /* Number of non-transaction savepoints */ + int nStatement; /* Number of nested statement-transactions */ + i64 nDeferredCons; /* Net deferred constraints this transaction. */ + i64 nDeferredImmCons; /* Net deferred immediate constraints */ + int *pnBytesFreed; /* If not NULL, increment this in DbFree() */ +#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY + /* The following variables are all protected by the STATIC_MASTER + ** mutex, not by sqlite3.mutex. They are used by code in notify.c. + ** + ** When X.pUnlockConnection==Y, that means that X is waiting for Y to + ** unlock so that it can proceed. + ** + ** When X.pBlockingConnection==Y, that means that something that X tried + ** tried to do recently failed with an SQLITE_LOCKED error due to locks + ** held by Y. + */ + sqlite3 *pBlockingConnection; /* Connection that caused SQLITE_LOCKED */ + sqlite3 *pUnlockConnection; /* Connection to watch for unlock */ + void *pUnlockArg; /* Argument to xUnlockNotify */ + void (*xUnlockNotify)(void **, int); /* Unlock notify callback */ + sqlite3 *pNextBlocked; /* Next in list of all blocked connections */ +#endif +#ifdef SQLITE_USER_AUTHENTICATION + sqlite3_userauth auth; /* User authentication information */ +#endif +}; + +/* +** A macro to discover the encoding of a database. +*/ +#define SCHEMA_ENC(db) ((db)->aDb[0].pSchema->enc) +#define ENC(db) ((db)->enc) + +/* +** Possible values for the sqlite3.flags. +*/ +#define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */ +#define SQLITE_InternChanges 0x00000002 /* Uncommitted Hash table changes */ +#define SQLITE_FullFSync 0x00000004 /* Use full fsync on the backend */ +#define SQLITE_CkptFullFSync 0x00000008 /* Use full fsync for checkpoint */ +#define SQLITE_CacheSpill 0x00000010 /* OK to spill pager cache */ +#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_VdbeAddopTrace 0x00001000 /* Trace sqlite3VdbeAddOp() calls */ +#define SQLITE_IgnoreChecks 0x00002000 /* Do not enforce check constraints */ +#define SQLITE_ReadUncommitted 0x0004000 /* For shared-cache mode */ +#define SQLITE_LegacyFileFmt 0x00008000 /* Create new databases in format 1 */ +#define SQLITE_RecoveryMode 0x00010000 /* Ignore schema errors */ +#define SQLITE_ReverseOrder 0x00020000 /* Reverse unordered SELECTs */ +#define SQLITE_RecTriggers 0x00040000 /* Enable recursive triggers */ +#define SQLITE_ForeignKeys 0x00080000 /* Enforce foreign key constraints */ +#define SQLITE_AutoIndex 0x00100000 /* Enable automatic indexes */ +#define SQLITE_PreferBuiltin 0x00200000 /* Preference to built-in funcs */ +#define SQLITE_LoadExtension 0x00400000 /* Enable load_extension */ +#define SQLITE_EnableTrigger 0x00800000 /* True to enable triggers */ +#define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */ +#define SQLITE_QueryOnly 0x02000000 /* Disable database changes */ +#define SQLITE_VdbeEQP 0x04000000 /* Debug EXPLAIN QUERY PLAN */ +#define SQLITE_Vacuum 0x08000000 /* Currently in a VACUUM */ + + +/* +** Bits of the sqlite3.dbOptFlags field that are used by the +** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to +** selectively disable various optimizations. +*/ +#define SQLITE_QueryFlattener 0x0001 /* Query flattening */ +#define SQLITE_ColumnCache 0x0002 /* Column cache */ +#define SQLITE_GroupByOrder 0x0004 /* GROUPBY cover of ORDERBY */ +#define SQLITE_FactorOutConst 0x0008 /* Constant factoring */ +/* not used 0x0010 // Was: SQLITE_IdxRealAsInt */ +#define SQLITE_DistinctOpt 0x0020 /* DISTINCT using indexes */ +#define SQLITE_CoverIdxScan 0x0040 /* Covering index scans */ +#define SQLITE_OrderByIdxJoin 0x0080 /* ORDER BY of joins via index */ +#define SQLITE_SubqCoroutine 0x0100 /* Evaluate subqueries as coroutines */ +#define SQLITE_Transitive 0x0200 /* Transitive constraints */ +#define SQLITE_OmitNoopJoin 0x0400 /* Omit unused tables in joins */ +#define SQLITE_Stat34 0x0800 /* Use STAT3 or STAT4 data */ +#define SQLITE_AllOpts 0xffff /* All optimizations */ + +/* +** Macros for testing whether or not optimizations are enabled or disabled. +*/ +#ifndef SQLITE_OMIT_BUILTIN_TEST +#define OptimizationDisabled(db, mask) (((db)->dbOptFlags&(mask))!=0) +#define OptimizationEnabled(db, mask) (((db)->dbOptFlags&(mask))==0) +#else +#define OptimizationDisabled(db, mask) 0 +#define OptimizationEnabled(db, mask) 1 +#endif + +/* +** Return true if it OK to factor constant expressions into the initialization +** code. The argument is a Parse object for the code generator. +*/ +#define ConstFactorOk(P) ((P)->okConstFactor) + +/* +** 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_SICK 0x4b771290 /* Error and awaiting close */ +#define SQLITE_MAGIC_BUSY 0xf03b7906 /* Database currently in use */ +#define SQLITE_MAGIC_ERROR 0xb5357930 /* An SQLITE_MISUSE error occurred */ +#define SQLITE_MAGIC_ZOMBIE 0x64cffc7f /* Close with last statement close */ + +/* +** 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 */ + u16 funcFlags; /* 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 finalizer */ + char *zName; /* SQL name of the function. */ + FuncDef *pHash; /* Next with a different name but the same hash */ + FuncDestructor *pDestructor; /* Reference counted destructor function */ +}; + +/* +** This structure encapsulates a user-function destructor callback (as +** configured using create_function_v2()) and a reference counter. When +** create_function_v2() is called to create a function with a destructor, +** a single object of this type is allocated. FuncDestructor.nRef is set to +** the number of FuncDef objects created (either 1 or 3, depending on whether +** or not the specified encoding is SQLITE_ANY). The FuncDef.pDestructor +** member of each of the new FuncDef objects is set to point to the allocated +** FuncDestructor. +** +** Thereafter, when one of the FuncDef objects is deleted, the reference +** count on this object is decremented. When it reaches 0, the destructor +** is invoked and the FuncDestructor structure freed. +*/ +struct FuncDestructor { + int nRef; + void (*xDestroy)(void *); + void *pUserData; +}; + +/* +** Possible values for FuncDef.flags. Note that the _LENGTH and _TYPEOF +** values must correspond to OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG. There +** are assert() statements in the code to verify this. +*/ +#define SQLITE_FUNC_ENCMASK 0x003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */ +#define SQLITE_FUNC_LIKE 0x004 /* Candidate for the LIKE optimization */ +#define SQLITE_FUNC_CASE 0x008 /* Case-sensitive LIKE-type function */ +#define SQLITE_FUNC_EPHEM 0x010 /* Ephemeral. Delete with VDBE */ +#define SQLITE_FUNC_NEEDCOLL 0x020 /* sqlite3GetFuncCollSeq() might be called */ +#define SQLITE_FUNC_LENGTH 0x040 /* Built-in length() function */ +#define SQLITE_FUNC_TYPEOF 0x080 /* Built-in typeof() function */ +#define SQLITE_FUNC_COUNT 0x100 /* Built-in count(*) aggregate */ +#define SQLITE_FUNC_COALESCE 0x200 /* Built-in coalesce() or ifnull() */ +#define SQLITE_FUNC_UNLIKELY 0x400 /* Built-in unlikely() function */ +#define SQLITE_FUNC_CONSTANT 0x800 /* Constant inputs give a constant output */ +#define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */ + +/* +** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are +** used to create the initializers for the FuncDef structures. +** +** FUNCTION(zName, nArg, iArg, bNC, xFunc) +** Used to create a scalar function definition of a function zName +** implemented by C function xFunc that accepts nArg arguments. The +** value passed as iArg is cast to a (void*) and made available +** as the user-data (sqlite3_user_data()) for the function. If +** argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set. +** +** VFUNCTION(zName, nArg, iArg, bNC, xFunc) +** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag. +** +** AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal) +** Used to create an aggregate function definition implemented by +** the C functions xStep and xFinal. The first four parameters +** are interpreted in the same way as the first 4 parameters to +** FUNCTION(). +** +** LIKEFUNC(zName, nArg, pArg, flags) +** Used to create a scalar function definition of a function zName +** that accepts nArg arguments and is implemented by a call to C +** function likeFunc. Argument pArg is cast to a (void *) and made +** available as the function user-data (sqlite3_user_data()). The +** FuncDef.flags variable is set to the value passed as the flags +** parameter. +*/ +#define FUNCTION(zName, nArg, iArg, bNC, xFunc) \ + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} +#define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \ + {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} +#define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \ + {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\ + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} +#define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \ + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ + pArg, 0, xFunc, 0, 0, #zName, 0, 0} +#define LIKEFUNC(zName, nArg, arg, flags) \ + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \ + (void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0} +#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \ + {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \ + SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0} +#define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \ + {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \ + SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0} + +/* +** All current savepoints are stored in a linked list starting at +** sqlite3.pSavepoint. The first element in the list is the most recently +** opened savepoint. Savepoints are added to the list by the vdbe +** OP_Savepoint instruction. +*/ +struct Savepoint { + char *zName; /* Savepoint name (nul-terminated) */ + i64 nDeferredCons; /* Number of deferred fk violations */ + i64 nDeferredImmCons; /* Number of deferred imm fk. */ + Savepoint *pNext; /* Parent savepoint (if any) */ +}; + +/* +** The following are used as the second parameter to sqlite3Savepoint(), +** and as the P1 argument to the OP_Savepoint instruction. +*/ +#define SAVEPOINT_BEGIN 0 +#define SAVEPOINT_RELEASE 1 +#define SAVEPOINT_ROLLBACK 2 + + +/* +** Each SQLite module (virtual table definition) is defined by an +** instance of the following structure, stored in the sqlite3.aModule +** hash table. +*/ +struct Module { + const sqlite3_module *pModule; /* Callback pointers */ + const char *zName; /* Name passed to create_module() */ + void *pAux; /* pAux passed to create_module() */ + void (*xDestroy)(void *); /* Module destructor 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 *zDflt; /* Original text of the default value */ + char *zType; /* Data type for this column */ + char *zColl; /* Collating sequence. If NULL, use the default */ + u8 notNull; /* An OE_ code for handling a NOT NULL constraint */ + char affinity; /* One of the SQLITE_AFF_... values */ + u8 szEst; /* Estimated size of this column. INT==1 */ + u8 colFlags; /* Boolean properties. See COLFLAG_ defines below */ +}; + +/* Allowed values for Column.colFlags: +*/ +#define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */ +#define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */ + +/* +** 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. +** +** If CollSeq.xCmp is 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*); + void (*xDel)(void*); /* Destructor for pUser */ +}; + +/* +** 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 numbering 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 P4 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. And the NONE type is first. +*/ +#define SQLITE_AFF_NONE 'A' +#define SQLITE_AFF_TEXT 'B' +#define SQLITE_AFF_NUMERIC 'C' +#define SQLITE_AFF_INTEGER 'D' +#define SQLITE_AFF_REAL 'E' + +#define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) + +/* +** The SQLITE_AFF_MASK values masks off the significant bits of an +** affinity value. +*/ +#define SQLITE_AFF_MASK 0x47 + +/* +** Additional bit values that can be ORed with an affinity without +** changing the affinity. +** +** The SQLITE_NOTNULL flag is a combination of NULLEQ and JUMPIFNULL. +** It causes an assert() to fire if either operand to a comparison +** operator is NULL. It is added to certain comparison operators to +** prove that the operands are always NOT NULL. +*/ +#define SQLITE_JUMPIFNULL 0x10 /* jumps if either operand is NULL */ +#define SQLITE_STOREP2 0x20 /* Store result in reg[P2] rather than jump */ +#define SQLITE_NULLEQ 0x80 /* NULL=NULL */ +#define SQLITE_NOTNULL 0x90 /* Assert that operands are never NULL */ + +/* +** An object of this type is created for each virtual table present in +** the database schema. +** +** If the database schema is shared, then there is one instance of this +** structure for each database connection (sqlite3*) that uses the shared +** schema. This is because each database connection requires its own unique +** instance of the sqlite3_vtab* handle used to access the virtual table +** implementation. sqlite3_vtab* handles can not be shared between +** database connections, even when the rest of the in-memory database +** schema is shared, as the implementation often stores the database +** connection handle passed to it via the xConnect() or xCreate() method +** during initialization internally. This database connection handle may +** then be used by the virtual table implementation to access real tables +** within the database. So that they appear as part of the callers +** transaction, these accesses need to be made via the same database +** connection as that used to execute SQL operations on the virtual table. +** +** All VTable objects that correspond to a single table in a shared +** database schema are initially stored in a linked-list pointed to by +** the Table.pVTable member variable of the corresponding Table object. +** When an sqlite3_prepare() operation is required to access the virtual +** table, it searches the list for the VTable that corresponds to the +** database connection doing the preparing so as to use the correct +** sqlite3_vtab* handle in the compiled query. +** +** When an in-memory Table object is deleted (for example when the +** schema is being reloaded for some reason), the VTable objects are not +** deleted and the sqlite3_vtab* handles are not xDisconnect()ed +** immediately. Instead, they are moved from the Table.pVTable list to +** another linked list headed by the sqlite3.pDisconnect member of the +** corresponding sqlite3 structure. They are then deleted/xDisconnected +** next time a statement is prepared using said sqlite3*. This is done +** to avoid deadlock issues involving multiple sqlite3.mutex mutexes. +** Refer to comments above function sqlite3VtabUnlockList() for an +** explanation as to why it is safe to add an entry to an sqlite3.pDisconnect +** list without holding the corresponding sqlite3.mutex mutex. +** +** The memory for objects of this type is always allocated by +** sqlite3DbMalloc(), using the connection handle stored in VTable.db as +** the first argument. +*/ +struct VTable { + sqlite3 *db; /* Database connection associated with this table */ + Module *pMod; /* Pointer to module implementation */ + sqlite3_vtab *pVtab; /* Pointer to vtab instance */ + int nRef; /* Number of pointers to this structure */ + u8 bConstraint; /* True if constraints are supported */ + int iSavepoint; /* Depth of the SAVEPOINT stack */ + VTable *pNext; /* Next in linked list (see above) */ +}; + +/* +** The schema for each SQL table and view is represented in memory +** by an instance of the following structure. +*/ +struct Table { + char *zName; /* Name of the table or view */ + Column *aCol; /* Information about each column */ + Index *pIndex; /* List of SQL indexes on this table. */ + Select *pSelect; /* NULL for tables. Points to definition if a view. */ + FKey *pFKey; /* Linked list of all foreign keys in this table */ + char *zColAff; /* String defining the affinity of each column */ +#ifndef SQLITE_OMIT_CHECK + ExprList *pCheck; /* All CHECK constraints */ +#endif + int tnum; /* Root BTree page for this table */ + i16 iPKey; /* If not negative, use aCol[iPKey] as the rowid */ + i16 nCol; /* Number of columns in this table */ + u16 nRef; /* Number of pointers to this Table */ + LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */ + LogEst szTabRow; /* Estimated size of each table row in bytes */ +#ifdef SQLITE_ENABLE_COSTMULT + LogEst costMult; /* Cost multiplier for using this table */ +#endif + u8 tabFlags; /* Mask of TF_* values */ + u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ +#ifndef SQLITE_OMIT_ALTERTABLE + int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */ +#endif +#ifndef SQLITE_OMIT_VIRTUALTABLE + int nModuleArg; /* Number of arguments to the module */ + char **azModuleArg; /* Text of all module args. [0] is module name */ + VTable *pVTable; /* List of VTable objects. */ +#endif + Trigger *pTrigger; /* List of triggers stored in pSchema */ + Schema *pSchema; /* Schema that contains this table */ + Table *pNextZombie; /* Next on the Parse.pZombieTab list */ +}; + +/* +** Allowed values for Table.tabFlags. +** +** TF_OOOHidden applies to virtual tables that have hidden columns that are +** followed by non-hidden columns. Example: "CREATE VIRTUAL TABLE x USING +** vtab1(a HIDDEN, b);". Since "b" is a non-hidden column but "a" is hidden, +** the TF_OOOHidden attribute would apply in this case. Such tables require +** special handling during INSERT processing. +*/ +#define TF_Readonly 0x01 /* Read-only system table */ +#define TF_Ephemeral 0x02 /* An ephemeral table */ +#define TF_HasPrimaryKey 0x04 /* Table has a primary key */ +#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */ +#define TF_Virtual 0x10 /* Is a virtual table */ +#define TF_WithoutRowid 0x20 /* No rowid used. PRIMARY KEY is the key */ +#define TF_OOOHidden 0x40 /* Out-of-Order hidden columns */ + + +/* +** Test to see whether or not a table is a virtual table. This is +** done as a macro so that it will be optimized out when virtual +** table support is omitted from the build. +*/ +#ifndef SQLITE_OMIT_VIRTUALTABLE +# define IsVirtual(X) (((X)->tabFlags & TF_Virtual)!=0) +# define IsHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0) +#else +# define IsVirtual(X) 0 +# define IsHiddenColumn(X) 0 +#endif + +/* Does the table have a rowid */ +#define HasRowid(X) (((X)->tabFlags & TF_WithoutRowid)==0) + +/* +** 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 +** key. The "to" table is the table that is named in the REFERENCES clause. +** Consider this example: +** +** CREATE TABLE ex1( +** a INTEGER PRIMARY KEY, +** b INTEGER CONSTRAINT fk1 REFERENCES ex2(x) +** ); +** +** For foreign key "fk1", the from-table is "ex1" and the to-table is "ex2". +** Equivalent names: +** +** from-table == child-table +** to-table == parent-table +** +** Each REFERENCES clause generates an instance of the following structure +** which is attached to the from-table. The to-table need not exist when +** the from-table is created. The existence of the to-table is not checked. +** +** The list of all parents for child Table X is held at X.pFKey. +** +** A list of all children for a table named Z (which might not even exist) +** is held in Schema.fkeyHash with a hash key of Z. +*/ +struct FKey { + Table *pFrom; /* Table containing the REFERENCES clause (aka: Child) */ + FKey *pNextFrom; /* Next FKey with the same in pFrom. Next parent of pFrom */ + char *zTo; /* Name of table that the key points to (aka: Parent) */ + FKey *pNextTo; /* Next with the same zTo. Next child of zTo. */ + FKey *pPrevTo; /* Previous with the same zTo */ + int nCol; /* Number of columns in this key */ + /* EV: R-30323-21917 */ + u8 isDeferred; /* True if constraint checking is deferred till COMMIT */ + u8 aAction[2]; /* ON DELETE and ON UPDATE actions, respectively */ + Trigger *apTrigger[2];/* Triggers for aAction[] actions */ + struct sColMap { /* Mapping of columns in pFrom to columns in zTo */ + int iFrom; /* Index of column in pFrom */ + char *zCol; /* Name of column in zTo. If NULL use PRIMARY KEY */ + } aCol[1]; /* One entry for each of nCol columns */ +}; + +/* +** SQLite supports many different ways to resolve a constraint +** error. ROLLBACK processing means that a constraint violation +** causes the operation in process to fail and for the current transaction +** to be rolled back. ABORT processing means the operation in process +** fails and any prior changes from that one operation are backed out, +** but the transaction is not rolled back. FAIL processing means that +** the operation in progress stops and returns an error code. But prior +** changes due to the same operation are not backed out and no rollback +** occurs. IGNORE means that the particular row that caused the constraint +** error is not inserted or updated. Processing continues and no error +** is returned. REPLACE means that preexisting database rows that caused +** a UNIQUE constraint violation are removed so that the new insert or +** update can proceed. Processing continues and no error is reported. +** +** RESTRICT, SETNULL, and CASCADE actions apply only to foreign keys. +** RESTRICT is the same as ABORT for IMMEDIATE foreign keys and the +** same as ROLLBACK for DEFERRED keys. SETNULL means that the foreign +** key is set to NULL. CASCADE means that a DELETE or UPDATE of the +** referenced table row is propagated into the row that holds the +** foreign key. +** +** The following symbolic values are used to record which type +** of action to take. +*/ +#define OE_None 0 /* There is no constraint to check */ +#define OE_Rollback 1 /* Fail the operation and rollback the transaction */ +#define OE_Abort 2 /* Back out changes but do no rollback transaction */ +#define OE_Fail 3 /* Stop the operation but leave all prior changes */ +#define OE_Ignore 4 /* Ignore the error. Do not do the INSERT or UPDATE */ +#define OE_Replace 5 /* Delete existing record, then do INSERT or UPDATE */ + +#define OE_Restrict 6 /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */ +#define OE_SetNull 7 /* Set the foreign key value to NULL */ +#define OE_SetDflt 8 /* Set the foreign key value to its default */ +#define OE_Cascade 9 /* Cascade the changes */ + +#define OE_Default 10 /* Do whatever the default action is */ + + +/* +** 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. +** +** Note that aSortOrder[] and aColl[] have nField+1 slots. There +** are nField slots for the columns of an index then one extra slot +** for the rowid at the end. +*/ +struct KeyInfo { + u32 nRef; /* Number of references to this KeyInfo object */ + u8 enc; /* Text encoding - one of the SQLITE_UTF* values */ + u16 nField; /* Number of key columns in the index */ + u16 nXField; /* Number of columns beyond the key columns */ + sqlite3 *db; /* The database connection */ + u8 *aSortOrder; /* Sort order for each column. */ + CollSeq *aColl[1]; /* Collating sequence for each term of the key */ +}; + +/* +** An instance of the following structure holds information about a +** single index record that has already been parsed out into individual +** values. +** +** A record is an object that contains one or more fields of data. +** Records are used to store the content of a table row and to store +** the key of an index. A blob encoding of a record is created by +** the OP_MakeRecord opcode of the VDBE and is disassembled by the +** OP_Column opcode. +** +** This structure holds a record that has already been disassembled +** into its constituent fields. +** +** The r1 and r2 member variables are only used by the optimized comparison +** functions vdbeRecordCompareInt() and vdbeRecordCompareString(). +*/ +struct UnpackedRecord { + KeyInfo *pKeyInfo; /* Collation and sort-order information */ + u16 nField; /* Number of entries in apMem[] */ + i8 default_rc; /* Comparison result if keys are equal */ + u8 errCode; /* Error detected by xRecordCompare (CORRUPT or NOMEM) */ + Mem *aMem; /* Values */ + int r1; /* Value to return if (lhs > rhs) */ + int r2; /* Value to return if (rhs < lhs) */ +}; + + +/* +** Each SQL index is represented in memory by an +** instance of the following structure. +** +** The columns of the table that are to be indexed are described +** by the aiColumn[] field of this structure. For example, suppose +** we have the following table and index: +** +** CREATE TABLE Ex1(c1 int, c2 int, c3 text); +** CREATE INDEX Ex2 ON Ex1(c3,c1); +** +** In the Table structure describing Ex1, nCol==3 because there are +** three columns in the table. In the Index structure describing +** Ex2, nColumn==2 since 2 of the 3 columns of Ex1 are indexed. +** The value of aiColumn is {2, 0}. aiColumn[0]==2 because the +** first column to be indexed (c3) has an index of 2 in Ex1.aCol[]. +** The second column to be indexed (c1) has an index of 0 in +** Ex1.aCol[], hence Ex2.aiColumn[1]==0. +** +** The Index.onError field determines whether or not the indexed columns +** must be unique and what to do if they are not. When Index.onError=OE_None, +** it means this is not a unique index. Otherwise it is a unique index +** and the value of Index.onError indicate the which conflict resolution +** algorithm to employ whenever an attempt is made to insert a non-unique +** element. +*/ +struct Index { + char *zName; /* Name of this index */ + i16 *aiColumn; /* Which columns are used by this index. 1st is 0 */ + LogEst *aiRowLogEst; /* From ANALYZE: Est. rows selected by each column */ + Table *pTable; /* The SQL table being indexed */ + 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; /* for each column: True==DESC, False==ASC */ + char **azColl; /* Array of collation sequence names for index */ + Expr *pPartIdxWhere; /* WHERE clause for partial indices */ + int tnum; /* DB Page containing root of this index */ + LogEst szIdxRow; /* Estimated average row size in bytes */ + u16 nKeyCol; /* Number of columns forming the key */ + u16 nColumn; /* Number of columns stored in the index */ + u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ + unsigned idxType:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */ + unsigned bUnordered:1; /* Use this index for == or IN queries only */ + unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */ + unsigned isResized:1; /* True if resizeIndexObject() has been called */ + unsigned isCovering:1; /* True if this is a covering index */ + unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + int nSample; /* Number of elements in aSample[] */ + int nSampleCol; /* Size of IndexSample.anEq[] and so on */ + tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */ + IndexSample *aSample; /* Samples of the left-most key */ + tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this index */ + tRowcnt nRowEst0; /* Non-logarithmic number of rows in the index */ +#endif +}; + +/* +** Allowed values for Index.idxType +*/ +#define SQLITE_IDXTYPE_APPDEF 0 /* Created using CREATE INDEX */ +#define SQLITE_IDXTYPE_UNIQUE 1 /* Implements a UNIQUE constraint */ +#define SQLITE_IDXTYPE_PRIMARYKEY 2 /* Is the PRIMARY KEY for the table */ + +/* Return true if index X is a PRIMARY KEY index */ +#define IsPrimaryKeyIndex(X) ((X)->idxType==SQLITE_IDXTYPE_PRIMARYKEY) + +/* Return true if index X is a UNIQUE index */ +#define IsUniqueIndex(X) ((X)->onError!=OE_None) + +/* +** Each sample stored in the sqlite_stat3 table is represented in memory +** using a structure of this type. See documentation at the top of the +** analyze.c source file for additional information. +*/ +struct IndexSample { + void *p; /* Pointer to sampled record */ + int n; /* Size of record in bytes */ + tRowcnt *anEq; /* Est. number of rows where the key equals this sample */ + tRowcnt *anLt; /* Est. number of rows where key is less than this sample */ + tRowcnt *anDLt; /* Est. number of distinct keys less than this sample */ +}; + +/* +** 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 assumptions about Token.dyn +** and Token.n when Token.z==0. +*/ +struct Token { + const char *z; /* Text of the token. Not NULL-terminated! */ + unsigned int n; /* 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 */ + int sortingIdxPTab; /* Cursor number of pseudo-table */ + int nSortingColumn; /* Number of columns in the sorting index */ + int mnReg, mxReg; /* Range of registers allocated for aCol and aFunc */ + ExprList *pGroupBy; /* The group by clause */ + struct AggInfo_col { /* For each column used in source tables */ + Table *pTab; /* Source table */ + 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 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; /* Ephemeral table used to enforce DISTINCT */ + } *aFunc; + int nFunc; /* Number of entries in aFunc[] */ +}; + +/* +** The datatype ynVar is a signed integer, either 16-bit or 32-bit. +** Usually it is 16-bits. But if SQLITE_MAX_VARIABLE_NUMBER is greater +** than 32767 we have to make it 32-bit. 16-bit is preferred because +** it uses less memory in the Expr object, which is a big memory user +** in systems with lots of prepared statements. And few applications +** need more than about 10 or 20 variables. But some extreme users want +** to have prepared statements with over 32767 variables, and for them +** the option is available (at compile-time). +*/ +#if SQLITE_MAX_VARIABLE_NUMBER<=32767 +typedef i16 ynVar; +#else +typedef int ynVar; +#endif + +/* +** 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 +** to represent the greater-than-or-equal-to operator in the expression +** tree. +** +** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB, +** or TK_STRING), then Expr.token contains the text of the SQL literal. If +** the expression is a variable (TK_VARIABLE), then Expr.token contains the +** variable name. Finally, if the expression is an SQL function (TK_FUNCTION), +** then Expr.token contains the name of the function. +** +** Expr.pRight and Expr.pLeft are the left and right subexpressions of a +** binary operator. Either or both may be NULL. +** +** Expr.x.pList is a list of arguments if the expression is an SQL function, +** a CASE expression or an IN expression of the form " IN (, ...)". +** Expr.x.pSelect is used if the expression is a sub-select or an expression of +** the form " IN (SELECT ...)". If the EP_xIsSelect bit is set in the +** Expr.flags mask, then Expr.x.pSelect is valid. Otherwise, Expr.x.pList is +** valid. +** +** An expression of the form ID or ID.ID refers to a column in a table. +** For such expressions, Expr.op is set to TK_COLUMN and Expr.iTable is +** the integer cursor number of a VDBE cursor pointing to that table and +** Expr.iColumn is the column number for the specific column. If the +** expression is used as a result in an aggregate SELECT, then the +** value is also stored in the Expr.iAgg column in the aggregate so that +** it can be accessed after all aggregates are computed. +** +** If the expression is an unbound variable marker (a question mark +** character '?' in the original SQL) then the Expr.iTable holds the index +** number for that variable. +** +** If the expression is a subquery then Expr.iColumn holds an integer +** register number containing the result of the subquery. If the +** subquery gives a constant result, then iTable is -1. If the subquery +** gives a different answer at different times during statement processing +** then iTable is the address of a subroutine that computes the subquery. +** +** 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. +** +** ALLOCATION NOTES: +** +** Expr objects can use a lot of memory space in database schema. To +** help reduce memory requirements, sometimes an Expr object will be +** truncated. And to reduce the number of memory allocations, sometimes +** two or more Expr objects will be stored in a single memory allocation, +** together with Expr.zToken strings. +** +** If the EP_Reduced and EP_TokenOnly flags are set when +** an Expr object is truncated. When EP_Reduced is set, then all +** the child Expr objects in the Expr.pLeft and Expr.pRight subtrees +** are contained within the same memory allocation. Note, however, that +** the subtrees in Expr.x.pList or Expr.x.pSelect are always separately +** allocated, regardless of whether or not EP_Reduced is set. +*/ +struct Expr { + u8 op; /* Operation performed by this node */ + char affinity; /* The affinity of the column or 0 if not a column */ + u32 flags; /* Various flags. EP_* See below */ + union { + char *zToken; /* Token value. Zero terminated and dequoted */ + int iValue; /* Non-negative integer value if EP_IntValue */ + } u; + + /* If the EP_TokenOnly flag is set in the Expr.flags mask, then no + ** space is allocated for the fields below this point. An attempt to + ** access them will result in a segfault or malfunction. + *********************************************************************/ + + Expr *pLeft; /* Left subnode */ + Expr *pRight; /* Right subnode */ + union { + ExprList *pList; /* op = IN, EXISTS, SELECT, CASE, FUNCTION, BETWEEN */ + Select *pSelect; /* EP_xIsSelect and op = IN, EXISTS, SELECT */ + } x; + + /* If the EP_Reduced flag is set in the Expr.flags mask, then no + ** space is allocated for the fields below this point. An attempt to + ** access them will result in a segfault or malfunction. + *********************************************************************/ + +#if SQLITE_MAX_EXPR_DEPTH>0 + int nHeight; /* Height of the tree headed by this node */ +#endif + int iTable; /* TK_COLUMN: cursor number of table holding column + ** TK_REGISTER: register number + ** TK_TRIGGER: 1 -> new, 0 -> old + ** EP_Unlikely: 134217728 times likelihood */ + ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid. + ** TK_VARIABLE: variable number (always >= 1). */ + i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ + i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */ + u8 op2; /* TK_REGISTER: original value of Expr.op + ** TK_COLUMN: the value of p5 for OP_Column + ** TK_AGG_FUNCTION: nesting depth */ + AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ + Table *pTab; /* Table for TK_COLUMN expressions. */ +}; + +/* +** The following are the meanings of bits in the Expr.flags field. +*/ +#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */ +#define EP_Agg 0x000002 /* Contains one or more aggregate functions */ +#define EP_Resolved 0x000004 /* IDs have been resolved to COLUMNs */ +#define EP_Error 0x000008 /* Expression contains one or more errors */ +#define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */ +#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */ +#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */ +#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */ +#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */ +#define EP_Generic 0x000200 /* Ignore COLLATE or affinity on this tree */ +#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */ +#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */ +#define EP_Skip 0x001000 /* COLLATE, AS, or UNLIKELY */ +#define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */ +#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ +#define EP_Static 0x008000 /* Held in memory not obtained from malloc() */ +#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */ +#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */ +#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */ +#define EP_ConstFunc 0x080000 /* Node is a SQLITE_FUNC_CONSTANT function */ +#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */ +#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */ + +/* +** Combinations of two or more EP_* flags +*/ +#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */ + +/* +** These macros can be used to test, set, or clear bits in the +** Expr.flags field. +*/ +#define ExprHasProperty(E,P) (((E)->flags&(P))!=0) +#define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P)) +#define ExprSetProperty(E,P) (E)->flags|=(P) +#define ExprClearProperty(E,P) (E)->flags&=~(P) + +/* The ExprSetVVAProperty() macro is used for Verification, Validation, +** and Accreditation only. It works like ExprSetProperty() during VVA +** processes but is a no-op for delivery. +*/ +#ifdef SQLITE_DEBUG +# define ExprSetVVAProperty(E,P) (E)->flags|=(P) +#else +# define ExprSetVVAProperty(E,P) +#endif + +/* +** Macros to determine the number of bytes required by a normal Expr +** struct, an Expr struct with the EP_Reduced flag set in Expr.flags +** and an Expr struct with the EP_TokenOnly flag set. +*/ +#define EXPR_FULLSIZE sizeof(Expr) /* Full size */ +#define EXPR_REDUCEDSIZE offsetof(Expr,iTable) /* Common features */ +#define EXPR_TOKENONLYSIZE offsetof(Expr,pLeft) /* Fewer features */ + +/* +** Flags passed to the sqlite3ExprDup() function. See the header comment +** above sqlite3ExprDup() for details. +*/ +#define EXPRDUP_REDUCE 0x0001 /* Used reduced-size Expr nodes */ + +/* +** A list of expressions. Each expression may optionally have a +** name. An expr/name combination can be used in several ways, such +** as the list of "expr AS ID" fields following a "SELECT" or in the +** 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. +** +** By default the Expr.zSpan field holds a human-readable description of +** the expression that is used in the generation of error messages and +** column labels. In this case, Expr.zSpan is typically the text of a +** column expression as it exists in a SELECT statement. However, if +** the bSpanIsTab flag is set, then zSpan is overloaded to mean the name +** of the result column in the form: DATABASE.TABLE.COLUMN. This later +** form is used for name resolution with nested FROM clauses. +*/ +struct ExprList { + int nExpr; /* Number of expressions on the list */ + struct ExprList_item { /* For each expression in the list */ + Expr *pExpr; /* The list of expressions */ + char *zName; /* Token associated with this expression */ + char *zSpan; /* Original text of the expression */ + u8 sortOrder; /* 1 for DESC or 0 for ASC */ + unsigned done :1; /* A flag to indicate when processing is finished */ + unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */ + unsigned reusable :1; /* Constant expression is reusable */ + union { + struct { + u16 iOrderByCol; /* For ORDER BY, column number in result set */ + u16 iAlias; /* Index into Parse.aAlias[] for zName */ + } x; + int iConstExprReg; /* Register in which Expr value is cached */ + } u; + } *a; /* Alloc a power of two greater or equal to nExpr */ +}; + +/* +** An instance of this structure is used by the parser to record both +** the parse tree for an expression and the span of input text for an +** expression. +*/ +struct ExprSpan { + Expr *pExpr; /* The expression parse tree */ + const char *zStart; /* First character of input text */ + const char *zEnd; /* One character past the end of input text */ +}; + +/* +** An instance of this structure can hold a simple list of identifiers, +** such as the list "a,b,c" in the following statements: +** +** INSERT INTO t(a,b,c) VALUES ...; +** CREATE INDEX idx ON t(a,b,c); +** CREATE TRIGGER trig BEFORE UPDATE ON t(a,b,c) ...; +** +** The IdList.a.idx field is used when the IdList represents the list of +** 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 */ +}; + +/* +** The bitmask datatype defined below is used for various optimizations. +** +** Changing this from a 64-bit to a 32-bit type limits the number of +** tables in a join to 32 instead of 64. But it also reduces the size +** of the library by 738 bytes on ix86. +*/ +typedef u64 Bitmask; + +/* +** The number of bits in a Bitmask. "BMS" means "BitMask Size". +*/ +#define BMS ((int)(sizeof(Bitmask)*8)) + +/* +** A bit in a Bitmask +*/ +#define MASKBIT(n) (((Bitmask)1)<<(n)) +#define MASKBIT32(n) (((unsigned int)1)<<(n)) + +/* +** The following structure describes the FROM clause of a SELECT statement. +** Each table or subquery in the FROM clause is a separate element of +** the SrcList.a[] array. +** +** With the addition of multiple database support, the following structure +** can also be used to describe a particular table such as the table that +** is modified by an INSERT, DELETE, or UPDATE statement. In standard SQL, +** such a table must be a simple name: ID. But in SQLite, the table can +** now be identified by a database name, a dot, then the table name: ID.ID. +** +** The jointype starts out showing the join type between the current table +** and the next table on the list. The parser builds the list this way. +** But sqlite3SrcListShiftJoinType() later shifts the jointypes so that each +** jointype expresses the join between the table and the previous table. +** +** In the colUsed field, the high-order bit (bit 63) is set if the table +** contains more than 63 columns and the 64-th or later column is used. +*/ +struct SrcList { + int nSrc; /* Number of tables or subqueries in the FROM clause */ + u32 nAlloc; /* Number of entries allocated in a[] below */ + struct SrcList_item { + Schema *pSchema; /* Schema to which this item is fixed */ + 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 addrFillSub; /* Address of subroutine to manifest a subquery */ + int regReturn; /* Register holding return address of addrFillSub */ + int regResult; /* Registers holding results of a co-routine */ + u8 jointype; /* Type of join between this able and the previous */ + unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ + unsigned isCorrelated :1; /* True if sub-query is correlated */ + unsigned viaCoroutine :1; /* Implemented as a co-routine */ + unsigned isRecursive :1; /* True for recursive reference in WITH */ +#ifndef SQLITE_OMIT_EXPLAIN + u8 iSelectId; /* If pSelect!=0, the id of the sub-select in EQP */ +#endif + 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<" clause */ + Index *pIndex; /* Index structure corresponding to zIndex, if any */ + } 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 */ + + +/* +** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin() +** and the WhereInfo.wctrlFlags member. +*/ +#define WHERE_ORDERBY_NORMAL 0x0000 /* No-op */ +#define WHERE_ORDERBY_MIN 0x0001 /* ORDER BY processing for min() func */ +#define WHERE_ORDERBY_MAX 0x0002 /* ORDER BY processing for max() func */ +#define WHERE_ONEPASS_DESIRED 0x0004 /* Want to do one-pass UPDATE/DELETE */ +#define WHERE_DUPLICATES_OK 0x0008 /* Ok to return a row more than once */ +#define WHERE_OMIT_OPEN_CLOSE 0x0010 /* Table cursors are already open */ +#define WHERE_FORCE_TABLE 0x0020 /* Do not use an index-only search */ +#define WHERE_ONETABLE_ONLY 0x0040 /* Only code the 1st table in pTabList */ +#define WHERE_NO_AUTOINDEX 0x0080 /* Disallow automatic indexes */ +#define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */ +#define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */ +#define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */ +#define WHERE_SORTBYGROUP 0x0800 /* Support sqlite3WhereIsSorted() */ +#define WHERE_REOPEN_IDX 0x1000 /* Try to use OP_ReopenIdx */ + +/* Allowed return values from sqlite3WhereIsDistinct() +*/ +#define WHERE_DISTINCT_NOOP 0 /* DISTINCT keyword not used */ +#define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */ +#define WHERE_DISTINCT_ORDERED 2 /* All duplicates are adjacent */ +#define WHERE_DISTINCT_UNORDERED 3 /* Duplicates are scattered */ + +/* +** A NameContext defines a context in which to resolve table and column +** names. The context consists of a list of tables (the pSrcList) field and +** a list of named expression (pEList). The named expression list may +** be NULL. The pSrc corresponds to the FROM clause of a SELECT or +** to the table being operated on by INSERT, UPDATE, or DELETE. The +** pEList corresponds to the result set of a SELECT and is NULL for +** other statements. +** +** NameContexts can be nested. When resolving names, the inner-most +** context is searched first. If no match is found, the next outer +** context is checked. If there is still no match, the next context +** is checked. This process continues until either a match is found +** or all contexts are check. When a match is found, the nRef member of +** the context containing the match is incremented. +** +** Each subquery gets a new NameContext. The pNext field points to the +** NameContext in the parent query. Thus the process of scanning the +** NameContext list corresponds to searching through successively outer +** subqueries looking for a match. +*/ +struct NameContext { + Parse *pParse; /* The parser */ + SrcList *pSrcList; /* One or more tables used to resolve names */ + ExprList *pEList; /* Optional list of result-set columns */ + AggInfo *pAggInfo; /* Information about aggregates at this level */ + NameContext *pNext; /* Next outer name context. NULL for outermost */ + int nRef; /* Number of names resolved by this context */ + int nErr; /* Number of errors encountered while resolving names */ + u16 ncFlags; /* Zero or more NC_* flags defined below */ +}; + +/* +** Allowed values for the NameContext, ncFlags field. +** +** Note: NC_MinMaxAgg must have the same value as SF_MinMaxAgg and +** SQLITE_FUNC_MINMAX. +** +*/ +#define NC_AllowAgg 0x0001 /* Aggregate functions are allowed here */ +#define NC_HasAgg 0x0002 /* One or more aggregate functions seen */ +#define NC_IsCheck 0x0004 /* True if resolving names in a CHECK constraint */ +#define NC_InAggFunc 0x0008 /* True if analyzing arguments to an agg func */ +#define NC_PartIdx 0x0010 /* True if resolving a partial index WHERE */ +#define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */ + +/* +** 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. +** +** addrOpenEphm[] entries contain the address of OP_OpenEphemeral opcodes. +** These addresses must be stored so that we can go back and fill in +** the P4_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_OpenEphm instruction is coded because not +** enough information about the compound query is known at that point. +** The KeyInfo for addrOpenTran[0] and [1] contains collating sequences +** for the result set. The KeyInfo for addrOpenEphm[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 */ + u16 selFlags; /* Various SF_* values */ + int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */ +#if SELECTTRACE_ENABLED + char zSelName[12]; /* Symbolic name of this SELECT use for debugging */ +#endif + int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */ + u64 nSelectRow; /* Estimated number of result rows */ + 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 *pNext; /* Next select to the left in a compound */ + Expr *pLimit; /* LIMIT expression. NULL means not used. */ + Expr *pOffset; /* OFFSET expression. NULL means not used. */ + With *pWith; /* WITH clause attached to this select. Or NULL. */ +}; + +/* +** Allowed values for Select.selFlags. The "SF" prefix stands for +** "Select Flag". +*/ +#define SF_Distinct 0x0001 /* Output should be DISTINCT */ +#define SF_Resolved 0x0002 /* Identifiers have been resolved */ +#define SF_Aggregate 0x0004 /* Contains aggregate functions */ +#define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */ +#define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */ +#define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ +#define SF_Compound 0x0040 /* Part of a compound query */ +#define SF_Values 0x0080 /* Synthesized from VALUES clause */ +#define SF_MultiValue 0x0100 /* Single VALUES term with multiple rows */ +#define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */ +#define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */ +#define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */ +#define SF_MinMaxAgg 0x1000 /* Aggregate containing min() or max() */ +#define SF_Converted 0x2000 /* By convertCompoundSelectToSubquery() */ + + +/* +** The results of a SELECT can be distributed in several ways, as defined +** by one of the following macros. The "SRT" prefix means "SELECT Result +** Type". +** +** SRT_Union Store results as a key in a temporary index +** identified by pDest->iSDParm. +** +** SRT_Except Remove results from the temporary index pDest->iSDParm. +** +** SRT_Exists Store a 1 in memory cell pDest->iSDParm if the result +** set is not empty. +** +** SRT_Discard Throw the results away. This is used by SELECT +** statements within triggers whose only purpose is +** the side-effects of functions. +** +** All of the above are free to ignore their ORDER BY clause. Those that +** follow must honor the ORDER BY clause. +** +** SRT_Output Generate a row of output (using the OP_ResultRow +** opcode) for each row in the result set. +** +** SRT_Mem Only valid if the result is a single column. +** Store the first column of the first result row +** in register pDest->iSDParm then abandon the rest +** of the query. This destination implies "LIMIT 1". +** +** SRT_Set The result must be a single column. Store each +** row of result as the key in table pDest->iSDParm. +** Apply the affinity pDest->affSdst before storing +** results. Used to implement "IN (SELECT ...)". +** +** SRT_EphemTab Create an temporary table pDest->iSDParm and store +** the result there. The cursor is left open after +** returning. This is like SRT_Table except that +** this destination uses OP_OpenEphemeral to create +** the table first. +** +** SRT_Coroutine Generate a co-routine that returns a new row of +** results each time it is invoked. The entry point +** of the co-routine is stored in register pDest->iSDParm +** and the result row is stored in pDest->nDest registers +** starting with pDest->iSdst. +** +** SRT_Table Store results in temporary table pDest->iSDParm. +** SRT_Fifo This is like SRT_EphemTab except that the table +** is assumed to already be open. SRT_Fifo has +** the additional property of being able to ignore +** the ORDER BY clause. +** +** SRT_DistFifo Store results in a temporary table pDest->iSDParm. +** But also use temporary table pDest->iSDParm+1 as +** a record of all prior results and ignore any duplicate +** rows. Name means: "Distinct Fifo". +** +** SRT_Queue Store results in priority queue pDest->iSDParm (really +** an index). Append a sequence number so that all entries +** are distinct. +** +** SRT_DistQueue Store results in priority queue pDest->iSDParm only if +** the same record has never been stored before. The +** index at pDest->iSDParm+1 hold all prior stores. +*/ +#define SRT_Union 1 /* Store result as keys in an index */ +#define SRT_Except 2 /* Remove result from a UNION index */ +#define SRT_Exists 3 /* Store 1 if the result is not empty */ +#define SRT_Discard 4 /* Do not save the results anywhere */ +#define SRT_Fifo 5 /* Store result as data with an automatic rowid */ +#define SRT_DistFifo 6 /* Like SRT_Fifo, but unique results only */ +#define SRT_Queue 7 /* Store result in an queue */ +#define SRT_DistQueue 8 /* Like SRT_Queue, but unique results only */ + +/* The ORDER BY clause is ignored for all of the above */ +#define IgnorableOrderby(X) ((X->eDest)<=SRT_DistQueue) + +#define SRT_Output 9 /* Output each row of result */ +#define SRT_Mem 10 /* Store result in a memory cell */ +#define SRT_Set 11 /* Store results as keys in an index */ +#define SRT_EphemTab 12 /* Create transient tab and store like SRT_Table */ +#define SRT_Coroutine 13 /* Generate a single row of result */ +#define SRT_Table 14 /* Store result as data with an automatic rowid */ + +/* +** An instance of this object describes where to put of the results of +** a SELECT statement. +*/ +struct SelectDest { + u8 eDest; /* How to dispose of the results. On of SRT_* above. */ + char affSdst; /* Affinity used when eDest==SRT_Set */ + int iSDParm; /* A parameter used by the eDest disposal method */ + int iSdst; /* Base register where results are written */ + int nSdst; /* Number of registers allocated */ + ExprList *pOrderBy; /* Key columns for SRT_Queue and SRT_DistQueue */ +}; + +/* +** During code generation of statements that do inserts into AUTOINCREMENT +** tables, the following information is attached to the Table.u.autoInc.p +** pointer of each autoincrement table to record some side information that +** the code generator needs. We have to keep per-table autoincrement +** information in case inserts are down within triggers. Triggers do not +** normally coordinate their activities, but we do need to coordinate the +** loading and saving of autoincrement information. +*/ +struct AutoincInfo { + AutoincInfo *pNext; /* Next info block in a list of them all */ + Table *pTab; /* Table this info block refers to */ + int iDb; /* Index in sqlite3.aDb[] of database holding pTab */ + int regCtr; /* Memory register holding the rowid counter */ +}; + +/* +** Size of the column cache +*/ +#ifndef SQLITE_N_COLCACHE +# define SQLITE_N_COLCACHE 10 +#endif + +/* +** At least one instance of the following structure is created for each +** trigger that may be fired while parsing an INSERT, UPDATE or DELETE +** statement. All such objects are stored in the linked list headed at +** Parse.pTriggerPrg and deleted once statement compilation has been +** completed. +** +** A Vdbe sub-program that implements the body and WHEN clause of trigger +** TriggerPrg.pTrigger, assuming a default ON CONFLICT clause of +** TriggerPrg.orconf, is stored in the TriggerPrg.pProgram variable. +** The Parse.pTriggerPrg list never contains two entries with the same +** values for both pTrigger and orconf. +** +** The TriggerPrg.aColmask[0] variable is set to a mask of old.* columns +** accessed (or set to 0 for triggers fired as a result of INSERT +** statements). Similarly, the TriggerPrg.aColmask[1] variable is set to +** a mask of new.* columns used by the program. +*/ +struct TriggerPrg { + Trigger *pTrigger; /* Trigger this program was coded from */ + TriggerPrg *pNext; /* Next entry in Parse.pTriggerPrg list */ + SubProgram *pProgram; /* Program implementing pTrigger/orconf */ + int orconf; /* Default ON CONFLICT policy */ + u32 aColmask[2]; /* Masks of old.*, new.* columns accessed */ +}; + +/* +** The yDbMask datatype for the bitmask of all attached databases. +*/ +#if SQLITE_MAX_ATTACHED>30 + typedef unsigned char yDbMask[(SQLITE_MAX_ATTACHED+9)/8]; +# define DbMaskTest(M,I) (((M)[(I)/8]&(1<<((I)&7)))!=0) +# define DbMaskZero(M) memset((M),0,sizeof(M)) +# define DbMaskSet(M,I) (M)[(I)/8]|=(1<<((I)&7)) +# define DbMaskAllZero(M) sqlite3DbMaskAllZero(M) +# define DbMaskNonZero(M) (sqlite3DbMaskAllZero(M)==0) +#else + typedef unsigned int yDbMask; +# define DbMaskTest(M,I) (((M)&(((yDbMask)1)<<(I)))!=0) +# define DbMaskZero(M) (M)=0 +# define DbMaskSet(M,I) (M)|=(((yDbMask)1)<<(I)) +# define DbMaskAllZero(M) (M)==0 +# define DbMaskNonZero(M) (M)!=0 +#endif + +/* +** 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 */ + char *zErrMsg; /* An error message */ + Vdbe *pVdbe; /* An engine for executing database bytecode */ + int rc; /* Return code from execution */ + u8 colNamesSet; /* TRUE after OP_ColumnName has been issued to pVdbe */ + u8 checkSchema; /* Causes schema cookie check after an error */ + u8 nested; /* Number of nested calls to the parser/code generator */ + u8 nTempReg; /* Number of temporary registers in aTempReg[] */ + u8 isMultiWrite; /* True if statement may modify/insert multiple rows */ + u8 mayAbort; /* True if statement may throw an ABORT exception */ + u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ + u8 okConstFactor; /* OK to factor out constants */ + int aTempReg[8]; /* Holding area for temporary registers */ + int nRangeReg; /* Size of the temporary register block */ + int iRangeReg; /* First register in temporary register block */ + 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 nOnce; /* Number of OP_Once instructions so far */ + int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */ + int iFixedOp; /* Never back out opcodes iFixedOp-1 or earlier */ + int ckBase; /* Base register of data during check constraints */ + int iPartIdxTab; /* Table corresponding to a partial index */ + int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */ + int iCacheCnt; /* Counter used to generate aColCache[].lru values */ + int nLabel; /* Number of labels used */ + int *aLabel; /* Space to hold the labels */ + struct yColCache { + int iTable; /* Table cursor number */ + i16 iColumn; /* Table column number */ + u8 tempReg; /* iReg is a temp register that needs to be freed */ + int iLevel; /* Nesting level */ + int iReg; /* Reg with value of this column. 0 means none. */ + int lru; /* Least recently used entry has the smallest value */ + } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */ + ExprList *pConstExpr;/* Constant expressions */ + Token constraintName;/* Name of the constraint currently being parsed */ + yDbMask writeMask; /* Start a write transaction on these databases */ + yDbMask cookieMask; /* Bitmask of schema verified databases */ + int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */ + int regRowid; /* Register holding rowid of CREATE TABLE entry */ + int regRoot; /* Register holding root page number for new objects */ + int nMaxArg; /* Max args passed to user function by sub-program */ +#if SELECTTRACE_ENABLED + int nSelect; /* Number of SELECT statements seen */ + int nSelectIndent; /* How far to indent SELECTTRACE() output */ +#endif +#ifndef SQLITE_OMIT_SHARED_CACHE + int nTableLock; /* Number of locks in aTableLock */ + TableLock *aTableLock; /* Required table locks for shared-cache mode */ +#endif + AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */ + + /* Information used while coding trigger programs. */ + Parse *pToplevel; /* Parse structure for main program (or NULL) */ + Table *pTriggerTab; /* Table triggers are being coded for */ + int addrCrTab; /* Address of OP_CreateTable opcode on CREATE TABLE */ + int addrSkipPK; /* Address of instruction to skip PRIMARY KEY index */ + u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ + u32 oldmask; /* Mask of old.* columns referenced */ + u32 newmask; /* Mask of new.* columns referenced */ + u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ + u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ + u8 disableTriggers; /* True to disable triggers */ + + /************************************************************************ + ** Above is constant between recursions. Below is reset before and after + ** each recursion. The boundary between these two regions is determined + ** using offsetof(Parse,nVar) so the nVar field must be the first field + ** in the recursive region. + ************************************************************************/ + + int nVar; /* Number of '?' variables seen in the SQL so far */ + int nzVar; /* Number of available slots in azVar[] */ + u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */ + u8 bFreeWith; /* True if pWith should be freed with parser */ + u8 explain; /* True if the EXPLAIN flag is found on the query */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + u8 declareVtab; /* True if inside sqlite3_declare_vtab() */ + int nVtabLock; /* Number of virtual tables to lock */ +#endif + int nAlias; /* Number of aliased result set columns */ + int nHeight; /* Expression tree height of current sub-select */ +#ifndef SQLITE_OMIT_EXPLAIN + int iSelectId; /* ID of current select for EXPLAIN output */ + int iNextSelectId; /* Next available select ID for EXPLAIN output */ +#endif + char **azVar; /* Pointers to names of parameters */ + Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */ + 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 */ + const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */ + Token sNameToken; /* Token with unqualified schema object name */ + Token sLastToken; /* The last token parsed */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + Token sArg; /* Complete text of a module argument */ + Table **apVtabLock; /* Pointer to virtual tables needing locking */ +#endif + Table *pZombieTab; /* List of Table objects to delete after code gen */ + TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ + With *pWith; /* Current WITH clause, or NULL */ +}; + +/* +** Return true if currently inside an sqlite3_declare_vtab() call. +*/ +#ifdef SQLITE_OMIT_VIRTUALTABLE + #define IN_DECLARE_VTAB 0 +#else + #define IN_DECLARE_VTAB (pParse->declareVtab) +#endif + +/* +** 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 P5 value in various opcodes. +*/ +#define OPFLAG_NCHANGE 0x01 /* Set to update db->nChange */ +#define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */ +#define OPFLAG_LASTROWID 0x02 /* Set to update db->lastRowid */ +#define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */ +#define OPFLAG_APPEND 0x08 /* This is likely to be an append */ +#define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */ +#define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */ +#define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */ +#define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */ +#define OPFLAG_SEEKEQ 0x02 /* OP_Open** cursor uses EQ seek only */ +#define OPFLAG_P2ISREG 0x04 /* P2 to OP_Open** is a register number */ +#define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */ + +/* + * 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 *zName; /* 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 expression (may be NULL) */ + IdList *pColumns; /* If this is an UPDATE OF trigger, + the is stored here */ + 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. +** +** If there are multiple triggers, you might of some BEFORE and some AFTER. +** In that cases, the constants below can be ORed together. +*/ +#define TRIGGER_BEFORE 1 +#define TRIGGER_AFTER 2 + +/* + * An instance of struct TriggerStep is used to store a single SQL statement + * that is a part of a trigger-program. + * + * Instances of struct TriggerStep are stored in a singly linked list (linked + * using the "pNext" member) referenced by the "step_list" member of the + * associated struct Trigger instance. The first element of the linked list is + * the first step of the trigger-program. + * + * The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or + * "SELECT" statement. The meanings of the other members is determined by the + * value of "op" as follows: + * + * (op == TK_INSERT) + * orconf -> stores the ON CONFLICT algorithm + * pSelect -> If this is an INSERT INTO ... SELECT ... statement, then + * this stores a pointer to the SELECT statement. Otherwise NULL. + * zTarget -> Dequoted name of the table to insert into. + * pExprList -> If this is an INSERT INTO ... VALUES ... statement, then + * this stores values to be inserted. Otherwise NULL. + * pIdList -> If this is an INSERT INTO ... () VALUES ... + * statement, then this stores the column-names to be + * inserted into. + * + * (op == TK_DELETE) + * zTarget -> Dequoted name of the table to delete from. + * pWhere -> The WHERE clause of the DELETE statement if one is specified. + * Otherwise NULL. + * + * (op == TK_UPDATE) + * zTarget -> Dequoted name of the table to update. + * pWhere -> The WHERE clause of the UPDATE statement if one is specified. + * Otherwise NULL. + * pExprList -> A list of the columns to update and the expressions to update + * them to. See sqlite3Update() documentation of "pChanges" + * argument. + * + */ +struct TriggerStep { + u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */ + u8 orconf; /* OE_Rollback etc. */ + Trigger *pTrig; /* The trigger that this step is a part of */ + Select *pSelect; /* SELECT statement or RHS of INSERT INTO SELECT ... */ + char *zTarget; /* Target table for DELETE, UPDATE, INSERT */ + Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */ + ExprList *pExprList; /* SET clause for UPDATE. */ + IdList *pIdList; /* Column names for INSERT */ + TriggerStep *pNext; /* Next in the link-list */ + TriggerStep *pLast; /* Last element in link-list. Valid for 1st elem only */ +}; + +/* +** The following structure contains information used by the sqliteFix... +** routines as they walk the parse tree to make database references +** explicit. +*/ +typedef struct DbFixer DbFixer; +struct DbFixer { + Parse *pParse; /* The parsing context. Error messages written here */ + Schema *pSchema; /* Fix items to this schema */ + int bVarOnly; /* Check for variable references only */ + const char *zDb; /* Make sure all objects are contained in this database */ + const char *zType; /* Type of the container - used for error messages */ + const Token *pName; /* Name of the container - used for error messages */ +}; + +/* +** An objected used to accumulate the text of a string where we +** do not necessarily know how big the string will be in the end. +*/ +struct StrAccum { + sqlite3 *db; /* Optional database for lookaside. Can be NULL */ + char *zBase; /* A base allocation. Not from malloc. */ + char *zText; /* The string collected so far */ + int nChar; /* Length of the string so far */ + int nAlloc; /* Amount of space allocated in zText */ + int mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */ + u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */ +}; +#define STRACCUM_NOMEM 1 +#define STRACCUM_TOOBIG 2 + +/* +** A pointer to this structure is used to communicate information +** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback. +*/ +typedef struct { + sqlite3 *db; /* The database being initialized */ + char **pzErrMsg; /* Error message stored here */ + int iDb; /* 0 for main database. 1 for TEMP, 2.. for ATTACHed */ + int rc; /* Result code stored here */ +} InitData; + +/* +** Structure containing global configuration data for the SQLite library. +** +** This structure also contains some state information. +*/ +struct Sqlite3Config { + int bMemstat; /* True to enable memory status */ + int bCoreMutex; /* True to enable core mutexing */ + int bFullMutex; /* True to enable full mutexing */ + int bOpenUri; /* True to interpret filenames as URIs */ + int bUseCis; /* Use covering indices for full-scans */ + int mxStrlen; /* Maximum string length */ + int neverCorrupt; /* Database is always well-formed */ + int szLookaside; /* Default lookaside buffer size */ + int nLookaside; /* Default lookaside buffer count */ + sqlite3_mem_methods m; /* Low-level memory allocation interface */ + sqlite3_mutex_methods mutex; /* Low-level mutex interface */ + sqlite3_pcache_methods2 pcache2; /* Low-level page-cache interface */ + void *pHeap; /* Heap storage space */ + int nHeap; /* Size of pHeap[] */ + int mnReq, mxReq; /* Min and max heap requests sizes */ + sqlite3_int64 szMmap; /* mmap() space per open file */ + sqlite3_int64 mxMmap; /* Maximum value for szMmap */ + void *pScratch; /* Scratch memory */ + int szScratch; /* Size of each scratch buffer */ + int nScratch; /* Number of scratch buffers */ + void *pPage; /* Page cache memory */ + int szPage; /* Size of each page in pPage[] */ + int nPage; /* Number of pages in pPage[] */ + int mxParserStack; /* maximum depth of the parser stack */ + int sharedCacheEnabled; /* true if shared-cache mode enabled */ + u32 szPma; /* Maximum Sorter PMA size */ + /* The above might be initialized to non-zero. The following need to always + ** initially be zero, however. */ + int isInit; /* True after initialization has finished */ + int inProgress; /* True while initialization in progress */ + int isMutexInit; /* True after mutexes are initialized */ + int isMallocInit; /* True after malloc is initialized */ + int isPCacheInit; /* True after malloc is initialized */ + int nRefInitMutex; /* Number of users of pInitMutex */ + sqlite3_mutex *pInitMutex; /* Mutex used by sqlite3_initialize() */ + void (*xLog)(void*,int,const char*); /* Function for logging */ + void *pLogArg; /* First argument to xLog() */ +#ifdef SQLITE_ENABLE_SQLLOG + void(*xSqllog)(void*,sqlite3*,const char*, int); + void *pSqllogArg; +#endif +#ifdef SQLITE_VDBE_COVERAGE + /* The following callback (if not NULL) is invoked on every VDBE branch + ** operation. Set the callback using SQLITE_TESTCTRL_VDBE_COVERAGE. + */ + void (*xVdbeBranch)(void*,int iSrcLine,u8 eThis,u8 eMx); /* Callback */ + void *pVdbeBranchArg; /* 1st argument */ +#endif +#ifndef SQLITE_OMIT_BUILTIN_TEST + int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */ +#endif + int bLocaltimeFault; /* True to fail localtime() calls */ +}; + +/* +** This macro is used inside of assert() statements to indicate that +** the assert is only valid on a well-formed database. Instead of: +** +** assert( X ); +** +** One writes: +** +** assert( X || CORRUPT_DB ); +** +** CORRUPT_DB is true during normal operation. CORRUPT_DB does not indicate +** that the database is definitely corrupt, only that it might be corrupt. +** For most test cases, CORRUPT_DB is set to false using a special +** sqlite3_test_control(). This enables assert() statements to prove +** things that are always true for well-formed databases. +*/ +#define CORRUPT_DB (sqlite3Config.neverCorrupt==0) + +/* +** Context pointer passed down through the tree-walk. +*/ +struct Walker { + int (*xExprCallback)(Walker*, Expr*); /* Callback for expressions */ + int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */ + void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */ + Parse *pParse; /* Parser context. */ + int walkerDepth; /* Number of subqueries */ + u8 eCode; /* A small processing code */ + union { /* Extra data for callback */ + NameContext *pNC; /* Naming context */ + int n; /* A counter */ + int iCur; /* A cursor number */ + SrcList *pSrcList; /* FROM clause */ + struct SrcCount *pSrcCount; /* Counting column references */ + } u; +}; + +/* Forward declarations */ +SQLITE_PRIVATE int sqlite3WalkExpr(Walker*, Expr*); +SQLITE_PRIVATE int sqlite3WalkExprList(Walker*, ExprList*); +SQLITE_PRIVATE int sqlite3WalkSelect(Walker*, Select*); +SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker*, Select*); +SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker*, Select*); + +/* +** Return code from the parse-tree walking primitives and their +** callbacks. +*/ +#define WRC_Continue 0 /* Continue down into children */ +#define WRC_Prune 1 /* Omit children but continue walking siblings */ +#define WRC_Abort 2 /* Abandon the tree walk */ + +/* +** An instance of this structure represents a set of one or more CTEs +** (common table expressions) created by a single WITH clause. +*/ +struct With { + int nCte; /* Number of CTEs in the WITH clause */ + With *pOuter; /* Containing WITH clause, or NULL */ + struct Cte { /* For each CTE in the WITH clause.... */ + char *zName; /* Name of this CTE */ + ExprList *pCols; /* List of explicit column names, or NULL */ + Select *pSelect; /* The definition of this CTE */ + const char *zErr; /* Error message for circular references */ + } a[1]; +}; + +#ifdef SQLITE_DEBUG +/* +** An instance of the TreeView object is used for printing the content of +** data structures on sqlite3DebugPrintf() using a tree-like view. +*/ +struct TreeView { + int iLevel; /* Which level of the tree we are on */ + u8 bLine[100]; /* Draw vertical in column i if bLine[i] is true */ +}; +#endif /* SQLITE_DEBUG */ + +/* +** Assuming zIn points to the first byte of a UTF-8 character, +** advance zIn to point to the first byte of the next UTF-8 character. +*/ +#define SQLITE_SKIP_UTF8(zIn) { \ + if( (*(zIn++))>=0xc0 ){ \ + while( (*zIn & 0xc0)==0x80 ){ zIn++; } \ + } \ +} + +/* +** The SQLITE_*_BKPT macros are substitutes for the error codes with +** the same name but without the _BKPT suffix. These macros invoke +** routines that report the line-number on which the error originated +** using sqlite3_log(). The routines also provide a convenient place +** to set a debugger breakpoint. +*/ +SQLITE_PRIVATE int sqlite3CorruptError(int); +SQLITE_PRIVATE int sqlite3MisuseError(int); +SQLITE_PRIVATE int sqlite3CantopenError(int); +#define SQLITE_CORRUPT_BKPT sqlite3CorruptError(__LINE__) +#define SQLITE_MISUSE_BKPT sqlite3MisuseError(__LINE__) +#define SQLITE_CANTOPEN_BKPT sqlite3CantopenError(__LINE__) + + +/* +** FTS4 is really an extension for FTS3. It is enabled using the +** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also call +** the SQLITE_ENABLE_FTS4 macro to serve as an alias for SQLITE_ENABLE_FTS3. +*/ +#if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3) +# define SQLITE_ENABLE_FTS3 1 +#endif + +/* +** The ctype.h header is needed for non-ASCII systems. It is also +** needed by FTS3 when FTS3 is included in the amalgamation. +*/ +#if !defined(SQLITE_ASCII) || \ + (defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_AMALGAMATION)) +# include +#endif + +/* +** The following macros mimic the standard library functions toupper(), +** isspace(), isalnum(), isdigit() and isxdigit(), respectively. The +** sqlite versions only work for ASCII characters, regardless of locale. +*/ +#ifdef SQLITE_ASCII +# define sqlite3Toupper(x) ((x)&~(sqlite3CtypeMap[(unsigned char)(x)]&0x20)) +# define sqlite3Isspace(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x01) +# define sqlite3Isalnum(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x06) +# define sqlite3Isalpha(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x02) +# define sqlite3Isdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x04) +# define sqlite3Isxdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x08) +# define sqlite3Tolower(x) (sqlite3UpperToLower[(unsigned char)(x)]) +#else +# define sqlite3Toupper(x) toupper((unsigned char)(x)) +# define sqlite3Isspace(x) isspace((unsigned char)(x)) +# define sqlite3Isalnum(x) isalnum((unsigned char)(x)) +# define sqlite3Isalpha(x) isalpha((unsigned char)(x)) +# define sqlite3Isdigit(x) isdigit((unsigned char)(x)) +# define sqlite3Isxdigit(x) isxdigit((unsigned char)(x)) +# define sqlite3Tolower(x) tolower((unsigned char)(x)) +#endif +SQLITE_PRIVATE int sqlite3IsIdChar(u8); + +/* +** Internal function prototypes +*/ +#define sqlite3StrICmp sqlite3_stricmp +SQLITE_PRIVATE int sqlite3Strlen30(const char*); +#define sqlite3StrNICmp sqlite3_strnicmp + +SQLITE_PRIVATE int sqlite3MallocInit(void); +SQLITE_PRIVATE void sqlite3MallocEnd(void); +SQLITE_PRIVATE void *sqlite3Malloc(u64); +SQLITE_PRIVATE void *sqlite3MallocZero(u64); +SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3*, u64); +SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3*, u64); +SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3*,const char*); +SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3*,const char*, u64); +SQLITE_PRIVATE void *sqlite3Realloc(void*, u64); +SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64); +SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, u64); +SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*); +SQLITE_PRIVATE int sqlite3MallocSize(void*); +SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, void*); +SQLITE_PRIVATE void *sqlite3ScratchMalloc(int); +SQLITE_PRIVATE void sqlite3ScratchFree(void*); +SQLITE_PRIVATE void *sqlite3PageMalloc(int); +SQLITE_PRIVATE void sqlite3PageFree(void*); +SQLITE_PRIVATE void sqlite3MemSetDefault(void); +SQLITE_PRIVATE void sqlite3BenignMallocHooks(void (*)(void), void (*)(void)); +SQLITE_PRIVATE int sqlite3HeapNearlyFull(void); + +/* +** On systems with ample stack space and that support alloca(), make +** use of alloca() to obtain space for large automatic objects. By default, +** obtain space from malloc(). +** +** The alloca() routine never returns NULL. This will cause code paths +** that deal with sqlite3StackAlloc() failures to be unreachable. +*/ +#ifdef SQLITE_USE_ALLOCA +# define sqlite3StackAllocRaw(D,N) alloca(N) +# define sqlite3StackAllocZero(D,N) memset(alloca(N), 0, N) +# define sqlite3StackFree(D,P) +#else +# define sqlite3StackAllocRaw(D,N) sqlite3DbMallocRaw(D,N) +# define sqlite3StackAllocZero(D,N) sqlite3DbMallocZero(D,N) +# define sqlite3StackFree(D,P) sqlite3DbFree(D,P) +#endif + +#ifdef SQLITE_ENABLE_MEMSYS3 +SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void); +#endif +#ifdef SQLITE_ENABLE_MEMSYS5 +SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void); +#endif + + +#ifndef SQLITE_MUTEX_OMIT +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void); +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void); +SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int); +SQLITE_PRIVATE int sqlite3MutexInit(void); +SQLITE_PRIVATE int sqlite3MutexEnd(void); +#endif + +SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int); +SQLITE_PRIVATE void sqlite3StatusUp(int, int); +SQLITE_PRIVATE void sqlite3StatusDown(int, int); +SQLITE_PRIVATE void sqlite3StatusSet(int, int); + +/* Access to mutexes used by sqlite3_status() */ +SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void); +SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void); + +#ifndef SQLITE_OMIT_FLOATING_POINT +SQLITE_PRIVATE int sqlite3IsNaN(double); +#else +# define sqlite3IsNaN(X) 0 +#endif + +/* +** An instance of the following structure holds information about SQL +** functions arguments that are the parameters to the printf() function. +*/ +struct PrintfArguments { + int nArg; /* Total number of arguments */ + int nUsed; /* Number of arguments used so far */ + sqlite3_value **apArg; /* The argument values */ +}; + +#define SQLITE_PRINTF_INTERNAL 0x01 +#define SQLITE_PRINTF_SQLFUNC 0x02 +SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, u32, const char*, va_list); +SQLITE_PRIVATE void sqlite3XPrintf(StrAccum*, u32, const char*, ...); +SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...); +SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list); +SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3*,char*,const char*,...); +#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) +SQLITE_PRIVATE void sqlite3DebugPrintf(const char*, ...); +#endif +#if defined(SQLITE_TEST) +SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*); +#endif + +#if defined(SQLITE_DEBUG) +SQLITE_PRIVATE TreeView *sqlite3TreeViewPush(TreeView*,u8); +SQLITE_PRIVATE void sqlite3TreeViewPop(TreeView*); +SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView*, const char*, ...); +SQLITE_PRIVATE void sqlite3TreeViewItem(TreeView*, const char*, u8); +SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8); +SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*); +SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8); +#endif + + +SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*, ...); +SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...); +SQLITE_PRIVATE int sqlite3Dequote(char*); +SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int); +SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*, char **); +SQLITE_PRIVATE void sqlite3FinishCoding(Parse*); +SQLITE_PRIVATE int sqlite3GetTempReg(Parse*); +SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse*,int); +SQLITE_PRIVATE int sqlite3GetTempRange(Parse*,int); +SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse*,int,int); +SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse*); +SQLITE_PRIVATE Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int); +SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*); +SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*); +SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*); +SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*); +SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*); +SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*); +SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*); +SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); +SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int); +SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*); +SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); +SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*); +SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**); +SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**); +SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int); +SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3*); +SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3*,int); +SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3*); +SQLITE_PRIVATE void sqlite3BeginParse(Parse*,int); +SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3*); +SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*); +SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *, int); +SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table*); +SQLITE_PRIVATE i16 sqlite3ColumnOfIndex(Index*, i16); +SQLITE_PRIVATE void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int); +SQLITE_PRIVATE void sqlite3AddColumn(Parse*,Token*); +SQLITE_PRIVATE void sqlite3AddNotNull(Parse*, int); +SQLITE_PRIVATE void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int); +SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*); +SQLITE_PRIVATE void sqlite3AddColumnType(Parse*,Token*); +SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,ExprSpan*); +SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*); +SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*); +SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*, + sqlite3_vfs**,char**,char **); +SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*); +SQLITE_PRIVATE int sqlite3CodeOnce(Parse *); + +#ifdef SQLITE_OMIT_BUILTIN_TEST +# define sqlite3FaultSim(X) SQLITE_OK +#else +SQLITE_PRIVATE int sqlite3FaultSim(int); +#endif + +SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32); +SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec*, u32); +SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec*, u32); +SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec*, u32, void*); +SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec*); +SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec*); +SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*); + +SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int); +SQLITE_PRIVATE void sqlite3RowSetClear(RowSet*); +SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet*, i64); +SQLITE_PRIVATE int sqlite3RowSetTest(RowSet*, int iBatch, i64); +SQLITE_PRIVATE int sqlite3RowSetNext(RowSet*, i64*); + +SQLITE_PRIVATE void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int); + +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) +SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse*,Table*); +#else +# define sqlite3ViewGetColumnNames(A,B) 0 +#endif + +#if SQLITE_MAX_ATTACHED>30 +SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask); +#endif +SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int); +SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int); +SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*); +#ifndef SQLITE_OMIT_AUTOINCREMENT +SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse); +SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse); +#else +# define sqlite3AutoincrementBegin(X) +# define sqlite3AutoincrementEnd(X) +#endif +SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int); +SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*); +SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*); +SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*); +SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(sqlite3*, SrcList*, int, int); +SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*); +SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, + Token*, Select*, Expr*, IdList*); +SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); +SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, struct SrcList_item *); +SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*); +SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*); +SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*); +SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*); +SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**); +SQLITE_PRIVATE Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, + Expr*, int, int); +SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int); +SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*); +SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, + Expr*,ExprList*,u16,Expr*,Expr*); +SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*); +SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*); +SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int); +SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); +#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) +SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,Expr*,char*); +#endif +SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); +SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); +SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int); +SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*); +SQLITE_PRIVATE u64 sqlite3WhereOutputRowCount(WhereInfo*); +SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*); +SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*); +SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo*); +SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo*); +SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo*); +SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo*, int*); +SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); +SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); +SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int); +SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse*, int, int, int); +SQLITE_PRIVATE void sqlite3ExprCachePush(Parse*); +SQLITE_PRIVATE void sqlite3ExprCachePop(Parse*); +SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse*, int, int); +SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse*); +SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse*, int, int); +SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int); +SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int); +SQLITE_PRIVATE void sqlite3ExprCodeAtInit(Parse*, Expr*, int, u8); +SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse*, Expr*, int*); +SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse*, Expr*, int); +SQLITE_PRIVATE void sqlite3ExprCodeAndCache(Parse*, Expr*, int); +SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, u8); +#define SQLITE_ECEL_DUP 0x01 /* Deep, not shallow copies */ +#define SQLITE_ECEL_FACTOR 0x02 /* Factor out constant terms */ +SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse*, Expr*, int, int); +SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse*, Expr*, int, int); +SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3*,const char*, const char*); +SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,int isView,const char*, const char*); +SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,int isView,struct SrcList_item *); +SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*); +SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); +SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); +SQLITE_PRIVATE void sqlite3Vacuum(Parse*); +SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*); +SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*); +SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*, int); +SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*, int); +SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr*, Expr*, int); +SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); +SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); +SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*); +SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*); +SQLITE_PRIVATE void sqlite3PrngSaveState(void); +SQLITE_PRIVATE void sqlite3PrngRestoreState(void); +SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3*,int); +SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse*, int); +SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb); +SQLITE_PRIVATE void sqlite3BeginTransaction(Parse*, int); +SQLITE_PRIVATE void sqlite3CommitTransaction(Parse*); +SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse*); +SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*); +SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *); +SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*); +SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*); +SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*); +SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8); +SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int); +SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*); +SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); +SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); +SQLITE_PRIVATE int sqlite3IsRowid(const char*); +SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8); +SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*); +SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int); +SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse*,int); +SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int, + u8,u8,int,int*); +SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int); +SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int, u8*, int*, int*); +SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int); +SQLITE_PRIVATE void sqlite3MultiWrite(Parse*); +SQLITE_PRIVATE void sqlite3MayAbort(Parse*); +SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, int, char*, i8, u8); +SQLITE_PRIVATE void sqlite3UniqueConstraint(Parse*, int, Index*); +SQLITE_PRIVATE void sqlite3RowidConstraint(Parse*, int, Table*); +SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int); +SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int); +SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int); +SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*); +SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int); +#if SELECTTRACE_ENABLED +SQLITE_PRIVATE void sqlite3SelectSetName(Select*,const char*); +#else +# define sqlite3SelectSetName(A,B) +#endif +SQLITE_PRIVATE void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*); +SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,u8); +SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3*); +SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void); +SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void); +SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*); +SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*); +SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int); + +#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) +SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, int); +#endif + +#ifndef SQLITE_OMIT_TRIGGER +SQLITE_PRIVATE void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*, + Expr*,int, int); +SQLITE_PRIVATE void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*); +SQLITE_PRIVATE void sqlite3DropTrigger(Parse*, SrcList*, int); +SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse*, Trigger*); +SQLITE_PRIVATE Trigger *sqlite3TriggersExist(Parse *, Table*, int, ExprList*, int *pMask); +SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *, Table *); +SQLITE_PRIVATE void sqlite3CodeRowTrigger(Parse*, Trigger *, int, ExprList*, int, Table *, + int, int, int); +SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect(Parse *, Trigger *, Table *, int, int, int); + void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*); +SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*); +SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*); +SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*, + Select*,u8); +SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, u8); +SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*); +SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3*, Trigger*); +SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*); +SQLITE_PRIVATE u32 sqlite3TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Table*,int); +# define sqlite3ParseToplevel(p) ((p)->pToplevel ? (p)->pToplevel : (p)) +#else +# define sqlite3TriggersExist(B,C,D,E,F) 0 +# define sqlite3DeleteTrigger(A,B) +# define sqlite3DropTriggerPtr(A,B) +# define sqlite3UnlinkAndDeleteTrigger(A,B,C) +# define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I) +# define sqlite3CodeRowTriggerDirect(A,B,C,D,E,F) +# define sqlite3TriggerList(X, Y) 0 +# define sqlite3ParseToplevel(p) p +# define sqlite3TriggerColmask(A,B,C,D,E,F,G) 0 +#endif + +SQLITE_PRIVATE int sqlite3JoinType(Parse*, Token*, Token*, Token*); +SQLITE_PRIVATE void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int); +SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse*, int); +#ifndef SQLITE_OMIT_AUTHORIZATION +SQLITE_PRIVATE void sqlite3AuthRead(Parse*,Expr*,Schema*,SrcList*); +SQLITE_PRIVATE int sqlite3AuthCheck(Parse*,int, const char*, const char*, const char*); +SQLITE_PRIVATE void sqlite3AuthContextPush(Parse*, AuthContext*, const char*); +SQLITE_PRIVATE void sqlite3AuthContextPop(AuthContext*); +SQLITE_PRIVATE int sqlite3AuthReadCol(Parse*, const char *, const char *, int); +#else +# define sqlite3AuthRead(a,b,c,d) +# define sqlite3AuthCheck(a,b,c,d,e) SQLITE_OK +# define sqlite3AuthContextPush(a,b,c) +# define sqlite3AuthContextPop(a) ((void)(a)) +#endif +SQLITE_PRIVATE void sqlite3Attach(Parse*, Expr*, Expr*, Expr*); +SQLITE_PRIVATE void sqlite3Detach(Parse*, Expr*); +SQLITE_PRIVATE void sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*); +SQLITE_PRIVATE int sqlite3FixSrcList(DbFixer*, SrcList*); +SQLITE_PRIVATE int sqlite3FixSelect(DbFixer*, Select*); +SQLITE_PRIVATE int sqlite3FixExpr(DbFixer*, Expr*); +SQLITE_PRIVATE int sqlite3FixExprList(DbFixer*, ExprList*); +SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); +SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*, int, u8); +SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*); +SQLITE_PRIVATE int sqlite3Atoi(const char*); +SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar); +SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte); +SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**); +SQLITE_PRIVATE LogEst sqlite3LogEst(u64); +SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst); +#ifndef SQLITE_OMIT_VIRTUALTABLE +SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double); +#endif +SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst); + +/* +** Routines to read and write variable-length integers. These used to +** be defined locally, but now we use the varint routines in the util.c +** file. +*/ +SQLITE_PRIVATE int sqlite3PutVarint(unsigned char*, u64); +SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *, u64 *); +SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *, u32 *); +SQLITE_PRIVATE int sqlite3VarintLen(u64 v); + +/* +** The common case is for a varint to be a single byte. They following +** macros handle the common case without a procedure call, but then call +** the procedure for larger varints. +*/ +#define getVarint32(A,B) \ + (u8)((*(A)<(u8)0x80)?((B)=(u32)*(A)),1:sqlite3GetVarint32((A),(u32 *)&(B))) +#define putVarint32(A,B) \ + (u8)(((u32)(B)<(u32)0x80)?(*(A)=(unsigned char)(B)),1:\ + sqlite3PutVarint((A),(B))) +#define getVarint sqlite3GetVarint +#define putVarint sqlite3PutVarint + + +SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *, Index *); +SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int); +SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2); +SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); +SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr); +SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); +SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*); +SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); +SQLITE_PRIVATE void sqlite3Error(sqlite3*,int); +SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); +SQLITE_PRIVATE u8 sqlite3HexToInt(int h); +SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); + +#if defined(SQLITE_NEED_ERR_NAME) +SQLITE_PRIVATE const char *sqlite3ErrName(int); +#endif + +SQLITE_PRIVATE const char *sqlite3ErrStr(int); +SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse); +SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); +SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); +SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int); +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*); +SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*); +SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *); +SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *); +SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int); +SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64); +SQLITE_PRIVATE int sqlite3SubInt64(i64*,i64); +SQLITE_PRIVATE int sqlite3MulInt64(i64*,i64); +SQLITE_PRIVATE int sqlite3AbsInt32(int); +#ifdef SQLITE_ENABLE_8_3_NAMES +SQLITE_PRIVATE void sqlite3FileSuffix3(const char*, char*); +#else +# define sqlite3FileSuffix3(X,Y) +#endif +SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,u8); + +SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8); +SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8); +SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, + void(*)(void*)); +SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value*); +SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*); +SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *); +SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8); +SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **); +SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8); +#ifndef SQLITE_AMALGAMATION +SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[]; +SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[]; +SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[]; +SQLITE_PRIVATE const Token sqlite3IntTokens[]; +SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config; +SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions; +#ifndef SQLITE_OMIT_WSD +SQLITE_PRIVATE int sqlite3PendingByte; +#endif +#endif +SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3*, int, int, int); +SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*); +SQLITE_PRIVATE void sqlite3AlterFunctions(void); +SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*); +SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *); +SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...); +SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*); +SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *, Expr *, int, int); +SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*); +SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*); +SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*); +SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*); +SQLITE_PRIVATE void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*); +SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*); +SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int); +SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *); +SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *); +SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*); +SQLITE_PRIVATE char sqlite3AffinityType(const char*, u8*); +SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*); +SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*); +SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*); +SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *); +SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB); +SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3*,Index*); +SQLITE_PRIVATE void sqlite3DefaultRowEst(Index*); +SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3*, int); +SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*); +SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse*, int, int); +SQLITE_PRIVATE void sqlite3SchemaClear(void *); +SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *, Btree *); +SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *); +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int); +SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo*); +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo*); +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*); +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo*); +#endif +SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, + void (*)(sqlite3_context*,int,sqlite3_value **), + void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*), + FuncDestructor *pDestructor +); +SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int); +SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *); + +SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); +SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int); +SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum*,const char*); +SQLITE_PRIVATE void sqlite3AppendChar(StrAccum*,int,char); +SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*); +SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*); +SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int); +SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); + +SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *); +SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *); + +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 +SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void); +SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(Parse*,Index*,UnpackedRecord**,Expr*,u8,int,int*); +SQLITE_PRIVATE int sqlite3Stat4ValueFromExpr(Parse*, Expr*, u8, sqlite3_value**); +SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord*); +SQLITE_PRIVATE int sqlite3Stat4Column(sqlite3*, const void*, int, int, sqlite3_value**); +#endif + +/* +** The interface to the LEMON-generated parser +*/ +SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(u64)); +SQLITE_PRIVATE void sqlite3ParserFree(void*, void(*)(void*)); +SQLITE_PRIVATE void sqlite3Parser(void*, int, Token, Parse*); +#ifdef YYTRACKMAXSTACKDEPTH +SQLITE_PRIVATE int sqlite3ParserStackPeak(void*); +#endif + +SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3*); +#ifndef SQLITE_OMIT_LOAD_EXTENSION +SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3*); +#else +# define sqlite3CloseExtensions(X) +#endif + +#ifndef SQLITE_OMIT_SHARED_CACHE +SQLITE_PRIVATE void sqlite3TableLock(Parse *, int, int, u8, const char *); +#else + #define sqlite3TableLock(v,w,x,y,z) +#endif + +#ifdef SQLITE_TEST +SQLITE_PRIVATE int sqlite3Utf8To8(unsigned char*); +#endif + +#ifdef SQLITE_OMIT_VIRTUALTABLE +# define sqlite3VtabClear(Y) +# define sqlite3VtabSync(X,Y) SQLITE_OK +# define sqlite3VtabRollback(X) +# define sqlite3VtabCommit(X) +# define sqlite3VtabInSync(db) 0 +# define sqlite3VtabLock(X) +# define sqlite3VtabUnlock(X) +# define sqlite3VtabUnlockList(X) +# define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK +# define sqlite3GetVTable(X,Y) ((VTable*)0) +#else +SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table*); +SQLITE_PRIVATE void sqlite3VtabDisconnect(sqlite3 *db, Table *p); +SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, Vdbe*); +SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db); +SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db); +SQLITE_PRIVATE void sqlite3VtabLock(VTable *); +SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *); +SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3*); +SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *, int, int); +SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*); +SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3*, Table*); +# define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0) +#endif +SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*); +SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int); +SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse*, Token*); +SQLITE_PRIVATE void sqlite3VtabArgInit(Parse*); +SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse*, Token*); +SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **); +SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse*, Table*); +SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *); +SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *); +SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); +SQLITE_PRIVATE void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**); +SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); +SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); +SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); +SQLITE_PRIVATE void sqlite3ParserReset(Parse*); +SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*); +SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*); +SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); +SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*); +SQLITE_PRIVATE const char *sqlite3JournalModename(int); +#ifndef SQLITE_OMIT_WAL +SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3*, int, int, int*, int*); +SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int); +#endif +#ifndef SQLITE_OMIT_CTE +SQLITE_PRIVATE With *sqlite3WithAdd(Parse*,With*,Token*,ExprList*,Select*); +SQLITE_PRIVATE void sqlite3WithDelete(sqlite3*,With*); +SQLITE_PRIVATE void sqlite3WithPush(Parse*, With*, u8); +#else +#define sqlite3WithPush(x,y,z) +#define sqlite3WithDelete(x,y) +#endif + +/* Declarations for functions in fkey.c. All of these are replaced by +** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign +** key functionality is available. If OMIT_TRIGGER is defined but +** OMIT_FOREIGN_KEY is not, only some of the functions are no-oped. In +** this case foreign keys are parsed, but no other functionality is +** provided (enforcement of FK constraints requires the triggers sub-system). +*/ +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) +SQLITE_PRIVATE void sqlite3FkCheck(Parse*, Table*, int, int, int*, int); +SQLITE_PRIVATE void sqlite3FkDropTable(Parse*, SrcList *, Table*); +SQLITE_PRIVATE void sqlite3FkActions(Parse*, Table*, ExprList*, int, int*, int); +SQLITE_PRIVATE int sqlite3FkRequired(Parse*, Table*, int*, int); +SQLITE_PRIVATE u32 sqlite3FkOldmask(Parse*, Table*); +SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *); +#else + #define sqlite3FkActions(a,b,c,d,e,f) + #define sqlite3FkCheck(a,b,c,d,e,f) + #define sqlite3FkDropTable(a,b,c) + #define sqlite3FkOldmask(a,b) 0 + #define sqlite3FkRequired(a,b,c,d) 0 +#endif +#ifndef SQLITE_OMIT_FOREIGN_KEY +SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *, Table*); +SQLITE_PRIVATE int sqlite3FkLocateIndex(Parse*,Table*,FKey*,Index**,int**); +#else + #define sqlite3FkDelete(a,b) + #define sqlite3FkLocateIndex(a,b,c,d,e) +#endif + + +/* +** Available fault injectors. Should be numbered beginning with 0. +*/ +#define SQLITE_FAULTINJECTOR_MALLOC 0 +#define SQLITE_FAULTINJECTOR_COUNT 1 + +/* +** The interface to the code in fault.c used for identifying "benign" +** malloc failures. This is only present if SQLITE_OMIT_BUILTIN_TEST +** is not defined. +*/ +#ifndef SQLITE_OMIT_BUILTIN_TEST +SQLITE_PRIVATE void sqlite3BeginBenignMalloc(void); +SQLITE_PRIVATE void sqlite3EndBenignMalloc(void); +#else + #define sqlite3BeginBenignMalloc() + #define sqlite3EndBenignMalloc() +#endif + +/* +** Allowed return values from sqlite3FindInIndex() +*/ +#define IN_INDEX_ROWID 1 /* Search the rowid of the table */ +#define IN_INDEX_EPH 2 /* Search an ephemeral b-tree */ +#define IN_INDEX_INDEX_ASC 3 /* Existing index ASCENDING */ +#define IN_INDEX_INDEX_DESC 4 /* Existing index DESCENDING */ +#define IN_INDEX_NOOP 5 /* No table available. Use comparisons */ +/* +** Allowed flags for the 3rd parameter to sqlite3FindInIndex(). +*/ +#define IN_INDEX_NOOP_OK 0x0001 /* OK to return IN_INDEX_NOOP */ +#define IN_INDEX_MEMBERSHIP 0x0002 /* IN operator used for membership test */ +#define IN_INDEX_LOOP 0x0004 /* IN operator used as a loop */ +SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*); + +#ifdef SQLITE_ENABLE_ATOMIC_WRITE +SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int); +SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *); +SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *); +SQLITE_PRIVATE int sqlite3JournalExists(sqlite3_file *p); +#else + #define sqlite3JournalSize(pVfs) ((pVfs)->szOsFile) + #define sqlite3JournalExists(p) 1 +#endif + +SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *); +SQLITE_PRIVATE int sqlite3MemJournalSize(void); +SQLITE_PRIVATE int sqlite3IsMemJournal(sqlite3_file *); + +SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p); +#if SQLITE_MAX_EXPR_DEPTH>0 +SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *); +SQLITE_PRIVATE int sqlite3ExprCheckHeight(Parse*, int); +#else + #define sqlite3SelectExprHeight(x) 0 + #define sqlite3ExprCheckHeight(x,y) +#endif + +SQLITE_PRIVATE u32 sqlite3Get4byte(const u8*); +SQLITE_PRIVATE void sqlite3Put4byte(u8*, u32); + +#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY +SQLITE_PRIVATE void sqlite3ConnectionBlocked(sqlite3 *, sqlite3 *); +SQLITE_PRIVATE void sqlite3ConnectionUnlocked(sqlite3 *db); +SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db); +#else + #define sqlite3ConnectionBlocked(x,y) + #define sqlite3ConnectionUnlocked(x) + #define sqlite3ConnectionClosed(x) +#endif + +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE void sqlite3ParserTrace(FILE*, char *); +#endif + +/* +** If the SQLITE_ENABLE IOTRACE exists then the global variable +** sqlite3IoTrace is a pointer to a printf-like routine used to +** print I/O tracing messages. +*/ +#ifdef SQLITE_ENABLE_IOTRACE +# define IOTRACE(A) if( sqlite3IoTrace ){ sqlite3IoTrace A; } +SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe*); +SQLITE_API SQLITE_EXTERN void (SQLITE_CDECL *sqlite3IoTrace)(const char*,...); +#else +# define IOTRACE(A) +# define sqlite3VdbeIOTraceSql(X) +#endif + +/* +** These routines are available for the mem2.c debugging memory allocator +** only. They are used to verify that different "types" of memory +** allocations are properly tracked by the system. +** +** sqlite3MemdebugSetType() sets the "type" of an allocation to one of +** the MEMTYPE_* macros defined below. The type must be a bitmask with +** a single bit set. +** +** sqlite3MemdebugHasType() returns true if any of the bits in its second +** argument match the type set by the previous sqlite3MemdebugSetType(). +** sqlite3MemdebugHasType() is intended for use inside assert() statements. +** +** sqlite3MemdebugNoType() returns true if none of the bits in its second +** argument match the type set by the previous sqlite3MemdebugSetType(). +** +** Perhaps the most important point is the difference between MEMTYPE_HEAP +** and MEMTYPE_LOOKASIDE. If an allocation is MEMTYPE_LOOKASIDE, that means +** it might have been allocated by lookaside, except the allocation was +** too large or lookaside was already full. It is important to verify +** that allocations that might have been satisfied by lookaside are not +** passed back to non-lookaside free() routines. Asserts such as the +** example above are placed on the non-lookaside free() routines to verify +** this constraint. +** +** All of this is no-op for a production build. It only comes into +** play when the SQLITE_MEMDEBUG compile-time option is used. +*/ +#ifdef SQLITE_MEMDEBUG +SQLITE_PRIVATE void sqlite3MemdebugSetType(void*,u8); +SQLITE_PRIVATE int sqlite3MemdebugHasType(void*,u8); +SQLITE_PRIVATE int sqlite3MemdebugNoType(void*,u8); +#else +# define sqlite3MemdebugSetType(X,Y) /* no-op */ +# define sqlite3MemdebugHasType(X,Y) 1 +# define sqlite3MemdebugNoType(X,Y) 1 +#endif +#define MEMTYPE_HEAP 0x01 /* General heap allocations */ +#define MEMTYPE_LOOKASIDE 0x02 /* Heap that might have been lookaside */ +#define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */ +#define MEMTYPE_PCACHE 0x08 /* Page cache allocations */ + +/* +** Threading interface +*/ +#if SQLITE_MAX_WORKER_THREADS>0 +SQLITE_PRIVATE int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*); +SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread*, void**); +#endif + +#endif /* _SQLITEINT_H_ */ + +/************** End of sqliteInt.h *******************************************/ +/************** Begin file global.c ******************************************/ +/* +** 2008 June 13 +** +** 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 definitions of global variables and constants. +*/ + +/* An array to map all upper-case characters into their corresponding +** lower-case character. +** +** SQLite only considers US-ASCII (or EBCDIC) characters. We do not +** handle case conversions for the UTF character set since the tables +** involved are nearly as big or bigger than SQLite itself. +*/ +SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[] = { +#ifdef SQLITE_ASCII + 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, 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, 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 +#endif +#ifdef SQLITE_EBCDIC + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 0x */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 1x */ + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 2x */ + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 3x */ + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 4x */ + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 5x */ + 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 6x */ + 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /* 7x */ + 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, /* 8x */ + 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, /* 9x */ + 160,161,162,163,164,165,166,167,168,169,170,171,140,141,142,175, /* Ax */ + 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, /* Bx */ + 192,129,130,131,132,133,134,135,136,137,202,203,204,205,206,207, /* Cx */ + 208,145,146,147,148,149,150,151,152,153,218,219,220,221,222,223, /* Dx */ + 224,225,162,163,164,165,166,167,168,169,234,235,236,237,238,239, /* Ex */ + 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, /* Fx */ +#endif +}; + +/* +** The following 256 byte lookup table is used to support SQLites built-in +** equivalents to the following standard library functions: +** +** isspace() 0x01 +** isalpha() 0x02 +** isdigit() 0x04 +** isalnum() 0x06 +** isxdigit() 0x08 +** toupper() 0x20 +** SQLite identifier character 0x40 +** +** Bit 0x20 is set if the mapped character requires translation to upper +** case. i.e. if the character is a lower-case ASCII character. +** If x is a lower-case ASCII character, then its upper-case equivalent +** is (x - 0x20). Therefore toupper() can be implemented as: +** +** (x & ~(map[x]&0x20)) +** +** Standard function tolower() is implemented using the sqlite3UpperToLower[] +** array. tolower() is used more often than toupper() by SQLite. +** +** Bit 0x40 is set if the character non-alphanumeric and can be used in an +** SQLite identifier. Identifiers are alphanumerics, "_", "$", and any +** non-ASCII UTF character. Hence the test for whether or not a character is +** part of an identifier is 0x46. +** +** SQLite's versions are identical to the standard versions assuming a +** locale of "C". They are implemented as macros in sqliteInt.h. +*/ +#ifdef SQLITE_ASCII +SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00..07 ........ */ + 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, /* 08..0f ........ */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10..17 ........ */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 18..1f ........ */ + 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, /* 20..27 !"#$%&' */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 28..2f ()*+,-./ */ + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, /* 30..37 01234567 */ + 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38..3f 89:;<=>? */ + + 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x02, /* 40..47 @ABCDEFG */ + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 48..4f HIJKLMNO */ + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 50..57 PQRSTUVW */ + 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40, /* 58..5f XYZ[\]^_ */ + 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22, /* 60..67 `abcdefg */ + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 68..6f hijklmno */ + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 70..77 pqrstuvw */ + 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78..7f xyz{|}~. */ + + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 80..87 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 88..8f ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 90..97 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 98..9f ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* a0..a7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* a8..af ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* b0..b7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* b8..bf ........ */ + + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* c0..c7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* c8..cf ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* d0..d7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* d8..df ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* e0..e7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* e8..ef ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* f0..f7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 /* f8..ff ........ */ +}; +#endif + +/* EVIDENCE-OF: R-02982-34736 In order to maintain full backwards +** compatibility for legacy applications, the URI filename capability is +** disabled by default. +** +** EVIDENCE-OF: R-38799-08373 URI filenames can be enabled or disabled +** using the SQLITE_USE_URI=1 or SQLITE_USE_URI=0 compile-time options. +** +** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally +** disabled. The default value may be changed by compiling with the +** SQLITE_USE_URI symbol defined. +*/ +#ifndef SQLITE_USE_URI +# define SQLITE_USE_URI 0 +#endif + +/* EVIDENCE-OF: R-38720-18127 The default setting is determined by the +** SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option, or is "on" if +** that compile-time option is omitted. +*/ +#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN +# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1 +#endif + +/* The minimum PMA size is set to this value multiplied by the database +** page size in bytes. +*/ +#ifndef SQLITE_SORTER_PMASZ +# define SQLITE_SORTER_PMASZ 250 +#endif + +/* +** The following singleton contains the global configuration for +** the SQLite library. +*/ +SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { + SQLITE_DEFAULT_MEMSTATUS, /* bMemstat */ + 1, /* bCoreMutex */ + SQLITE_THREADSAFE==1, /* bFullMutex */ + SQLITE_USE_URI, /* bOpenUri */ + SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ + 0x7ffffffe, /* mxStrlen */ + 0, /* neverCorrupt */ + 128, /* szLookaside */ + 500, /* nLookaside */ + {0,0,0,0,0,0,0,0}, /* m */ + {0,0,0,0,0,0,0,0,0}, /* mutex */ + {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */ + (void*)0, /* pHeap */ + 0, /* nHeap */ + 0, 0, /* mnHeap, mxHeap */ + SQLITE_DEFAULT_MMAP_SIZE, /* szMmap */ + SQLITE_MAX_MMAP_SIZE, /* mxMmap */ + (void*)0, /* pScratch */ + 0, /* szScratch */ + 0, /* nScratch */ + (void*)0, /* pPage */ + 0, /* szPage */ + 0, /* nPage */ + 0, /* mxParserStack */ + 0, /* sharedCacheEnabled */ + SQLITE_SORTER_PMASZ, /* szPma */ + /* All the rest should always be initialized to zero */ + 0, /* isInit */ + 0, /* inProgress */ + 0, /* isMutexInit */ + 0, /* isMallocInit */ + 0, /* isPCacheInit */ + 0, /* nRefInitMutex */ + 0, /* pInitMutex */ + 0, /* xLog */ + 0, /* pLogArg */ +#ifdef SQLITE_ENABLE_SQLLOG + 0, /* xSqllog */ + 0, /* pSqllogArg */ +#endif +#ifdef SQLITE_VDBE_COVERAGE + 0, /* xVdbeBranch */ + 0, /* pVbeBranchArg */ +#endif +#ifndef SQLITE_OMIT_BUILTIN_TEST + 0, /* xTestCallback */ +#endif + 0 /* bLocaltimeFault */ +}; + +/* +** Hash table for global functions - functions common to all +** database connections. After initialization, this table is +** read-only. +*/ +SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions; + +/* +** Constant tokens for values 0 and 1. +*/ +SQLITE_PRIVATE const Token sqlite3IntTokens[] = { + { "0", 1 }, + { "1", 1 } +}; + + +/* +** The value of the "pending" byte must be 0x40000000 (1 byte past the +** 1-gibabyte boundary) in a compatible database. SQLite never uses +** the database page that contains the pending byte. It never attempts +** to read or write that page. The pending byte page is set assign +** for use by the VFS layers as space for managing file locks. +** +** During testing, it is often desirable to move the pending byte to +** a different position in the file. This allows code that has to +** deal with the pending byte to run on files that are much smaller +** than 1 GiB. The sqlite3_test_control() interface can be used to +** move the pending byte. +** +** IMPORTANT: Changing the pending byte to any value other than +** 0x40000000 results in an incompatible database file format! +** Changing the pending byte during operation will result in undefined +** and incorrect behavior. +*/ +#ifndef SQLITE_OMIT_WSD +SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000; +#endif + +/* +** Properties of opcodes. The OPFLG_INITIALIZER macro is +** created by mkopcodeh.awk during compilation. Data is obtained +** from the comments following the "case OP_xxxx:" statements in +** the vdbe.c file. +*/ +SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER; + +/************** End of global.c **********************************************/ +/************** Begin file ctime.c *******************************************/ +/* +** 2010 February 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 implements routines used to report what compile-time options +** SQLite was built with. +*/ + +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS + + +/* +** An array of names of all compile-time options. This array should +** be sorted A-Z. +** +** This array looks large, but in a typical installation actually uses +** only a handful of compile-time options, so most times this array is usually +** rather short and uses little memory space. +*/ +static const char * const azCompileOpt[] = { + +/* These macros are provided to "stringify" the value of the define +** for those options in which the value is meaningful. */ +#define CTIMEOPT_VAL_(opt) #opt +#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt) + +#if SQLITE_32BIT_ROWID + "32BIT_ROWID", +#endif +#if SQLITE_4_BYTE_ALIGNED_MALLOC + "4_BYTE_ALIGNED_MALLOC", +#endif +#if SQLITE_CASE_SENSITIVE_LIKE + "CASE_SENSITIVE_LIKE", +#endif +#if SQLITE_CHECK_PAGES + "CHECK_PAGES", +#endif +#if SQLITE_COVERAGE_TEST + "COVERAGE_TEST", +#endif +#if SQLITE_DEBUG + "DEBUG", +#endif +#if SQLITE_DEFAULT_LOCKING_MODE + "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE), +#endif +#if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc) + "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE), +#endif +#if SQLITE_DISABLE_DIRSYNC + "DISABLE_DIRSYNC", +#endif +#if SQLITE_DISABLE_LFS + "DISABLE_LFS", +#endif +#if SQLITE_ENABLE_API_ARMOR + "ENABLE_API_ARMOR", +#endif +#if SQLITE_ENABLE_ATOMIC_WRITE + "ENABLE_ATOMIC_WRITE", +#endif +#if SQLITE_ENABLE_CEROD + "ENABLE_CEROD", +#endif +#if SQLITE_ENABLE_COLUMN_METADATA + "ENABLE_COLUMN_METADATA", +#endif +#if SQLITE_ENABLE_DBSTAT_VTAB + "ENABLE_DBSTAT_VTAB", +#endif +#if SQLITE_ENABLE_EXPENSIVE_ASSERT + "ENABLE_EXPENSIVE_ASSERT", +#endif +#if SQLITE_ENABLE_FTS1 + "ENABLE_FTS1", +#endif +#if SQLITE_ENABLE_FTS2 + "ENABLE_FTS2", +#endif +#if SQLITE_ENABLE_FTS3 + "ENABLE_FTS3", +#endif +#if SQLITE_ENABLE_FTS3_PARENTHESIS + "ENABLE_FTS3_PARENTHESIS", +#endif +#if SQLITE_ENABLE_FTS4 + "ENABLE_FTS4", +#endif +#if SQLITE_ENABLE_ICU + "ENABLE_ICU", +#endif +#if SQLITE_ENABLE_IOTRACE + "ENABLE_IOTRACE", +#endif +#if SQLITE_ENABLE_LOAD_EXTENSION + "ENABLE_LOAD_EXTENSION", +#endif +#if SQLITE_ENABLE_LOCKING_STYLE + "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE), +#endif +#if SQLITE_ENABLE_MEMORY_MANAGEMENT + "ENABLE_MEMORY_MANAGEMENT", +#endif +#if SQLITE_ENABLE_MEMSYS3 + "ENABLE_MEMSYS3", +#endif +#if SQLITE_ENABLE_MEMSYS5 + "ENABLE_MEMSYS5", +#endif +#if SQLITE_ENABLE_OVERSIZE_CELL_CHECK + "ENABLE_OVERSIZE_CELL_CHECK", +#endif +#if SQLITE_ENABLE_RTREE + "ENABLE_RTREE", +#endif +#if defined(SQLITE_ENABLE_STAT4) + "ENABLE_STAT4", +#elif defined(SQLITE_ENABLE_STAT3) + "ENABLE_STAT3", +#endif +#if SQLITE_ENABLE_UNLOCK_NOTIFY + "ENABLE_UNLOCK_NOTIFY", +#endif +#if SQLITE_ENABLE_UPDATE_DELETE_LIMIT + "ENABLE_UPDATE_DELETE_LIMIT", +#endif +#if SQLITE_HAS_CODEC + "HAS_CODEC", +#endif +#if HAVE_ISNAN || SQLITE_HAVE_ISNAN + "HAVE_ISNAN", +#endif +#if SQLITE_HOMEGROWN_RECURSIVE_MUTEX + "HOMEGROWN_RECURSIVE_MUTEX", +#endif +#if SQLITE_IGNORE_AFP_LOCK_ERRORS + "IGNORE_AFP_LOCK_ERRORS", +#endif +#if SQLITE_IGNORE_FLOCK_LOCK_ERRORS + "IGNORE_FLOCK_LOCK_ERRORS", +#endif +#ifdef SQLITE_INT64_TYPE + "INT64_TYPE", +#endif +#if SQLITE_LOCK_TRACE + "LOCK_TRACE", +#endif +#if defined(SQLITE_MAX_MMAP_SIZE) && !defined(SQLITE_MAX_MMAP_SIZE_xc) + "MAX_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE), +#endif +#ifdef SQLITE_MAX_SCHEMA_RETRY + "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY), +#endif +#if SQLITE_MEMDEBUG + "MEMDEBUG", +#endif +#if SQLITE_MIXED_ENDIAN_64BIT_FLOAT + "MIXED_ENDIAN_64BIT_FLOAT", +#endif +#if SQLITE_NO_SYNC + "NO_SYNC", +#endif +#if SQLITE_OMIT_ALTERTABLE + "OMIT_ALTERTABLE", +#endif +#if SQLITE_OMIT_ANALYZE + "OMIT_ANALYZE", +#endif +#if SQLITE_OMIT_ATTACH + "OMIT_ATTACH", +#endif +#if SQLITE_OMIT_AUTHORIZATION + "OMIT_AUTHORIZATION", +#endif +#if SQLITE_OMIT_AUTOINCREMENT + "OMIT_AUTOINCREMENT", +#endif +#if SQLITE_OMIT_AUTOINIT + "OMIT_AUTOINIT", +#endif +#if SQLITE_OMIT_AUTOMATIC_INDEX + "OMIT_AUTOMATIC_INDEX", +#endif +#if SQLITE_OMIT_AUTORESET + "OMIT_AUTORESET", +#endif +#if SQLITE_OMIT_AUTOVACUUM + "OMIT_AUTOVACUUM", +#endif +#if SQLITE_OMIT_BETWEEN_OPTIMIZATION + "OMIT_BETWEEN_OPTIMIZATION", +#endif +#if SQLITE_OMIT_BLOB_LITERAL + "OMIT_BLOB_LITERAL", +#endif +#if SQLITE_OMIT_BTREECOUNT + "OMIT_BTREECOUNT", +#endif +#if SQLITE_OMIT_BUILTIN_TEST + "OMIT_BUILTIN_TEST", +#endif +#if SQLITE_OMIT_CAST + "OMIT_CAST", +#endif +#if SQLITE_OMIT_CHECK + "OMIT_CHECK", +#endif +#if SQLITE_OMIT_COMPLETE + "OMIT_COMPLETE", +#endif +#if SQLITE_OMIT_COMPOUND_SELECT + "OMIT_COMPOUND_SELECT", +#endif +#if SQLITE_OMIT_CTE + "OMIT_CTE", +#endif +#if SQLITE_OMIT_DATETIME_FUNCS + "OMIT_DATETIME_FUNCS", +#endif +#if SQLITE_OMIT_DECLTYPE + "OMIT_DECLTYPE", +#endif +#if SQLITE_OMIT_DEPRECATED + "OMIT_DEPRECATED", +#endif +#if SQLITE_OMIT_DISKIO + "OMIT_DISKIO", +#endif +#if SQLITE_OMIT_EXPLAIN + "OMIT_EXPLAIN", +#endif +#if SQLITE_OMIT_FLAG_PRAGMAS + "OMIT_FLAG_PRAGMAS", +#endif +#if SQLITE_OMIT_FLOATING_POINT + "OMIT_FLOATING_POINT", +#endif +#if SQLITE_OMIT_FOREIGN_KEY + "OMIT_FOREIGN_KEY", +#endif +#if SQLITE_OMIT_GET_TABLE + "OMIT_GET_TABLE", +#endif +#if SQLITE_OMIT_INCRBLOB + "OMIT_INCRBLOB", +#endif +#if SQLITE_OMIT_INTEGRITY_CHECK + "OMIT_INTEGRITY_CHECK", +#endif +#if SQLITE_OMIT_LIKE_OPTIMIZATION + "OMIT_LIKE_OPTIMIZATION", +#endif +#if SQLITE_OMIT_LOAD_EXTENSION + "OMIT_LOAD_EXTENSION", +#endif +#if SQLITE_OMIT_LOCALTIME + "OMIT_LOCALTIME", +#endif +#if SQLITE_OMIT_LOOKASIDE + "OMIT_LOOKASIDE", +#endif +#if SQLITE_OMIT_MEMORYDB + "OMIT_MEMORYDB", +#endif +#if SQLITE_OMIT_OR_OPTIMIZATION + "OMIT_OR_OPTIMIZATION", +#endif +#if SQLITE_OMIT_PAGER_PRAGMAS + "OMIT_PAGER_PRAGMAS", +#endif +#if SQLITE_OMIT_PRAGMA + "OMIT_PRAGMA", +#endif +#if SQLITE_OMIT_PROGRESS_CALLBACK + "OMIT_PROGRESS_CALLBACK", +#endif +#if SQLITE_OMIT_QUICKBALANCE + "OMIT_QUICKBALANCE", +#endif +#if SQLITE_OMIT_REINDEX + "OMIT_REINDEX", +#endif +#if SQLITE_OMIT_SCHEMA_PRAGMAS + "OMIT_SCHEMA_PRAGMAS", +#endif +#if SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS + "OMIT_SCHEMA_VERSION_PRAGMAS", +#endif +#if SQLITE_OMIT_SHARED_CACHE + "OMIT_SHARED_CACHE", +#endif +#if SQLITE_OMIT_SUBQUERY + "OMIT_SUBQUERY", +#endif +#if SQLITE_OMIT_TCL_VARIABLE + "OMIT_TCL_VARIABLE", +#endif +#if SQLITE_OMIT_TEMPDB + "OMIT_TEMPDB", +#endif +#if SQLITE_OMIT_TRACE + "OMIT_TRACE", +#endif +#if SQLITE_OMIT_TRIGGER + "OMIT_TRIGGER", +#endif +#if SQLITE_OMIT_TRUNCATE_OPTIMIZATION + "OMIT_TRUNCATE_OPTIMIZATION", +#endif +#if SQLITE_OMIT_UTF16 + "OMIT_UTF16", +#endif +#if SQLITE_OMIT_VACUUM + "OMIT_VACUUM", +#endif +#if SQLITE_OMIT_VIEW + "OMIT_VIEW", +#endif +#if SQLITE_OMIT_VIRTUALTABLE + "OMIT_VIRTUALTABLE", +#endif +#if SQLITE_OMIT_WAL + "OMIT_WAL", +#endif +#if SQLITE_OMIT_WSD + "OMIT_WSD", +#endif +#if SQLITE_OMIT_XFER_OPT + "OMIT_XFER_OPT", +#endif +#if SQLITE_PERFORMANCE_TRACE + "PERFORMANCE_TRACE", +#endif +#if SQLITE_PROXY_DEBUG + "PROXY_DEBUG", +#endif +#if SQLITE_RTREE_INT_ONLY + "RTREE_INT_ONLY", +#endif +#if SQLITE_SECURE_DELETE + "SECURE_DELETE", +#endif +#if SQLITE_SMALL_STACK + "SMALL_STACK", +#endif +#if SQLITE_SOUNDEX + "SOUNDEX", +#endif +#if SQLITE_SYSTEM_MALLOC + "SYSTEM_MALLOC", +#endif +#if SQLITE_TCL + "TCL", +#endif +#if defined(SQLITE_TEMP_STORE) && !defined(SQLITE_TEMP_STORE_xc) + "TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE), +#endif +#if SQLITE_TEST + "TEST", +#endif +#if defined(SQLITE_THREADSAFE) + "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE), +#endif +#if SQLITE_USE_ALLOCA + "USE_ALLOCA", +#endif +#if SQLITE_USER_AUTHENTICATION + "USER_AUTHENTICATION", +#endif +#if SQLITE_WIN32_MALLOC + "WIN32_MALLOC", +#endif +#if SQLITE_ZERO_MALLOC + "ZERO_MALLOC" +#endif +}; + +/* +** Given the name of a compile-time option, return true if that option +** was used and false if not. +** +** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix +** is not required for a match. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName){ + int i, n; + +#if SQLITE_ENABLE_API_ARMOR + if( zOptName==0 ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7; + n = sqlite3Strlen30(zOptName); + + /* Since ArraySize(azCompileOpt) is normally in single digits, a + ** linear search is adequate. No need for a binary search. */ + for(i=0; i=0 && NaDb[] (or -1) */ + u8 nullRow; /* True if pointing to a row with no data */ + u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ + Bool isEphemeral:1; /* True for an ephemeral table */ + Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ + Bool isTable:1; /* True if a table requiring integer keys */ + Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */ + Pgno pgnoRoot; /* Root page of the open btree cursor */ + sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ + i64 seqCount; /* Sequence counter */ + i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ + VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ + + /* Cached information about the header for the data record that the + ** cursor is currently pointing to. Only valid if cacheStatus matches + ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of + ** CACHE_STALE and so setting cacheStatus=CACHE_STALE guarantees that + ** the cache is out of date. + ** + ** aRow might point to (ephemeral) data for the current row, or it might + ** be NULL. + */ + u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ + u32 payloadSize; /* Total number of bytes in the record */ + u32 szRow; /* Byte available in aRow */ + u32 iHdrOffset; /* Offset to next unparsed byte of the header */ + const u8 *aRow; /* Data for the current row, if all on one page */ + u32 *aOffset; /* Pointer to aType[nField] */ + u32 aType[1]; /* Type values for all entries in the record */ + /* 2*nField extra array elements allocated for aType[], beyond the one + ** static element declared in the structure. nField total array slots for + ** aType[] and nField+1 array slots for aOffset[] */ +}; +typedef struct VdbeCursor VdbeCursor; + +/* +** When a sub-program is executed (OP_Program), a structure of this type +** is allocated to store the current value of the program counter, as +** well as the current memory cell array and various other frame specific +** values stored in the Vdbe struct. When the sub-program is finished, +** these values are copied back to the Vdbe from the VdbeFrame structure, +** restoring the state of the VM to as it was before the sub-program +** began executing. +** +** The memory for a VdbeFrame object is allocated and managed by a memory +** cell in the parent (calling) frame. When the memory cell is deleted or +** overwritten, the VdbeFrame object is not freed immediately. Instead, it +** is linked into the Vdbe.pDelFrame list. The contents of the Vdbe.pDelFrame +** list is deleted when the VM is reset in VdbeHalt(). The reason for doing +** this instead of deleting the VdbeFrame immediately is to avoid recursive +** calls to sqlite3VdbeMemRelease() when the memory cells belonging to the +** child frame are released. +** +** The currently executing frame is stored in Vdbe.pFrame. Vdbe.pFrame is +** set to NULL if the currently executing frame is the main program. +*/ +typedef struct VdbeFrame VdbeFrame; +struct VdbeFrame { + Vdbe *v; /* VM this frame belongs to */ + VdbeFrame *pParent; /* Parent of this frame, or NULL if parent is main */ + Op *aOp; /* Program instructions for parent frame */ + i64 *anExec; /* Event counters from parent frame */ + Mem *aMem; /* Array of memory cells for parent frame */ + u8 *aOnceFlag; /* Array of OP_Once flags for parent frame */ + VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */ + void *token; /* Copy of SubProgram.token */ + i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */ + int nCursor; /* Number of entries in apCsr */ + int pc; /* Program Counter in parent (calling) frame */ + int nOp; /* Size of aOp array */ + int nMem; /* Number of entries in aMem */ + int nOnceFlag; /* Number of entries in aOnceFlag */ + int nChildMem; /* Number of memory cells for child frame */ + int nChildCsr; /* Number of cursors for child frame */ + int nChange; /* Statement changes (Vdbe.nChange) */ + int nDbChange; /* Value of db->nChange */ +}; + +#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))]) + +/* +** A value for VdbeCursor.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. +*/ +struct Mem { + union MemValue { + double r; /* Real value used when MEM_Real is set in flags */ + i64 i; /* Integer value used when MEM_Int is set in flags */ + int nZero; /* Used when bit MEM_Zero is set in flags */ + FuncDef *pDef; /* Used only when flags==MEM_Agg */ + RowSet *pRowSet; /* Used only when flags==MEM_RowSet */ + VdbeFrame *pFrame; /* Used when flags==MEM_Frame */ + } u; + u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */ + u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */ + int n; /* Number of characters in string value, excluding '\0' */ + char *z; /* String or BLOB value */ + /* ShallowCopy only needs to copy the information above */ + char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */ + int szMalloc; /* Size of the zMalloc allocation */ + u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */ + sqlite3 *db; /* The associated database connection */ + void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */ +#ifdef SQLITE_DEBUG + Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ + void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */ +#endif +}; + +/* 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. +** Usually this is encoded in the same unicode encoding as the main +** database (see below for exceptions). If the MEM_Term flag is also +** set, then the string is nul terminated. The MEM_Int and MEM_Real +** flags may coexist with the MEM_Str flag. +*/ +#define MEM_Null 0x0001 /* Value is NULL */ +#define MEM_Str 0x0002 /* Value is a string */ +#define MEM_Int 0x0004 /* Value is an integer */ +#define MEM_Real 0x0008 /* Value is a real number */ +#define MEM_Blob 0x0010 /* Value is a BLOB */ +#define MEM_AffMask 0x001f /* Mask of affinity bits */ +#define MEM_RowSet 0x0020 /* Value is a RowSet object */ +#define MEM_Frame 0x0040 /* Value is a VdbeFrame object */ +#define MEM_Undefined 0x0080 /* Value is undefined */ +#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */ +#define MEM_TypeMask 0x01ff /* Mask of type bits */ + + +/* Whenever Mem contains a valid string or blob representation, one of +** the following flags must be set to determine the memory management +** policy for Mem.z. The MEM_Term flag tells us whether or not the +** string is \000 or \u0000 terminated +*/ +#define MEM_Term 0x0200 /* String rep is nul terminated */ +#define MEM_Dyn 0x0400 /* Need to call Mem.xDel() on Mem.z */ +#define MEM_Static 0x0800 /* Mem.z points to a static string */ +#define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */ +#define MEM_Agg 0x2000 /* Mem.z points to an agg function context */ +#define MEM_Zero 0x4000 /* Mem.i contains count of 0s appended to blob */ +#ifdef SQLITE_OMIT_INCRBLOB + #undef MEM_Zero + #define MEM_Zero 0x0000 +#endif + +/* +** Clear any existing type flags from a Mem and replace them with f +*/ +#define MemSetTypeFlag(p, f) \ + ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f) + +/* +** Return true if a memory cell is not marked as invalid. This macro +** is for use inside assert() statements only. +*/ +#ifdef SQLITE_DEBUG +#define memIsValid(M) ((M)->flags & MEM_Undefined)==0 +#endif + +/* +** Each auxiliary data pointer stored by a user defined function +** implementation calling sqlite3_set_auxdata() is stored in an instance +** of this structure. All such structures associated with a single VM +** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed +** when the VM is halted (if not before). +*/ +struct AuxData { + int iOp; /* Instruction number of OP_Function opcode */ + int iArg; /* Index of function argument. */ + void *pAux; /* Aux data pointer */ + void (*xDelete)(void *); /* Destructor for the aux data */ + AuxData *pNext; /* Next element in list */ +}; + +/* +** The "context" argument for an installable function. A pointer to an +** instance of this structure is the first argument to the routines used +** 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 { + Mem *pOut; /* The return value is stored here */ + FuncDef *pFunc; /* Pointer to function information */ + Mem *pMem; /* Memory cell used to store aggregate context */ + Vdbe *pVdbe; /* The VM that owns this context */ + int iOp; /* Instruction number of OP_Function */ + int isError; /* Error code returned by the function. */ + u8 skipFlag; /* Skip accumulator loading if true */ + u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */ +}; + +/* +** An Explain object accumulates indented output which is helpful +** in describing recursive data structures. +*/ +struct Explain { + Vdbe *pVdbe; /* Attach the explanation to this Vdbe */ + StrAccum str; /* The string being accumulated */ + int nIndent; /* Number of elements in aIndent */ + u16 aIndent[100]; /* Levels of indentation */ + char zBase[100]; /* Initial space */ +}; + +/* A bitfield type for use inside of structures. Always follow with :N where +** N is the number of bits. +*/ +typedef unsigned bft; /* Bit Field Type */ + +typedef struct ScanStatus ScanStatus; +struct ScanStatus { + int addrExplain; /* OP_Explain for loop */ + int addrLoop; /* Address of "loops" counter */ + int addrVisit; /* Address of "rows visited" counter */ + int iSelectID; /* The "Select-ID" for this loop */ + LogEst nEst; /* Estimated output rows per loop */ + char *zName; /* Name of table or index */ +}; + +/* +** 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_prepare() +** is really a pointer to an instance of this structure. +*/ +struct Vdbe { + sqlite3 *db; /* The database connection that owns this statement */ + Op *aOp; /* Space to hold the virtual machine's program */ + Mem *aMem; /* The memory locations */ + Mem **apArg; /* Arguments to currently executing user function */ + Mem *aColName; /* Column names to return */ + Mem *pResultSet; /* Pointer to an array of results */ + Parse *pParse; /* Parsing context used to create this Vdbe */ + int nMem; /* Number of memory locations currently allocated */ + int nOp; /* Number of instructions in the program */ + int nCursor; /* Number of slots in apCsr[] */ + u32 magic; /* Magic number for sanity checking */ + char *zErrMsg; /* Error message written here */ + Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ + VdbeCursor **apCsr; /* One element of this array for each open cursor */ + Mem *aVar; /* Values for the OP_Variable opcode. */ + char **azVar; /* Name of variables */ + ynVar nVar; /* Number of entries in aVar[] */ + ynVar nzVar; /* Number of entries in azVar[] */ + u32 cacheCtr; /* VdbeCursor row cache generation counter */ + int pc; /* The program counter */ + int rc; /* Value to return */ +#ifdef SQLITE_DEBUG + int rcApp; /* errcode set by sqlite3_result_error_code() */ +#endif + u16 nResColumn; /* Number of columns in one row of the result set */ + u8 errorAction; /* Recovery action to do in case of an error */ + u8 minWriteFileFormat; /* Minimum file format for writable database files */ + bft explain:2; /* True if EXPLAIN present on SQL command */ + bft changeCntOn:1; /* True to update the change-counter */ + bft expired:1; /* True if the VM needs to be recompiled */ + bft runOnlyOnce:1; /* Automatically expire on reset */ + bft usesStmtJournal:1; /* True if uses a statement journal */ + bft readOnly:1; /* True for statements that do not write */ + bft bIsReader:1; /* True for statements that read */ + bft isPrepareV2:1; /* True if prepared with prepare_v2() */ + bft doingRerun:1; /* True if rerunning after an auto-reprepare */ + int nChange; /* Number of db changes made since last reset */ + yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ + yDbMask lockMask; /* Subset of btreeMask that requires a lock */ + int iStatement; /* Statement number (or 0 if has not opened stmt) */ + u32 aCounter[5]; /* Counters used by sqlite3_stmt_status() */ +#ifndef SQLITE_OMIT_TRACE + i64 startTime; /* Time when query started - used for profiling */ +#endif + i64 iCurrentTime; /* Value of julianday('now') for this statement */ + i64 nFkConstraint; /* Number of imm. FK constraints this VM */ + i64 nStmtDefCons; /* Number of def. constraints when stmt started */ + i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */ + char *zSql; /* Text of the SQL statement that generated this */ + void *pFree; /* Free this when deleting the vdbe */ + VdbeFrame *pFrame; /* Parent frame */ + VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */ + int nFrame; /* Number of frames in pFrame list */ + u32 expmask; /* Binding to these vars invalidates VM */ + SubProgram *pProgram; /* Linked list of all sub-programs used by VM */ + int nOnceFlag; /* Size of array aOnceFlag[] */ + u8 *aOnceFlag; /* Flags for OP_Once */ + AuxData *pAuxData; /* Linked list of auxdata allocations */ +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + i64 *anExec; /* Number of times each op has been executed */ + int nScan; /* Entries in aScan[] */ + ScanStatus *aScan; /* Scan definitions for sqlite3_stmt_scanstatus() */ +#endif +}; + +/* +** 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 +*/ +SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); +void sqliteVdbePopStack(Vdbe*,int); +SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*); +SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*); +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) +SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*); +#endif +SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32); +SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int); +SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32); +SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); +SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe*, int, int); + +int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); +SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*); +SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*); +SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*); +SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*); +SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*); +SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int); +SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem*, const Mem*); +SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int); +SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem*, Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*)); +SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem*, i64); +#ifdef SQLITE_OMIT_FLOATING_POINT +# define sqlite3VdbeMemSetDouble sqlite3VdbeMemSetInt64 +#else +SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double); +#endif +SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16); +SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*); +SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int); +SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8); +SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*); +SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*); +SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*); +SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem*,u8,u8); +SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*); +SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p); +#define VdbeMemDynamic(X) \ + (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0) +SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*); +SQLITE_PRIVATE const char *sqlite3OpcodeName(int); +SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); +SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n); +SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int); +SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); +SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *); +SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p); + +SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, int, VdbeCursor *); +SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *, VdbeSorter *); +SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *); +SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *); +SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *); +SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *, int *); +SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *); +SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *); + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 +SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe*); +#else +# define sqlite3VdbeEnter(X) +# define sqlite3VdbeLeave(X) +#endif + +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe*,Mem*); +SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem*); +#endif + +#ifndef SQLITE_OMIT_FOREIGN_KEY +SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *, int); +#else +# define sqlite3VdbeCheckFk(p,i) 0 +#endif + +SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem*, u8); +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf); +#endif +SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem); + +#ifndef SQLITE_OMIT_INCRBLOB +SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *); + #define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0) +#else + #define sqlite3VdbeMemExpandBlob(x) SQLITE_OK + #define ExpandBlob(P) SQLITE_OK +#endif + +#endif /* !defined(_VDBEINT_H_) */ + +/************** End of vdbeInt.h *********************************************/ +/************** Continuing where we left off in status.c *********************/ + +/* +** Variables in which to record status information. +*/ +typedef struct sqlite3StatType sqlite3StatType; +static SQLITE_WSD struct sqlite3StatType { +#if SQLITE_PTRSIZE>4 + sqlite3_int64 nowValue[10]; /* Current value */ + sqlite3_int64 mxValue[10]; /* Maximum value */ +#else + u32 nowValue[10]; /* Current value */ + u32 mxValue[10]; /* Maximum value */ +#endif +} sqlite3Stat = { {0,}, {0,} }; + +/* +** Elements of sqlite3Stat[] are protected by either the memory allocator +** mutex, or by the pcache1 mutex. The following array determines which. +*/ +static const char statMutex[] = { + 0, /* SQLITE_STATUS_MEMORY_USED */ + 1, /* SQLITE_STATUS_PAGECACHE_USED */ + 1, /* SQLITE_STATUS_PAGECACHE_OVERFLOW */ + 0, /* SQLITE_STATUS_SCRATCH_USED */ + 0, /* SQLITE_STATUS_SCRATCH_OVERFLOW */ + 0, /* SQLITE_STATUS_MALLOC_SIZE */ + 0, /* SQLITE_STATUS_PARSER_STACK */ + 1, /* SQLITE_STATUS_PAGECACHE_SIZE */ + 0, /* SQLITE_STATUS_SCRATCH_SIZE */ + 0, /* SQLITE_STATUS_MALLOC_COUNT */ +}; + + +/* The "wsdStat" macro will resolve to the status information +** state vector. If writable static data is unsupported on the target, +** we have to locate the state vector at run-time. In the more common +** case where writable static data is supported, wsdStat can refer directly +** to the "sqlite3Stat" state vector declared above. +*/ +#ifdef SQLITE_OMIT_WSD +# define wsdStatInit sqlite3StatType *x = &GLOBAL(sqlite3StatType,sqlite3Stat) +# define wsdStat x[0] +#else +# define wsdStatInit +# define wsdStat sqlite3Stat +#endif + +/* +** Return the current value of a status parameter. The caller must +** be holding the appropriate mutex. +*/ +SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int op){ + wsdStatInit; + assert( op>=0 && op=0 && op=0 && op=0 && opwsdStat.mxValue[op] ){ + wsdStat.mxValue[op] = wsdStat.nowValue[op]; + } +} +SQLITE_PRIVATE void sqlite3StatusDown(int op, int N){ + wsdStatInit; + assert( N>=0 ); + assert( op>=0 && op=0 && op=0 && op=0 && opwsdStat.mxValue[op] ){ + wsdStat.mxValue[op] = wsdStat.nowValue[op]; + } +} + +/* +** Query status information. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_status64( + int op, + sqlite3_int64 *pCurrent, + sqlite3_int64 *pHighwater, + int resetFlag +){ + sqlite3_mutex *pMutex; + wsdStatInit; + if( op<0 || op>=ArraySize(wsdStat.nowValue) ){ + return SQLITE_MISUSE_BKPT; + } +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT; +#endif + pMutex = statMutex[op] ? sqlite3Pcache1Mutex() : sqlite3MallocMutex(); + sqlite3_mutex_enter(pMutex); + *pCurrent = wsdStat.nowValue[op]; + *pHighwater = wsdStat.mxValue[op]; + if( resetFlag ){ + wsdStat.mxValue[op] = wsdStat.nowValue[op]; + } + sqlite3_mutex_leave(pMutex); + (void)pMutex; /* Prevent warning when SQLITE_THREADSAFE=0 */ + return SQLITE_OK; +} +SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){ + sqlite3_int64 iCur, iHwtr; + int rc; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT; +#endif + rc = sqlite3_status64(op, &iCur, &iHwtr, resetFlag); + if( rc==0 ){ + *pCurrent = (int)iCur; + *pHighwater = (int)iHwtr; + } + return rc; +} + +/* +** Query status information for a single database connection +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_db_status( + sqlite3 *db, /* The database connection whose status is desired */ + int op, /* Status verb */ + int *pCurrent, /* Write current value here */ + int *pHighwater, /* Write high-water mark here */ + int resetFlag /* Reset high-water mark if true */ +){ + int rc = SQLITE_OK; /* Return code */ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwater==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + sqlite3_mutex_enter(db->mutex); + switch( op ){ + case SQLITE_DBSTATUS_LOOKASIDE_USED: { + *pCurrent = db->lookaside.nOut; + *pHighwater = db->lookaside.mxOut; + if( resetFlag ){ + db->lookaside.mxOut = db->lookaside.nOut; + } + break; + } + + case SQLITE_DBSTATUS_LOOKASIDE_HIT: + case SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE: + case SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL: { + testcase( op==SQLITE_DBSTATUS_LOOKASIDE_HIT ); + testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE ); + testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL ); + assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)>=0 ); + assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)<3 ); + *pCurrent = 0; + *pHighwater = db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT]; + if( resetFlag ){ + db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT] = 0; + } + break; + } + + /* + ** Return an approximation for the amount of memory currently used + ** by all pagers associated with the given database connection. The + ** highwater mark is meaningless and is returned as zero. + */ + case SQLITE_DBSTATUS_CACHE_USED: { + int totalUsed = 0; + int i; + sqlite3BtreeEnterAll(db); + for(i=0; inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + Pager *pPager = sqlite3BtreePager(pBt); + totalUsed += sqlite3PagerMemUsed(pPager); + } + } + sqlite3BtreeLeaveAll(db); + *pCurrent = totalUsed; + *pHighwater = 0; + break; + } + + /* + ** *pCurrent gets an accurate estimate of the amount of memory used + ** to store the schema for all databases (main, temp, and any ATTACHed + ** databases. *pHighwater is set to zero. + */ + case SQLITE_DBSTATUS_SCHEMA_USED: { + int i; /* Used to iterate through schemas */ + int nByte = 0; /* Used to accumulate return value */ + + sqlite3BtreeEnterAll(db); + db->pnBytesFreed = &nByte; + for(i=0; inDb; i++){ + Schema *pSchema = db->aDb[i].pSchema; + if( ALWAYS(pSchema!=0) ){ + HashElem *p; + + nByte += sqlite3GlobalConfig.m.xRoundup(sizeof(HashElem)) * ( + pSchema->tblHash.count + + pSchema->trigHash.count + + pSchema->idxHash.count + + pSchema->fkeyHash.count + ); + nByte += sqlite3MallocSize(pSchema->tblHash.ht); + nByte += sqlite3MallocSize(pSchema->trigHash.ht); + nByte += sqlite3MallocSize(pSchema->idxHash.ht); + nByte += sqlite3MallocSize(pSchema->fkeyHash.ht); + + for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){ + sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p)); + } + for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){ + sqlite3DeleteTable(db, (Table *)sqliteHashData(p)); + } + } + } + db->pnBytesFreed = 0; + sqlite3BtreeLeaveAll(db); + + *pHighwater = 0; + *pCurrent = nByte; + break; + } + + /* + ** *pCurrent gets an accurate estimate of the amount of memory used + ** to store all prepared statements. + ** *pHighwater is set to zero. + */ + case SQLITE_DBSTATUS_STMT_USED: { + struct Vdbe *pVdbe; /* Used to iterate through VMs */ + int nByte = 0; /* Used to accumulate return value */ + + db->pnBytesFreed = &nByte; + for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){ + sqlite3VdbeClearObject(db, pVdbe); + sqlite3DbFree(db, pVdbe); + } + db->pnBytesFreed = 0; + + *pHighwater = 0; /* IMP: R-64479-57858 */ + *pCurrent = nByte; + + break; + } + + /* + ** Set *pCurrent to the total cache hits or misses encountered by all + ** pagers the database handle is connected to. *pHighwater is always set + ** to zero. + */ + case SQLITE_DBSTATUS_CACHE_HIT: + case SQLITE_DBSTATUS_CACHE_MISS: + case SQLITE_DBSTATUS_CACHE_WRITE:{ + int i; + int nRet = 0; + assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 ); + assert( SQLITE_DBSTATUS_CACHE_WRITE==SQLITE_DBSTATUS_CACHE_HIT+2 ); + + for(i=0; inDb; i++){ + if( db->aDb[i].pBt ){ + Pager *pPager = sqlite3BtreePager(db->aDb[i].pBt); + sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet); + } + } + *pHighwater = 0; /* IMP: R-42420-56072 */ + /* IMP: R-54100-20147 */ + /* IMP: R-29431-39229 */ + *pCurrent = nRet; + break; + } + + /* Set *pCurrent to non-zero if there are unresolved deferred foreign + ** key constraints. Set *pCurrent to zero if all foreign key constraints + ** have been satisfied. The *pHighwater is always set to zero. + */ + case SQLITE_DBSTATUS_DEFERRED_FKS: { + *pHighwater = 0; /* IMP: R-11967-56545 */ + *pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0; + break; + } + + default: { + rc = SQLITE_ERROR; + } + } + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/************** End of status.c **********************************************/ +/************** Begin file date.c ********************************************/ +/* +** 2003 October 31 +** +** 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 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. +** +** 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. +** +** 1970-01-01 00:00:00 is JD 2440587.5 +** 2000-01-01 00:00:00 is JD 2451544.5 +** +** This implementation requires years to be expressed as a 4-digit number +** which means that only dates between 0000-01-01 and 9999-12-31 can +** be represented, even though julian day numbers allow a much wider +** range of dates. +** +** The Gregorian calendar system is used for all dates and times, +** even those that predate the Gregorian calendar. Historians usually +** use the julian calendar for dates prior to 1582-10-15 and for some +** dates afterwards, depending on locale. Beware of this difference. +** +** The conversion algorithms are implemented based on descriptions +** in the following text: +** +** Jean Meeus +** Astronomical Algorithms, 2nd Edition, 1998 +** ISBM 0-943396-61-1 +** Willmann-Bell, Inc +** Richmond, Virginia (USA) +*/ +/* #include */ +/* #include */ +#include + +#ifndef SQLITE_OMIT_DATETIME_FUNCS + + +/* +** A structure for holding a single date and time. +*/ +typedef struct DateTime DateTime; +struct DateTime { + sqlite3_int64 iJD; /* The julian day number times 86400000 */ + int Y, M, D; /* Year, month, and day */ + int h, m; /* Hour and minutes */ + int tz; /* Timezone offset in minutes */ + double s; /* Seconds */ + char validYMD; /* True (1) if Y,M,D are valid */ + char validHMS; /* True (1) if h,m,s are valid */ + char validJD; /* True (1) if iJD is valid */ + char validTZ; /* True (1) if tz is valid */ +}; + + +/* +** Convert zDate into one or more integers. Additional arguments +** come in groups of 5 as follows: +** +** N number of digits in the integer +** min minimum allowed value of the integer +** max maximum allowed value of the integer +** nextC first character after the integer +** pVal where to write the integers value. +** +** Conversions continue until one with nextC==0 is encountered. +** The function returns the number of successful conversions. +*/ +static int getDigits(const char *zDate, ...){ + va_list ap; + int val; + int N; + int min; + int max; + int nextC; + int *pVal; + int cnt = 0; + va_start(ap, zDate); + do{ + N = va_arg(ap, int); + 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( !sqlite3Isdigit(*zDate) ){ + goto end_getDigits; + } + val = val*10 + *zDate - '0'; + zDate++; + } + if( valmax || (nextC!=0 && nextC!=*zDate) ){ + goto end_getDigits; + } + *pVal = val; + zDate++; + cnt++; + }while( nextC ); +end_getDigits: + va_end(ap); + return cnt; +} + +/* +** Parse a timezone extension on the end of a date-time. +** The extension is of the form: +** +** (+/-)HH:MM +** +** Or the "zulu" notation: +** +** Z +** +** If the parse is successful, write the number of minutes +** of change in p->tz and return 0. If a parser error occurs, +** return non-zero. +** +** A missing specifier is not considered an error. +*/ +static int parseTimezone(const char *zDate, DateTime *p){ + int sgn = 0; + int nHr, nMn; + int c; + while( sqlite3Isspace(*zDate) ){ zDate++; } + p->tz = 0; + c = *zDate; + if( c=='-' ){ + sgn = -1; + }else if( c=='+' ){ + sgn = +1; + }else if( c=='Z' || c=='z' ){ + zDate++; + goto zulu_time; + }else{ + return c!=0; + } + zDate++; + if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){ + return 1; + } + zDate += 5; + p->tz = sgn*(nMn + nHr*60); +zulu_time: + while( sqlite3Isspace(*zDate) ){ zDate++; } + return *zDate!=0; +} + +/* +** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF. +** The HH, MM, and SS must each be exactly 2 digits. The +** fractional seconds FFFF can be one or more digits. +** +** Return 1 if there is a parsing error and 0 on success. +*/ +static int parseHhMmSs(const char *zDate, DateTime *p){ + int h, m, s; + double ms = 0.0; + if( getDigits(zDate, 2, 0, 24, ':', &h, 2, 0, 59, 0, &m)!=2 ){ + return 1; + } + zDate += 5; + if( *zDate==':' ){ + zDate++; + if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){ + return 1; + } + zDate += 2; + if( *zDate=='.' && sqlite3Isdigit(zDate[1]) ){ + double rScale = 1.0; + zDate++; + while( sqlite3Isdigit(*zDate) ){ + ms = ms*10.0 + *zDate - '0'; + rScale *= 10.0; + zDate++; + } + ms /= rScale; + } + }else{ + s = 0; + } + p->validJD = 0; + p->validHMS = 1; + p->h = h; + p->m = m; + p->s = s + ms; + if( parseTimezone(zDate, p) ) return 1; + p->validTZ = (p->tz!=0)?1:0; + return 0; +} + +/* +** Convert from YYYY-MM-DD HH:MM:SS to julian day. We always assume +** that the YYYY-MM-DD is according to the Gregorian calendar. +** +** Reference: Meeus page 61 +*/ +static void computeJD(DateTime *p){ + int Y, M, D, A, B, X1, X2; + + if( p->validJD ) return; + if( p->validYMD ){ + Y = p->Y; + M = p->M; + D = p->D; + }else{ + Y = 2000; /* If no YMD specified, assume 2000-Jan-01 */ + M = 1; + D = 1; + } + if( M<=2 ){ + Y--; + M += 12; + } + A = Y/100; + B = 2 - A + (A/4); + X1 = 36525*(Y+4716)/100; + X2 = 306001*(M+1)/10000; + p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000); + p->validJD = 1; + if( p->validHMS ){ + p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000); + if( p->validTZ ){ + p->iJD -= p->tz*60000; + p->validYMD = 0; + p->validHMS = 0; + p->validTZ = 0; + } + } +} + +/* +** Parse dates of the form +** +** YYYY-MM-DD HH:MM:SS.FFF +** YYYY-MM-DD HH:MM:SS +** YYYY-MM-DD HH:MM +** YYYY-MM-DD +** +** Write the result into the DateTime structure and return 0 +** on success and 1 if the input string is not a well-formed +** date. +*/ +static int parseYyyyMmDd(const char *zDate, DateTime *p){ + int Y, M, D, neg; + + if( zDate[0]=='-' ){ + zDate++; + neg = 1; + }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( sqlite3Isspace(*zDate) || 'T'==*(u8*)zDate ){ zDate++; } + if( parseHhMmSs(zDate, p)==0 ){ + /* We got the time */ + }else if( *zDate==0 ){ + p->validHMS = 0; + }else{ + return 1; + } + p->validJD = 0; + p->validYMD = 1; + p->Y = neg ? -Y : Y; + p->M = M; + p->D = D; + if( p->validTZ ){ + computeJD(p); + } + return 0; +} + +/* +** Set the time to the current time reported by the VFS. +** +** Return the number of errors. +*/ +static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){ + p->iJD = sqlite3StmtCurrentTime(context); + if( p->iJD>0 ){ + p->validJD = 1; + return 0; + }else{ + return 1; + } +} + +/* +** Attempt to parse the given string into a julian day number. Return +** the number of errors. +** +** The following are acceptable forms for the input string: +** +** YYYY-MM-DD HH:MM:SS.FFF +/-HH:MM +** DDDD.DD +** now +** +** In the first form, the +/-HH:MM is always optional. The fractional +** seconds extension (the ".FFF") is optional. The seconds portion +** (":SS.FFF") is option. The year and date can be omitted as long +** as there is a time string. The time string can be omitted as long +** as there is a year and date. +*/ +static int parseDateOrTime( + sqlite3_context *context, + const char *zDate, + DateTime *p +){ + double r; + if( parseYyyyMmDd(zDate,p)==0 ){ + return 0; + }else if( parseHhMmSs(zDate, p)==0 ){ + return 0; + }else if( sqlite3StrICmp(zDate,"now")==0){ + return setDateTimeToCurrent(context, p); + }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){ + p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5); + p->validJD = 1; + return 0; + } + return 1; +} + +/* +** Compute the Year, Month, and Day from the julian day number. +*/ +static void computeYMD(DateTime *p){ + int Z, A, B, C, D, E, X1; + if( p->validYMD ) return; + if( !p->validJD ){ + p->Y = 2000; + p->M = 1; + p->D = 1; + }else{ + Z = (int)((p->iJD + 43200000)/86400000); + A = (int)((Z - 1867216.25)/36524.25); + A = Z + 1 + A - (A/4); + B = A + 1524; + C = (int)((B - 122.1)/365.25); + D = (36525*C)/100; + E = (int)((B-D)/30.6001); + X1 = (int)(30.6001*E); + p->D = B - D - X1; + p->M = E<14 ? E-1 : E-13; + p->Y = p->M>2 ? C - 4716 : C - 4715; + } + p->validYMD = 1; +} + +/* +** Compute the Hour, Minute, and Seconds from the julian day number. +*/ +static void computeHMS(DateTime *p){ + int s; + if( p->validHMS ) return; + computeJD(p); + s = (int)((p->iJD + 43200000) % 86400000); + p->s = s/1000.0; + s = (int)p->s; + p->s -= s; + p->h = s/3600; + s -= p->h*3600; + p->m = s/60; + p->s += s - p->m*60; + p->validHMS = 1; +} + +/* +** Compute both YMD and HMS +*/ +static void computeYMD_HMS(DateTime *p){ + computeYMD(p); + computeHMS(p); +} + +/* +** Clear the YMD and HMS and the TZ +*/ +static void clearYMD_HMS_TZ(DateTime *p){ + p->validYMD = 0; + p->validHMS = 0; + p->validTZ = 0; +} + +/* +** On recent Windows platforms, the localtime_s() function is available +** as part of the "Secure CRT". It is essentially equivalent to +** localtime_r() available under most POSIX platforms, except that the +** order of the parameters is reversed. +** +** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx. +** +** If the user has not indicated to use localtime_r() or localtime_s() +** already, check for an MSVC build environment that provides +** localtime_s(). +*/ +#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S \ + && defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE) +#undef HAVE_LOCALTIME_S +#define HAVE_LOCALTIME_S 1 +#endif + +#ifndef SQLITE_OMIT_LOCALTIME +/* +** The following routine implements the rough equivalent of localtime_r() +** using whatever operating-system specific localtime facility that +** is available. This routine returns 0 on success and +** non-zero on any kind of error. +** +** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this +** routine will always fail. +** +** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C +** library function localtime_r() is used to assist in the calculation of +** local time. +*/ +static int osLocaltime(time_t *t, struct tm *pTm){ + int rc; +#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S + struct tm *pX; +#if SQLITE_THREADSAFE>0 + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); +#endif + sqlite3_mutex_enter(mutex); + pX = localtime(t); +#ifndef SQLITE_OMIT_BUILTIN_TEST + if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0; +#endif + if( pX ) *pTm = *pX; + sqlite3_mutex_leave(mutex); + rc = pX==0; +#else +#ifndef SQLITE_OMIT_BUILTIN_TEST + if( sqlite3GlobalConfig.bLocaltimeFault ) return 1; +#endif +#if HAVE_LOCALTIME_R + rc = localtime_r(t, pTm)==0; +#else + rc = localtime_s(pTm, t); +#endif /* HAVE_LOCALTIME_R */ +#endif /* HAVE_LOCALTIME_R || HAVE_LOCALTIME_S */ + return rc; +} +#endif /* SQLITE_OMIT_LOCALTIME */ + + +#ifndef SQLITE_OMIT_LOCALTIME +/* +** Compute the difference (in milliseconds) between localtime and UTC +** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs, +** return this value and set *pRc to SQLITE_OK. +** +** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value +** is undefined in this case. +*/ +static sqlite3_int64 localtimeOffset( + DateTime *p, /* Date at which to calculate offset */ + sqlite3_context *pCtx, /* Write error here if one occurs */ + int *pRc /* OUT: Error code. SQLITE_OK or ERROR */ +){ + DateTime x, y; + time_t t; + struct tm sLocal; + + /* Initialize the contents of sLocal to avoid a compiler warning. */ + memset(&sLocal, 0, sizeof(sLocal)); + + x = *p; + computeYMD_HMS(&x); + if( x.Y<1971 || x.Y>=2038 ){ + /* EVIDENCE-OF: R-55269-29598 The localtime_r() C function normally only + ** works for years between 1970 and 2037. For dates outside this range, + ** SQLite attempts to map the year into an equivalent year within this + ** range, do the calculation, then map the year back. + */ + x.Y = 2000; + x.M = 1; + x.D = 1; + x.h = 0; + x.m = 0; + x.s = 0.0; + } else { + int s = (int)(x.s + 0.5); + x.s = s; + } + x.tz = 0; + x.validJD = 0; + computeJD(&x); + t = (time_t)(x.iJD/1000 - 21086676*(i64)10000); + if( osLocaltime(&t, &sLocal) ){ + sqlite3_result_error(pCtx, "local time unavailable", -1); + *pRc = SQLITE_ERROR; + return 0; + } + y.Y = sLocal.tm_year + 1900; + y.M = sLocal.tm_mon + 1; + y.D = sLocal.tm_mday; + y.h = sLocal.tm_hour; + y.m = sLocal.tm_min; + y.s = sLocal.tm_sec; + y.validYMD = 1; + y.validHMS = 1; + y.validJD = 0; + y.validTZ = 0; + computeJD(&y); + *pRc = SQLITE_OK; + return y.iJD - x.iJD; +} +#endif /* SQLITE_OMIT_LOCALTIME */ + +/* +** Process a modifier to a date-time stamp. The modifiers are +** as follows: +** +** NNN days +** NNN hours +** NNN minutes +** NNN.NNNN seconds +** NNN months +** NNN years +** start of month +** start of year +** start of week +** start of day +** weekday N +** unixepoch +** localtime +** utc +** +** Return 0 on success and 1 if there is any kind of error. If the error +** is in a system call (i.e. localtime()), then an error message is written +** to context pCtx. If the error is an unrecognized modifier, no error is +** written to pCtx. +*/ +static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ + int rc = 1; + int n; + double r; + char *z, zBuf[30]; + z = zBuf; + for(n=0; niJD += localtimeOffset(p, pCtx, &rc); + clearYMD_HMS_TZ(p); + } + break; + } +#endif + case 'u': { + /* + ** unixepoch + ** + ** Treat the current value of p->iJD as the number of + ** seconds since 1970. Convert to a real julian day number. + */ + if( strcmp(z, "unixepoch")==0 && p->validJD ){ + p->iJD = (p->iJD + 43200)/86400 + 21086676*(i64)10000000; + clearYMD_HMS_TZ(p); + rc = 0; + } +#ifndef SQLITE_OMIT_LOCALTIME + else if( strcmp(z, "utc")==0 ){ + sqlite3_int64 c1; + computeJD(p); + c1 = localtimeOffset(p, pCtx, &rc); + if( rc==SQLITE_OK ){ + p->iJD -= c1; + clearYMD_HMS_TZ(p); + p->iJD += c1 - localtimeOffset(p, pCtx, &rc); + } + } +#endif + break; + } + case 'w': { + /* + ** weekday N + ** + ** Move the date to the same time on the next occurrence of + ** weekday N where 0==Sunday, 1==Monday, and so forth. If the + ** date is already on the appropriate weekday, this is a no-op. + */ + if( strncmp(z, "weekday ", 8)==0 + && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8) + && (n=(int)r)==r && n>=0 && r<7 ){ + sqlite3_int64 Z; + computeYMD_HMS(p); + p->validTZ = 0; + p->validJD = 0; + computeJD(p); + Z = ((p->iJD + 129600000)/86400000) % 7; + if( Z>n ) Z -= 7; + p->iJD += (n - Z)*86400000; + clearYMD_HMS_TZ(p); + rc = 0; + } + break; + } + case 's': { + /* + ** start of TTTTT + ** + ** Move the date backwards to the beginning of the current day, + ** or month or year. + */ + if( strncmp(z, "start of ", 9)!=0 ) break; + z += 9; + computeYMD(p); + p->validHMS = 1; + p->h = p->m = 0; + p->s = 0.0; + p->validTZ = 0; + p->validJD = 0; + if( strcmp(z,"month")==0 ){ + p->D = 1; + rc = 0; + }else if( strcmp(z,"year")==0 ){ + computeYMD(p); + p->M = 1; + p->D = 1; + rc = 0; + }else if( strcmp(z,"day")==0 ){ + rc = 0; + } + break; + } + case '+': + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': { + double rRounder; + for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){} + if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){ + rc = 1; + break; + } + if( z[n]==':' ){ + /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the + ** specified number of hours, minutes, seconds, and fractional seconds + ** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be + ** omitted. + */ + const char *z2 = z; + DateTime tx; + sqlite3_int64 day; + if( !sqlite3Isdigit(*z2) ) z2++; + memset(&tx, 0, sizeof(tx)); + if( parseHhMmSs(z2, &tx) ) break; + computeJD(&tx); + tx.iJD -= 43200000; + day = tx.iJD/86400000; + tx.iJD -= day*86400000; + if( z[0]=='-' ) tx.iJD = -tx.iJD; + computeJD(p); + clearYMD_HMS_TZ(p); + p->iJD += tx.iJD; + rc = 0; + break; + } + z += n; + while( sqlite3Isspace(*z) ) z++; + n = sqlite3Strlen30(z); + if( n>10 || n<3 ) break; + if( z[n-1]=='s' ){ z[n-1] = 0; n--; } + computeJD(p); + rc = 0; + rRounder = r<0 ? -0.5 : +0.5; + if( n==3 && strcmp(z,"day")==0 ){ + p->iJD += (sqlite3_int64)(r*86400000.0 + rRounder); + }else if( n==4 && strcmp(z,"hour")==0 ){ + p->iJD += (sqlite3_int64)(r*(86400000.0/24.0) + rRounder); + }else if( n==6 && strcmp(z,"minute")==0 ){ + p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0)) + rRounder); + }else if( n==6 && strcmp(z,"second")==0 ){ + p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0*60.0)) + rRounder); + }else if( n==5 && strcmp(z,"month")==0 ){ + int x, y; + computeYMD_HMS(p); + p->M += (int)r; + x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; + p->Y += x; + p->M -= x*12; + p->validJD = 0; + computeJD(p); + y = (int)r; + if( y!=r ){ + p->iJD += (sqlite3_int64)((r - y)*30.0*86400000.0 + rRounder); + } + }else if( n==4 && strcmp(z,"year")==0 ){ + int y = (int)r; + computeYMD_HMS(p); + p->Y += y; + p->validJD = 0; + computeJD(p); + if( y!=r ){ + p->iJD += (sqlite3_int64)((r - y)*365.0*86400000.0 + rRounder); + } + }else{ + rc = 1; + } + clearYMD_HMS_TZ(p); + break; + } + default: { + break; + } + } + return rc; +} + +/* +** Process time function arguments. argv[0] is a date-time stamp. +** argv[1] and following are modifiers. Parse them all and write +** the resulting time into the DateTime structure p. Return 0 +** on success and 1 if there are any errors. +** +** If there are zero parameters (if even argv[0] is undefined) +** then assume a default value of "now" for argv[0]. +*/ +static int isDate( + sqlite3_context *context, + int argc, + sqlite3_value **argv, + DateTime *p +){ + int i; + const unsigned char *z; + int eType; + memset(p, 0, sizeof(*p)); + if( argc==0 ){ + return setDateTimeToCurrent(context, p); + } + if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT + || eType==SQLITE_INTEGER ){ + p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*86400000.0 + 0.5); + p->validJD = 1; + }else{ + z = sqlite3_value_text(argv[0]); + if( !z || parseDateOrTime(context, (char*)z, p) ){ + return 1; + } + } + for(i=1; iaLimit[SQLITE_LIMIT_LENGTH]+1 ); + testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ); + if( n(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ){ + sqlite3_result_error_toobig(context); + return; + }else{ + z = sqlite3DbMallocRaw(db, (int)n); + if( z==0 ){ + sqlite3_result_error_nomem(context); + return; + } + } + computeJD(&x); + computeYMD_HMS(&x); + for(i=j=0; zFmt[i]; i++){ + if( zFmt[i]!='%' ){ + z[j++] = zFmt[i]; + }else{ + i++; + switch( zFmt[i] ){ + case 'd': sqlite3_snprintf(3, &z[j],"%02d",x.D); j+=2; break; + case 'f': { + double s = x.s; + if( s>59.999 ) s = 59.999; + sqlite3_snprintf(7, &z[j],"%06.3f", s); + j += sqlite3Strlen30(&z[j]); + break; + } + case 'H': sqlite3_snprintf(3, &z[j],"%02d",x.h); j+=2; break; + case 'W': /* Fall thru */ + case 'j': { + int nDay; /* Number of days since 1st day of year */ + DateTime y = x; + y.validJD = 0; + y.M = 1; + y.D = 1; + computeJD(&y); + nDay = (int)((x.iJD-y.iJD+43200000)/86400000); + if( zFmt[i]=='W' ){ + int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */ + wd = (int)(((x.iJD+43200000)/86400000)%7); + sqlite3_snprintf(3, &z[j],"%02d",(nDay+7-wd)/7); + j += 2; + }else{ + sqlite3_snprintf(4, &z[j],"%03d",nDay+1); + j += 3; + } + break; + } + case 'J': { + sqlite3_snprintf(20, &z[j],"%.16g",x.iJD/86400000.0); + j+=sqlite3Strlen30(&z[j]); + break; + } + case 'm': sqlite3_snprintf(3, &z[j],"%02d",x.M); j+=2; break; + case 'M': sqlite3_snprintf(3, &z[j],"%02d",x.m); j+=2; break; + case 's': { + sqlite3_snprintf(30,&z[j],"%lld", + (i64)(x.iJD/1000 - 21086676*(i64)10000)); + j += sqlite3Strlen30(&z[j]); + break; + } + case 'S': sqlite3_snprintf(3,&z[j],"%02d",(int)x.s); j+=2; break; + case 'w': { + z[j++] = (char)(((x.iJD+129600000)/86400000) % 7) + '0'; + break; + } + case 'Y': { + sqlite3_snprintf(5,&z[j],"%04d",x.Y); j+=sqlite3Strlen30(&z[j]); + break; + } + default: z[j++] = '%'; break; + } + } + } + z[j] = 0; + sqlite3_result_text(context, z, -1, + z==zBuf ? SQLITE_TRANSIENT : SQLITE_DYNAMIC); +} + +/* +** current_time() +** +** This function returns the same value as time('now'). +*/ +static void ctimeFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **NotUsed2 +){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + timeFunc(context, 0, 0); +} + +/* +** current_date() +** +** This function returns the same value as date('now'). +*/ +static void cdateFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **NotUsed2 +){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + dateFunc(context, 0, 0); +} + +/* +** current_timestamp() +** +** This function returns the same value as datetime('now'). +*/ +static void ctimestampFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **NotUsed2 +){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + datetimeFunc(context, 0, 0); +} +#endif /* !defined(SQLITE_OMIT_DATETIME_FUNCS) */ + +#ifdef SQLITE_OMIT_DATETIME_FUNCS +/* +** If the library is compiled to omit the full-scale date and time +** handling (to get a smaller binary), the following minimal version +** of the functions current_time(), current_date() and current_timestamp() +** are included instead. This is to support column declarations that +** include "DEFAULT CURRENT_TIME" etc. +** +** This function uses the C-library functions time(), gmtime() +** and strftime(). The format string to pass to strftime() is supplied +** as the user-data for the function. +*/ +static void currentTimeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + time_t t; + char *zFormat = (char *)sqlite3_user_data(context); + sqlite3 *db; + sqlite3_int64 iT; + struct tm *pTm; + struct tm sNow; + char zBuf[20]; + + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(argv); + + iT = sqlite3StmtCurrentTime(context); + if( iT<=0 ) return; + t = iT/1000 - 10000*(sqlite3_int64)21086676; +#if HAVE_GMTIME_R + pTm = gmtime_r(&t, &sNow); +#else + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); + pTm = gmtime(&t); + if( pTm ) memcpy(&sNow, pTm, sizeof(sNow)); + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +#endif + if( pTm ){ + strftime(zBuf, 20, zFormat, &sNow); + sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); + } +} +#endif + +/* +** This function registered all of the above C functions as SQL +** functions. This should be the only routine in this file with +** external linkage. +*/ +SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){ + static SQLITE_WSD FuncDef aDateTimeFuncs[] = { +#ifndef SQLITE_OMIT_DATETIME_FUNCS + FUNCTION(julianday, -1, 0, 0, juliandayFunc ), + FUNCTION(date, -1, 0, 0, dateFunc ), + FUNCTION(time, -1, 0, 0, timeFunc ), + FUNCTION(datetime, -1, 0, 0, datetimeFunc ), + FUNCTION(strftime, -1, 0, 0, strftimeFunc ), + FUNCTION(current_time, 0, 0, 0, ctimeFunc ), + FUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc), + FUNCTION(current_date, 0, 0, 0, cdateFunc ), +#else + STR_FUNCTION(current_time, 0, "%H:%M:%S", 0, currentTimeFunc), + STR_FUNCTION(current_date, 0, "%Y-%m-%d", 0, currentTimeFunc), + STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc), +#endif + }; + int i; + FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions); + FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aDateTimeFuncs); + + for(i=0; ipMethods ){ + rc = pId->pMethods->xClose(pId); + pId->pMethods = 0; + } + return rc; +} +SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){ + DO_OS_MALLOC_TEST(id); + return id->pMethods->xRead(id, pBuf, amt, offset); +} +SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){ + DO_OS_MALLOC_TEST(id); + return id->pMethods->xWrite(id, pBuf, amt, offset); +} +SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file *id, i64 size){ + return id->pMethods->xTruncate(id, size); +} +SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file *id, int flags){ + DO_OS_MALLOC_TEST(id); + return id->pMethods->xSync(id, flags); +} +SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){ + DO_OS_MALLOC_TEST(id); + return id->pMethods->xFileSize(id, pSize); +} +SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file *id, int lockType){ + DO_OS_MALLOC_TEST(id); + return id->pMethods->xLock(id, lockType); +} +SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file *id, int lockType){ + return id->pMethods->xUnlock(id, lockType); +} +SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){ + DO_OS_MALLOC_TEST(id); + return id->pMethods->xCheckReservedLock(id, pResOut); +} + +/* +** Use sqlite3OsFileControl() when we are doing something that might fail +** and we need to know about the failures. Use sqlite3OsFileControlHint() +** when simply tossing information over the wall to the VFS and we do not +** really care if the VFS receives and understands the information since it +** is only a hint and can be safely ignored. The sqlite3OsFileControlHint() +** routine has no return value since the return value would be meaningless. +*/ +SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ +#ifdef SQLITE_TEST + if( op!=SQLITE_FCNTL_COMMIT_PHASETWO ){ + /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite + ** is using a regular VFS, it is called after the corresponding + ** transaction has been committed. Injecting a fault at this point + ** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM + ** but the transaction is committed anyway. + ** + ** The core must call OsFileControl() though, not OsFileControlHint(), + ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably + ** means the commit really has failed and an error should be returned + ** to the user. */ + DO_OS_MALLOC_TEST(id); + } +#endif + return id->pMethods->xFileControl(id, op, pArg); +} +SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){ + (void)id->pMethods->xFileControl(id, op, pArg); +} + +SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id){ + int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize; + return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE); +} +SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id){ + return id->pMethods->xDeviceCharacteristics(id); +} +SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){ + return id->pMethods->xShmLock(id, offset, n, flags); +} +SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id){ + id->pMethods->xShmBarrier(id); +} +SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){ + return id->pMethods->xShmUnmap(id, deleteFlag); +} +SQLITE_PRIVATE int sqlite3OsShmMap( + sqlite3_file *id, /* Database file handle */ + int iPage, + int pgsz, + int bExtend, /* True to extend file if necessary */ + void volatile **pp /* OUT: Pointer to mapping */ +){ + DO_OS_MALLOC_TEST(id); + return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp); +} + +#if SQLITE_MAX_MMAP_SIZE>0 +/* The real implementation of xFetch and xUnfetch */ +SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){ + DO_OS_MALLOC_TEST(id); + return id->pMethods->xFetch(id, iOff, iAmt, pp); +} +SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){ + return id->pMethods->xUnfetch(id, iOff, p); +} +#else +/* No-op stubs to use when memory-mapped I/O is disabled */ +SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){ + *pp = 0; + return SQLITE_OK; +} +SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){ + return SQLITE_OK; +} +#endif + +/* +** The next group of routines are convenience wrappers around the +** VFS methods. +*/ +SQLITE_PRIVATE int sqlite3OsOpen( + sqlite3_vfs *pVfs, + const char *zPath, + sqlite3_file *pFile, + int flags, + int *pFlagsOut +){ + int rc; + DO_OS_MALLOC_TEST(0); + /* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed + ** down into the VFS layer. Some SQLITE_OPEN_ flags (for example, + ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before + ** reaching the VFS. */ + rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f7f, pFlagsOut); + assert( rc==SQLITE_OK || pFile->pMethods==0 ); + return rc; +} +SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ + DO_OS_MALLOC_TEST(0); + assert( dirSync==0 || dirSync==1 ); + return pVfs->xDelete(pVfs, zPath, dirSync); +} +SQLITE_PRIVATE int sqlite3OsAccess( + sqlite3_vfs *pVfs, + const char *zPath, + int flags, + int *pResOut +){ + DO_OS_MALLOC_TEST(0); + return pVfs->xAccess(pVfs, zPath, flags, pResOut); +} +SQLITE_PRIVATE int sqlite3OsFullPathname( + sqlite3_vfs *pVfs, + const char *zPath, + int nPathOut, + char *zPathOut +){ + DO_OS_MALLOC_TEST(0); + zPathOut[0] = 0; + return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut); +} +#ifndef SQLITE_OMIT_LOAD_EXTENSION +SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){ + return pVfs->xDlOpen(pVfs, zPath); +} +SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ + pVfs->xDlError(pVfs, nByte, zBufOut); +} +SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){ + return pVfs->xDlSym(pVfs, pHdle, zSym); +} +SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){ + pVfs->xDlClose(pVfs, pHandle); +} +#endif /* SQLITE_OMIT_LOAD_EXTENSION */ +SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ + return pVfs->xRandomness(pVfs, nByte, zBufOut); +} +SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){ + return pVfs->xSleep(pVfs, nMicro); +} +SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ + int rc; + /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64() + ** method to get the current date and time if that method is available + ** (if iVersion is 2 or greater and the function pointer is not NULL) and + ** will fall back to xCurrentTime() if xCurrentTimeInt64() is + ** unavailable. + */ + if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){ + rc = pVfs->xCurrentTimeInt64(pVfs, pTimeOut); + }else{ + double r; + rc = pVfs->xCurrentTime(pVfs, &r); + *pTimeOut = (sqlite3_int64)(r*86400000.0); + } + return rc; +} + +SQLITE_PRIVATE int sqlite3OsOpenMalloc( + sqlite3_vfs *pVfs, + const char *zFile, + sqlite3_file **ppFile, + int flags, + int *pOutFlags +){ + int rc = SQLITE_NOMEM; + sqlite3_file *pFile; + pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile); + if( pFile ){ + rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags); + if( rc!=SQLITE_OK ){ + sqlite3_free(pFile); + }else{ + *ppFile = pFile; + } + } + return rc; +} +SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *pFile){ + int rc = SQLITE_OK; + assert( pFile ); + rc = sqlite3OsClose(pFile); + sqlite3_free(pFile); + return rc; +} + +/* +** This function is a wrapper around the OS specific implementation of +** sqlite3_os_init(). The purpose of the wrapper is to provide the +** ability to simulate a malloc failure, so that the handling of an +** error in sqlite3_os_init() by the upper layers can be tested. +*/ +SQLITE_PRIVATE int sqlite3OsInit(void){ + void *p = sqlite3_malloc(10); + if( p==0 ) return SQLITE_NOMEM; + sqlite3_free(p); + return sqlite3_os_init(); +} + +/* +** The list of all registered VFS implementations. +*/ +static sqlite3_vfs * SQLITE_WSD vfsList = 0; +#define vfsList GLOBAL(sqlite3_vfs *, vfsList) + +/* +** Locate a VFS by name. If no name is given, simply return the +** first VFS on the list. +*/ +SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfs){ + sqlite3_vfs *pVfs = 0; +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex; +#endif +#ifndef SQLITE_OMIT_AUTOINIT + int rc = sqlite3_initialize(); + if( rc ) return 0; +#endif +#if SQLITE_THREADSAFE + mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); +#endif + sqlite3_mutex_enter(mutex); + for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){ + if( zVfs==0 ) break; + if( strcmp(zVfs, pVfs->zName)==0 ) break; + } + sqlite3_mutex_leave(mutex); + return pVfs; +} + +/* +** Unlink a VFS from the linked list +*/ +static void vfsUnlink(sqlite3_vfs *pVfs){ + assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) ); + if( pVfs==0 ){ + /* No-op */ + }else if( vfsList==pVfs ){ + vfsList = pVfs->pNext; + }else if( vfsList ){ + sqlite3_vfs *p = vfsList; + while( p->pNext && p->pNext!=pVfs ){ + p = p->pNext; + } + if( p->pNext==pVfs ){ + p->pNext = pVfs->pNext; + } + } +} + +/* +** Register a VFS with the system. It is harmless to register the same +** VFS multiple times. The new VFS becomes the default if makeDflt is +** true. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){ + MUTEX_LOGIC(sqlite3_mutex *mutex;) +#ifndef SQLITE_OMIT_AUTOINIT + int rc = sqlite3_initialize(); + if( rc ) return rc; +#endif +#ifdef SQLITE_ENABLE_API_ARMOR + if( pVfs==0 ) return SQLITE_MISUSE_BKPT; +#endif + + MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) + sqlite3_mutex_enter(mutex); + vfsUnlink(pVfs); + if( makeDflt || vfsList==0 ){ + pVfs->pNext = vfsList; + vfsList = pVfs; + }else{ + pVfs->pNext = vfsList->pNext; + vfsList->pNext = pVfs; + } + assert(vfsList); + sqlite3_mutex_leave(mutex); + return SQLITE_OK; +} + +/* +** Unregister a VFS so that it is no longer accessible. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); +#endif + sqlite3_mutex_enter(mutex); + vfsUnlink(pVfs); + sqlite3_mutex_leave(mutex); + return SQLITE_OK; +} + +/************** End of os.c **************************************************/ +/************** Begin file fault.c *******************************************/ +/* +** 2008 Jan 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 file contains code to support the concept of "benign" +** malloc failures (when the xMalloc() or xRealloc() method of the +** sqlite3_mem_methods structure fails to allocate a block of memory +** and returns 0). +** +** Most malloc failures are non-benign. After they occur, SQLite +** abandons the current operation and returns an error code (usually +** SQLITE_NOMEM) to the user. However, sometimes a fault is not necessarily +** fatal. For example, if a malloc fails while resizing a hash table, this +** is completely recoverable simply by not carrying out the resize. The +** hash table will continue to function normally. So a malloc failure +** during a hash table resize is a benign fault. +*/ + + +#ifndef SQLITE_OMIT_BUILTIN_TEST + +/* +** Global variables. +*/ +typedef struct BenignMallocHooks BenignMallocHooks; +static SQLITE_WSD struct BenignMallocHooks { + void (*xBenignBegin)(void); + void (*xBenignEnd)(void); +} sqlite3Hooks = { 0, 0 }; + +/* The "wsdHooks" macro will resolve to the appropriate BenignMallocHooks +** structure. If writable static data is unsupported on the target, +** we have to locate the state vector at run-time. In the more common +** case where writable static data is supported, wsdHooks can refer directly +** to the "sqlite3Hooks" state vector declared above. +*/ +#ifdef SQLITE_OMIT_WSD +# define wsdHooksInit \ + BenignMallocHooks *x = &GLOBAL(BenignMallocHooks,sqlite3Hooks) +# define wsdHooks x[0] +#else +# define wsdHooksInit +# define wsdHooks sqlite3Hooks +#endif + + +/* +** Register hooks to call when sqlite3BeginBenignMalloc() and +** sqlite3EndBenignMalloc() are called, respectively. +*/ +SQLITE_PRIVATE void sqlite3BenignMallocHooks( + void (*xBenignBegin)(void), + void (*xBenignEnd)(void) +){ + wsdHooksInit; + wsdHooks.xBenignBegin = xBenignBegin; + wsdHooks.xBenignEnd = xBenignEnd; +} + +/* +** This (sqlite3EndBenignMalloc()) is called by SQLite code to indicate that +** subsequent malloc failures are benign. A call to sqlite3EndBenignMalloc() +** indicates that subsequent malloc failures are non-benign. +*/ +SQLITE_PRIVATE void sqlite3BeginBenignMalloc(void){ + wsdHooksInit; + if( wsdHooks.xBenignBegin ){ + wsdHooks.xBenignBegin(); + } +} +SQLITE_PRIVATE void sqlite3EndBenignMalloc(void){ + wsdHooksInit; + if( wsdHooks.xBenignEnd ){ + wsdHooks.xBenignEnd(); + } +} + +#endif /* #ifndef SQLITE_OMIT_BUILTIN_TEST */ + +/************** End of fault.c ***********************************************/ +/************** Begin file mem0.c ********************************************/ +/* +** 2008 October 28 +** +** 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 a no-op memory allocation drivers for use when +** SQLITE_ZERO_MALLOC is defined. The allocation drivers implemented +** here always fail. SQLite will not operate with these drivers. These +** are merely placeholders. Real drivers must be substituted using +** sqlite3_config() before SQLite will operate. +*/ + +/* +** This version of the memory allocator is the default. It is +** used when no other memory allocator is specified using compile-time +** macros. +*/ +#ifdef SQLITE_ZERO_MALLOC + +/* +** No-op versions of all memory allocation routines +*/ +static void *sqlite3MemMalloc(int nByte){ return 0; } +static void sqlite3MemFree(void *pPrior){ return; } +static void *sqlite3MemRealloc(void *pPrior, int nByte){ return 0; } +static int sqlite3MemSize(void *pPrior){ return 0; } +static int sqlite3MemRoundup(int n){ return n; } +static int sqlite3MemInit(void *NotUsed){ return SQLITE_OK; } +static void sqlite3MemShutdown(void *NotUsed){ return; } + +/* +** This routine is the only routine in this file with external linkage. +** +** Populate the low-level memory allocation function pointers in +** sqlite3GlobalConfig.m with pointers to the routines in this file. +*/ +SQLITE_PRIVATE void sqlite3MemSetDefault(void){ + static const sqlite3_mem_methods defaultMethods = { + sqlite3MemMalloc, + sqlite3MemFree, + sqlite3MemRealloc, + sqlite3MemSize, + sqlite3MemRoundup, + sqlite3MemInit, + sqlite3MemShutdown, + 0 + }; + sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); +} + +#endif /* SQLITE_ZERO_MALLOC */ + +/************** End of mem0.c ************************************************/ +/************** Begin file mem1.c ********************************************/ +/* +** 2007 August 14 +** +** 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 low-level memory allocation drivers for when +** SQLite will use the standard C-library malloc/realloc/free interface +** to obtain the memory it needs. +** +** This file contains implementations of the low-level memory allocation +** routines specified in the sqlite3_mem_methods object. The content of +** this file is only used if SQLITE_SYSTEM_MALLOC is defined. The +** SQLITE_SYSTEM_MALLOC macro is defined automatically if neither the +** SQLITE_MEMDEBUG nor the SQLITE_WIN32_MALLOC macros are defined. The +** default configuration is to use memory allocation routines in this +** file. +** +** C-preprocessor macro summary: +** +** HAVE_MALLOC_USABLE_SIZE The configure script sets this symbol if +** the malloc_usable_size() interface exists +** on the target platform. Or, this symbol +** can be set manually, if desired. +** If an equivalent interface exists by +** a different name, using a separate -D +** option to rename it. +** +** SQLITE_WITHOUT_ZONEMALLOC Some older macs lack support for the zone +** memory allocator. Set this symbol to enable +** building on older macs. +** +** SQLITE_WITHOUT_MSIZE Set this symbol to disable the use of +** _msize() on windows systems. This might +** be necessary when compiling for Delphi, +** for example. +*/ + +/* +** This version of the memory allocator is the default. It is +** used when no other memory allocator is specified using compile-time +** macros. +*/ +#ifdef SQLITE_SYSTEM_MALLOC +#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) + +/* +** Use the zone allocator available on apple products unless the +** SQLITE_WITHOUT_ZONEMALLOC symbol is defined. +*/ +#include +#include +#include +static malloc_zone_t* _sqliteZone_; +#define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x)) +#define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x)); +#define SQLITE_REALLOC(x,y) malloc_zone_realloc(_sqliteZone_, (x), (y)) +#define SQLITE_MALLOCSIZE(x) \ + (_sqliteZone_ ? _sqliteZone_->size(_sqliteZone_,x) : malloc_size(x)) + +#else /* if not __APPLE__ */ + +/* +** Use standard C library malloc and free on non-Apple systems. +** Also used by Apple systems if SQLITE_WITHOUT_ZONEMALLOC is defined. +*/ +#define SQLITE_MALLOC(x) malloc(x) +#define SQLITE_FREE(x) free(x) +#define SQLITE_REALLOC(x,y) realloc((x),(y)) + +/* +** The malloc.h header file is needed for malloc_usable_size() function +** on some systems (e.g. Linux). +*/ +#if HAVE_MALLOC_H && HAVE_MALLOC_USABLE_SIZE +# define SQLITE_USE_MALLOC_H 1 +# define SQLITE_USE_MALLOC_USABLE_SIZE 1 +/* +** The MSVCRT has malloc_usable_size(), but it is called _msize(). The +** use of _msize() is automatic, but can be disabled by compiling with +** -DSQLITE_WITHOUT_MSIZE. Using the _msize() function also requires +** the malloc.h header file. +*/ +#elif defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE) +# define SQLITE_USE_MALLOC_H +# define SQLITE_USE_MSIZE +#endif + +/* +** Include the malloc.h header file, if necessary. Also set define macro +** SQLITE_MALLOCSIZE to the appropriate function name, which is _msize() +** for MSVC and malloc_usable_size() for most other systems (e.g. Linux). +** The memory size function can always be overridden manually by defining +** the macro SQLITE_MALLOCSIZE to the desired function name. +*/ +#if defined(SQLITE_USE_MALLOC_H) +# include +# if defined(SQLITE_USE_MALLOC_USABLE_SIZE) +# if !defined(SQLITE_MALLOCSIZE) +# define SQLITE_MALLOCSIZE(x) malloc_usable_size(x) +# endif +# elif defined(SQLITE_USE_MSIZE) +# if !defined(SQLITE_MALLOCSIZE) +# define SQLITE_MALLOCSIZE _msize +# endif +# endif +#endif /* defined(SQLITE_USE_MALLOC_H) */ + +#endif /* __APPLE__ or not __APPLE__ */ + +/* +** Like malloc(), but remember the size of the allocation +** so that we can find it later using sqlite3MemSize(). +** +** For this low-level routine, we are guaranteed that nByte>0 because +** cases of nByte<=0 will be intercepted and dealt with by higher level +** routines. +*/ +static void *sqlite3MemMalloc(int nByte){ +#ifdef SQLITE_MALLOCSIZE + void *p = SQLITE_MALLOC( nByte ); + if( p==0 ){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte); + } + return p; +#else + sqlite3_int64 *p; + assert( nByte>0 ); + nByte = ROUND8(nByte); + p = SQLITE_MALLOC( nByte+8 ); + if( p ){ + p[0] = nByte; + p++; + }else{ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte); + } + return (void *)p; +#endif +} + +/* +** Like free() but works for allocations obtained from sqlite3MemMalloc() +** or sqlite3MemRealloc(). +** +** For this low-level routine, we already know that pPrior!=0 since +** cases where pPrior==0 will have been intecepted and dealt with +** by higher-level routines. +*/ +static void sqlite3MemFree(void *pPrior){ +#ifdef SQLITE_MALLOCSIZE + SQLITE_FREE(pPrior); +#else + sqlite3_int64 *p = (sqlite3_int64*)pPrior; + assert( pPrior!=0 ); + p--; + SQLITE_FREE(p); +#endif +} + +/* +** Report the allocated size of a prior return from xMalloc() +** or xRealloc(). +*/ +static int sqlite3MemSize(void *pPrior){ +#ifdef SQLITE_MALLOCSIZE + return pPrior ? (int)SQLITE_MALLOCSIZE(pPrior) : 0; +#else + sqlite3_int64 *p; + if( pPrior==0 ) return 0; + p = (sqlite3_int64*)pPrior; + p--; + return (int)p[0]; +#endif +} + +/* +** Like realloc(). Resize an allocation previously obtained from +** sqlite3MemMalloc(). +** +** For this low-level interface, we know that pPrior!=0. Cases where +** pPrior==0 while have been intercepted by higher-level routine and +** redirected to xMalloc. Similarly, we know that nByte>0 because +** cases where nByte<=0 will have been intercepted by higher-level +** routines and redirected to xFree. +*/ +static void *sqlite3MemRealloc(void *pPrior, int nByte){ +#ifdef SQLITE_MALLOCSIZE + void *p = SQLITE_REALLOC(pPrior, nByte); + if( p==0 ){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, + "failed memory resize %u to %u bytes", + SQLITE_MALLOCSIZE(pPrior), nByte); + } + return p; +#else + sqlite3_int64 *p = (sqlite3_int64*)pPrior; + assert( pPrior!=0 && nByte>0 ); + assert( nByte==ROUND8(nByte) ); /* EV: R-46199-30249 */ + p--; + p = SQLITE_REALLOC(p, nByte+8 ); + if( p ){ + p[0] = nByte; + p++; + }else{ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, + "failed memory resize %u to %u bytes", + sqlite3MemSize(pPrior), nByte); + } + return (void*)p; +#endif +} + +/* +** Round up a request size to the next valid allocation size. +*/ +static int sqlite3MemRoundup(int n){ + return ROUND8(n); +} + +/* +** Initialize this module. +*/ +static int sqlite3MemInit(void *NotUsed){ +#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) + int cpuCount; + size_t len; + if( _sqliteZone_ ){ + return SQLITE_OK; + } + len = sizeof(cpuCount); + /* One usually wants to use hw.acctivecpu for MT decisions, but not here */ + sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0); + if( cpuCount>1 ){ + /* defer MT decisions to system malloc */ + _sqliteZone_ = malloc_default_zone(); + }else{ + /* only 1 core, use our own zone to contention over global locks, + ** e.g. we have our own dedicated locks */ + bool success; + malloc_zone_t* newzone = malloc_create_zone(4096, 0); + malloc_set_zone_name(newzone, "Sqlite_Heap"); + do{ + success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone, + (void * volatile *)&_sqliteZone_); + }while(!_sqliteZone_); + if( !success ){ + /* somebody registered a zone first */ + malloc_destroy_zone(newzone); + } + } +#endif + UNUSED_PARAMETER(NotUsed); + return SQLITE_OK; +} + +/* +** Deinitialize this module. +*/ +static void sqlite3MemShutdown(void *NotUsed){ + UNUSED_PARAMETER(NotUsed); + return; +} + +/* +** This routine is the only routine in this file with external linkage. +** +** Populate the low-level memory allocation function pointers in +** sqlite3GlobalConfig.m with pointers to the routines in this file. +*/ +SQLITE_PRIVATE void sqlite3MemSetDefault(void){ + static const sqlite3_mem_methods defaultMethods = { + sqlite3MemMalloc, + sqlite3MemFree, + sqlite3MemRealloc, + sqlite3MemSize, + sqlite3MemRoundup, + sqlite3MemInit, + sqlite3MemShutdown, + 0 + }; + sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); +} + +#endif /* SQLITE_SYSTEM_MALLOC */ + +/************** End of mem1.c ************************************************/ +/************** Begin file mem2.c ********************************************/ +/* +** 2007 August 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. +** +************************************************************************* +** +** This file contains low-level memory allocation drivers for when +** SQLite will use the standard C-library malloc/realloc/free interface +** to obtain the memory it needs while adding lots of additional debugging +** information to each allocation in order to help detect and fix memory +** leaks and memory usage errors. +** +** This file contains implementations of the low-level memory allocation +** routines specified in the sqlite3_mem_methods object. +*/ + +/* +** This version of the memory allocator is used only if the +** SQLITE_MEMDEBUG macro is defined +*/ +#ifdef SQLITE_MEMDEBUG + +/* +** The backtrace functionality is only available with GLIBC +*/ +#ifdef __GLIBC__ + extern int backtrace(void**,int); + extern void backtrace_symbols_fd(void*const*,int,int); +#else +# define backtrace(A,B) 1 +# define backtrace_symbols_fd(A,B,C) +#endif +/* #include */ + +/* +** Each memory allocation looks like this: +** +** ------------------------------------------------------------------------ +** | Title | backtrace pointers | MemBlockHdr | allocation | EndGuard | +** ------------------------------------------------------------------------ +** +** The application code sees only a pointer to the allocation. We have +** to back up from the allocation pointer to find the MemBlockHdr. The +** MemBlockHdr tells us the size of the allocation and the number of +** backtrace pointers. There is also a guard word at the end of the +** MemBlockHdr. +*/ +struct MemBlockHdr { + i64 iSize; /* Size of this allocation */ + struct MemBlockHdr *pNext, *pPrev; /* Linked list of all unfreed memory */ + char nBacktrace; /* Number of backtraces on this alloc */ + char nBacktraceSlots; /* Available backtrace slots */ + u8 nTitle; /* Bytes of title; includes '\0' */ + u8 eType; /* Allocation type code */ + int iForeGuard; /* Guard word for sanity */ +}; + +/* +** Guard words +*/ +#define FOREGUARD 0x80F5E153 +#define REARGUARD 0xE4676B53 + +/* +** Number of malloc size increments to track. +*/ +#define NCSIZE 1000 + +/* +** All of the static variables used by this module are collected +** into a single structure named "mem". This is to keep the +** static variables organized and to reduce namespace pollution +** when this module is combined with other in the amalgamation. +*/ +static struct { + + /* + ** Mutex to control access to the memory allocation subsystem. + */ + sqlite3_mutex *mutex; + + /* + ** Head and tail of a linked list of all outstanding allocations + */ + struct MemBlockHdr *pFirst; + struct MemBlockHdr *pLast; + + /* + ** The number of levels of backtrace to save in new allocations. + */ + int nBacktrace; + void (*xBacktrace)(int, int, void **); + + /* + ** Title text to insert in front of each block + */ + int nTitle; /* Bytes of zTitle to save. Includes '\0' and padding */ + char zTitle[100]; /* The title text */ + + /* + ** sqlite3MallocDisallow() increments the following counter. + ** sqlite3MallocAllow() decrements it. + */ + int disallow; /* Do not allow memory allocation */ + + /* + ** Gather statistics on the sizes of memory allocations. + ** nAlloc[i] is the number of allocation attempts of i*8 + ** bytes. i==NCSIZE is the number of allocation attempts for + ** sizes more than NCSIZE*8 bytes. + */ + int nAlloc[NCSIZE]; /* Total number of allocations */ + int nCurrent[NCSIZE]; /* Current number of allocations */ + int mxCurrent[NCSIZE]; /* Highwater mark for nCurrent */ + +} mem; + + +/* +** Adjust memory usage statistics +*/ +static void adjustStats(int iSize, int increment){ + int i = ROUND8(iSize)/8; + if( i>NCSIZE-1 ){ + i = NCSIZE - 1; + } + if( increment>0 ){ + mem.nAlloc[i]++; + mem.nCurrent[i]++; + if( mem.nCurrent[i]>mem.mxCurrent[i] ){ + mem.mxCurrent[i] = mem.nCurrent[i]; + } + }else{ + mem.nCurrent[i]--; + assert( mem.nCurrent[i]>=0 ); + } +} + +/* +** Given an allocation, find the MemBlockHdr for that allocation. +** +** This routine checks the guards at either end of the allocation and +** if they are incorrect it asserts. +*/ +static struct MemBlockHdr *sqlite3MemsysGetHeader(void *pAllocation){ + struct MemBlockHdr *p; + int *pInt; + u8 *pU8; + int nReserve; + + p = (struct MemBlockHdr*)pAllocation; + p--; + assert( p->iForeGuard==(int)FOREGUARD ); + nReserve = ROUND8(p->iSize); + pInt = (int*)pAllocation; + pU8 = (u8*)pAllocation; + assert( pInt[nReserve/sizeof(int)]==(int)REARGUARD ); + /* This checks any of the "extra" bytes allocated due + ** to rounding up to an 8 byte boundary to ensure + ** they haven't been overwritten. + */ + while( nReserve-- > p->iSize ) assert( pU8[nReserve]==0x65 ); + return p; +} + +/* +** Return the number of bytes currently allocated at address p. +*/ +static int sqlite3MemSize(void *p){ + struct MemBlockHdr *pHdr; + if( !p ){ + return 0; + } + pHdr = sqlite3MemsysGetHeader(p); + return (int)pHdr->iSize; +} + +/* +** Initialize the memory allocation subsystem. +*/ +static int sqlite3MemInit(void *NotUsed){ + UNUSED_PARAMETER(NotUsed); + assert( (sizeof(struct MemBlockHdr)&7) == 0 ); + if( !sqlite3GlobalConfig.bMemstat ){ + /* If memory status is enabled, then the malloc.c wrapper will already + ** hold the STATIC_MEM mutex when the routines here are invoked. */ + mem.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); + } + return SQLITE_OK; +} + +/* +** Deinitialize the memory allocation subsystem. +*/ +static void sqlite3MemShutdown(void *NotUsed){ + UNUSED_PARAMETER(NotUsed); + mem.mutex = 0; +} + +/* +** Round up a request size to the next valid allocation size. +*/ +static int sqlite3MemRoundup(int n){ + return ROUND8(n); +} + +/* +** Fill a buffer with pseudo-random bytes. This is used to preset +** the content of a new memory allocation to unpredictable values and +** to clear the content of a freed allocation to unpredictable values. +*/ +static void randomFill(char *pBuf, int nByte){ + unsigned int x, y, r; + x = SQLITE_PTR_TO_INT(pBuf); + y = nByte | 1; + while( nByte >= 4 ){ + x = (x>>1) ^ (-(int)(x&1) & 0xd0000001); + y = y*1103515245 + 12345; + r = x ^ y; + *(int*)pBuf = r; + pBuf += 4; + nByte -= 4; + } + while( nByte-- > 0 ){ + x = (x>>1) ^ (-(int)(x&1) & 0xd0000001); + y = y*1103515245 + 12345; + r = x ^ y; + *(pBuf++) = r & 0xff; + } +} + +/* +** Allocate nByte bytes of memory. +*/ +static void *sqlite3MemMalloc(int nByte){ + struct MemBlockHdr *pHdr; + void **pBt; + char *z; + int *pInt; + void *p = 0; + int totalSize; + int nReserve; + sqlite3_mutex_enter(mem.mutex); + assert( mem.disallow==0 ); + nReserve = ROUND8(nByte); + totalSize = nReserve + sizeof(*pHdr) + sizeof(int) + + mem.nBacktrace*sizeof(void*) + mem.nTitle; + p = malloc(totalSize); + if( p ){ + z = p; + pBt = (void**)&z[mem.nTitle]; + pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace]; + pHdr->pNext = 0; + pHdr->pPrev = mem.pLast; + if( mem.pLast ){ + mem.pLast->pNext = pHdr; + }else{ + mem.pFirst = pHdr; + } + mem.pLast = pHdr; + pHdr->iForeGuard = FOREGUARD; + pHdr->eType = MEMTYPE_HEAP; + pHdr->nBacktraceSlots = mem.nBacktrace; + pHdr->nTitle = mem.nTitle; + if( mem.nBacktrace ){ + void *aAddr[40]; + pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1; + memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*)); + assert(pBt[0]); + if( mem.xBacktrace ){ + mem.xBacktrace(nByte, pHdr->nBacktrace-1, &aAddr[1]); + } + }else{ + pHdr->nBacktrace = 0; + } + if( mem.nTitle ){ + memcpy(z, mem.zTitle, mem.nTitle); + } + pHdr->iSize = nByte; + adjustStats(nByte, +1); + pInt = (int*)&pHdr[1]; + pInt[nReserve/sizeof(int)] = REARGUARD; + randomFill((char*)pInt, nByte); + memset(((char*)pInt)+nByte, 0x65, nReserve-nByte); + p = (void*)pInt; + } + sqlite3_mutex_leave(mem.mutex); + return p; +} + +/* +** Free memory. +*/ +static void sqlite3MemFree(void *pPrior){ + struct MemBlockHdr *pHdr; + void **pBt; + char *z; + assert( sqlite3GlobalConfig.bMemstat || sqlite3GlobalConfig.bCoreMutex==0 + || mem.mutex!=0 ); + pHdr = sqlite3MemsysGetHeader(pPrior); + pBt = (void**)pHdr; + pBt -= pHdr->nBacktraceSlots; + sqlite3_mutex_enter(mem.mutex); + if( pHdr->pPrev ){ + assert( pHdr->pPrev->pNext==pHdr ); + pHdr->pPrev->pNext = pHdr->pNext; + }else{ + assert( mem.pFirst==pHdr ); + mem.pFirst = pHdr->pNext; + } + if( pHdr->pNext ){ + assert( pHdr->pNext->pPrev==pHdr ); + pHdr->pNext->pPrev = pHdr->pPrev; + }else{ + assert( mem.pLast==pHdr ); + mem.pLast = pHdr->pPrev; + } + z = (char*)pBt; + z -= pHdr->nTitle; + adjustStats((int)pHdr->iSize, -1); + randomFill(z, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) + + (int)pHdr->iSize + sizeof(int) + pHdr->nTitle); + free(z); + sqlite3_mutex_leave(mem.mutex); +} + +/* +** Change the size of an existing memory allocation. +** +** For this debugging implementation, we *always* make a copy of the +** allocation into a new place in memory. In this way, if the +** higher level code is using pointer to the old allocation, it is +** much more likely to break and we are much more liking to find +** the error. +*/ +static void *sqlite3MemRealloc(void *pPrior, int nByte){ + struct MemBlockHdr *pOldHdr; + void *pNew; + assert( mem.disallow==0 ); + assert( (nByte & 7)==0 ); /* EV: R-46199-30249 */ + pOldHdr = sqlite3MemsysGetHeader(pPrior); + pNew = sqlite3MemMalloc(nByte); + if( pNew ){ + memcpy(pNew, pPrior, (int)(nByteiSize ? nByte : pOldHdr->iSize)); + if( nByte>pOldHdr->iSize ){ + randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - (int)pOldHdr->iSize); + } + sqlite3MemFree(pPrior); + } + return pNew; +} + +/* +** Populate the low-level memory allocation function pointers in +** sqlite3GlobalConfig.m with pointers to the routines in this file. +*/ +SQLITE_PRIVATE void sqlite3MemSetDefault(void){ + static const sqlite3_mem_methods defaultMethods = { + sqlite3MemMalloc, + sqlite3MemFree, + sqlite3MemRealloc, + sqlite3MemSize, + sqlite3MemRoundup, + sqlite3MemInit, + sqlite3MemShutdown, + 0 + }; + sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); +} + +/* +** Set the "type" of an allocation. +*/ +SQLITE_PRIVATE void sqlite3MemdebugSetType(void *p, u8 eType){ + if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){ + struct MemBlockHdr *pHdr; + pHdr = sqlite3MemsysGetHeader(p); + assert( pHdr->iForeGuard==FOREGUARD ); + pHdr->eType = eType; + } +} + +/* +** Return TRUE if the mask of type in eType matches the type of the +** allocation p. Also return true if p==NULL. +** +** This routine is designed for use within an assert() statement, to +** verify the type of an allocation. For example: +** +** assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); +*/ +SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){ + int rc = 1; + if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){ + struct MemBlockHdr *pHdr; + pHdr = sqlite3MemsysGetHeader(p); + assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */ + if( (pHdr->eType&eType)==0 ){ + rc = 0; + } + } + return rc; +} + +/* +** Return TRUE if the mask of type in eType matches no bits of the type of the +** allocation p. Also return true if p==NULL. +** +** This routine is designed for use within an assert() statement, to +** verify the type of an allocation. For example: +** +** assert( sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); +*/ +SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){ + int rc = 1; + if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){ + struct MemBlockHdr *pHdr; + pHdr = sqlite3MemsysGetHeader(p); + assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */ + if( (pHdr->eType&eType)!=0 ){ + rc = 0; + } + } + return rc; +} + +/* +** Set the number of backtrace levels kept for each allocation. +** A value of zero turns off backtracing. The number is always rounded +** up to a multiple of 2. +*/ +SQLITE_PRIVATE void sqlite3MemdebugBacktrace(int depth){ + if( depth<0 ){ depth = 0; } + if( depth>20 ){ depth = 20; } + depth = (depth+1)&0xfe; + mem.nBacktrace = depth; +} + +SQLITE_PRIVATE void sqlite3MemdebugBacktraceCallback(void (*xBacktrace)(int, int, void **)){ + mem.xBacktrace = xBacktrace; +} + +/* +** Set the title string for subsequent allocations. +*/ +SQLITE_PRIVATE void sqlite3MemdebugSettitle(const char *zTitle){ + unsigned int n = sqlite3Strlen30(zTitle) + 1; + sqlite3_mutex_enter(mem.mutex); + if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1; + memcpy(mem.zTitle, zTitle, n); + mem.zTitle[n] = 0; + mem.nTitle = ROUND8(n); + sqlite3_mutex_leave(mem.mutex); +} + +SQLITE_PRIVATE void sqlite3MemdebugSync(){ + struct MemBlockHdr *pHdr; + for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){ + void **pBt = (void**)pHdr; + pBt -= pHdr->nBacktraceSlots; + mem.xBacktrace((int)pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]); + } +} + +/* +** Open the file indicated and write a log of all unfreed memory +** allocations into that log. +*/ +SQLITE_PRIVATE void sqlite3MemdebugDump(const char *zFilename){ + FILE *out; + struct MemBlockHdr *pHdr; + void **pBt; + int i; + out = fopen(zFilename, "w"); + if( out==0 ){ + fprintf(stderr, "** Unable to output memory debug output log: %s **\n", + zFilename); + return; + } + for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){ + char *z = (char*)pHdr; + z -= pHdr->nBacktraceSlots*sizeof(void*) + pHdr->nTitle; + fprintf(out, "**** %lld bytes at %p from %s ****\n", + pHdr->iSize, &pHdr[1], pHdr->nTitle ? z : "???"); + if( pHdr->nBacktrace ){ + fflush(out); + pBt = (void**)pHdr; + pBt -= pHdr->nBacktraceSlots; + backtrace_symbols_fd(pBt, pHdr->nBacktrace, fileno(out)); + fprintf(out, "\n"); + } + } + fprintf(out, "COUNTS:\n"); + for(i=0; i=1 ); + size = mem3.aPool[i-1].u.hdr.size4x/4; + assert( size==mem3.aPool[i+size-1].u.hdr.prevSize ); + assert( size>=2 ); + if( size <= MX_SMALL ){ + memsys3UnlinkFromList(i, &mem3.aiSmall[size-2]); + }else{ + hash = size % N_HASH; + memsys3UnlinkFromList(i, &mem3.aiHash[hash]); + } +} + +/* +** Link the chunk at mem3.aPool[i] so that is on the list rooted +** at *pRoot. +*/ +static void memsys3LinkIntoList(u32 i, u32 *pRoot){ + assert( sqlite3_mutex_held(mem3.mutex) ); + mem3.aPool[i].u.list.next = *pRoot; + mem3.aPool[i].u.list.prev = 0; + if( *pRoot ){ + mem3.aPool[*pRoot].u.list.prev = i; + } + *pRoot = i; +} + +/* +** Link the chunk at index i into either the appropriate +** small chunk list, or into the large chunk hash table. +*/ +static void memsys3Link(u32 i){ + u32 size, hash; + assert( sqlite3_mutex_held(mem3.mutex) ); + assert( i>=1 ); + assert( (mem3.aPool[i-1].u.hdr.size4x & 1)==0 ); + size = mem3.aPool[i-1].u.hdr.size4x/4; + assert( size==mem3.aPool[i+size-1].u.hdr.prevSize ); + assert( size>=2 ); + if( size <= MX_SMALL ){ + memsys3LinkIntoList(i, &mem3.aiSmall[size-2]); + }else{ + hash = size % N_HASH; + memsys3LinkIntoList(i, &mem3.aiHash[hash]); + } +} + +/* +** If the STATIC_MEM mutex is not already held, obtain it now. The mutex +** will already be held (obtained by code in malloc.c) if +** sqlite3GlobalConfig.bMemStat is true. +*/ +static void memsys3Enter(void){ + if( sqlite3GlobalConfig.bMemstat==0 && mem3.mutex==0 ){ + mem3.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); + } + sqlite3_mutex_enter(mem3.mutex); +} +static void memsys3Leave(void){ + sqlite3_mutex_leave(mem3.mutex); +} + +/* +** Called when we are unable to satisfy an allocation of nBytes. +*/ +static void memsys3OutOfMemory(int nByte){ + if( !mem3.alarmBusy ){ + mem3.alarmBusy = 1; + assert( sqlite3_mutex_held(mem3.mutex) ); + sqlite3_mutex_leave(mem3.mutex); + sqlite3_release_memory(nByte); + sqlite3_mutex_enter(mem3.mutex); + mem3.alarmBusy = 0; + } +} + + +/* +** Chunk i is a free chunk that has been unlinked. Adjust its +** size parameters for check-out and return a pointer to the +** user portion of the chunk. +*/ +static void *memsys3Checkout(u32 i, u32 nBlock){ + u32 x; + assert( sqlite3_mutex_held(mem3.mutex) ); + assert( i>=1 ); + assert( mem3.aPool[i-1].u.hdr.size4x/4==nBlock ); + assert( mem3.aPool[i+nBlock-1].u.hdr.prevSize==nBlock ); + x = mem3.aPool[i-1].u.hdr.size4x; + mem3.aPool[i-1].u.hdr.size4x = nBlock*4 | 1 | (x&2); + mem3.aPool[i+nBlock-1].u.hdr.prevSize = nBlock; + mem3.aPool[i+nBlock-1].u.hdr.size4x |= 2; + return &mem3.aPool[i]; +} + +/* +** Carve a piece off of the end of the mem3.iMaster free chunk. +** Return a pointer to the new allocation. Or, if the master chunk +** is not large enough, return 0. +*/ +static void *memsys3FromMaster(u32 nBlock){ + assert( sqlite3_mutex_held(mem3.mutex) ); + assert( mem3.szMaster>=nBlock ); + if( nBlock>=mem3.szMaster-1 ){ + /* Use the entire master */ + void *p = memsys3Checkout(mem3.iMaster, mem3.szMaster); + mem3.iMaster = 0; + mem3.szMaster = 0; + mem3.mnMaster = 0; + return p; + }else{ + /* Split the master block. Return the tail. */ + u32 newi, x; + newi = mem3.iMaster + mem3.szMaster - nBlock; + assert( newi > mem3.iMaster+1 ); + mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = nBlock; + mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x |= 2; + mem3.aPool[newi-1].u.hdr.size4x = nBlock*4 + 1; + mem3.szMaster -= nBlock; + mem3.aPool[newi-1].u.hdr.prevSize = mem3.szMaster; + x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2; + mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x; + if( mem3.szMaster < mem3.mnMaster ){ + mem3.mnMaster = mem3.szMaster; + } + return (void*)&mem3.aPool[newi]; + } +} + +/* +** *pRoot is the head of a list of free chunks of the same size +** or same size hash. In other words, *pRoot is an entry in either +** mem3.aiSmall[] or mem3.aiHash[]. +** +** This routine examines all entries on the given list and tries +** to coalesce each entries with adjacent free chunks. +** +** If it sees a chunk that is larger than mem3.iMaster, it replaces +** the current mem3.iMaster with the new larger chunk. In order for +** this mem3.iMaster replacement to work, the master chunk must be +** linked into the hash tables. That is not the normal state of +** affairs, of course. The calling routine must link the master +** chunk before invoking this routine, then must unlink the (possibly +** changed) master chunk once this routine has finished. +*/ +static void memsys3Merge(u32 *pRoot){ + u32 iNext, prev, size, i, x; + + assert( sqlite3_mutex_held(mem3.mutex) ); + for(i=*pRoot; i>0; i=iNext){ + iNext = mem3.aPool[i].u.list.next; + size = mem3.aPool[i-1].u.hdr.size4x; + assert( (size&1)==0 ); + if( (size&2)==0 ){ + memsys3UnlinkFromList(i, pRoot); + assert( i > mem3.aPool[i-1].u.hdr.prevSize ); + prev = i - mem3.aPool[i-1].u.hdr.prevSize; + if( prev==iNext ){ + iNext = mem3.aPool[prev].u.list.next; + } + memsys3Unlink(prev); + size = i + size/4 - prev; + x = mem3.aPool[prev-1].u.hdr.size4x & 2; + mem3.aPool[prev-1].u.hdr.size4x = size*4 | x; + mem3.aPool[prev+size-1].u.hdr.prevSize = size; + memsys3Link(prev); + i = prev; + }else{ + size /= 4; + } + if( size>mem3.szMaster ){ + mem3.iMaster = i; + mem3.szMaster = size; + } + } +} + +/* +** Return a block of memory of at least nBytes in size. +** Return NULL if unable. +** +** This function assumes that the necessary mutexes, if any, are +** already held by the caller. Hence "Unsafe". +*/ +static void *memsys3MallocUnsafe(int nByte){ + u32 i; + u32 nBlock; + u32 toFree; + + assert( sqlite3_mutex_held(mem3.mutex) ); + assert( sizeof(Mem3Block)==8 ); + if( nByte<=12 ){ + nBlock = 2; + }else{ + nBlock = (nByte + 11)/8; + } + assert( nBlock>=2 ); + + /* STEP 1: + ** Look for an entry of the correct size in either the small + ** chunk table or in the large chunk hash table. This is + ** successful most of the time (about 9 times out of 10). + */ + if( nBlock <= MX_SMALL ){ + i = mem3.aiSmall[nBlock-2]; + if( i>0 ){ + memsys3UnlinkFromList(i, &mem3.aiSmall[nBlock-2]); + return memsys3Checkout(i, nBlock); + } + }else{ + int hash = nBlock % N_HASH; + for(i=mem3.aiHash[hash]; i>0; i=mem3.aPool[i].u.list.next){ + if( mem3.aPool[i-1].u.hdr.size4x/4==nBlock ){ + memsys3UnlinkFromList(i, &mem3.aiHash[hash]); + return memsys3Checkout(i, nBlock); + } + } + } + + /* STEP 2: + ** Try to satisfy the allocation by carving a piece off of the end + ** of the master chunk. This step usually works if step 1 fails. + */ + if( mem3.szMaster>=nBlock ){ + return memsys3FromMaster(nBlock); + } + + + /* STEP 3: + ** Loop through the entire memory pool. Coalesce adjacent free + ** chunks. Recompute the master chunk as the largest free chunk. + ** Then try again to satisfy the allocation by carving a piece off + ** of the end of the master chunk. This step happens very + ** rarely (we hope!) + */ + for(toFree=nBlock*16; toFree<(mem3.nPool*16); toFree *= 2){ + memsys3OutOfMemory(toFree); + if( mem3.iMaster ){ + memsys3Link(mem3.iMaster); + mem3.iMaster = 0; + mem3.szMaster = 0; + } + for(i=0; i=nBlock ){ + return memsys3FromMaster(nBlock); + } + } + } + + /* If none of the above worked, then we fail. */ + return 0; +} + +/* +** Free an outstanding memory allocation. +** +** This function assumes that the necessary mutexes, if any, are +** already held by the caller. Hence "Unsafe". +*/ +static void memsys3FreeUnsafe(void *pOld){ + Mem3Block *p = (Mem3Block*)pOld; + int i; + u32 size, x; + assert( sqlite3_mutex_held(mem3.mutex) ); + assert( p>mem3.aPool && p<&mem3.aPool[mem3.nPool] ); + i = p - mem3.aPool; + assert( (mem3.aPool[i-1].u.hdr.size4x&1)==1 ); + size = mem3.aPool[i-1].u.hdr.size4x/4; + assert( i+size<=mem3.nPool+1 ); + mem3.aPool[i-1].u.hdr.size4x &= ~1; + mem3.aPool[i+size-1].u.hdr.prevSize = size; + mem3.aPool[i+size-1].u.hdr.size4x &= ~2; + memsys3Link(i); + + /* Try to expand the master using the newly freed chunk */ + if( mem3.iMaster ){ + while( (mem3.aPool[mem3.iMaster-1].u.hdr.size4x&2)==0 ){ + size = mem3.aPool[mem3.iMaster-1].u.hdr.prevSize; + mem3.iMaster -= size; + mem3.szMaster += size; + memsys3Unlink(mem3.iMaster); + x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2; + mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x; + mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = mem3.szMaster; + } + x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2; + while( (mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x&1)==0 ){ + memsys3Unlink(mem3.iMaster+mem3.szMaster); + mem3.szMaster += mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x/4; + mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x; + mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = mem3.szMaster; + } + } +} + +/* +** Return the size of an outstanding allocation, in bytes. The +** size returned omits the 8-byte header overhead. This only +** works for chunks that are currently checked out. +*/ +static int memsys3Size(void *p){ + Mem3Block *pBlock; + if( p==0 ) return 0; + pBlock = (Mem3Block*)p; + assert( (pBlock[-1].u.hdr.size4x&1)!=0 ); + return (pBlock[-1].u.hdr.size4x&~3)*2 - 4; +} + +/* +** Round up a request size to the next valid allocation size. +*/ +static int memsys3Roundup(int n){ + if( n<=12 ){ + return 12; + }else{ + return ((n+11)&~7) - 4; + } +} + +/* +** Allocate nBytes of memory. +*/ +static void *memsys3Malloc(int nBytes){ + sqlite3_int64 *p; + assert( nBytes>0 ); /* malloc.c filters out 0 byte requests */ + memsys3Enter(); + p = memsys3MallocUnsafe(nBytes); + memsys3Leave(); + return (void*)p; +} + +/* +** Free memory. +*/ +static void memsys3Free(void *pPrior){ + assert( pPrior ); + memsys3Enter(); + memsys3FreeUnsafe(pPrior); + memsys3Leave(); +} + +/* +** Change the size of an existing memory allocation +*/ +static void *memsys3Realloc(void *pPrior, int nBytes){ + int nOld; + void *p; + if( pPrior==0 ){ + return sqlite3_malloc(nBytes); + } + if( nBytes<=0 ){ + sqlite3_free(pPrior); + return 0; + } + nOld = memsys3Size(pPrior); + if( nBytes<=nOld && nBytes>=nOld-128 ){ + return pPrior; + } + memsys3Enter(); + p = memsys3MallocUnsafe(nBytes); + if( p ){ + if( nOld>1)!=(size&1) ){ + fprintf(out, "%p tail checkout bit is incorrect\n", &mem3.aPool[i]); + assert( 0 ); + break; + } + if( size&1 ){ + fprintf(out, "%p %6d bytes checked out\n", &mem3.aPool[i], (size/4)*8-8); + }else{ + fprintf(out, "%p %6d bytes free%s\n", &mem3.aPool[i], (size/4)*8-8, + i==mem3.iMaster ? " **master**" : ""); + } + } + for(i=0; i0; j=mem3.aPool[j].u.list.next){ + fprintf(out, " %p(%d)", &mem3.aPool[j], + (mem3.aPool[j-1].u.hdr.size4x/4)*8-8); + } + fprintf(out, "\n"); + } + for(i=0; i0; j=mem3.aPool[j].u.list.next){ + fprintf(out, " %p(%d)", &mem3.aPool[j], + (mem3.aPool[j-1].u.hdr.size4x/4)*8-8); + } + fprintf(out, "\n"); + } + fprintf(out, "master=%d\n", mem3.iMaster); + fprintf(out, "nowUsed=%d\n", mem3.nPool*8 - mem3.szMaster*8); + fprintf(out, "mxUsed=%d\n", mem3.nPool*8 - mem3.mnMaster*8); + sqlite3_mutex_leave(mem3.mutex); + if( out==stdout ){ + fflush(stdout); + }else{ + fclose(out); + } +#else + UNUSED_PARAMETER(zFilename); +#endif +} + +/* +** This routine is the only routine in this file with external +** linkage. +** +** Populate the low-level memory allocation function pointers in +** sqlite3GlobalConfig.m with pointers to the routines in this file. The +** arguments specify the block of memory to manage. +** +** This routine is only called by sqlite3_config(), and therefore +** is not required to be threadsafe (it is not). +*/ +SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void){ + static const sqlite3_mem_methods mempoolMethods = { + memsys3Malloc, + memsys3Free, + memsys3Realloc, + memsys3Size, + memsys3Roundup, + memsys3Init, + memsys3Shutdown, + 0 + }; + return &mempoolMethods; +} + +#endif /* SQLITE_ENABLE_MEMSYS3 */ + +/************** End of mem3.c ************************************************/ +/************** Begin file mem5.c ********************************************/ +/* +** 2007 October 14 +** +** 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 C functions that implement a memory +** allocation subsystem for use by SQLite. +** +** This version of the memory allocation subsystem omits all +** use of malloc(). The application gives SQLite a block of memory +** before calling sqlite3_initialize() from which allocations +** are made and returned by the xMalloc() and xRealloc() +** implementations. Once sqlite3_initialize() has been called, +** the amount of memory available to SQLite is fixed and cannot +** be changed. +** +** This version of the memory allocation subsystem is included +** in the build only if SQLITE_ENABLE_MEMSYS5 is defined. +** +** This memory allocator uses the following algorithm: +** +** 1. All memory allocations sizes are rounded up to a power of 2. +** +** 2. If two adjacent free blocks are the halves of a larger block, +** then the two blocks are coalesced into the single larger block. +** +** 3. New memory is allocated from the first available free block. +** +** This algorithm is described in: J. M. Robson. "Bounds for Some Functions +** Concerning Dynamic Storage Allocation". Journal of the Association for +** Computing Machinery, Volume 21, Number 8, July 1974, pages 491-499. +** +** Let n be the size of the largest allocation divided by the minimum +** allocation size (after rounding all sizes up to a power of 2.) Let M +** be the maximum amount of memory ever outstanding at one time. Let +** N be the total amount of memory available for allocation. Robson +** proved that this memory allocator will never breakdown due to +** fragmentation as long as the following constraint holds: +** +** N >= M*(1 + log2(n)/2) - n + 1 +** +** The sqlite3_status() logic tracks the maximum values of n and M so +** that an application can, at any time, verify this constraint. +*/ + +/* +** This version of the memory allocator is used only when +** SQLITE_ENABLE_MEMSYS5 is defined. +*/ +#ifdef SQLITE_ENABLE_MEMSYS5 + +/* +** A minimum allocation is an instance of the following structure. +** Larger allocations are an array of these structures where the +** size of the array is a power of 2. +** +** The size of this object must be a power of two. That fact is +** verified in memsys5Init(). +*/ +typedef struct Mem5Link Mem5Link; +struct Mem5Link { + int next; /* Index of next free chunk */ + int prev; /* Index of previous free chunk */ +}; + +/* +** Maximum size of any allocation is ((1<=0 && i=0 && iLogsize<=LOGMAX ); + assert( (mem5.aCtrl[i] & CTRL_LOGSIZE)==iLogsize ); + + next = MEM5LINK(i)->next; + prev = MEM5LINK(i)->prev; + if( prev<0 ){ + mem5.aiFreelist[iLogsize] = next; + }else{ + MEM5LINK(prev)->next = next; + } + if( next>=0 ){ + MEM5LINK(next)->prev = prev; + } +} + +/* +** Link the chunk at mem5.aPool[i] so that is on the iLogsize +** free list. +*/ +static void memsys5Link(int i, int iLogsize){ + int x; + assert( sqlite3_mutex_held(mem5.mutex) ); + assert( i>=0 && i=0 && iLogsize<=LOGMAX ); + assert( (mem5.aCtrl[i] & CTRL_LOGSIZE)==iLogsize ); + + x = MEM5LINK(i)->next = mem5.aiFreelist[iLogsize]; + MEM5LINK(i)->prev = -1; + if( x>=0 ){ + assert( xprev = i; + } + mem5.aiFreelist[iLogsize] = i; +} + +/* +** If the STATIC_MEM mutex is not already held, obtain it now. The mutex +** will already be held (obtained by code in malloc.c) if +** sqlite3GlobalConfig.bMemStat is true. +*/ +static void memsys5Enter(void){ + sqlite3_mutex_enter(mem5.mutex); +} +static void memsys5Leave(void){ + sqlite3_mutex_leave(mem5.mutex); +} + +/* +** Return the size of an outstanding allocation, in bytes. The +** size returned omits the 8-byte header overhead. This only +** works for chunks that are currently checked out. +*/ +static int memsys5Size(void *p){ + int iSize = 0; + if( p ){ + int i = (int)(((u8 *)p-mem5.zPool)/mem5.szAtom); + assert( i>=0 && i0 ); + + /* Keep track of the maximum allocation request. Even unfulfilled + ** requests are counted */ + if( (u32)nByte>mem5.maxRequest ){ + mem5.maxRequest = nByte; + } + + /* Abort if the requested allocation size is larger than the largest + ** power of two that we can represent using 32-bit signed integers. + */ + if( nByte > 0x40000000 ){ + return 0; + } + + /* Round nByte up to the next valid power of two */ + for(iFullSz=mem5.szAtom, iLogsize=0; iFullSzLOGMAX ){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes", nByte); + return 0; + } + i = mem5.aiFreelist[iBin]; + memsys5Unlink(i, iBin); + while( iBin>iLogsize ){ + int newSize; + + iBin--; + newSize = 1 << iBin; + mem5.aCtrl[i+newSize] = CTRL_FREE | iBin; + memsys5Link(i+newSize, iBin); + } + mem5.aCtrl[i] = iLogsize; + + /* Update allocator performance statistics. */ + mem5.nAlloc++; + mem5.totalAlloc += iFullSz; + mem5.totalExcess += iFullSz - nByte; + mem5.currentCount++; + mem5.currentOut += iFullSz; + if( mem5.maxCount=0 && iBlock0 ); + assert( mem5.currentOut>=(size*mem5.szAtom) ); + mem5.currentCount--; + mem5.currentOut -= size*mem5.szAtom; + assert( mem5.currentOut>0 || mem5.currentCount==0 ); + assert( mem5.currentCount>0 || mem5.currentOut==0 ); + + mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize; + while( ALWAYS(iLogsize>iLogsize) & 1 ){ + iBuddy = iBlock - size; + }else{ + iBuddy = iBlock + size; + } + assert( iBuddy>=0 ); + if( (iBuddy+(1<mem5.nBlock ) break; + if( mem5.aCtrl[iBuddy]!=(CTRL_FREE | iLogsize) ) break; + memsys5Unlink(iBuddy, iLogsize); + iLogsize++; + if( iBuddy0 ){ + memsys5Enter(); + p = memsys5MallocUnsafe(nBytes); + memsys5Leave(); + } + return (void*)p; +} + +/* +** Free memory. +** +** The outer layer memory allocator prevents this routine from +** being called with pPrior==0. +*/ +static void memsys5Free(void *pPrior){ + assert( pPrior!=0 ); + memsys5Enter(); + memsys5FreeUnsafe(pPrior); + memsys5Leave(); +} + +/* +** Change the size of an existing memory allocation. +** +** The outer layer memory allocator prevents this routine from +** being called with pPrior==0. +** +** nBytes is always a value obtained from a prior call to +** memsys5Round(). Hence nBytes is always a non-negative power +** of two. If nBytes==0 that means that an oversize allocation +** (an allocation larger than 0x40000000) was requested and this +** routine should return 0 without freeing pPrior. +*/ +static void *memsys5Realloc(void *pPrior, int nBytes){ + int nOld; + void *p; + assert( pPrior!=0 ); + assert( (nBytes&(nBytes-1))==0 ); /* EV: R-46199-30249 */ + assert( nBytes>=0 ); + if( nBytes==0 ){ + return 0; + } + nOld = memsys5Size(pPrior); + if( nBytes<=nOld ){ + return pPrior; + } + memsys5Enter(); + p = memsys5MallocUnsafe(nBytes); + if( p ){ + memcpy(p, pPrior, nOld); + memsys5FreeUnsafe(pPrior); + } + memsys5Leave(); + return p; +} + +/* +** Round up a request size to the next valid allocation size. If +** the allocation is too large to be handled by this allocation system, +** return 0. +** +** All allocations must be a power of two and must be expressed by a +** 32-bit signed integer. Hence the largest allocation is 0x40000000 +** or 1073741824 bytes. +*/ +static int memsys5Roundup(int n){ + int iFullSz; + if( n > 0x40000000 ) return 0; + for(iFullSz=mem5.szAtom; iFullSz 0 +** memsys5Log(2) -> 1 +** memsys5Log(4) -> 2 +** memsys5Log(5) -> 3 +** memsys5Log(8) -> 3 +** memsys5Log(9) -> 4 +*/ +static int memsys5Log(int iValue){ + int iLog; + for(iLog=0; (iLog<(int)((sizeof(int)*8)-1)) && (1<mem5.szAtom ){ + mem5.szAtom = mem5.szAtom << 1; + } + + mem5.nBlock = (nByte / (mem5.szAtom+sizeof(u8))); + mem5.zPool = zByte; + mem5.aCtrl = (u8 *)&mem5.zPool[mem5.nBlock*mem5.szAtom]; + + for(ii=0; ii<=LOGMAX; ii++){ + mem5.aiFreelist[ii] = -1; + } + + iOffset = 0; + for(ii=LOGMAX; ii>=0; ii--){ + int nAlloc = (1<mem5.nBlock); + } + + /* If a mutex is required for normal operation, allocate one */ + if( sqlite3GlobalConfig.bMemstat==0 ){ + mem5.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); + } + + return SQLITE_OK; +} + +/* +** Deinitialize this module. +*/ +static void memsys5Shutdown(void *NotUsed){ + UNUSED_PARAMETER(NotUsed); + mem5.mutex = 0; + return; +} + +#ifdef SQLITE_TEST +/* +** Open the file indicated and write a log of all unfreed memory +** allocations into that log. +*/ +SQLITE_PRIVATE void sqlite3Memsys5Dump(const char *zFilename){ + FILE *out; + int i, j, n; + int nMinLog; + + if( zFilename==0 || zFilename[0]==0 ){ + out = stdout; + }else{ + out = fopen(zFilename, "w"); + if( out==0 ){ + fprintf(stderr, "** Unable to output memory debug output log: %s **\n", + zFilename); + return; + } + } + memsys5Enter(); + nMinLog = memsys5Log(mem5.szAtom); + for(i=0; i<=LOGMAX && i+nMinLog<32; i++){ + for(n=0, j=mem5.aiFreelist[i]; j>=0; j = MEM5LINK(j)->next, n++){} + fprintf(out, "freelist items of size %d: %d\n", mem5.szAtom << i, n); + } + fprintf(out, "mem5.nAlloc = %llu\n", mem5.nAlloc); + fprintf(out, "mem5.totalAlloc = %llu\n", mem5.totalAlloc); + fprintf(out, "mem5.totalExcess = %llu\n", mem5.totalExcess); + fprintf(out, "mem5.currentOut = %u\n", mem5.currentOut); + fprintf(out, "mem5.currentCount = %u\n", mem5.currentCount); + fprintf(out, "mem5.maxOut = %u\n", mem5.maxOut); + fprintf(out, "mem5.maxCount = %u\n", mem5.maxCount); + fprintf(out, "mem5.maxRequest = %u\n", mem5.maxRequest); + memsys5Leave(); + if( out==stdout ){ + fflush(stdout); + }else{ + fclose(out); + } +} +#endif + +/* +** This routine is the only routine in this file with external +** linkage. It returns a pointer to a static sqlite3_mem_methods +** struct populated with the memsys5 methods. +*/ +SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void){ + static const sqlite3_mem_methods memsys5Methods = { + memsys5Malloc, + memsys5Free, + memsys5Realloc, + memsys5Size, + memsys5Roundup, + memsys5Init, + memsys5Shutdown, + 0 + }; + return &memsys5Methods; +} + +#endif /* SQLITE_ENABLE_MEMSYS5 */ + +/************** End of mem5.c ************************************************/ +/************** Begin file mutex.c *******************************************/ +/* +** 2007 August 14 +** +** 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 C functions that implement mutexes. +** +** This file contains code that is common across all mutex implementations. +*/ + +#if defined(SQLITE_DEBUG) && !defined(SQLITE_MUTEX_OMIT) +/* +** For debugging purposes, record when the mutex subsystem is initialized +** and uninitialized so that we can assert() if there is an attempt to +** allocate a mutex while the system is uninitialized. +*/ +static SQLITE_WSD int mutexIsInit = 0; +#endif /* SQLITE_DEBUG */ + + +#ifndef SQLITE_MUTEX_OMIT +/* +** Initialize the mutex system. +*/ +SQLITE_PRIVATE int sqlite3MutexInit(void){ + int rc = SQLITE_OK; + if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){ + /* If the xMutexAlloc method has not been set, then the user did not + ** install a mutex implementation via sqlite3_config() prior to + ** sqlite3_initialize() being called. This block copies pointers to + ** the default implementation into the sqlite3GlobalConfig structure. + */ + sqlite3_mutex_methods const *pFrom; + sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex; + + if( sqlite3GlobalConfig.bCoreMutex ){ + pFrom = sqlite3DefaultMutex(); + }else{ + pFrom = sqlite3NoopMutex(); + } + memcpy(pTo, pFrom, offsetof(sqlite3_mutex_methods, xMutexAlloc)); + memcpy(&pTo->xMutexFree, &pFrom->xMutexFree, + sizeof(*pTo) - offsetof(sqlite3_mutex_methods, xMutexFree)); + pTo->xMutexAlloc = pFrom->xMutexAlloc; + } + rc = sqlite3GlobalConfig.mutex.xMutexInit(); + +#ifdef SQLITE_DEBUG + GLOBAL(int, mutexIsInit) = 1; +#endif + + return rc; +} + +/* +** Shutdown the mutex system. This call frees resources allocated by +** sqlite3MutexInit(). +*/ +SQLITE_PRIVATE int sqlite3MutexEnd(void){ + int rc = SQLITE_OK; + if( sqlite3GlobalConfig.mutex.xMutexEnd ){ + rc = sqlite3GlobalConfig.mutex.xMutexEnd(); + } + +#ifdef SQLITE_DEBUG + GLOBAL(int, mutexIsInit) = 0; +#endif + + return rc; +} + +/* +** Retrieve a pointer to a static mutex or allocate a new dynamic one. +*/ +SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int id){ +#ifndef SQLITE_OMIT_AUTOINIT + if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0; + if( id>SQLITE_MUTEX_RECURSIVE && sqlite3MutexInit() ) return 0; +#endif + return sqlite3GlobalConfig.mutex.xMutexAlloc(id); +} + +SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){ + if( !sqlite3GlobalConfig.bCoreMutex ){ + return 0; + } + assert( GLOBAL(int, mutexIsInit) ); + return sqlite3GlobalConfig.mutex.xMutexAlloc(id); +} + +/* +** Free a dynamic mutex. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex *p){ + if( p ){ + sqlite3GlobalConfig.mutex.xMutexFree(p); + } +} + +/* +** Obtain the mutex p. If some other thread already has the mutex, block +** until it can be obtained. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex *p){ + if( p ){ + sqlite3GlobalConfig.mutex.xMutexEnter(p); + } +} + +/* +** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another +** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex *p){ + int rc = SQLITE_OK; + if( p ){ + return sqlite3GlobalConfig.mutex.xMutexTry(p); + } + return rc; +} + +/* +** The sqlite3_mutex_leave() routine exits a mutex that was previously +** entered by the same thread. The behavior is undefined if the mutex +** is not currently entered. If a NULL pointer is passed as an argument +** this function is a no-op. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex *p){ + if( p ){ + sqlite3GlobalConfig.mutex.xMutexLeave(p); + } +} + +#ifndef NDEBUG +/* +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are +** intended for use inside assert() statements. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex *p){ + return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p); +} +SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex *p){ + return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p); +} +#endif + +#endif /* !defined(SQLITE_MUTEX_OMIT) */ + +/************** End of mutex.c ***********************************************/ +/************** Begin file mutex_noop.c **************************************/ +/* +** 2008 October 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 the C functions that implement mutexes. +** +** This implementation in this file does not provide any mutual +** exclusion and is thus suitable for use only in applications +** that use SQLite in a single thread. The routines defined +** here are place-holders. Applications can substitute working +** mutex routines at start-time using the +** +** sqlite3_config(SQLITE_CONFIG_MUTEX,...) +** +** interface. +** +** If compiled with SQLITE_DEBUG, then additional logic is inserted +** that does error checking on mutexes to make sure they are being +** called correctly. +*/ + +#ifndef SQLITE_MUTEX_OMIT + +#ifndef SQLITE_DEBUG +/* +** Stub routines for all mutex methods. +** +** This routines provide no mutual exclusion or error checking. +*/ +static int noopMutexInit(void){ return SQLITE_OK; } +static int noopMutexEnd(void){ return SQLITE_OK; } +static sqlite3_mutex *noopMutexAlloc(int id){ + UNUSED_PARAMETER(id); + return (sqlite3_mutex*)8; +} +static void noopMutexFree(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } +static void noopMutexEnter(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } +static int noopMutexTry(sqlite3_mutex *p){ + UNUSED_PARAMETER(p); + return SQLITE_OK; +} +static void noopMutexLeave(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } + +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void){ + static const sqlite3_mutex_methods sMutex = { + noopMutexInit, + noopMutexEnd, + noopMutexAlloc, + noopMutexFree, + noopMutexEnter, + noopMutexTry, + noopMutexLeave, + + 0, + 0, + }; + + return &sMutex; +} +#endif /* !SQLITE_DEBUG */ + +#ifdef SQLITE_DEBUG +/* +** In this implementation, error checking is provided for testing +** and debugging purposes. The mutexes still do not provide any +** mutual exclusion. +*/ + +/* +** The mutex object +*/ +typedef struct sqlite3_debug_mutex { + int id; /* The mutex type */ + int cnt; /* Number of entries without a matching leave */ +} sqlite3_debug_mutex; + +/* +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are +** intended for use inside assert() statements. +*/ +static int debugMutexHeld(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; + return p==0 || p->cnt>0; +} +static int debugMutexNotheld(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; + return p==0 || p->cnt==0; +} + +/* +** Initialize and deinitialize the mutex subsystem. +*/ +static int debugMutexInit(void){ return SQLITE_OK; } +static int debugMutexEnd(void){ return SQLITE_OK; } + +/* +** The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. If it returns NULL +** that means that a mutex could not be allocated. +*/ +static sqlite3_mutex *debugMutexAlloc(int id){ + static sqlite3_debug_mutex aStatic[SQLITE_MUTEX_STATIC_APP3 - 1]; + sqlite3_debug_mutex *pNew = 0; + switch( id ){ + case SQLITE_MUTEX_FAST: + case SQLITE_MUTEX_RECURSIVE: { + pNew = sqlite3Malloc(sizeof(*pNew)); + if( pNew ){ + pNew->id = id; + pNew->cnt = 0; + } + break; + } + default: { +#ifdef SQLITE_ENABLE_API_ARMOR + if( id-2<0 || id-2>=ArraySize(aStatic) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + pNew = &aStatic[id-2]; + pNew->id = id; + break; + } + } + return (sqlite3_mutex*)pNew; +} + +/* +** This routine deallocates a previously allocated mutex. +*/ +static void debugMutexFree(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; + assert( p->cnt==0 ); + if( p->id==SQLITE_MUTEX_RECURSIVE || p->id==SQLITE_MUTEX_FAST ){ + sqlite3_free(p); + }else{ +#ifdef SQLITE_ENABLE_API_ARMOR + (void)SQLITE_MISUSE_BKPT; +#endif + } +} + +/* +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK +** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can +** be entered multiple times by the same thread. In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter. If the same thread tries to enter any other kind of mutex +** more than once, the behavior is undefined. +*/ +static void debugMutexEnter(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; + assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); + p->cnt++; +} +static int debugMutexTry(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; + assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); + p->cnt++; + return SQLITE_OK; +} + +/* +** The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered or +** is not currently allocated. SQLite will never do either. +*/ +static void debugMutexLeave(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; + assert( debugMutexHeld(pX) ); + p->cnt--; + assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); +} + +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void){ + static const sqlite3_mutex_methods sMutex = { + debugMutexInit, + debugMutexEnd, + debugMutexAlloc, + debugMutexFree, + debugMutexEnter, + debugMutexTry, + debugMutexLeave, + + debugMutexHeld, + debugMutexNotheld + }; + + return &sMutex; +} +#endif /* SQLITE_DEBUG */ + +/* +** If compiled with SQLITE_MUTEX_NOOP, then the no-op mutex implementation +** is used regardless of the run-time threadsafety setting. +*/ +#ifdef SQLITE_MUTEX_NOOP +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ + return sqlite3NoopMutex(); +} +#endif /* defined(SQLITE_MUTEX_NOOP) */ +#endif /* !defined(SQLITE_MUTEX_OMIT) */ + +/************** End of mutex_noop.c ******************************************/ +/************** Begin file mutex_unix.c **************************************/ +/* +** 2007 August 28 +** +** 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 C functions that implement mutexes for pthreads +*/ + +/* +** The code in this file is only used if we are compiling threadsafe +** under unix with pthreads. +** +** Note that this implementation requires a version of pthreads that +** supports recursive mutexes. +*/ +#ifdef SQLITE_MUTEX_PTHREADS + +#include + +/* +** The sqlite3_mutex.id, sqlite3_mutex.nRef, and sqlite3_mutex.owner fields +** are necessary under two condidtions: (1) Debug builds and (2) using +** home-grown mutexes. Encapsulate these conditions into a single #define. +*/ +#if defined(SQLITE_DEBUG) || defined(SQLITE_HOMEGROWN_RECURSIVE_MUTEX) +# define SQLITE_MUTEX_NREF 1 +#else +# define SQLITE_MUTEX_NREF 0 +#endif + +/* +** Each recursive mutex is an instance of the following structure. +*/ +struct sqlite3_mutex { + pthread_mutex_t mutex; /* Mutex controlling the lock */ +#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR) + int id; /* Mutex type */ +#endif +#if SQLITE_MUTEX_NREF + volatile int nRef; /* Number of entrances */ + volatile pthread_t owner; /* Thread that is within this mutex */ + int trace; /* True to trace changes */ +#endif +}; +#if SQLITE_MUTEX_NREF +#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0, 0 } +#else +#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER } +#endif + +/* +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are +** intended for use only inside assert() statements. On some platforms, +** there might be race conditions that can cause these routines to +** deliver incorrect results. In particular, if pthread_equal() is +** not an atomic operation, then these routines might delivery +** incorrect results. On most platforms, pthread_equal() is a +** comparison of two integers and is therefore atomic. But we are +** told that HPUX is not such a platform. If so, then these routines +** will not always work correctly on HPUX. +** +** On those platforms where pthread_equal() is not atomic, SQLite +** should be compiled without -DSQLITE_DEBUG and with -DNDEBUG to +** make sure no assert() statements are evaluated and hence these +** routines are never called. +*/ +#if !defined(NDEBUG) || defined(SQLITE_DEBUG) +static int pthreadMutexHeld(sqlite3_mutex *p){ + return (p->nRef!=0 && pthread_equal(p->owner, pthread_self())); +} +static int pthreadMutexNotheld(sqlite3_mutex *p){ + return p->nRef==0 || pthread_equal(p->owner, pthread_self())==0; +} +#endif + +/* +** Initialize and deinitialize the mutex subsystem. +*/ +static int pthreadMutexInit(void){ return SQLITE_OK; } +static int pthreadMutexEnd(void){ return SQLITE_OK; } + +/* +** The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. If it returns NULL +** that means that a mutex could not be allocated. SQLite +** will unwind its stack and return an error. The argument +** to sqlite3_mutex_alloc() is one of these integer constants: +** +**
      +**
    • SQLITE_MUTEX_FAST +**
    • SQLITE_MUTEX_RECURSIVE +**
    • SQLITE_MUTEX_STATIC_MASTER +**
    • SQLITE_MUTEX_STATIC_MEM +**
    • SQLITE_MUTEX_STATIC_OPEN +**
    • SQLITE_MUTEX_STATIC_PRNG +**
    • SQLITE_MUTEX_STATIC_LRU +**
    • SQLITE_MUTEX_STATIC_PMEM +**
    • SQLITE_MUTEX_STATIC_APP1 +**
    • SQLITE_MUTEX_STATIC_APP2 +**
    • SQLITE_MUTEX_STATIC_APP3 +**
    +** +** The first two constants cause sqlite3_mutex_alloc() to create +** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. But SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** The other allowed parameters to sqlite3_mutex_alloc() each return +** a pointer to a static preexisting mutex. Six static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. But for the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +*/ +static sqlite3_mutex *pthreadMutexAlloc(int iType){ + static sqlite3_mutex staticMutexes[] = { + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER + }; + sqlite3_mutex *p; + switch( iType ){ + case SQLITE_MUTEX_RECURSIVE: { + p = sqlite3MallocZero( sizeof(*p) ); + if( p ){ +#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX + /* If recursive mutexes are not available, we will have to + ** build our own. See below. */ + pthread_mutex_init(&p->mutex, 0); +#else + /* Use a recursive mutex if it is available */ + pthread_mutexattr_t recursiveAttr; + pthread_mutexattr_init(&recursiveAttr); + pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&p->mutex, &recursiveAttr); + pthread_mutexattr_destroy(&recursiveAttr); +#endif + } + break; + } + case SQLITE_MUTEX_FAST: { + p = sqlite3MallocZero( sizeof(*p) ); + if( p ){ + pthread_mutex_init(&p->mutex, 0); + } + break; + } + default: { +#ifdef SQLITE_ENABLE_API_ARMOR + if( iType-2<0 || iType-2>=ArraySize(staticMutexes) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + p = &staticMutexes[iType-2]; + break; + } + } +#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR) + if( p ) p->id = iType; +#endif + return p; +} + + +/* +** This routine deallocates a previously +** allocated mutex. SQLite is careful to deallocate every +** mutex that it allocates. +*/ +static void pthreadMutexFree(sqlite3_mutex *p){ + assert( p->nRef==0 ); +#if SQLITE_ENABLE_API_ARMOR + if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ) +#endif + { + pthread_mutex_destroy(&p->mutex); + sqlite3_free(p); + } +#ifdef SQLITE_ENABLE_API_ARMOR + else{ + (void)SQLITE_MISUSE_BKPT; + } +#endif +} + +/* +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK +** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can +** be entered multiple times by the same thread. In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter. If the same thread tries to enter any other kind of mutex +** more than once, the behavior is undefined. +*/ +static void pthreadMutexEnter(sqlite3_mutex *p){ + assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) ); + +#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX + /* If recursive mutexes are not available, then we have to grow + ** our own. This implementation assumes that pthread_equal() + ** is atomic - that it cannot be deceived into thinking self + ** and p->owner are equal if p->owner changes between two values + ** that are not equal to self while the comparison is taking place. + ** This implementation also assumes a coherent cache - that + ** separate processes cannot read different values from the same + ** address at the same time. If either of these two conditions + ** are not met, then the mutexes will fail and problems will result. + */ + { + pthread_t self = pthread_self(); + if( p->nRef>0 && pthread_equal(p->owner, self) ){ + p->nRef++; + }else{ + pthread_mutex_lock(&p->mutex); + assert( p->nRef==0 ); + p->owner = self; + p->nRef = 1; + } + } +#else + /* Use the built-in recursive mutexes if they are available. + */ + pthread_mutex_lock(&p->mutex); +#if SQLITE_MUTEX_NREF + assert( p->nRef>0 || p->owner==0 ); + p->owner = pthread_self(); + p->nRef++; +#endif +#endif + +#ifdef SQLITE_DEBUG + if( p->trace ){ + printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); + } +#endif +} +static int pthreadMutexTry(sqlite3_mutex *p){ + int rc; + assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) ); + +#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX + /* If recursive mutexes are not available, then we have to grow + ** our own. This implementation assumes that pthread_equal() + ** is atomic - that it cannot be deceived into thinking self + ** and p->owner are equal if p->owner changes between two values + ** that are not equal to self while the comparison is taking place. + ** This implementation also assumes a coherent cache - that + ** separate processes cannot read different values from the same + ** address at the same time. If either of these two conditions + ** are not met, then the mutexes will fail and problems will result. + */ + { + pthread_t self = pthread_self(); + if( p->nRef>0 && pthread_equal(p->owner, self) ){ + p->nRef++; + rc = SQLITE_OK; + }else if( pthread_mutex_trylock(&p->mutex)==0 ){ + assert( p->nRef==0 ); + p->owner = self; + p->nRef = 1; + rc = SQLITE_OK; + }else{ + rc = SQLITE_BUSY; + } + } +#else + /* Use the built-in recursive mutexes if they are available. + */ + if( pthread_mutex_trylock(&p->mutex)==0 ){ +#if SQLITE_MUTEX_NREF + p->owner = pthread_self(); + p->nRef++; +#endif + rc = SQLITE_OK; + }else{ + rc = SQLITE_BUSY; + } +#endif + +#ifdef SQLITE_DEBUG + if( rc==SQLITE_OK && p->trace ){ + printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); + } +#endif + return rc; +} + +/* +** The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered or +** is not currently allocated. SQLite will never do either. +*/ +static void pthreadMutexLeave(sqlite3_mutex *p){ + assert( pthreadMutexHeld(p) ); +#if SQLITE_MUTEX_NREF + p->nRef--; + if( p->nRef==0 ) p->owner = 0; +#endif + assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); + +#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX + if( p->nRef==0 ){ + pthread_mutex_unlock(&p->mutex); + } +#else + pthread_mutex_unlock(&p->mutex); +#endif + +#ifdef SQLITE_DEBUG + if( p->trace ){ + printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); + } +#endif +} + +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ + static const sqlite3_mutex_methods sMutex = { + pthreadMutexInit, + pthreadMutexEnd, + pthreadMutexAlloc, + pthreadMutexFree, + pthreadMutexEnter, + pthreadMutexTry, + pthreadMutexLeave, +#ifdef SQLITE_DEBUG + pthreadMutexHeld, + pthreadMutexNotheld +#else + 0, + 0 +#endif + }; + + return &sMutex; +} + +#endif /* SQLITE_MUTEX_PTHREADS */ + +/************** End of mutex_unix.c ******************************************/ +/************** Begin file mutex_w32.c ***************************************/ +/* +** 2007 August 14 +** +** 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 C functions that implement mutexes for Win32. +*/ + +#if SQLITE_OS_WIN +/* +** Include code that is common to all os_*.c files +*/ +/************** Include os_common.h in the middle of mutex_w32.c *************/ +/************** Begin file os_common.h ***************************************/ +/* +** 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 file contains macros and a little bit of code that is common to +** all of the platform-specific files (os_*.c) and is #included into those +** files. +** +** This file should be #included by the os_*.c files only. It is not a +** general purpose header file. +*/ +#ifndef _OS_COMMON_H_ +#define _OS_COMMON_H_ + +/* +** At least two bugs have slipped in because we changed the MEMORY_DEBUG +** macro to SQLITE_DEBUG and some older makefiles have not yet made the +** 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 + +/* +** Macros for performance tracing. Normally turned off. Only works +** on i486 hardware. +*/ +#ifdef SQLITE_PERFORMANCE_TRACE + +/* +** hwtime.h contains inline assembler code for implementing +** high-performance timing routines. +*/ +/************** Include hwtime.h in the middle of os_common.h ****************/ +/************** Begin file hwtime.h ******************************************/ +/* +** 2008 May 27 +** +** 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 inline asm code for retrieving "high-performance" +** counters for x86 class CPUs. +*/ +#ifndef _HWTIME_H_ +#define _HWTIME_H_ + +/* +** The following routine only works on pentium-class (or newer) processors. +** It uses the RDTSC opcode to read the cycle count value out of the +** processor and returns that value. This can be used for high-res +** profiling. +*/ +#if (defined(__GNUC__) || defined(_MSC_VER)) && \ + (defined(i386) || defined(__i386__) || defined(_M_IX86)) + + #if defined(__GNUC__) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned int lo, hi; + __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); + return (sqlite_uint64)hi << 32 | lo; + } + + #elif defined(_MSC_VER) + + __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ + __asm { + rdtsc + ret ; return value at EDX:EAX + } + } + + #endif + +#elif (defined(__GNUC__) && defined(__x86_64__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned long val; + __asm__ __volatile__ ("rdtsc" : "=A" (val)); + return val; + } + +#elif (defined(__GNUC__) && defined(__ppc__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned long long retval; + unsigned long junk; + __asm__ __volatile__ ("\n\ + 1: mftbu %1\n\ + mftb %L0\n\ + mftbu %0\n\ + cmpw %0,%1\n\ + bne 1b" + : "=r" (retval), "=r" (junk)); + return retval; + } + +#else + + #error Need implementation of sqlite3Hwtime() for your platform. + + /* + ** To compile without implementing sqlite3Hwtime() for your platform, + ** you can remove the above #error and use the following + ** stub function. You will lose timing support for many + ** of the debugging and testing utilities, but it should at + ** least compile and run. + */ +SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } + +#endif + +#endif /* !defined(_HWTIME_H_) */ + +/************** End of hwtime.h **********************************************/ +/************** Continuing where we left off in os_common.h ******************/ + +static sqlite_uint64 g_start; +static sqlite_uint64 g_elapsed; +#define TIMER_START g_start=sqlite3Hwtime() +#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start +#define TIMER_ELAPSED g_elapsed +#else +#define TIMER_START +#define TIMER_END +#define TIMER_ELAPSED ((sqlite_uint64)0) +#endif + +/* +** 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 +SQLITE_API int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */ +SQLITE_API int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */ +SQLITE_API int sqlite3_io_error_pending = 0; /* Count down to first I/O error */ +SQLITE_API int sqlite3_io_error_persist = 0; /* True if I/O errors persist */ +SQLITE_API int sqlite3_io_error_benign = 0; /* True if errors are benign */ +SQLITE_API int sqlite3_diskfull_pending = 0; +SQLITE_API int sqlite3_diskfull = 0; +#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) +#define SimulateIOError(CODE) \ + if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ + || sqlite3_io_error_pending-- == 1 ) \ + { local_ioerr(); CODE; } +static void local_ioerr(){ + IOTRACE(("IOERR\n")); + sqlite3_io_error_hit++; + if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; +} +#define SimulateDiskfullError(CODE) \ + if( sqlite3_diskfull_pending ){ \ + if( sqlite3_diskfull_pending == 1 ){ \ + local_ioerr(); \ + sqlite3_diskfull = 1; \ + sqlite3_io_error_hit = 1; \ + CODE; \ + }else{ \ + sqlite3_diskfull_pending--; \ + } \ + } +#else +#define SimulateIOErrorBenign(X) +#define SimulateIOError(A) +#define SimulateDiskfullError(A) +#endif + +/* +** When testing, keep a count of the number of open files. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_open_file_count = 0; +#define OpenCounter(X) sqlite3_open_file_count+=(X) +#else +#define OpenCounter(X) +#endif + +#endif /* !defined(_OS_COMMON_H_) */ + +/************** End of os_common.h *******************************************/ +/************** Continuing where we left off in mutex_w32.c ******************/ + +/* +** Include the header file for the Windows VFS. +*/ +/************** Include os_win.h in the middle of mutex_w32.c ****************/ +/************** Begin file os_win.h ******************************************/ +/* +** 2013 November 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 code that is specific to Windows. +*/ +#ifndef _OS_WIN_H_ +#define _OS_WIN_H_ + +/* +** Include the primary Windows SDK header file. +*/ +#include "windows.h" + +#ifdef __CYGWIN__ +# include +# include /* amalgamator: dontcache */ +#endif + +/* +** Determine if we are dealing with Windows NT. +** +** We ought to be able to determine if we are compiling for Windows 9x or +** Windows NT using the _WIN32_WINNT macro as follows: +** +** #if defined(_WIN32_WINNT) +** # define SQLITE_OS_WINNT 1 +** #else +** # define SQLITE_OS_WINNT 0 +** #endif +** +** However, Visual Studio 2005 does not set _WIN32_WINNT by default, as +** it ought to, so the above test does not work. We'll just assume that +** everything is Windows NT unless the programmer explicitly says otherwise +** by setting SQLITE_OS_WINNT to 0. +*/ +#if SQLITE_OS_WIN && !defined(SQLITE_OS_WINNT) +# define SQLITE_OS_WINNT 1 +#endif + +/* +** Determine if we are dealing with Windows CE - which has a much reduced +** API. +*/ +#if defined(_WIN32_WCE) +# define SQLITE_OS_WINCE 1 +#else +# define SQLITE_OS_WINCE 0 +#endif + +/* +** Determine if we are dealing with WinRT, which provides only a subset of +** the full Win32 API. +*/ +#if !defined(SQLITE_OS_WINRT) +# define SQLITE_OS_WINRT 0 +#endif + +/* +** For WinCE, some API function parameters do not appear to be declared as +** volatile. +*/ +#if SQLITE_OS_WINCE +# define SQLITE_WIN32_VOLATILE +#else +# define SQLITE_WIN32_VOLATILE volatile +#endif + +/* +** For some Windows sub-platforms, the _beginthreadex() / _endthreadex() +** functions are not available (e.g. those not using MSVC, Cygwin, etc). +*/ +#if SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \ + SQLITE_THREADSAFE>0 && !defined(__CYGWIN__) +# define SQLITE_OS_WIN_THREADS 1 +#else +# define SQLITE_OS_WIN_THREADS 0 +#endif + +#endif /* _OS_WIN_H_ */ + +/************** End of os_win.h **********************************************/ +/************** Continuing where we left off in mutex_w32.c ******************/ +#endif + +/* +** The code in this file is only used if we are compiling multithreaded +** on a Win32 system. +*/ +#ifdef SQLITE_MUTEX_W32 + +/* +** Each recursive mutex is an instance of the following structure. +*/ +struct sqlite3_mutex { + CRITICAL_SECTION mutex; /* Mutex controlling the lock */ + int id; /* Mutex type */ +#ifdef SQLITE_DEBUG + volatile int nRef; /* Number of enterances */ + volatile DWORD owner; /* Thread holding this mutex */ + volatile int trace; /* True to trace changes */ +#endif +}; + +/* +** These are the initializer values used when declaring a "static" mutex +** on Win32. It should be noted that all mutexes require initialization +** on the Win32 platform. +*/ +#define SQLITE_W32_MUTEX_INITIALIZER { 0 } + +#ifdef SQLITE_DEBUG +#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, \ + 0L, (DWORD)0, 0 } +#else +#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 } +#endif + +#ifdef SQLITE_DEBUG +/* +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are +** intended for use only inside assert() statements. +*/ +static int winMutexHeld(sqlite3_mutex *p){ + return p->nRef!=0 && p->owner==GetCurrentThreadId(); +} + +static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){ + return p->nRef==0 || p->owner!=tid; +} + +static int winMutexNotheld(sqlite3_mutex *p){ + DWORD tid = GetCurrentThreadId(); + return winMutexNotheld2(p, tid); +} +#endif + +/* +** Initialize and deinitialize the mutex subsystem. +*/ +static sqlite3_mutex winMutex_staticMutexes[] = { + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER, + SQLITE3_MUTEX_INITIALIZER +}; + +static int winMutex_isInit = 0; +static int winMutex_isNt = -1; /* <0 means "need to query" */ + +/* As the winMutexInit() and winMutexEnd() functions are called as part +** of the sqlite3_initialize() and sqlite3_shutdown() processing, the +** "interlocked" magic used here is probably not strictly necessary. +*/ +static LONG SQLITE_WIN32_VOLATILE winMutex_lock = 0; + +SQLITE_API int SQLITE_STDCALL sqlite3_win32_is_nt(void); /* os_win.c */ +SQLITE_API void SQLITE_STDCALL sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ + +static int winMutexInit(void){ + /* The first to increment to 1 does actual initialization */ + if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){ + int i; + for(i=0; i +**
  1. SQLITE_MUTEX_FAST +**
  2. SQLITE_MUTEX_RECURSIVE +**
  3. SQLITE_MUTEX_STATIC_MASTER +**
  4. SQLITE_MUTEX_STATIC_MEM +**
  5. SQLITE_MUTEX_STATIC_OPEN +**
  6. SQLITE_MUTEX_STATIC_PRNG +**
  7. SQLITE_MUTEX_STATIC_LRU +**
  8. SQLITE_MUTEX_STATIC_PMEM +**
  9. SQLITE_MUTEX_STATIC_APP1 +**
  10. SQLITE_MUTEX_STATIC_APP2 +**
  11. SQLITE_MUTEX_STATIC_APP3 +** +** +** The first two constants cause sqlite3_mutex_alloc() to create +** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. But SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** The other allowed parameters to sqlite3_mutex_alloc() each return +** a pointer to a static preexisting mutex. Six static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. But for the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +*/ +static sqlite3_mutex *winMutexAlloc(int iType){ + sqlite3_mutex *p; + + switch( iType ){ + case SQLITE_MUTEX_FAST: + case SQLITE_MUTEX_RECURSIVE: { + p = sqlite3MallocZero( sizeof(*p) ); + if( p ){ + p->id = iType; +#ifdef SQLITE_DEBUG +#ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC + p->trace = 1; +#endif +#endif +#if SQLITE_OS_WINRT + InitializeCriticalSectionEx(&p->mutex, 0, 0); +#else + InitializeCriticalSection(&p->mutex); +#endif + } + break; + } + default: { +#ifdef SQLITE_ENABLE_API_ARMOR + if( iType-2<0 || iType-2>=ArraySize(winMutex_staticMutexes) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + p = &winMutex_staticMutexes[iType-2]; + p->id = iType; +#ifdef SQLITE_DEBUG +#ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC + p->trace = 1; +#endif +#endif + break; + } + } + return p; +} + + +/* +** This routine deallocates a previously +** allocated mutex. SQLite is careful to deallocate every +** mutex that it allocates. +*/ +static void winMutexFree(sqlite3_mutex *p){ + assert( p ); + assert( p->nRef==0 && p->owner==0 ); + if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ){ + DeleteCriticalSection(&p->mutex); + sqlite3_free(p); + }else{ +#ifdef SQLITE_ENABLE_API_ARMOR + (void)SQLITE_MISUSE_BKPT; +#endif + } +} + +/* +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK +** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can +** be entered multiple times by the same thread. In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter. If the same thread tries to enter any other kind of mutex +** more than once, the behavior is undefined. +*/ +static void winMutexEnter(sqlite3_mutex *p){ +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + DWORD tid = GetCurrentThreadId(); +#endif +#ifdef SQLITE_DEBUG + assert( p ); + assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); +#else + assert( p ); +#endif + assert( winMutex_isInit==1 ); + EnterCriticalSection(&p->mutex); +#ifdef SQLITE_DEBUG + assert( p->nRef>0 || p->owner==0 ); + p->owner = tid; + p->nRef++; + if( p->trace ){ + OSTRACE(("ENTER-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n", + tid, p, p->trace, p->nRef)); + } +#endif +} + +static int winMutexTry(sqlite3_mutex *p){ +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + DWORD tid = GetCurrentThreadId(); +#endif + int rc = SQLITE_BUSY; + assert( p ); + assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); + /* + ** The sqlite3_mutex_try() routine is very rarely used, and when it + ** is used it is merely an optimization. So it is OK for it to always + ** fail. + ** + ** The TryEnterCriticalSection() interface is only available on WinNT. + ** And some windows compilers complain if you try to use it without + ** first doing some #defines that prevent SQLite from building on Win98. + ** For that reason, we will omit this optimization for now. See + ** ticket #2685. + */ +#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0400 + assert( winMutex_isInit==1 ); + assert( winMutex_isNt>=-1 && winMutex_isNt<=1 ); + if( winMutex_isNt<0 ){ + winMutex_isNt = sqlite3_win32_is_nt(); + } + assert( winMutex_isNt==0 || winMutex_isNt==1 ); + if( winMutex_isNt && TryEnterCriticalSection(&p->mutex) ){ +#ifdef SQLITE_DEBUG + p->owner = tid; + p->nRef++; +#endif + rc = SQLITE_OK; + } +#else + UNUSED_PARAMETER(p); +#endif +#ifdef SQLITE_DEBUG + if( p->trace ){ + OSTRACE(("TRY-MUTEX tid=%lu, mutex=%p (%d), owner=%lu, nRef=%d, rc=%s\n", + tid, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc))); + } +#endif + return rc; +} + +/* +** The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered or +** is not currently allocated. SQLite will never do either. +*/ +static void winMutexLeave(sqlite3_mutex *p){ +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + DWORD tid = GetCurrentThreadId(); +#endif + assert( p ); +#ifdef SQLITE_DEBUG + assert( p->nRef>0 ); + assert( p->owner==tid ); + p->nRef--; + if( p->nRef==0 ) p->owner = 0; + assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); +#endif + assert( winMutex_isInit==1 ); + LeaveCriticalSection(&p->mutex); +#ifdef SQLITE_DEBUG + if( p->trace ){ + OSTRACE(("LEAVE-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n", + tid, p, p->trace, p->nRef)); + } +#endif +} + +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ + static const sqlite3_mutex_methods sMutex = { + winMutexInit, + winMutexEnd, + winMutexAlloc, + winMutexFree, + winMutexEnter, + winMutexTry, + winMutexLeave, +#ifdef SQLITE_DEBUG + winMutexHeld, + winMutexNotheld +#else + 0, + 0 +#endif + }; + return &sMutex; +} + +#endif /* SQLITE_MUTEX_W32 */ + +/************** End of mutex_w32.c *******************************************/ +/************** Begin file malloc.c ******************************************/ +/* +** 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. +** +************************************************************************* +** +** Memory allocation functions used throughout sqlite. +*/ +/* #include */ + +/* +** Attempt to release up to n bytes of non-essential memory currently +** held by SQLite. An example of non-essential memory is memory used to +** cache database pages that are not currently in use. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int n){ +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT + return sqlite3PcacheReleaseMemory(n); +#else + /* IMPLEMENTATION-OF: R-34391-24921 The sqlite3_release_memory() routine + ** is a no-op returning zero if SQLite is not compiled with + ** SQLITE_ENABLE_MEMORY_MANAGEMENT. */ + UNUSED_PARAMETER(n); + return 0; +#endif +} + +/* +** An instance of the following object records the location of +** each unused scratch buffer. +*/ +typedef struct ScratchFreeslot { + struct ScratchFreeslot *pNext; /* Next unused scratch buffer */ +} ScratchFreeslot; + +/* +** State information local to the memory allocation subsystem. +*/ +static SQLITE_WSD struct Mem0Global { + sqlite3_mutex *mutex; /* Mutex to serialize access */ + + /* + ** The alarm callback and its arguments. The mem0.mutex lock will + ** be held while the callback is running. Recursive calls into + ** the memory subsystem are allowed, but no new callbacks will be + ** issued. + */ + sqlite3_int64 alarmThreshold; + void (*alarmCallback)(void*, sqlite3_int64,int); + void *alarmArg; + + /* + ** Pointers to the end of sqlite3GlobalConfig.pScratch memory + ** (so that a range test can be used to determine if an allocation + ** being freed came from pScratch) and a pointer to the list of + ** unused scratch allocations. + */ + void *pScratchEnd; + ScratchFreeslot *pScratchFree; + u32 nScratchFree; + + /* + ** True if heap is nearly "full" where "full" is defined by the + ** sqlite3_soft_heap_limit() setting. + */ + int nearlyFull; +} mem0 = { 0, 0, 0, 0, 0, 0, 0, 0 }; + +#define mem0 GLOBAL(struct Mem0Global, mem0) + +/* +** Return the memory allocator mutex. sqlite3_status() needs it. +*/ +SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void){ + return mem0.mutex; +} + +/* +** This routine runs when the memory allocator sees that the +** total memory allocation is about to exceed the soft heap +** limit. +*/ +static void softHeapLimitEnforcer( + void *NotUsed, + sqlite3_int64 NotUsed2, + int allocSize +){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + sqlite3_release_memory(allocSize); +} + +/* +** Change the alarm callback +*/ +static int sqlite3MemoryAlarm( + void(*xCallback)(void *pArg, sqlite3_int64 used,int N), + void *pArg, + sqlite3_int64 iThreshold +){ + sqlite3_int64 nUsed; + sqlite3_mutex_enter(mem0.mutex); + mem0.alarmCallback = xCallback; + mem0.alarmArg = pArg; + mem0.alarmThreshold = iThreshold; + nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); + mem0.nearlyFull = (iThreshold>0 && iThreshold<=nUsed); + sqlite3_mutex_leave(mem0.mutex); + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** Deprecated external interface. Internal/core SQLite code +** should call sqlite3MemoryAlarm. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_memory_alarm( + void(*xCallback)(void *pArg, sqlite3_int64 used,int N), + void *pArg, + sqlite3_int64 iThreshold +){ + return sqlite3MemoryAlarm(xCallback, pArg, iThreshold); +} +#endif + +/* +** Set the soft heap-size limit for the library. Passing a zero or +** negative value indicates no limit. +*/ +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 n){ + sqlite3_int64 priorLimit; + sqlite3_int64 excess; +#ifndef SQLITE_OMIT_AUTOINIT + int rc = sqlite3_initialize(); + if( rc ) return -1; +#endif + sqlite3_mutex_enter(mem0.mutex); + priorLimit = mem0.alarmThreshold; + sqlite3_mutex_leave(mem0.mutex); + if( n<0 ) return priorLimit; + if( n>0 ){ + sqlite3MemoryAlarm(softHeapLimitEnforcer, 0, n); + }else{ + sqlite3MemoryAlarm(0, 0, 0); + } + excess = sqlite3_memory_used() - n; + if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff)); + return priorLimit; +} +SQLITE_API void SQLITE_STDCALL sqlite3_soft_heap_limit(int n){ + if( n<0 ) n = 0; + sqlite3_soft_heap_limit64(n); +} + +/* +** Initialize the memory allocation subsystem. +*/ +SQLITE_PRIVATE int sqlite3MallocInit(void){ + int rc; + if( sqlite3GlobalConfig.m.xMalloc==0 ){ + sqlite3MemSetDefault(); + } + memset(&mem0, 0, sizeof(mem0)); + if( sqlite3GlobalConfig.bCoreMutex ){ + mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); + } + if( sqlite3GlobalConfig.pScratch && sqlite3GlobalConfig.szScratch>=100 + && sqlite3GlobalConfig.nScratch>0 ){ + int i, n, sz; + ScratchFreeslot *pSlot; + sz = ROUNDDOWN8(sqlite3GlobalConfig.szScratch); + sqlite3GlobalConfig.szScratch = sz; + pSlot = (ScratchFreeslot*)sqlite3GlobalConfig.pScratch; + n = sqlite3GlobalConfig.nScratch; + mem0.pScratchFree = pSlot; + mem0.nScratchFree = n; + for(i=0; ipNext = (ScratchFreeslot*)(sz+(char*)pSlot); + pSlot = pSlot->pNext; + } + pSlot->pNext = 0; + mem0.pScratchEnd = (void*)&pSlot[1]; + }else{ + mem0.pScratchEnd = 0; + sqlite3GlobalConfig.pScratch = 0; + sqlite3GlobalConfig.szScratch = 0; + sqlite3GlobalConfig.nScratch = 0; + } + if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512 + || sqlite3GlobalConfig.nPage<1 ){ + sqlite3GlobalConfig.pPage = 0; + sqlite3GlobalConfig.szPage = 0; + sqlite3GlobalConfig.nPage = 0; + } + rc = sqlite3GlobalConfig.m.xInit(sqlite3GlobalConfig.m.pAppData); + if( rc!=SQLITE_OK ) memset(&mem0, 0, sizeof(mem0)); + return rc; +} + +/* +** Return true if the heap is currently under memory pressure - in other +** words if the amount of heap used is close to the limit set by +** sqlite3_soft_heap_limit(). +*/ +SQLITE_PRIVATE int sqlite3HeapNearlyFull(void){ + return mem0.nearlyFull; +} + +/* +** Deinitialize the memory allocation subsystem. +*/ +SQLITE_PRIVATE void sqlite3MallocEnd(void){ + if( sqlite3GlobalConfig.m.xShutdown ){ + sqlite3GlobalConfig.m.xShutdown(sqlite3GlobalConfig.m.pAppData); + } + memset(&mem0, 0, sizeof(mem0)); +} + +/* +** Return the amount of memory currently checked out. +*/ +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void){ + int n, mx; + sqlite3_int64 res; + sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, 0); + res = (sqlite3_int64)n; /* Work around bug in Borland C. Ticket #3216 */ + return res; +} + +/* +** Return the maximum amount of memory that has ever been +** checked out since either the beginning of this process +** or since the most recent reset. +*/ +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag){ + int n, mx; + sqlite3_int64 res; + sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, resetFlag); + res = (sqlite3_int64)mx; /* Work around bug in Borland C. Ticket #3216 */ + return res; +} + +/* +** Trigger the alarm +*/ +static void sqlite3MallocAlarm(int nByte){ + void (*xCallback)(void*,sqlite3_int64,int); + sqlite3_int64 nowUsed; + void *pArg; + if( mem0.alarmCallback==0 ) return; + xCallback = mem0.alarmCallback; + nowUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); + pArg = mem0.alarmArg; + mem0.alarmCallback = 0; + sqlite3_mutex_leave(mem0.mutex); + xCallback(pArg, nowUsed, nByte); + sqlite3_mutex_enter(mem0.mutex); + mem0.alarmCallback = xCallback; + mem0.alarmArg = pArg; +} + +/* +** Do a memory allocation with statistics and alarms. Assume the +** lock is already held. +*/ +static int mallocWithAlarm(int n, void **pp){ + int nFull; + void *p; + assert( sqlite3_mutex_held(mem0.mutex) ); + nFull = sqlite3GlobalConfig.m.xRoundup(n); + sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n); + if( mem0.alarmCallback!=0 ){ + sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); + if( nUsed >= mem0.alarmThreshold - nFull ){ + mem0.nearlyFull = 1; + sqlite3MallocAlarm(nFull); + }else{ + mem0.nearlyFull = 0; + } + } + p = sqlite3GlobalConfig.m.xMalloc(nFull); +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT + if( p==0 && mem0.alarmCallback ){ + sqlite3MallocAlarm(nFull); + p = sqlite3GlobalConfig.m.xMalloc(nFull); + } +#endif + if( p ){ + nFull = sqlite3MallocSize(p); + sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nFull); + sqlite3StatusUp(SQLITE_STATUS_MALLOC_COUNT, 1); + } + *pp = p; + return nFull; +} + +/* +** Allocate memory. This routine is like sqlite3_malloc() except that it +** assumes the memory subsystem has already been initialized. +*/ +SQLITE_PRIVATE void *sqlite3Malloc(u64 n){ + void *p; + if( n==0 || n>=0x7fffff00 ){ + /* A memory allocation of a number of bytes which is near the maximum + ** signed integer value might cause an integer overflow inside of the + ** xMalloc(). Hence we limit the maximum size to 0x7fffff00, giving + ** 255 bytes of overhead. SQLite itself will never use anything near + ** this amount. The only way to reach the limit is with sqlite3_malloc() */ + p = 0; + }else if( sqlite3GlobalConfig.bMemstat ){ + sqlite3_mutex_enter(mem0.mutex); + mallocWithAlarm((int)n, &p); + sqlite3_mutex_leave(mem0.mutex); + }else{ + p = sqlite3GlobalConfig.m.xMalloc((int)n); + } + assert( EIGHT_BYTE_ALIGNMENT(p) ); /* IMP: R-11148-40995 */ + return p; +} + +/* +** This version of the memory allocation is for use by the application. +** First make sure the memory subsystem is initialized, then do the +** allocation. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int n){ +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return n<=0 ? 0 : sqlite3Malloc(n); +} +SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64 n){ +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return sqlite3Malloc(n); +} + +/* +** Each thread may only have a single outstanding allocation from +** xScratchMalloc(). We verify this constraint in the single-threaded +** case by setting scratchAllocOut to 1 when an allocation +** is outstanding clearing it when the allocation is freed. +*/ +#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) +static int scratchAllocOut = 0; +#endif + + +/* +** Allocate memory that is to be used and released right away. +** This routine is similar to alloca() in that it is not intended +** for situations where the memory might be held long-term. This +** routine is intended to get memory to old large transient data +** structures that would not normally fit on the stack of an +** embedded processor. +*/ +SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){ + void *p; + assert( n>0 ); + + sqlite3_mutex_enter(mem0.mutex); + sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n); + if( mem0.nScratchFree && sqlite3GlobalConfig.szScratch>=n ){ + p = mem0.pScratchFree; + mem0.pScratchFree = mem0.pScratchFree->pNext; + mem0.nScratchFree--; + sqlite3StatusUp(SQLITE_STATUS_SCRATCH_USED, 1); + sqlite3_mutex_leave(mem0.mutex); + }else{ + sqlite3_mutex_leave(mem0.mutex); + p = sqlite3Malloc(n); + if( sqlite3GlobalConfig.bMemstat && p ){ + sqlite3_mutex_enter(mem0.mutex); + sqlite3StatusUp(SQLITE_STATUS_SCRATCH_OVERFLOW, sqlite3MallocSize(p)); + sqlite3_mutex_leave(mem0.mutex); + } + sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH); + } + assert( sqlite3_mutex_notheld(mem0.mutex) ); + + +#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) + /* EVIDENCE-OF: R-12970-05880 SQLite will not use more than one scratch + ** buffers per thread. + ** + ** This can only be checked in single-threaded mode. + */ + assert( scratchAllocOut==0 ); + if( p ) scratchAllocOut++; +#endif + + return p; +} +SQLITE_PRIVATE void sqlite3ScratchFree(void *p){ + if( p ){ + +#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) + /* Verify that no more than two scratch allocation per thread + ** is outstanding at one time. (This is only checked in the + ** single-threaded case since checking in the multi-threaded case + ** would be much more complicated.) */ + assert( scratchAllocOut>=1 && scratchAllocOut<=2 ); + scratchAllocOut--; +#endif + + if( p>=sqlite3GlobalConfig.pScratch && ppNext = mem0.pScratchFree; + mem0.pScratchFree = pSlot; + mem0.nScratchFree++; + assert( mem0.nScratchFree <= (u32)sqlite3GlobalConfig.nScratch ); + sqlite3StatusDown(SQLITE_STATUS_SCRATCH_USED, 1); + sqlite3_mutex_leave(mem0.mutex); + }else{ + /* Release memory back to the heap */ + assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) ); + assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_SCRATCH) ); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); + if( sqlite3GlobalConfig.bMemstat ){ + int iSize = sqlite3MallocSize(p); + sqlite3_mutex_enter(mem0.mutex); + sqlite3StatusDown(SQLITE_STATUS_SCRATCH_OVERFLOW, iSize); + sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, iSize); + sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1); + sqlite3GlobalConfig.m.xFree(p); + sqlite3_mutex_leave(mem0.mutex); + }else{ + sqlite3GlobalConfig.m.xFree(p); + } + } + } +} + +/* +** TRUE if p is a lookaside memory allocation from db +*/ +#ifndef SQLITE_OMIT_LOOKASIDE +static int isLookaside(sqlite3 *db, void *p){ + return p>=db->lookaside.pStart && plookaside.pEnd; +} +#else +#define isLookaside(A,B) 0 +#endif + +/* +** Return the size of a memory allocation previously obtained from +** sqlite3Malloc() or sqlite3_malloc(). +*/ +SQLITE_PRIVATE int sqlite3MallocSize(void *p){ + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); + return sqlite3GlobalConfig.m.xSize(p); +} +SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){ + if( db==0 ){ + assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); + return sqlite3MallocSize(p); + }else{ + assert( sqlite3_mutex_held(db->mutex) ); + if( isLookaside(db, p) ){ + return db->lookaside.sz; + }else{ + assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + return sqlite3GlobalConfig.m.xSize(p); + } + } +} +SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void *p){ + assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); + return (sqlite3_uint64)sqlite3GlobalConfig.m.xSize(p); +} + +/* +** Free memory previously obtained from sqlite3Malloc(). +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_free(void *p){ + if( p==0 ) return; /* IMP: R-49053-54554 */ + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); + assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); + if( sqlite3GlobalConfig.bMemstat ){ + sqlite3_mutex_enter(mem0.mutex); + sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, sqlite3MallocSize(p)); + sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1); + sqlite3GlobalConfig.m.xFree(p); + sqlite3_mutex_leave(mem0.mutex); + }else{ + sqlite3GlobalConfig.m.xFree(p); + } +} + +/* +** Add the size of memory allocation "p" to the count in +** *db->pnBytesFreed. +*/ +static SQLITE_NOINLINE void measureAllocationSize(sqlite3 *db, void *p){ + *db->pnBytesFreed += sqlite3DbMallocSize(db,p); +} + +/* +** Free memory that might be associated with a particular database +** connection. +*/ +SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){ + assert( db==0 || sqlite3_mutex_held(db->mutex) ); + if( p==0 ) return; + if( db ){ + if( db->pnBytesFreed ){ + measureAllocationSize(db, p); + return; + } + if( isLookaside(db, p) ){ + LookasideSlot *pBuf = (LookasideSlot*)p; +#if SQLITE_DEBUG + /* Trash all content in the buffer being freed */ + memset(p, 0xaa, db->lookaside.sz); +#endif + pBuf->pNext = db->lookaside.pFree; + db->lookaside.pFree = pBuf; + db->lookaside.nOut--; + return; + } + } + assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); + sqlite3_free(p); +} + +/* +** Change the size of an existing memory allocation +*/ +SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){ + int nOld, nNew, nDiff; + void *pNew; + assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) ); + assert( sqlite3MemdebugNoType(pOld, (u8)~MEMTYPE_HEAP) ); + if( pOld==0 ){ + return sqlite3Malloc(nBytes); /* IMP: R-04300-56712 */ + } + if( nBytes==0 ){ + sqlite3_free(pOld); /* IMP: R-26507-47431 */ + return 0; + } + if( nBytes>=0x7fffff00 ){ + /* The 0x7ffff00 limit term is explained in comments on sqlite3Malloc() */ + return 0; + } + nOld = sqlite3MallocSize(pOld); + /* IMPLEMENTATION-OF: R-46199-30249 SQLite guarantees that the second + ** argument to xRealloc is always a value returned by a prior call to + ** xRoundup. */ + nNew = sqlite3GlobalConfig.m.xRoundup((int)nBytes); + if( nOld==nNew ){ + pNew = pOld; + }else if( sqlite3GlobalConfig.bMemstat ){ + sqlite3_mutex_enter(mem0.mutex); + sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes); + nDiff = nNew - nOld; + if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= + mem0.alarmThreshold-nDiff ){ + sqlite3MallocAlarm(nDiff); + } + pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); + if( pNew==0 && mem0.alarmCallback ){ + sqlite3MallocAlarm((int)nBytes); + pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); + } + if( pNew ){ + nNew = sqlite3MallocSize(pNew); + sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld); + } + sqlite3_mutex_leave(mem0.mutex); + }else{ + pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); + } + assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-11148-40995 */ + return pNew; +} + +/* +** The public interface to sqlite3Realloc. Make sure that the memory +** subsystem is initialized prior to invoking sqliteRealloc. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void *pOld, int n){ +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + if( n<0 ) n = 0; /* IMP: R-26507-47431 */ + return sqlite3Realloc(pOld, n); +} +SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void *pOld, sqlite3_uint64 n){ +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return sqlite3Realloc(pOld, n); +} + + +/* +** Allocate and zero memory. +*/ +SQLITE_PRIVATE void *sqlite3MallocZero(u64 n){ + void *p = sqlite3Malloc(n); + if( p ){ + memset(p, 0, (size_t)n); + } + return p; +} + +/* +** Allocate and zero memory. If the allocation fails, make +** the mallocFailed flag in the connection pointer. +*/ +SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3 *db, u64 n){ + void *p = sqlite3DbMallocRaw(db, n); + if( p ){ + memset(p, 0, (size_t)n); + } + return p; +} + +/* +** Allocate and zero memory. If the allocation fails, make +** the mallocFailed flag in the connection pointer. +** +** If db!=0 and db->mallocFailed is true (indicating a prior malloc +** failure on the same database connection) then always return 0. +** Hence for a particular database connection, once malloc starts +** failing, it fails consistently until mallocFailed is reset. +** This is an important assumption. There are many places in the +** code that do things like this: +** +** int *a = (int*)sqlite3DbMallocRaw(db, 100); +** int *b = (int*)sqlite3DbMallocRaw(db, 200); +** if( b ) a[10] = 9; +** +** In other words, if a subsequent malloc (ex: "b") worked, it is assumed +** that all prior mallocs (ex: "a") worked too. +*/ +SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, u64 n){ + void *p; + assert( db==0 || sqlite3_mutex_held(db->mutex) ); + assert( db==0 || db->pnBytesFreed==0 ); +#ifndef SQLITE_OMIT_LOOKASIDE + if( db ){ + LookasideSlot *pBuf; + if( db->mallocFailed ){ + return 0; + } + if( db->lookaside.bEnabled ){ + if( n>db->lookaside.sz ){ + db->lookaside.anStat[1]++; + }else if( (pBuf = db->lookaside.pFree)==0 ){ + db->lookaside.anStat[2]++; + }else{ + db->lookaside.pFree = pBuf->pNext; + db->lookaside.nOut++; + db->lookaside.anStat[0]++; + if( db->lookaside.nOut>db->lookaside.mxOut ){ + db->lookaside.mxOut = db->lookaside.nOut; + } + return (void*)pBuf; + } + } + } +#else + if( db && db->mallocFailed ){ + return 0; + } +#endif + p = sqlite3Malloc(n); + if( !p && db ){ + db->mallocFailed = 1; + } + sqlite3MemdebugSetType(p, + (db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP); + return p; +} + +/* +** Resize the block of memory pointed to by p to n bytes. If the +** resize fails, set the mallocFailed flag in the connection object. +*/ +SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){ + void *pNew = 0; + assert( db!=0 ); + assert( sqlite3_mutex_held(db->mutex) ); + if( db->mallocFailed==0 ){ + if( p==0 ){ + return sqlite3DbMallocRaw(db, n); + } + if( isLookaside(db, p) ){ + if( n<=db->lookaside.sz ){ + return p; + } + pNew = sqlite3DbMallocRaw(db, n); + if( pNew ){ + memcpy(pNew, p, db->lookaside.sz); + sqlite3DbFree(db, p); + } + }else{ + assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); + pNew = sqlite3_realloc64(p, n); + if( !pNew ){ + db->mallocFailed = 1; + } + sqlite3MemdebugSetType(pNew, + (db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP)); + } + } + return pNew; +} + +/* +** Attempt to reallocate p. If the reallocation fails, then free p +** and set the mallocFailed flag in the database connection. +*/ +SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *db, void *p, u64 n){ + void *pNew; + pNew = sqlite3DbRealloc(db, p, n); + if( !pNew ){ + sqlite3DbFree(db, p); + } + return pNew; +} + +/* +** 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. +*/ +SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3 *db, const char *z){ + char *zNew; + size_t n; + if( z==0 ){ + return 0; + } + n = sqlite3Strlen30(z) + 1; + assert( (n&0x7fffffff)==n ); + zNew = sqlite3DbMallocRaw(db, (int)n); + if( zNew ){ + memcpy(zNew, z, n); + } + return zNew; +} +SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, u64 n){ + char *zNew; + if( z==0 ){ + return 0; + } + assert( (n&0x7fffffff)==n ); + zNew = sqlite3DbMallocRaw(db, n+1); + if( zNew ){ + memcpy(zNew, z, (size_t)n); + zNew[n] = 0; + } + return zNew; +} + +/* +** Create a string from the zFromat argument and the va_list that follows. +** Store the string in memory obtained from sqliteMalloc() and make *pz +** point to that string. +*/ +SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zFormat, ...){ + va_list ap; + char *z; + + va_start(ap, zFormat); + z = sqlite3VMPrintf(db, zFormat, ap); + va_end(ap); + sqlite3DbFree(db, *pz); + *pz = z; +} + +/* +** Take actions at the end of an API call to indicate an OOM error +*/ +static SQLITE_NOINLINE int apiOomError(sqlite3 *db){ + db->mallocFailed = 0; + sqlite3Error(db, SQLITE_NOMEM); + return SQLITE_NOMEM; +} + +/* +** This function must be called before exiting any API function (i.e. +** returning control to the user) that has called sqlite3_malloc or +** sqlite3_realloc. +** +** The returned value is normally a copy of the second argument to this +** function. However, if a malloc() failure has occurred since the previous +** invocation SQLITE_NOMEM is returned instead. +** +** If the first argument, db, is not NULL and a malloc() error has occurred, +** then the connection error-code (the value returned by sqlite3_errcode()) +** is set to SQLITE_NOMEM. +*/ +SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){ + /* If the db handle is not NULL, then we must hold the connection handle + ** mutex here. Otherwise the read (and possible write) of db->mallocFailed + ** is unsafe, as is the call to sqlite3Error(). + */ + assert( !db || sqlite3_mutex_held(db->mutex) ); + if( db==0 ) return rc & 0xff; + if( db->mallocFailed || rc==SQLITE_IOERR_NOMEM ){ + return apiOomError(db); + } + return rc & db->errMask; +} + +/************** End of malloc.c **********************************************/ +/************** Begin file printf.c ******************************************/ +/* +** The "printf" code that follows dates from the 1980's. It is in +** the public domain. The original comments are included here for +** completeness. They are very out-of-date but might be useful as +** an historical reference. Most of the "enhancements" have been backed +** out so that the functionality is now the same as standard printf(). +** +************************************************************************** +** +** This file contains code for a set of "printf"-like routines. These +** routines format strings much like the printf() from the standard C +** library, though the implementation here has enhancements to support +** SQLlite. +*/ + +/* +** Conversion types fall into various categories as defined by the +** following enumeration. +*/ +#define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */ +#define etFLOAT 2 /* Floating point. %f */ +#define etEXP 3 /* Exponentional notation. %e and %E */ +#define etGENERIC 4 /* Floating or exponential, depending on exponent. %g */ +#define etSIZE 5 /* Return number of characters processed so far. %n */ +#define etSTRING 6 /* Strings. %s */ +#define etDYNSTRING 7 /* Dynamically allocated strings. %z */ +#define etPERCENT 8 /* Percent symbol. %% */ +#define etCHARX 9 /* Characters. %c */ +/* The rest are extensions, not normally found in printf() */ +#define etSQLESCAPE 10 /* Strings with '\'' doubled. %q */ +#define etSQLESCAPE2 11 /* Strings with '\'' doubled and enclosed in '', + NULL pointers replaced by SQL NULL. %Q */ +#define etTOKEN 12 /* a pointer to a Token structure */ +#define etSRCLIST 13 /* a pointer to a SrcList */ +#define etPOINTER 14 /* The %p conversion */ +#define etSQLESCAPE3 15 /* %w -> Strings with '\"' doubled */ +#define etORDINAL 16 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */ + +#define etINVALID 0 /* Any unrecognized conversion type */ + + +/* +** An "etByte" is an 8-bit unsigned value. +*/ +typedef unsigned char etByte; + +/* +** Each builtin conversion character (ex: the 'd' in "%d") is described +** by an instance of the following structure +*/ +typedef struct et_info { /* Information about each format field */ + char fmttype; /* The format field code letter */ + etByte base; /* The base for radix conversion */ + etByte flags; /* One or more of FLAG_ constants below */ + etByte type; /* Conversion paradigm */ + etByte charset; /* Offset into aDigits[] of the digits string */ + etByte prefix; /* Offset into aPrefix[] of the prefix string */ +} et_info; + +/* +** Allowed values for et_info.flags +*/ +#define FLAG_SIGNED 1 /* True if the value to convert is signed */ +#define FLAG_INTERN 2 /* True if for internal use only */ +#define FLAG_STRING 4 /* Allow infinity precision */ + + +/* +** The following table is searched linearly, so it is good to put the +** 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, 4, etDYNSTRING, 0, 0 }, + { 'q', 0, 4, etSQLESCAPE, 0, 0 }, + { 'Q', 0, 4, etSQLESCAPE2, 0, 0 }, + { 'w', 0, 4, etSQLESCAPE3, 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 }, + +/* All the rest have the FLAG_INTERN bit set and are thus for internal +** use only */ + { 'T', 0, 2, etTOKEN, 0, 0 }, + { 'S', 0, 2, etSRCLIST, 0, 0 }, + { 'r', 10, 3, etORDINAL, 0, 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 +** output: *val = 1.4159 function return = '3' +** +** The counter *cnt is incremented each time. After counter exceeds +** 16 (the number of significant digits in a 64-bit float) '0' is +** always returned. +*/ +static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){ + int digit; + LONGDOUBLE_TYPE d; + if( (*cnt)<=0 ) return '0'; + (*cnt)--; + digit = (int)*val; + d = digit; + digit += '0'; + *val = (*val - d)*10.0; + return (char)digit; +} +#endif /* SQLITE_OMIT_FLOATING_POINT */ + +/* +** Set the StrAccum object to an error mode. +*/ +static void setStrAccumError(StrAccum *p, u8 eError){ + assert( eError==STRACCUM_NOMEM || eError==STRACCUM_TOOBIG ); + p->accError = eError; + p->nAlloc = 0; +} + +/* +** Extra argument values from a PrintfArguments object +*/ +static sqlite3_int64 getIntArg(PrintfArguments *p){ + if( p->nArg<=p->nUsed ) return 0; + return sqlite3_value_int64(p->apArg[p->nUsed++]); +} +static double getDoubleArg(PrintfArguments *p){ + if( p->nArg<=p->nUsed ) return 0.0; + return sqlite3_value_double(p->apArg[p->nUsed++]); +} +static char *getTextArg(PrintfArguments *p){ + if( p->nArg<=p->nUsed ) return 0; + return (char*)sqlite3_value_text(p->apArg[p->nUsed++]); +} + + +/* +** On machines with a small stack size, you can redefine the +** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired. +*/ +#ifndef SQLITE_PRINT_BUF_SIZE +# define SQLITE_PRINT_BUF_SIZE 70 +#endif +#define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */ + +/* +** Render a string given by "fmt" into the StrAccum object. +*/ +SQLITE_PRIVATE void sqlite3VXPrintf( + StrAccum *pAccum, /* Accumulate results here */ + u32 bFlags, /* SQLITE_PRINTF_* flags */ + const char *fmt, /* Format string */ + va_list ap /* arguments */ +){ + int c; /* Next character in the format string */ + char *bufpt; /* Pointer to the conversion buffer */ + int precision; /* Precision of the current field */ + int length; /* Length of the field */ + int idx; /* A general purpose loop counter */ + 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 */ + etByte xtype = 0; /* Conversion paradigm */ + u8 bArgList; /* True for SQLITE_PRINTF_SQLFUNC */ + u8 useIntern; /* Ok to use internal conversions (ex: %T) */ + char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ + sqlite_uint64 longvalue; /* Value for integer types */ + LONGDOUBLE_TYPE realvalue; /* Value for real types */ + const et_info *infop; /* Pointer to the appropriate info structure */ + char *zOut; /* Rendering buffer */ + int nOut; /* Size of the rendering buffer */ + char *zExtra = 0; /* Malloced memory used by some conversion */ +#ifndef SQLITE_OMIT_FLOATING_POINT + int exp, e2; /* exponent of real numbers */ + int nsd; /* Number of significant digits returned */ + 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 */ +#endif + PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */ + char buf[etBUFSIZE]; /* Conversion buffer */ + + bufpt = 0; + if( bFlags ){ + if( (bArgList = (bFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){ + pArgList = va_arg(ap, PrintfArguments*); + } + useIntern = bFlags & SQLITE_PRINTF_INTERNAL; + }else{ + bArgList = useIntern = 0; + } + for(; (c=(*fmt))!=0; ++fmt){ + if( c!='%' ){ + bufpt = (char *)fmt; +#if HAVE_STRCHRNUL + fmt = strchrnul(fmt, '%'); +#else + do{ fmt++; }while( *fmt && *fmt != '%' ); +#endif + sqlite3StrAccumAppend(pAccum, bufpt, (int)(fmt - bufpt)); + if( *fmt==0 ) break; + } + if( (c=(*++fmt))==0 ){ + sqlite3StrAccumAppend(pAccum, "%", 1); + 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 */ + if( c=='*' ){ + if( bArgList ){ + width = (int)getIntArg(pArgList); + }else{ + width = va_arg(ap,int); + } + if( width<0 ){ + flag_leftjustify = 1; + width = width >= -2147483647 ? -width : 0; + } + c = *++fmt; + }else{ + unsigned wx = 0; + while( c>='0' && c<='9' ){ + wx = wx*10 + c - '0'; + c = *++fmt; + } + testcase( wx>0x7fffffff ); + width = wx & 0x7fffffff; + } + + /* Get the precision */ + if( c=='.' ){ + c = *++fmt; + if( c=='*' ){ + if( bArgList ){ + precision = (int)getIntArg(pArgList); + }else{ + precision = va_arg(ap,int); + } + c = *++fmt; + if( precision<0 ){ + precision = precision >= -2147483647 ? -precision : -1; + } + }else{ + unsigned px = 0; + while( c>='0' && c<='9' ){ + px = px*10 + c - '0'; + c = *++fmt; + } + testcase( px>0x7fffffff ); + precision = px & 0x7fffffff; + } + }else{ + precision = -1; + } + /* Get the conversion type modifier */ + if( c=='l' ){ + flag_long = 1; + c = *++fmt; + if( c=='l' ){ + flag_longlong = 1; + c = *++fmt; + }else{ + flag_longlong = 0; + } + }else{ + flag_long = flag_longlong = 0; + } + /* Fetch the info entry for the field */ + infop = &fmtinfo[0]; + xtype = etINVALID; + for(idx=0; idxflags & FLAG_INTERN)==0 ){ + xtype = infop->type; + }else{ + return; + } + break; + } + } + + /* + ** 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 + ** the conversion character. + ** flag_blanksign TRUE if a ' ' is present. + ** width The specified field width. This is + ** always non-negative. Zero is the default. + ** precision The specified precision. The default + ** is -1. + ** xtype The class of the conversion. + ** infop Pointer to the appropriate info struct. + */ + switch( xtype ){ + case etPOINTER: + flag_longlong = sizeof(char*)==sizeof(i64); + flag_long = sizeof(char*)==sizeof(long int); + /* Fall through into the next case */ + case etORDINAL: + case etRADIX: + if( infop->flags & FLAG_SIGNED ){ + i64 v; + if( bArgList ){ + v = getIntArg(pArgList); + }else if( flag_longlong ){ + v = va_arg(ap,i64); + }else if( flag_long ){ + v = va_arg(ap,long int); + }else{ + v = va_arg(ap,int); + } + if( v<0 ){ + if( v==SMALLEST_INT64 ){ + longvalue = ((u64)1)<<63; + }else{ + longvalue = -v; + } + prefix = '-'; + }else{ + longvalue = v; + if( flag_plussign ) prefix = '+'; + else if( flag_blanksign ) prefix = ' '; + else prefix = 0; + } + }else{ + if( bArgList ){ + longvalue = (u64)getIntArg(pArgList); + }else if( flag_longlong ){ + longvalue = va_arg(ap,u64); + }else if( flag_long ){ + longvalue = va_arg(ap,unsigned long int); + }else{ + longvalue = va_arg(ap,unsigned int); + } + prefix = 0; + } + if( longvalue==0 ) flag_alternateform = 0; + if( flag_zeropad && precision=4 || (longvalue/10)%10==1 ){ + x = 0; + } + *(--bufpt) = zOrd[x*2+1]; + *(--bufpt) = zOrd[x*2]; + } + { + const char *cset = &aDigits[infop->charset]; + u8 base = infop->base; + do{ /* Convert to ascii */ + *(--bufpt) = cset[longvalue%base]; + longvalue = longvalue/base; + }while( longvalue>0 ); + } + length = (int)(&zOut[nOut-1]-bufpt); + for(idx=precision-length; idx>0; idx--){ + *(--bufpt) = '0'; /* Zero pad */ + } + if( prefix ) *(--bufpt) = prefix; /* Add sign */ + if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */ + const char *pre; + char x; + pre = &aPrefix[infop->prefix]; + for(; (x=(*pre))!=0; pre++) *(--bufpt) = x; + } + length = (int)(&zOut[nOut-1]-bufpt); + break; + case etFLOAT: + case etEXP: + case etGENERIC: + if( bArgList ){ + realvalue = getDoubleArg(pArgList); + }else{ + realvalue = va_arg(ap,double); + } +#ifdef SQLITE_OMIT_FLOATING_POINT + length = 0; +#else + if( precision<0 ) precision = 6; /* Set default precision */ + 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--; + testcase( precision>0xfff ); + for(idx=precision&0xfff, rounder=0.5; idx>0; idx--, rounder*=0.1){} + if( xtype==etFLOAT ) realvalue += rounder; + /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ + exp = 0; + if( sqlite3IsNaN((double)realvalue) ){ + bufpt = "NaN"; + length = 3; + break; + } + if( realvalue>0.0 ){ + LONGDOUBLE_TYPE scale = 1.0; + while( realvalue>=1e100*scale && exp<=350 ){ scale *= 1e100;exp+=100;} + while( realvalue>=1e64*scale && exp<=350 ){ scale *= 1e64; exp+=64; } + while( realvalue>=1e8*scale && exp<=350 ){ scale *= 1e8; exp+=8; } + while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; } + realvalue /= scale; + while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; } + while( realvalue<1.0 ){ realvalue *= 10.0; exp--; } + if( exp>350 ){ + if( prefix=='-' ){ + bufpt = "-Inf"; + }else if( prefix=='+' ){ + bufpt = "+Inf"; + }else{ + bufpt = "Inf"; + } + length = sqlite3Strlen30(bufpt); + break; + } + } + bufpt = buf; + /* + ** If the field type is etGENERIC, then convert to either etEXP + ** or etFLOAT, as appropriate. + */ + if( xtype!=etFLOAT ){ + realvalue += rounder; + if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; } + } + if( xtype==etGENERIC ){ + flag_rtz = !flag_alternateform; + if( exp<-4 || exp>precision ){ + xtype = etEXP; + }else{ + precision = precision - exp; + xtype = etFLOAT; + } + }else{ + flag_rtz = flag_altform2; + } + if( xtype==etEXP ){ + e2 = 0; + }else{ + e2 = exp; + } + if( MAX(e2,0)+(i64)precision+(i64)width > etBUFSIZE - 15 ){ + bufpt = zExtra + = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 ); + if( bufpt==0 ){ + setStrAccumError(pAccum, STRACCUM_NOMEM); + return; + } + } + zOut = bufpt; + nsd = 16 + flag_altform2*10; + flag_dp = (precision>0 ?1: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--, e2++){ + assert( precision>0 ); + *(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>zOut ); + if( bufpt[-1]=='.' ){ + if( flag_altform2 ){ + *(bufpt++) = '0'; + }else{ + *(--bufpt) = 0; + } + } + } + /* Add the "eNNN" suffix */ + if( xtype==etEXP ){ + *(bufpt++) = aDigits[infop->charset]; + if( exp<0 ){ + *(bufpt++) = '-'; exp = -exp; + }else{ + *(bufpt++) = '+'; + } + if( exp>=100 ){ + *(bufpt++) = (char)((exp/100)+'0'); /* 100's digit */ + exp %= 100; + } + *(bufpt++) = (char)(exp/10+'0'); /* 10's digit */ + *(bufpt++) = (char)(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 = (int)(bufpt-zOut); + bufpt = zOut; + + /* Special case: Add leading zeros if the flag_zeropad flag is + ** set and we are not left justified */ + if( flag_zeropad && !flag_leftjustify && length < width){ + int i; + int nPad = width - length; + for(i=width; i>=nPad; i--){ + bufpt[i] = bufpt[i-nPad]; + } + i = prefix!=0; + while( nPad-- ) bufpt[i++] = '0'; + length = width; + } +#endif /* !defined(SQLITE_OMIT_FLOATING_POINT) */ + break; + case etSIZE: + if( !bArgList ){ + *(va_arg(ap,int*)) = pAccum->nChar; + } + length = width = 0; + break; + case etPERCENT: + buf[0] = '%'; + bufpt = buf; + length = 1; + break; + case etCHARX: + if( bArgList ){ + bufpt = getTextArg(pArgList); + c = bufpt ? bufpt[0] : 0; + }else{ + c = va_arg(ap,int); + } + if( precision>1 ){ + width -= precision-1; + if( width>1 && !flag_leftjustify ){ + sqlite3AppendChar(pAccum, width-1, ' '); + width = 0; + } + sqlite3AppendChar(pAccum, precision-1, c); + } + length = 1; + buf[0] = c; + bufpt = buf; + break; + case etSTRING: + case etDYNSTRING: + if( bArgList ){ + bufpt = getTextArg(pArgList); + }else{ + bufpt = va_arg(ap,char*); + } + if( bufpt==0 ){ + bufpt = ""; + }else if( xtype==etDYNSTRING && !bArgList ){ + zExtra = bufpt; + } + if( precision>=0 ){ + for(length=0; lengthetBUFSIZE ){ + bufpt = zExtra = sqlite3Malloc( n ); + if( bufpt==0 ){ + setStrAccumError(pAccum, STRACCUM_NOMEM); + return; + } + }else{ + bufpt = buf; + } + j = 0; + if( needQuote ) bufpt[j++] = q; + k = i; + for(i=0; i=0 && precisionn ){ + sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n); + } + length = width = 0; + break; + } + case etSRCLIST: { + SrcList *pSrc = va_arg(ap, SrcList*); + int k = va_arg(ap, int); + struct SrcList_item *pItem = &pSrc->a[k]; + assert( bArgList==0 ); + assert( k>=0 && knSrc ); + if( pItem->zDatabase ){ + sqlite3StrAccumAppendAll(pAccum, pItem->zDatabase); + sqlite3StrAccumAppend(pAccum, ".", 1); + } + sqlite3StrAccumAppendAll(pAccum, pItem->zName); + length = width = 0; + break; + } + default: { + assert( xtype==etINVALID ); + return; + } + }/* End switch over the format type */ + /* + ** The text of the conversion is pointed to by "bufpt" and is + ** "length" characters long. The field width is "width". Do + ** the output. + */ + width -= length; + if( width>0 && !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' '); + sqlite3StrAccumAppend(pAccum, bufpt, length); + if( width>0 && flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' '); + + if( zExtra ){ + sqlite3_free(zExtra); + zExtra = 0; + } + }/* End for loop over the format string */ +} /* End of function */ + +/* +** Enlarge the memory allocation on a StrAccum object so that it is +** able to accept at least N more bytes of text. +** +** Return the number of bytes of text that StrAccum is able to accept +** after the attempted enlargement. The value returned might be zero. +*/ +static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ + char *zNew; + assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */ + if( p->accError ){ + testcase(p->accError==STRACCUM_TOOBIG); + testcase(p->accError==STRACCUM_NOMEM); + return 0; + } + if( p->mxAlloc==0 ){ + N = p->nAlloc - p->nChar - 1; + setStrAccumError(p, STRACCUM_TOOBIG); + return N; + }else{ + char *zOld = (p->zText==p->zBase ? 0 : p->zText); + i64 szNew = p->nChar; + szNew += N + 1; + if( szNew+p->nChar<=p->mxAlloc ){ + /* Force exponential buffer size growth as long as it does not overflow, + ** to avoid having to call this routine too often */ + szNew += p->nChar; + } + if( szNew > p->mxAlloc ){ + sqlite3StrAccumReset(p); + setStrAccumError(p, STRACCUM_TOOBIG); + return 0; + }else{ + p->nAlloc = (int)szNew; + } + if( p->db ){ + zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc); + }else{ + zNew = sqlite3_realloc64(zOld, p->nAlloc); + } + if( zNew ){ + assert( p->zText!=0 || p->nChar==0 ); + if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar); + p->zText = zNew; + p->nAlloc = sqlite3DbMallocSize(p->db, zNew); + }else{ + sqlite3StrAccumReset(p); + setStrAccumError(p, STRACCUM_NOMEM); + return 0; + } + } + return N; +} + +/* +** Append N copies of character c to the given string buffer. +*/ +SQLITE_PRIVATE void sqlite3AppendChar(StrAccum *p, int N, char c){ + testcase( p->nChar + (i64)N > 0x7fffffff ); + if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){ + return; + } + while( (N--)>0 ) p->zText[p->nChar++] = c; +} + +/* +** The StrAccum "p" is not large enough to accept N new bytes of z[]. +** So enlarge if first, then do the append. +** +** This is a helper routine to sqlite3StrAccumAppend() that does special-case +** work (enlarging the buffer) using tail recursion, so that the +** sqlite3StrAccumAppend() routine can use fast calling semantics. +*/ +static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){ + N = sqlite3StrAccumEnlarge(p, N); + if( N>0 ){ + memcpy(&p->zText[p->nChar], z, N); + p->nChar += N; + } +} + +/* +** Append N bytes of text from z to the StrAccum object. Increase the +** size of the memory allocation for StrAccum if necessary. +*/ +SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ + assert( z!=0 || N==0 ); + assert( p->zText!=0 || p->nChar==0 || p->accError ); + assert( N>=0 ); + assert( p->accError==0 || p->nAlloc==0 ); + if( p->nChar+N >= p->nAlloc ){ + enlargeAndAppend(p,z,N); + }else{ + assert( p->zText ); + p->nChar += N; + memcpy(&p->zText[p->nChar-N], z, N); + } +} + +/* +** Append the complete text of zero-terminated string z[] to the p string. +*/ +SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){ + sqlite3StrAccumAppend(p, z, sqlite3Strlen30(z)); +} + + +/* +** Finish off a string by making sure it is zero-terminated. +** Return a pointer to the resulting string. Return a NULL +** pointer if any kind of error was encountered. +*/ +SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){ + if( p->zText ){ + p->zText[p->nChar] = 0; + if( p->mxAlloc>0 && p->zText==p->zBase ){ + p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); + if( p->zText ){ + memcpy(p->zText, p->zBase, p->nChar+1); + }else{ + setStrAccumError(p, STRACCUM_NOMEM); + } + } + } + return p->zText; +} + +/* +** Reset an StrAccum string. Reclaim all malloced memory. +*/ +SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){ + if( p->zText!=p->zBase ){ + sqlite3DbFree(p->db, p->zText); + } + p->zText = 0; +} + +/* +** Initialize a string accumulator. +** +** p: The accumulator to be initialized. +** db: Pointer to a database connection. May be NULL. Lookaside +** memory is used if not NULL. db->mallocFailed is set appropriately +** when not NULL. +** zBase: An initial buffer. May be NULL in which case the initial buffer +** is malloced. +** n: Size of zBase in bytes. If total space requirements never exceed +** n then no memory allocations ever occur. +** mx: Maximum number of bytes to accumulate. If mx==0 then no memory +** allocations will ever occur. +*/ +SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){ + p->zText = p->zBase = zBase; + p->db = db; + p->nChar = 0; + p->nAlloc = n; + p->mxAlloc = mx; + p->accError = 0; +} + +/* +** Print into memory obtained from sqliteMalloc(). Use the internal +** %-conversion extensions. +*/ +SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){ + char *z; + char zBase[SQLITE_PRINT_BUF_SIZE]; + StrAccum acc; + assert( db!=0 ); + sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase), + db->aLimit[SQLITE_LIMIT_LENGTH]); + sqlite3VXPrintf(&acc, SQLITE_PRINTF_INTERNAL, zFormat, ap); + z = sqlite3StrAccumFinish(&acc); + if( acc.accError==STRACCUM_NOMEM ){ + db->mallocFailed = 1; + } + return z; +} + +/* +** Print into memory obtained from sqliteMalloc(). Use the internal +** %-conversion extensions. +*/ +SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3 *db, const char *zFormat, ...){ + va_list ap; + char *z; + va_start(ap, zFormat); + z = sqlite3VMPrintf(db, zFormat, ap); + va_end(ap); + return z; +} + +/* +** Like sqlite3MPrintf(), but call sqlite3DbFree() on zStr after formatting +** the string and before returning. This routine is intended to be used +** to modify an existing string. For example: +** +** x = sqlite3MPrintf(db, x, "prefix %s suffix", x); +** +*/ +SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3 *db, char *zStr, const char *zFormat, ...){ + va_list ap; + char *z; + va_start(ap, zFormat); + z = sqlite3VMPrintf(db, zFormat, ap); + va_end(ap); + sqlite3DbFree(db, zStr); + return z; +} + +/* +** Print into memory obtained from sqlite3_malloc(). Omit the internal +** %-conversion extensions. +*/ +SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char *zFormat, va_list ap){ + char *z; + char zBase[SQLITE_PRINT_BUF_SIZE]; + StrAccum acc; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( zFormat==0 ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH); + sqlite3VXPrintf(&acc, 0, zFormat, ap); + z = sqlite3StrAccumFinish(&acc); + return z; +} + +/* +** Print into memory obtained from sqlite3_malloc()(). Omit the internal +** %-conversion extensions. +*/ +SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char *zFormat, ...){ + va_list ap; + char *z; +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + va_start(ap, zFormat); + z = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + return z; +} + +/* +** sqlite3_snprintf() works like snprintf() except that it ignores the +** current locale settings. This is important for SQLite because we +** are not able to use a "," as the decimal point in place of "." as +** specified by some locales. +** +** Oops: The first two arguments of sqlite3_snprintf() are backwards +** from the snprintf() standard. Unfortunately, it is too late to change +** this without breaking compatibility, so we just have to live with the +** mistake. +** +** sqlite3_vsnprintf() is the varargs version. +*/ +SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){ + StrAccum acc; + if( n<=0 ) return zBuf; +#ifdef SQLITE_ENABLE_API_ARMOR + if( zBuf==0 || zFormat==0 ) { + (void)SQLITE_MISUSE_BKPT; + if( zBuf ) zBuf[0] = 0; + return zBuf; + } +#endif + sqlite3StrAccumInit(&acc, 0, zBuf, n, 0); + sqlite3VXPrintf(&acc, 0, zFormat, ap); + return sqlite3StrAccumFinish(&acc); +} +SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ + char *z; + va_list ap; + va_start(ap,zFormat); + z = sqlite3_vsnprintf(n, zBuf, zFormat, ap); + va_end(ap); + return z; +} + +/* +** This is the routine that actually formats the sqlite3_log() message. +** We house it in a separate routine from sqlite3_log() to avoid using +** stack space on small-stack systems when logging is disabled. +** +** sqlite3_log() must render into a static buffer. It cannot dynamically +** allocate memory because it might be called while the memory allocator +** mutex is held. +*/ +static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ + StrAccum acc; /* String accumulator */ + char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */ + + sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0); + sqlite3VXPrintf(&acc, 0, zFormat, ap); + sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode, + sqlite3StrAccumFinish(&acc)); +} + +/* +** Format and write a message to the log if logging is enabled. +*/ +SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...){ + va_list ap; /* Vararg list */ + if( sqlite3GlobalConfig.xLog ){ + va_start(ap, zFormat); + renderLogMsg(iErrCode, zFormat, ap); + va_end(ap); + } +} + +#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) +/* +** A version of printf() that understands %lld. Used for debugging. +** The printf() built into some versions of windows does not understand %lld +** and segfaults if you give it a long long int. +*/ +SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){ + va_list ap; + StrAccum acc; + char zBuf[500]; + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + va_start(ap,zFormat); + sqlite3VXPrintf(&acc, 0, zFormat, ap); + va_end(ap); + sqlite3StrAccumFinish(&acc); + fprintf(stdout,"%s", zBuf); + fflush(stdout); +} +#endif + +#ifdef SQLITE_DEBUG +/************************************************************************* +** Routines for implementing the "TreeView" display of hierarchical +** data structures for debugging. +** +** The main entry points (coded elsewhere) are: +** sqlite3TreeViewExpr(0, pExpr, 0); +** sqlite3TreeViewExprList(0, pList, 0, 0); +** sqlite3TreeViewSelect(0, pSelect, 0); +** Insert calls to those routines while debugging in order to display +** a diagram of Expr, ExprList, and Select objects. +** +*/ +/* Add a new subitem to the tree. The moreToFollow flag indicates that this +** is not the last item in the tree. */ +SQLITE_PRIVATE TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){ + if( p==0 ){ + p = sqlite3_malloc64( sizeof(*p) ); + if( p==0 ) return 0; + memset(p, 0, sizeof(*p)); + }else{ + p->iLevel++; + } + assert( moreToFollow==0 || moreToFollow==1 ); + if( p->iLevelbLine) ) p->bLine[p->iLevel] = moreToFollow; + return p; +} +/* Finished with one layer of the tree */ +SQLITE_PRIVATE void sqlite3TreeViewPop(TreeView *p){ + if( p==0 ) return; + p->iLevel--; + if( p->iLevel<0 ) sqlite3_free(p); +} +/* Generate a single line of output for the tree, with a prefix that contains +** all the appropriate tree lines */ +SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){ + va_list ap; + int i; + StrAccum acc; + char zBuf[500]; + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + if( p ){ + for(i=0; iiLevel && ibLine)-1; i++){ + sqlite3StrAccumAppend(&acc, p->bLine[i] ? "| " : " ", 4); + } + sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4); + } + va_start(ap, zFormat); + sqlite3VXPrintf(&acc, 0, zFormat, ap); + va_end(ap); + if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1); + sqlite3StrAccumFinish(&acc); + fprintf(stdout,"%s", zBuf); + fflush(stdout); +} +/* Shorthand for starting a new tree item that consists of a single label */ +SQLITE_PRIVATE void sqlite3TreeViewItem(TreeView *p, const char *zLabel, u8 moreToFollow){ + p = sqlite3TreeViewPush(p, moreToFollow); + sqlite3TreeViewLine(p, "%s", zLabel); +} +#endif /* SQLITE_DEBUG */ + +/* +** variable-argument wrapper around sqlite3VXPrintf(). +*/ +SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, u32 bFlags, const char *zFormat, ...){ + va_list ap; + va_start(ap,zFormat); + sqlite3VXPrintf(p, bFlags, zFormat, ap); + va_end(ap); +} + +/************** End of printf.c **********************************************/ +/************** Begin file random.c ******************************************/ +/* +** 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. +** +************************************************************************* +** 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. +*/ + + +/* All threads share a single random number generator. +** This structure is the current state of the generator. +*/ +static SQLITE_WSD struct sqlite3PrngType { + unsigned char isInit; /* True if initialized */ + unsigned char i, j; /* State variables */ + unsigned char s[256]; /* State variables */ +} sqlite3Prng; + +/* +** Return N random bytes. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *pBuf){ + unsigned char t; + unsigned char *zBuf = pBuf; + + /* The "wsdPrng" macro will resolve to the pseudo-random number generator + ** state vector. If writable static data is unsupported on the target, + ** we have to locate the state vector at run-time. In the more common + ** case where writable static data is supported, wsdPrng can refer directly + ** to the "sqlite3Prng" state vector declared above. + */ +#ifdef SQLITE_OMIT_WSD + struct sqlite3PrngType *p = &GLOBAL(struct sqlite3PrngType, sqlite3Prng); +# define wsdPrng p[0] +#else +# define wsdPrng sqlite3Prng +#endif + +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex; +#endif + +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return; +#endif + +#if SQLITE_THREADSAFE + mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG); +#endif + + sqlite3_mutex_enter(mutex); + if( N<=0 || pBuf==0 ){ + wsdPrng.isInit = 0; + sqlite3_mutex_leave(mutex); + return; + } + + /* Initialize the state of the random number generator once, + ** the first time this routine is called. The seed value does + ** not need to contain a lot of randomness since we are not + ** trying to do secure encryption or anything like that... + ** + ** Nothing in this file or anywhere else in SQLite does any kind of + ** encryption. The RC4 algorithm is being used as a PRNG (pseudo-random + ** number generator) not as an encryption device. + */ + if( !wsdPrng.isInit ){ + int i; + char k[256]; + wsdPrng.j = 0; + wsdPrng.i = 0; + sqlite3OsRandomness(sqlite3_vfs_find(0), 256, k); + for(i=0; i<256; i++){ + wsdPrng.s[i] = (u8)i; + } + for(i=0; i<256; i++){ + wsdPrng.j += wsdPrng.s[i] + k[i]; + t = wsdPrng.s[wsdPrng.j]; + wsdPrng.s[wsdPrng.j] = wsdPrng.s[i]; + wsdPrng.s[i] = t; + } + wsdPrng.isInit = 1; + } + + assert( N>0 ); + do{ + wsdPrng.i++; + t = wsdPrng.s[wsdPrng.i]; + wsdPrng.j += t; + wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j]; + wsdPrng.s[wsdPrng.j] = t; + t += wsdPrng.s[wsdPrng.i]; + *(zBuf++) = wsdPrng.s[t]; + }while( --N ); + sqlite3_mutex_leave(mutex); +} + +#ifndef SQLITE_OMIT_BUILTIN_TEST +/* +** For testing purposes, we sometimes want to preserve the state of +** PRNG and restore the PRNG to its saved state at a later time, or +** to reset the PRNG to its initial state. These routines accomplish +** those tasks. +** +** The sqlite3_test_control() interface calls these routines to +** control the PRNG. +*/ +static SQLITE_WSD struct sqlite3PrngType sqlite3SavedPrng; +SQLITE_PRIVATE void sqlite3PrngSaveState(void){ + memcpy( + &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng), + &GLOBAL(struct sqlite3PrngType, sqlite3Prng), + sizeof(sqlite3Prng) + ); +} +SQLITE_PRIVATE void sqlite3PrngRestoreState(void){ + memcpy( + &GLOBAL(struct sqlite3PrngType, sqlite3Prng), + &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng), + sizeof(sqlite3Prng) + ); +} +#endif /* SQLITE_OMIT_BUILTIN_TEST */ + +/************** End of random.c **********************************************/ +/************** Begin file threads.c *****************************************/ +/* +** 2012 July 21 +** +** 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 presents a simple cross-platform threading interface for +** use internally by SQLite. +** +** A "thread" can be created using sqlite3ThreadCreate(). This thread +** runs independently of its creator until it is joined using +** sqlite3ThreadJoin(), at which point it terminates. +** +** Threads do not have to be real. It could be that the work of the +** "thread" is done by the main thread at either the sqlite3ThreadCreate() +** or sqlite3ThreadJoin() call. This is, in fact, what happens in +** single threaded systems. Nothing in SQLite requires multiple threads. +** This interface exists so that applications that want to take advantage +** of multiple cores can do so, while also allowing applications to stay +** single-threaded if desired. +*/ +#if SQLITE_OS_WIN +#endif + +#if SQLITE_MAX_WORKER_THREADS>0 + +/********************************* Unix Pthreads ****************************/ +#if SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) && SQLITE_THREADSAFE>0 + +#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */ +/* #include */ + +/* A running thread */ +struct SQLiteThread { + pthread_t tid; /* Thread ID */ + int done; /* Set to true when thread finishes */ + void *pOut; /* Result returned by the thread */ + void *(*xTask)(void*); /* The thread routine */ + void *pIn; /* Argument to the thread */ +}; + +/* Create a new thread */ +SQLITE_PRIVATE int sqlite3ThreadCreate( + SQLiteThread **ppThread, /* OUT: Write the thread object here */ + void *(*xTask)(void*), /* Routine to run in a separate thread */ + void *pIn /* Argument passed into xTask() */ +){ + SQLiteThread *p; + int rc; + + assert( ppThread!=0 ); + assert( xTask!=0 ); + /* This routine is never used in single-threaded mode */ + assert( sqlite3GlobalConfig.bCoreMutex!=0 ); + + *ppThread = 0; + p = sqlite3Malloc(sizeof(*p)); + if( p==0 ) return SQLITE_NOMEM; + memset(p, 0, sizeof(*p)); + p->xTask = xTask; + p->pIn = pIn; + if( sqlite3FaultSim(200) ){ + rc = 1; + }else{ + rc = pthread_create(&p->tid, 0, xTask, pIn); + } + if( rc ){ + p->done = 1; + p->pOut = xTask(pIn); + } + *ppThread = p; + return SQLITE_OK; +} + +/* Get the results of the thread */ +SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ + int rc; + + assert( ppOut!=0 ); + if( NEVER(p==0) ) return SQLITE_NOMEM; + if( p->done ){ + *ppOut = p->pOut; + rc = SQLITE_OK; + }else{ + rc = pthread_join(p->tid, ppOut) ? SQLITE_ERROR : SQLITE_OK; + } + sqlite3_free(p); + return rc; +} + +#endif /* SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) */ +/******************************** End Unix Pthreads *************************/ + + +/********************************* Win32 Threads ****************************/ +#if SQLITE_OS_WIN_THREADS + +#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */ +#include + +/* A running thread */ +struct SQLiteThread { + void *tid; /* The thread handle */ + unsigned id; /* The thread identifier */ + void *(*xTask)(void*); /* The routine to run as a thread */ + void *pIn; /* Argument to xTask */ + void *pResult; /* Result of xTask */ +}; + +/* Thread procedure Win32 compatibility shim */ +static unsigned __stdcall sqlite3ThreadProc( + void *pArg /* IN: Pointer to the SQLiteThread structure */ +){ + SQLiteThread *p = (SQLiteThread *)pArg; + + assert( p!=0 ); +#if 0 + /* + ** This assert appears to trigger spuriously on certain + ** versions of Windows, possibly due to _beginthreadex() + ** and/or CreateThread() not fully setting their thread + ** ID parameter before starting the thread. + */ + assert( p->id==GetCurrentThreadId() ); +#endif + assert( p->xTask!=0 ); + p->pResult = p->xTask(p->pIn); + + _endthreadex(0); + return 0; /* NOT REACHED */ +} + +/* Create a new thread */ +SQLITE_PRIVATE int sqlite3ThreadCreate( + SQLiteThread **ppThread, /* OUT: Write the thread object here */ + void *(*xTask)(void*), /* Routine to run in a separate thread */ + void *pIn /* Argument passed into xTask() */ +){ + SQLiteThread *p; + + assert( ppThread!=0 ); + assert( xTask!=0 ); + *ppThread = 0; + p = sqlite3Malloc(sizeof(*p)); + if( p==0 ) return SQLITE_NOMEM; + if( sqlite3GlobalConfig.bCoreMutex==0 ){ + memset(p, 0, sizeof(*p)); + }else{ + p->xTask = xTask; + p->pIn = pIn; + p->tid = (void*)_beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id); + if( p->tid==0 ){ + memset(p, 0, sizeof(*p)); + } + } + if( p->xTask==0 ){ + p->id = GetCurrentThreadId(); + p->pResult = xTask(pIn); + } + *ppThread = p; + return SQLITE_OK; +} + +SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject); /* os_win.c */ + +/* Get the results of the thread */ +SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ + DWORD rc; + BOOL bRc; + + assert( ppOut!=0 ); + if( NEVER(p==0) ) return SQLITE_NOMEM; + if( p->xTask==0 ){ + assert( p->id==GetCurrentThreadId() ); + rc = WAIT_OBJECT_0; + assert( p->tid==0 ); + }else{ + assert( p->id!=0 && p->id!=GetCurrentThreadId() ); + rc = sqlite3Win32Wait((HANDLE)p->tid); + assert( rc!=WAIT_IO_COMPLETION ); + bRc = CloseHandle((HANDLE)p->tid); + assert( bRc ); + } + if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult; + sqlite3_free(p); + return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR; +} + +#endif /* SQLITE_OS_WIN_THREADS */ +/******************************** End Win32 Threads *************************/ + + +/********************************* Single-Threaded **************************/ +#ifndef SQLITE_THREADS_IMPLEMENTED +/* +** This implementation does not actually create a new thread. It does the +** work of the thread in the main thread, when either the thread is created +** or when it is joined +*/ + +/* A running thread */ +struct SQLiteThread { + void *(*xTask)(void*); /* The routine to run as a thread */ + void *pIn; /* Argument to xTask */ + void *pResult; /* Result of xTask */ +}; + +/* Create a new thread */ +SQLITE_PRIVATE int sqlite3ThreadCreate( + SQLiteThread **ppThread, /* OUT: Write the thread object here */ + void *(*xTask)(void*), /* Routine to run in a separate thread */ + void *pIn /* Argument passed into xTask() */ +){ + SQLiteThread *p; + + assert( ppThread!=0 ); + assert( xTask!=0 ); + *ppThread = 0; + p = sqlite3Malloc(sizeof(*p)); + if( p==0 ) return SQLITE_NOMEM; + if( (SQLITE_PTR_TO_INT(p)/17)&1 ){ + p->xTask = xTask; + p->pIn = pIn; + }else{ + p->xTask = 0; + p->pResult = xTask(pIn); + } + *ppThread = p; + return SQLITE_OK; +} + +/* Get the results of the thread */ +SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ + + assert( ppOut!=0 ); + if( NEVER(p==0) ) return SQLITE_NOMEM; + if( p->xTask ){ + *ppOut = p->xTask(p->pIn); + }else{ + *ppOut = p->pResult; + } + sqlite3_free(p); + +#if defined(SQLITE_TEST) + { + void *pTstAlloc = sqlite3Malloc(10); + if (!pTstAlloc) return SQLITE_NOMEM; + sqlite3_free(pTstAlloc); + } +#endif + + return SQLITE_OK; +} + +#endif /* !defined(SQLITE_THREADS_IMPLEMENTED) */ +/****************************** End Single-Threaded *************************/ +#endif /* SQLITE_MAX_WORKER_THREADS>0 */ + +/************** End of threads.c *********************************************/ +/************** Begin file utf.c *********************************************/ +/* +** 2004 April 13 +** +** 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 routines used to translate between UTF-8, +** UTF-16, UTF-16BE, and UTF-16LE. +** +** 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 +** 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx 000uuuuu zzzzyyyy yyxxxxxx +** +** +** Notes on UTF-16: (with wwww+1==uuuuu) +** +** Word-0 Word-1 Value +** 110110ww wwzzzzyy 110111yy yyxxxxxx 000uuuuu zzzzyyyy yyxxxxxx +** zzzzyyyy yyxxxxxx 00000000 zzzzyyyy yyxxxxxx +** +** +** BOM or Byte Order Mark: +** 0xff 0xfe little-endian utf-16 follows +** 0xfe 0xff big-endian utf-16 follows +** +*/ +/* #include */ + +#ifndef SQLITE_AMALGAMATION +/* +** The following constant value is used by the SQLITE_BIGENDIAN and +** SQLITE_LITTLEENDIAN macros. +*/ +SQLITE_PRIVATE const int sqlite3one = 1; +#endif /* SQLITE_AMALGAMATION */ + +/* +** This lookup table is used to help decode the first byte of +** a multi-byte UTF8 character. +*/ +static const unsigned char sqlite3Utf8Trans1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00, +}; + + +#define WRITE_UTF8(zOut, c) { \ + if( c<0x00080 ){ \ + *zOut++ = (u8)(c&0xFF); \ + } \ + else if( c<0x00800 ){ \ + *zOut++ = 0xC0 + (u8)((c>>6)&0x1F); \ + *zOut++ = 0x80 + (u8)(c & 0x3F); \ + } \ + else if( c<0x10000 ){ \ + *zOut++ = 0xE0 + (u8)((c>>12)&0x0F); \ + *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \ + *zOut++ = 0x80 + (u8)(c & 0x3F); \ + }else{ \ + *zOut++ = 0xF0 + (u8)((c>>18) & 0x07); \ + *zOut++ = 0x80 + (u8)((c>>12) & 0x3F); \ + *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \ + *zOut++ = 0x80 + (u8)(c & 0x3F); \ + } \ +} + +#define WRITE_UTF16LE(zOut, c) { \ + if( c<=0xFFFF ){ \ + *zOut++ = (u8)(c&0x00FF); \ + *zOut++ = (u8)((c>>8)&0x00FF); \ + }else{ \ + *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0)); \ + *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03)); \ + *zOut++ = (u8)(c&0x00FF); \ + *zOut++ = (u8)(0x00DC + ((c>>8)&0x03)); \ + } \ +} + +#define WRITE_UTF16BE(zOut, c) { \ + if( c<=0xFFFF ){ \ + *zOut++ = (u8)((c>>8)&0x00FF); \ + *zOut++ = (u8)(c&0x00FF); \ + }else{ \ + *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03)); \ + *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0)); \ + *zOut++ = (u8)(0x00DC + ((c>>8)&0x03)); \ + *zOut++ = (u8)(c&0x00FF); \ + } \ +} + +#define READ_UTF16LE(zIn, TERM, c){ \ + c = (*zIn++); \ + c += ((*zIn++)<<8); \ + if( c>=0xD800 && c<0xE000 && TERM ){ \ + int c2 = (*zIn++); \ + c2 += ((*zIn++)<<8); \ + c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \ + } \ +} + +#define READ_UTF16BE(zIn, TERM, c){ \ + c = ((*zIn++)<<8); \ + c += (*zIn++); \ + if( c>=0xD800 && c<0xE000 && TERM ){ \ + int c2 = ((*zIn++)<<8); \ + c2 += (*zIn++); \ + c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \ + } \ +} + +/* +** Translate a single UTF-8 character. Return the unicode value. +** +** During translation, assume that the byte that zTerm points +** is a 0x00. +** +** Write a pointer to the next unread byte back into *pzNext. +** +** Notes On Invalid UTF-8: +** +** * This routine never allows a 7-bit character (0x00 through 0x7f) to +** be encoded as a multi-byte character. Any multi-byte character that +** attempts to encode a value between 0x00 and 0x7f is rendered as 0xfffd. +** +** * This routine never allows a UTF16 surrogate value to be encoded. +** If a multi-byte character attempts to encode a value between +** 0xd800 and 0xe000 then it is rendered as 0xfffd. +** +** * Bytes in the range of 0x80 through 0xbf which occur as the first +** byte of a character are interpreted as single-byte characters +** and rendered as themselves even though they are technically +** invalid characters. +** +** * This routine accepts over-length UTF8 encodings +** for unicode values 0x80 and greater. It does not change over-length +** encodings to 0xfffd as some systems recommend. +*/ +#define READ_UTF8(zIn, zTerm, c) \ + c = *(zIn++); \ + if( c>=0xc0 ){ \ + c = sqlite3Utf8Trans1[c-0xc0]; \ + while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \ + c = (c<<6) + (0x3f & *(zIn++)); \ + } \ + if( c<0x80 \ + || (c&0xFFFFF800)==0xD800 \ + || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \ + } +SQLITE_PRIVATE u32 sqlite3Utf8Read( + const unsigned char **pz /* Pointer to string from which to read char */ +){ + unsigned int c; + + /* Same as READ_UTF8() above but without the zTerm parameter. + ** For this routine, we assume the UTF8 string is always zero-terminated. + */ + c = *((*pz)++); + if( c>=0xc0 ){ + c = sqlite3Utf8Trans1[c-0xc0]; + while( (*(*pz) & 0xc0)==0x80 ){ + c = (c<<6) + (0x3f & *((*pz)++)); + } + if( c<0x80 + || (c&0xFFFFF800)==0xD800 + || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } + } + return c; +} + + + + +/* +** If the TRANSLATE_TRACE macro is defined, the value of each Mem is +** printed on stderr on the way into and out of sqlite3VdbeMemTranslate(). +*/ +/* #define TRANSLATE_TRACE 1 */ + +#ifndef SQLITE_OMIT_UTF16 +/* +** This routine transforms the internal text encoding used by pMem to +** desiredEnc. It is an error if the string is already of the desired +** encoding, or if *pMem does not contain a string value. +*/ +SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){ + int len; /* Maximum length of output string in bytes */ + unsigned char *zOut; /* Output buffer */ + unsigned char *zIn; /* Input iterator */ + unsigned char *zTerm; /* End of input */ + unsigned char *z; /* Output iterator */ + unsigned int c; + + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( pMem->flags&MEM_Str ); + assert( pMem->enc!=desiredEnc ); + assert( pMem->enc!=0 ); + assert( pMem->n>=0 ); + +#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG) + { + char zBuf[100]; + sqlite3VdbeMemPrettyPrint(pMem, zBuf); + fprintf(stderr, "INPUT: %s\n", zBuf); + } +#endif + + /* If the translation is between UTF-16 little and big endian, then + ** all that is required is to swap the byte order. This case is handled + ** differently from the others. + */ + if( pMem->enc!=SQLITE_UTF8 && desiredEnc!=SQLITE_UTF8 ){ + 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&~1]; + while( zInenc = desiredEnc; + goto translate_out; + } + + /* Set len to the maximum number of bytes required in the output buffer. */ + if( desiredEnc==SQLITE_UTF8 ){ + /* When converting from UTF-16, the maximum growth results from + ** translating a 2-byte character to a 4-byte UTF-8 character. + ** A single byte is required for the output string + ** nul-terminator. + */ + pMem->n &= ~1; + len = pMem->n * 2 + 1; + }else{ + /* When converting from UTF-8 to UTF-16 the maximum growth is caused + ** when a 1-byte UTF-8 character is translated into a 2-byte UTF-16 + ** character. Two bytes are required in the output buffer for the + ** nul-terminator. + */ + len = pMem->n * 2 + 2; + } + + /* 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, space obtained + ** from sqlite3_malloc(). + */ + zIn = (u8*)pMem->z; + zTerm = &zIn[pMem->n]; + zOut = sqlite3DbMallocRaw(pMem->db, len); + if( !zOut ){ + return SQLITE_NOMEM; + } + z = zOut; + + if( pMem->enc==SQLITE_UTF8 ){ + if( desiredEnc==SQLITE_UTF16LE ){ + /* UTF-8 -> UTF-16 Little-endian */ + while( zIn UTF-16 Big-endian */ + while( zInn = (int)(z - zOut); + *z++ = 0; + }else{ + assert( desiredEnc==SQLITE_UTF8 ); + if( pMem->enc==SQLITE_UTF16LE ){ + /* UTF-16 Little-endian -> UTF-8 */ + while( zIn UTF-8 */ + while( zInn = (int)(z - zOut); + } + *z = 0; + assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len ); + + c = pMem->flags; + sqlite3VdbeMemRelease(pMem); + pMem->flags = MEM_Str|MEM_Term|(c&MEM_AffMask); + pMem->enc = desiredEnc; + pMem->z = (char*)zOut; + pMem->zMalloc = pMem->z; + pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->z); + +translate_out: +#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG) + { + char zBuf[100]; + sqlite3VdbeMemPrettyPrint(pMem, zBuf); + fprintf(stderr, "OUTPUT: %s\n", zBuf); + } +#endif + return SQLITE_OK; +} + +/* +** This routine checks for a byte-order mark at the beginning of the +** UTF-16 string stored in *pMem. If one is present, it is removed and +** the encoding of the Mem adjusted. This routine does not do any +** byte-swapping, it just sets Mem.enc appropriately. +** +** The allocation (static, dynamic etc.) and encoding of the Mem may be +** changed by this function. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem){ + int rc = SQLITE_OK; + u8 bom = 0; + + assert( pMem->n>=0 ); + if( pMem->n>1 ){ + u8 b1 = *(u8 *)pMem->z; + u8 b2 = *(((u8 *)pMem->z) + 1); + if( b1==0xFE && b2==0xFF ){ + bom = SQLITE_UTF16BE; + } + if( b1==0xFF && b2==0xFE ){ + bom = SQLITE_UTF16LE; + } + } + + if( bom ){ + rc = sqlite3VdbeMemMakeWriteable(pMem); + if( rc==SQLITE_OK ){ + pMem->n -= 2; + memmove(pMem->z, &pMem->z[2], pMem->n); + pMem->z[pMem->n] = '\0'; + pMem->z[pMem->n+1] = '\0'; + pMem->flags |= MEM_Term; + pMem->enc = bom; + } + } + return rc; +} +#endif /* SQLITE_OMIT_UTF16 */ + +/* +** pZ is a UTF-8 encoded unicode string. If nByte is less than zero, +** return the number of unicode characters in pZ up to (but not including) +** the first 0x00 byte. If nByte is not less than zero, return the +** number of unicode characters in the first nByte of pZ (or up to +** the first 0x00, whichever comes first). +*/ +SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *zIn, int nByte){ + int r = 0; + const u8 *z = (const u8*)zIn; + const u8 *zTerm; + if( nByte>=0 ){ + zTerm = &z[nByte]; + }else{ + zTerm = (const u8*)(-1); + } + assert( z<=zTerm ); + while( *z!=0 && zmallocFailed ){ + sqlite3VdbeMemRelease(&m); + m.z = 0; + } + assert( (m.flags & MEM_Term)!=0 || db->mallocFailed ); + assert( (m.flags & MEM_Str)!=0 || db->mallocFailed ); + assert( m.z || db->mallocFailed ); + return m.z; +} + +/* +** zIn is a UTF-16 encoded unicode string at least nChar characters long. +** Return the number of bytes in the first nChar unicode characters +** in pZ. nChar must be non-negative. +*/ +SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nChar){ + int c; + unsigned char const *z = zIn; + int n = 0; + + if( SQLITE_UTF16NATIVE==SQLITE_UTF16BE ){ + while( n0 && n<=4 ); + z[0] = 0; + z = zBuf; + c = sqlite3Utf8Read((const u8**)&z); + t = i; + if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD; + if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD; + assert( c==t ); + assert( (z-zBuf)==n ); + } + for(i=0; i<0x00110000; i++){ + if( i>=0xD800 && i<0xE000 ) continue; + z = zBuf; + WRITE_UTF16LE(z, i); + n = (int)(z-zBuf); + assert( n>0 && n<=4 ); + z[0] = 0; + z = zBuf; + READ_UTF16LE(z, 1, c); + assert( c==i ); + assert( (z-zBuf)==n ); + } + for(i=0; i<0x00110000; i++){ + if( i>=0xD800 && i<0xE000 ) continue; + z = zBuf; + WRITE_UTF16BE(z, i); + n = (int)(z-zBuf); + assert( n>0 && n<=4 ); + z[0] = 0; + z = zBuf; + READ_UTF16BE(z, 1, c); + assert( c==i ); + assert( (z-zBuf)==n ); + } +} +#endif /* SQLITE_TEST */ +#endif /* SQLITE_OMIT_UTF16 */ + +/************** End of utf.c *************************************************/ +/************** Begin file util.c ********************************************/ +/* +** 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. +** +************************************************************************* +** Utility functions used throughout sqlite. +** +** This file contains functions for allocating memory, comparing +** strings, and stuff like that. +** +*/ +/* #include */ +#if HAVE_ISNAN || SQLITE_HAVE_ISNAN +# include +#endif + +/* +** Routine needed to support the testcase() macro. +*/ +#ifdef SQLITE_COVERAGE_TEST +SQLITE_PRIVATE void sqlite3Coverage(int x){ + static unsigned dummy = 0; + dummy += (unsigned)x; +} +#endif + +/* +** Give a callback to the test harness that can be used to simulate faults +** in places where it is difficult or expensive to do so purely by means +** of inputs. +** +** The intent of the integer argument is to let the fault simulator know +** which of multiple sqlite3FaultSim() calls has been hit. +** +** Return whatever integer value the test callback returns, or return +** SQLITE_OK if no test callback is installed. +*/ +#ifndef SQLITE_OMIT_BUILTIN_TEST +SQLITE_PRIVATE int sqlite3FaultSim(int iTest){ + int (*xCallback)(int) = sqlite3GlobalConfig.xTestCallback; + return xCallback ? xCallback(iTest) : SQLITE_OK; +} +#endif + +#ifndef SQLITE_OMIT_FLOATING_POINT +/* +** Return true if the floating point value is Not a Number (NaN). +** +** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN. +** Otherwise, we have our own implementation that works on most systems. +*/ +SQLITE_PRIVATE int sqlite3IsNaN(double x){ + int rc; /* The value return */ +#if !SQLITE_HAVE_ISNAN && !HAVE_ISNAN + /* + ** Systems that support the isnan() library function should probably + ** make use of it by compiling with -DSQLITE_HAVE_ISNAN. But we have + ** found that many systems do not have a working isnan() function so + ** this implementation is provided as an alternative. + ** + ** This NaN test sometimes fails if compiled on GCC with -ffast-math. + ** On the other hand, the use of -ffast-math comes with the following + ** warning: + ** + ** This option [-ffast-math] should never be turned on by any + ** -O option since it can result in incorrect output for programs + ** which depend on an exact implementation of IEEE or ISO + ** rules/specifications for math functions. + ** + ** Under MSVC, this NaN test may fail if compiled with a floating- + ** point precision mode other than /fp:precise. From the MSDN + ** documentation: + ** + ** The compiler [with /fp:precise] will properly handle comparisons + ** involving NaN. For example, x != x evaluates to true if x is NaN + ** ... + */ +#ifdef __FAST_MATH__ +# error SQLite will not work correctly with the -ffast-math option of GCC. +#endif + volatile double y = x; + volatile double z = y; + rc = (y!=z); +#else /* if HAVE_ISNAN */ + rc = isnan(x); +#endif /* HAVE_ISNAN */ + testcase( rc ); + return rc; +} +#endif /* SQLITE_OMIT_FLOATING_POINT */ + +/* +** Compute a string length that is limited to what can be stored in +** lower 30 bits of a 32-bit signed integer. +** +** The value returned will never be negative. Nor will it ever be greater +** than the actual length of the string. For very long strings (greater +** than 1GiB) the value returned might be less than the true string length. +*/ +SQLITE_PRIVATE int sqlite3Strlen30(const char *z){ + const char *z2 = z; + if( z==0 ) return 0; + while( *z2 ){ z2++; } + return 0x3fffffff & (int)(z2 - z); +} + +/* +** Set the current error code to err_code and clear any prior error message. +*/ +SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){ + assert( db!=0 ); + db->errCode = err_code; + if( db->pErr ) sqlite3ValueSetNull(db->pErr); +} + +/* +** 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. +*/ +SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *zFormat, ...){ + assert( db!=0 ); + db->errCode = err_code; + if( zFormat==0 ){ + sqlite3Error(db, err_code); + }else if( db->pErr || (db->pErr = sqlite3ValueNew(db))!=0 ){ + char *z; + va_list ap; + va_start(ap, zFormat); + z = sqlite3VMPrintf(db, zFormat, ap); + va_end(ap); + sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC); + } +} + +/* +** Add an error message to pParse->zErrMsg and increment pParse->nErr. +** The following formatting 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 +** +** This function should be used to report any error that occurs while +** compiling an SQL statement (i.e. within sqlite3_prepare()). The +** last thing the sqlite3_prepare() function does is copy the error +** stored by this function into the database handle using sqlite3Error(). +** Functions sqlite3Error() or sqlite3ErrorWithMsg() should be used +** during statement execution (sqlite3_step() etc.). +*/ +SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ + char *zMsg; + va_list ap; + sqlite3 *db = pParse->db; + va_start(ap, zFormat); + zMsg = sqlite3VMPrintf(db, zFormat, ap); + va_end(ap); + if( db->suppressErr ){ + sqlite3DbFree(db, zMsg); + }else{ + pParse->nErr++; + sqlite3DbFree(db, pParse->zErrMsg); + pParse->zErrMsg = zMsg; + pParse->rc = SQLITE_ERROR; + } +} + +/* +** 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. +** +** The input string must be zero-terminated. A new zero-terminator +** is added to the dequoted string. +** +** The return value is -1 if no dequoting occurs or the length of the +** dequoted string, exclusive of the zero terminator, if dequoting does +** occur. +** +** 2002-Feb-14: This routine is extended to remove MS-Access style +** brackets from around identifiers. For example: "[a-b-c]" becomes +** "a-b-c". +*/ +SQLITE_PRIVATE int sqlite3Dequote(char *z){ + char quote; + int i, j; + if( z==0 ) return -1; + quote = z[0]; + switch( quote ){ + case '\'': break; + case '"': break; + case '`': break; /* For MySQL compatibility */ + case '[': quote = ']'; break; /* For MS SqlServer compatibility */ + default: return -1; + } + for(i=1, j=0;; i++){ + assert( z[i] ); + if( z[i]==quote ){ + if( z[i+1]==quote ){ + z[j++] = quote; + i++; + }else{ + break; + } + }else{ + z[j++] = z[i]; + } + } + z[j] = 0; + return j; +} + +/* Convenient short-hand */ +#define UpperToLower sqlite3UpperToLower + +/* +** Some systems have stricmp(). Others have strcasecmp(). Because +** there is no consistency, we will define our own. +** +** IMPLEMENTATION-OF: R-30243-02494 The sqlite3_stricmp() and +** sqlite3_strnicmp() APIs allow applications and extensions to compare +** the contents of two buffers containing UTF-8 strings in a +** case-independent fashion, using the same definition of "case +** independence" that SQLite uses internally when comparing identifiers. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *zLeft, const char *zRight){ + register unsigned char *a, *b; + if( zLeft==0 ){ + return zRight ? -1 : 0; + }else if( zRight==0 ){ + return 1; + } + a = (unsigned char *)zLeft; + b = (unsigned char *)zRight; + while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; } + return UpperToLower[*a] - UpperToLower[*b]; +} +SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){ + register unsigned char *a, *b; + if( zLeft==0 ){ + return zRight ? -1 : 0; + }else if( zRight==0 ){ + return 1; + } + a = (unsigned char *)zLeft; + b = (unsigned char *)zRight; + while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; } + return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b]; +} + +/* +** The string z[] is an text representation of a real number. +** Convert this string to a double and write it into *pResult. +** +** The string z[] is length bytes in length (bytes, not characters) and +** uses the encoding enc. The string is not necessarily zero-terminated. +** +** Return TRUE if the result is a valid real number (or integer) and FALSE +** if the string is empty or contains extraneous text. Valid numbers +** are in one of these formats: +** +** [+-]digits[E[+-]digits] +** [+-]digits.[digits][E[+-]digits] +** [+-].digits[E[+-]digits] +** +** Leading and trailing whitespace is ignored for the purpose of determining +** validity. +** +** If some prefix of the input string is a valid number, this routine +** returns FALSE but it still converts the prefix and writes the result +** into *pResult. +*/ +SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ +#ifndef SQLITE_OMIT_FLOATING_POINT + int incr; + const char *zEnd = z + length; + /* sign * significand * (10 ^ (esign * exponent)) */ + int sign = 1; /* sign of significand */ + i64 s = 0; /* significand */ + int d = 0; /* adjust exponent for shifting decimal point */ + int esign = 1; /* sign of exponent */ + int e = 0; /* exponent */ + int eValid = 1; /* True exponent is either not used or is well-formed */ + double result; + int nDigits = 0; + int nonNum = 0; + + assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); + *pResult = 0.0; /* Default return value, in case of an error */ + + if( enc==SQLITE_UTF8 ){ + incr = 1; + }else{ + int i; + incr = 2; + assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); + for(i=3-enc; i=zEnd ) return 0; + + /* get sign of significand */ + if( *z=='-' ){ + sign = -1; + z+=incr; + }else if( *z=='+' ){ + z+=incr; + } + + /* skip leading zeroes */ + while( z=zEnd ) goto do_atof_calc; + + /* if decimal point is present */ + if( *z=='.' ){ + z+=incr; + /* copy digits from after decimal to significand + ** (decrease exponent by d to shift decimal right) */ + while( z=zEnd ) goto do_atof_calc; + + /* if exponent is present */ + if( *z=='e' || *z=='E' ){ + z+=incr; + eValid = 0; + if( z>=zEnd ) goto do_atof_calc; + /* get sign of exponent */ + if( *z=='-' ){ + esign = -1; + z+=incr; + }else if( *z=='+' ){ + z+=incr; + } + /* copy digits to exponent */ + while( z0 ){ + while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10; + }else{ + while( !(s%10) && e>0 ) e--,s/=10; + } + + /* adjust the sign of significand */ + s = sign<0 ? -s : s; + + /* if exponent, scale significand as appropriate + ** and store in result. */ + if( e ){ + LONGDOUBLE_TYPE scale = 1.0; + /* attempt to handle extremely small/large numbers better */ + if( e>307 && e<342 ){ + while( e%308 ) { scale *= 1.0e+1; e -= 1; } + if( esign<0 ){ + result = s / scale; + result /= 1.0e+308; + }else{ + result = s * scale; + result *= 1.0e+308; + } + }else if( e>=342 ){ + if( esign<0 ){ + result = 0.0*s; + }else{ + result = 1e308*1e308*s; /* Infinity */ + } + }else{ + /* 1.0e+22 is the largest power of 10 than can be + ** represented exactly. */ + while( e%22 ) { scale *= 1.0e+1; e -= 1; } + while( e>0 ) { scale *= 1.0e+22; e -= 22; } + if( esign<0 ){ + result = s / scale; + }else{ + result = s * scale; + } + } + } else { + result = (double)s; + } + } + + /* store the result */ + *pResult = result; + + /* return true if number and no extra non-whitespace chracters after */ + return z>=zEnd && nDigits>0 && eValid && nonNum==0; +#else + return !sqlite3Atoi64(z, pResult, length, enc); +#endif /* SQLITE_OMIT_FLOATING_POINT */ +} + +/* +** Compare the 19-character string zNum against the text representation +** value 2^63: 9223372036854775808. Return negative, zero, or positive +** if zNum is less than, equal to, or greater than the string. +** Note that zNum must contain exactly 19 characters. +** +** Unlike memcmp() this routine is guaranteed to return the difference +** in the values of the last digit if the only difference is in the +** last digit. So, for example, +** +** compare2pow63("9223372036854775800", 1) +** +** will return -8. +*/ +static int compare2pow63(const char *zNum, int incr){ + int c = 0; + int i; + /* 012345678901234567 */ + const char *pow63 = "922337203685477580"; + for(i=0; c==0 && i<18; i++){ + c = (zNum[i*incr]-pow63[i])*10; + } + if( c==0 ){ + c = zNum[18*incr] - '8'; + testcase( c==(-1) ); + testcase( c==0 ); + testcase( c==(+1) ); + } + return c; +} + +/* +** Convert zNum to a 64-bit signed integer. zNum must be decimal. This +** routine does *not* accept hexadecimal notation. +** +** If the zNum value is representable as a 64-bit twos-complement +** integer, then write that value into *pNum and return 0. +** +** If zNum is exactly 9223372036854775808, return 2. This special +** case is broken out because while 9223372036854775808 cannot be a +** signed 64-bit integer, its negative -9223372036854775808 can be. +** +** If zNum is too big for a 64-bit integer and is not +** 9223372036854775808 or if zNum contains any non-numeric text, +** then return 1. +** +** length is the number of bytes in the string (bytes, not characters). +** The string is not necessarily zero-terminated. The encoding is +** given by enc. +*/ +SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ + int incr; + u64 u = 0; + int neg = 0; /* assume positive */ + int i; + int c = 0; + int nonNum = 0; + const char *zStart; + const char *zEnd = zNum + length; + assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); + if( enc==SQLITE_UTF8 ){ + incr = 1; + }else{ + incr = 2; + assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); + for(i=3-enc; i='0' && c<='9'; i+=incr){ + u = u*10 + c - '0'; + } + if( u>LARGEST_INT64 ){ + *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64; + }else if( neg ){ + *pNum = -(i64)u; + }else{ + *pNum = (i64)u; + } + testcase( i==18 ); + testcase( i==19 ); + testcase( i==20 ); + if( (c!=0 && &zNum[i]19*incr || nonNum ){ + /* zNum is empty or contains non-numeric text or is longer + ** than 19 digits (thus guaranteeing that it is too large) */ + return 1; + }else if( i<19*incr ){ + /* Less than 19 digits, so we know that it fits in 64 bits */ + assert( u<=LARGEST_INT64 ); + return 0; + }else{ + /* zNum is a 19-digit numbers. Compare it against 9223372036854775808. */ + c = compare2pow63(zNum, incr); + if( c<0 ){ + /* zNum is less than 9223372036854775808 so it fits */ + assert( u<=LARGEST_INT64 ); + return 0; + }else if( c>0 ){ + /* zNum is greater than 9223372036854775808 so it overflows */ + return 1; + }else{ + /* zNum is exactly 9223372036854775808. Fits if negative. The + ** special case 2 overflow if positive */ + assert( u-1==LARGEST_INT64 ); + return neg ? 0 : 2; + } + } +} + +/* +** Transform a UTF-8 integer literal, in either decimal or hexadecimal, +** into a 64-bit signed integer. This routine accepts hexadecimal literals, +** whereas sqlite3Atoi64() does not. +** +** Returns: +** +** 0 Successful transformation. Fits in a 64-bit signed integer. +** 1 Integer too large for a 64-bit signed integer or is malformed +** 2 Special case of 9223372036854775808 +*/ +SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char *z, i64 *pOut){ +#ifndef SQLITE_OMIT_HEX_INTEGER + if( z[0]=='0' + && (z[1]=='x' || z[1]=='X') + && sqlite3Isxdigit(z[2]) + ){ + u64 u = 0; + int i, k; + for(i=2; z[i]=='0'; i++){} + for(k=i; sqlite3Isxdigit(z[k]); k++){ + u = u*16 + sqlite3HexToInt(z[k]); + } + memcpy(pOut, &u, 8); + return (z[k]==0 && k-i<=16) ? 0 : 1; + }else +#endif /* SQLITE_OMIT_HEX_INTEGER */ + { + return sqlite3Atoi64(z, pOut, sqlite3Strlen30(z), SQLITE_UTF8); + } +} + +/* +** If zNum represents an integer that will fit in 32-bits, then set +** *pValue to that integer and return true. Otherwise return false. +** +** This routine accepts both decimal and hexadecimal notation for integers. +** +** Any non-numeric characters that following zNum are ignored. +** This is different from sqlite3Atoi64() which requires the +** input number to be zero-terminated. +*/ +SQLITE_PRIVATE int sqlite3GetInt32(const char *zNum, int *pValue){ + sqlite_int64 v = 0; + int i, c; + int neg = 0; + if( zNum[0]=='-' ){ + neg = 1; + zNum++; + }else if( zNum[0]=='+' ){ + zNum++; + } +#ifndef SQLITE_OMIT_HEX_INTEGER + else if( zNum[0]=='0' + && (zNum[1]=='x' || zNum[1]=='X') + && sqlite3Isxdigit(zNum[2]) + ){ + u32 u = 0; + zNum += 2; + while( zNum[0]=='0' ) zNum++; + for(i=0; sqlite3Isxdigit(zNum[i]) && i<8; i++){ + u = u*16 + sqlite3HexToInt(zNum[i]); + } + if( (u&0x80000000)==0 && sqlite3Isxdigit(zNum[i])==0 ){ + memcpy(pValue, &u, 4); + return 1; + }else{ + return 0; + } + } +#endif + while( zNum[0]=='0' ) zNum++; + for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){ + v = v*10 + c; + } + + /* The longest decimal representation of a 32 bit integer is 10 digits: + ** + ** 1234567890 + ** 2^31 -> 2147483648 + */ + testcase( i==10 ); + if( i>10 ){ + return 0; + } + testcase( v-neg==2147483647 ); + if( v-neg>2147483647 ){ + return 0; + } + if( neg ){ + v = -v; + } + *pValue = (int)v; + return 1; +} + +/* +** Return a 32-bit integer value extracted from a string. If the +** string is not an integer, just return 0. +*/ +SQLITE_PRIVATE int sqlite3Atoi(const char *z){ + int x = 0; + if( z ) sqlite3GetInt32(z, &x); + return x; +} + +/* +** The variable-length integer encoding is as follows: +** +** KEY: +** A = 0xxxxxxx 7 bits of data and one flag bit +** B = 1xxxxxxx 7 bits of data and one flag bit +** C = xxxxxxxx 8 bits of data +** +** 7 bits - A +** 14 bits - BA +** 21 bits - BBA +** 28 bits - BBBA +** 35 bits - BBBBA +** 42 bits - BBBBBA +** 49 bits - BBBBBBA +** 56 bits - BBBBBBBA +** 64 bits - BBBBBBBBC +*/ + +/* +** Write a 64-bit variable-length integer to memory starting at p[0]. +** The length of data write will be between 1 and 9 bytes. The number +** of bytes written is returned. +** +** A variable-length integer consists of the lower 7 bits of each byte +** for all bytes that have the 8th bit set and one byte with the 8th +** bit clear. Except, if we get to the 9th byte, it stores the full +** 8 bits and is the last byte. +*/ +static int SQLITE_NOINLINE putVarint64(unsigned char *p, u64 v){ + int i, j, n; + u8 buf[10]; + if( v & (((u64)0xff000000)<<32) ){ + p[8] = (u8)v; + v >>= 8; + for(i=7; i>=0; i--){ + p[i] = (u8)((v & 0x7f) | 0x80); + v >>= 7; + } + return 9; + } + n = 0; + do{ + buf[n++] = (u8)((v & 0x7f) | 0x80); + v >>= 7; + }while( v!=0 ); + buf[0] &= 0x7f; + assert( n<=9 ); + for(i=0, j=n-1; j>=0; j--, i++){ + p[i] = buf[j]; + } + return n; +} +SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *p, u64 v){ + if( v<=0x7f ){ + p[0] = v&0x7f; + return 1; + } + if( v<=0x3fff ){ + p[0] = ((v>>7)&0x7f)|0x80; + p[1] = v&0x7f; + return 2; + } + return putVarint64(p,v); +} + +/* +** Bitmasks used by sqlite3GetVarint(). These precomputed constants +** are defined here rather than simply putting the constant expressions +** inline in order to work around bugs in the RVT compiler. +** +** SLOT_2_0 A mask for (0x7f<<14) | 0x7f +** +** SLOT_4_2_0 A mask for (0x7f<<28) | SLOT_2_0 +*/ +#define SLOT_2_0 0x001fc07f +#define SLOT_4_2_0 0xf01fc07f + + +/* +** Read a 64-bit variable-length integer from memory starting at p[0]. +** Return the number of bytes read. The value is stored in *v. +*/ +SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){ + u32 a,b,s; + + a = *p; + /* a: p0 (unmasked) */ + if (!(a&0x80)) + { + *v = a; + return 1; + } + + p++; + b = *p; + /* b: p1 (unmasked) */ + if (!(b&0x80)) + { + a &= 0x7f; + a = a<<7; + a |= b; + *v = a; + return 2; + } + + /* Verify that constants are precomputed correctly */ + assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) ); + assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) ); + + p++; + a = a<<14; + a |= *p; + /* a: p0<<14 | p2 (unmasked) */ + if (!(a&0x80)) + { + a &= SLOT_2_0; + b &= 0x7f; + b = b<<7; + a |= b; + *v = a; + return 3; + } + + /* CSE1 from below */ + a &= SLOT_2_0; + p++; + b = b<<14; + b |= *p; + /* b: p1<<14 | p3 (unmasked) */ + if (!(b&0x80)) + { + b &= SLOT_2_0; + /* moved CSE1 up */ + /* a &= (0x7f<<14)|(0x7f); */ + a = a<<7; + a |= b; + *v = a; + return 4; + } + + /* a: p0<<14 | p2 (masked) */ + /* b: p1<<14 | p3 (unmasked) */ + /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ + /* moved CSE1 up */ + /* a &= (0x7f<<14)|(0x7f); */ + b &= SLOT_2_0; + s = a; + /* s: p0<<14 | p2 (masked) */ + + p++; + a = a<<14; + a |= *p; + /* a: p0<<28 | p2<<14 | p4 (unmasked) */ + if (!(a&0x80)) + { + /* we can skip these cause they were (effectively) done above in calc'ing s */ + /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ + /* b &= (0x7f<<14)|(0x7f); */ + b = b<<7; + a |= b; + s = s>>18; + *v = ((u64)s)<<32 | a; + return 5; + } + + /* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ + s = s<<7; + s |= b; + /* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ + + p++; + b = b<<14; + b |= *p; + /* b: p1<<28 | p3<<14 | p5 (unmasked) */ + if (!(b&0x80)) + { + /* we can skip this cause it was (effectively) done above in calc'ing s */ + /* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ + a &= SLOT_2_0; + a = a<<7; + a |= b; + s = s>>18; + *v = ((u64)s)<<32 | a; + return 6; + } + + p++; + a = a<<14; + a |= *p; + /* a: p2<<28 | p4<<14 | p6 (unmasked) */ + if (!(a&0x80)) + { + a &= SLOT_4_2_0; + b &= SLOT_2_0; + b = b<<7; + a |= b; + s = s>>11; + *v = ((u64)s)<<32 | a; + return 7; + } + + /* CSE2 from below */ + a &= SLOT_2_0; + p++; + b = b<<14; + b |= *p; + /* b: p3<<28 | p5<<14 | p7 (unmasked) */ + if (!(b&0x80)) + { + b &= SLOT_4_2_0; + /* moved CSE2 up */ + /* a &= (0x7f<<14)|(0x7f); */ + a = a<<7; + a |= b; + s = s>>4; + *v = ((u64)s)<<32 | a; + return 8; + } + + p++; + a = a<<15; + a |= *p; + /* a: p4<<29 | p6<<15 | p8 (unmasked) */ + + /* moved CSE2 up */ + /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */ + b &= SLOT_2_0; + b = b<<8; + a |= b; + + s = s<<4; + b = p[-4]; + b &= 0x7f; + b = b>>3; + s |= b; + + *v = ((u64)s)<<32 | a; + + return 9; +} + +/* +** 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. +** +** If the varint stored in p[0] is larger than can fit in a 32-bit unsigned +** integer, then set *v to 0xffffffff. +** +** A MACRO version, getVarint32, is provided which inlines the +** single-byte case. All code should use the MACRO version as +** this function assumes the single-byte case has already been handled. +*/ +SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){ + u32 a,b; + + /* The 1-byte case. Overwhelmingly the most common. Handled inline + ** by the getVarin32() macro */ + a = *p; + /* a: p0 (unmasked) */ +#ifndef getVarint32 + if (!(a&0x80)) + { + /* Values between 0 and 127 */ + *v = a; + return 1; + } +#endif + + /* The 2-byte case */ + p++; + b = *p; + /* b: p1 (unmasked) */ + if (!(b&0x80)) + { + /* Values between 128 and 16383 */ + a &= 0x7f; + a = a<<7; + *v = a | b; + return 2; + } + + /* The 3-byte case */ + p++; + a = a<<14; + a |= *p; + /* a: p0<<14 | p2 (unmasked) */ + if (!(a&0x80)) + { + /* Values between 16384 and 2097151 */ + a &= (0x7f<<14)|(0x7f); + b &= 0x7f; + b = b<<7; + *v = a | b; + return 3; + } + + /* A 32-bit varint is used to store size information in btrees. + ** Objects are rarely larger than 2MiB limit of a 3-byte varint. + ** A 3-byte varint is sufficient, for example, to record the size + ** of a 1048569-byte BLOB or string. + ** + ** We only unroll the first 1-, 2-, and 3- byte cases. The very + ** rare larger cases can be handled by the slower 64-bit varint + ** routine. + */ +#if 1 + { + u64 v64; + u8 n; + + p -= 2; + n = sqlite3GetVarint(p, &v64); + assert( n>3 && n<=9 ); + if( (v64 & SQLITE_MAX_U32)!=v64 ){ + *v = 0xffffffff; + }else{ + *v = (u32)v64; + } + return n; + } + +#else + /* For following code (kept for historical record only) shows an + ** unrolling for the 3- and 4-byte varint cases. This code is + ** slightly faster, but it is also larger and much harder to test. + */ + p++; + b = b<<14; + b |= *p; + /* b: p1<<14 | p3 (unmasked) */ + if (!(b&0x80)) + { + /* Values between 2097152 and 268435455 */ + b &= (0x7f<<14)|(0x7f); + a &= (0x7f<<14)|(0x7f); + a = a<<7; + *v = a | b; + return 4; + } + + p++; + a = a<<14; + a |= *p; + /* a: p0<<28 | p2<<14 | p4 (unmasked) */ + if (!(a&0x80)) + { + /* Values between 268435456 and 34359738367 */ + a &= SLOT_4_2_0; + b &= SLOT_4_2_0; + b = b<<7; + *v = a | b; + return 5; + } + + /* We can only reach this point when reading a corrupt database + ** file. In that case we are not in any hurry. Use the (relatively + ** slow) general-purpose sqlite3GetVarint() routine to extract the + ** value. */ + { + u64 v64; + u8 n; + + p -= 4; + n = sqlite3GetVarint(p, &v64); + assert( n>5 && n<=9 ); + *v = (u32)v64; + return n; + } +#endif +} + +/* +** Return the number of bytes that will be needed to store the given +** 64-bit integer. +*/ +SQLITE_PRIVATE int sqlite3VarintLen(u64 v){ + int i = 0; + do{ + i++; + v >>= 7; + }while( v!=0 && ALWAYS(i<9) ); + return i; +} + + +/* +** Read or write a four-byte big-endian integer value. +*/ +SQLITE_PRIVATE u32 sqlite3Get4byte(const u8 *p){ + testcase( p[0]&0x80 ); + return ((unsigned)p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]; +} +SQLITE_PRIVATE void sqlite3Put4byte(unsigned char *p, u32 v){ + p[0] = (u8)(v>>24); + p[1] = (u8)(v>>16); + p[2] = (u8)(v>>8); + p[3] = (u8)v; +} + + + +/* +** Translate a single byte of Hex into an integer. +** This routine only works if h really is a valid hexadecimal +** character: 0..9a..fA..F +*/ +SQLITE_PRIVATE u8 sqlite3HexToInt(int h){ + assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') ); +#ifdef SQLITE_ASCII + h += 9*(1&(h>>6)); +#endif +#ifdef SQLITE_EBCDIC + h += 9*(1&~(h>>4)); +#endif + return (u8)(h & 0xf); +} + +#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. +*/ +SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){ + char *zBlob; + int i; + + zBlob = (char *)sqlite3DbMallocRaw(db, n/2 + 1); + n--; + if( zBlob ){ + for(i=0; imagic; + if( magic!=SQLITE_MAGIC_OPEN ){ + if( sqlite3SafetyCheckSickOrOk(db) ){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + logBadConnection("unopened"); + } + return 0; + }else{ + return 1; + } +} +SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3 *db){ + u32 magic; + magic = db->magic; + if( magic!=SQLITE_MAGIC_SICK && + magic!=SQLITE_MAGIC_OPEN && + magic!=SQLITE_MAGIC_BUSY ){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + logBadConnection("invalid"); + return 0; + }else{ + return 1; + } +} + +/* +** Attempt to add, substract, or multiply the 64-bit signed value iB against +** the other 64-bit signed integer at *pA and store the result in *pA. +** Return 0 on success. Or if the operation would have resulted in an +** overflow, leave *pA unchanged and return 1. +*/ +SQLITE_PRIVATE int sqlite3AddInt64(i64 *pA, i64 iB){ + i64 iA = *pA; + testcase( iA==0 ); testcase( iA==1 ); + testcase( iB==-1 ); testcase( iB==0 ); + if( iB>=0 ){ + testcase( iA>0 && LARGEST_INT64 - iA == iB ); + testcase( iA>0 && LARGEST_INT64 - iA == iB - 1 ); + if( iA>0 && LARGEST_INT64 - iA < iB ) return 1; + }else{ + testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 1 ); + testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 2 ); + if( iA<0 && -(iA + LARGEST_INT64) > iB + 1 ) return 1; + } + *pA += iB; + return 0; +} +SQLITE_PRIVATE int sqlite3SubInt64(i64 *pA, i64 iB){ + testcase( iB==SMALLEST_INT64+1 ); + if( iB==SMALLEST_INT64 ){ + testcase( (*pA)==(-1) ); testcase( (*pA)==0 ); + if( (*pA)>=0 ) return 1; + *pA -= iB; + return 0; + }else{ + return sqlite3AddInt64(pA, -iB); + } +} +#define TWOPOWER32 (((i64)1)<<32) +#define TWOPOWER31 (((i64)1)<<31) +SQLITE_PRIVATE int sqlite3MulInt64(i64 *pA, i64 iB){ + i64 iA = *pA; + i64 iA1, iA0, iB1, iB0, r; + + iA1 = iA/TWOPOWER32; + iA0 = iA % TWOPOWER32; + iB1 = iB/TWOPOWER32; + iB0 = iB % TWOPOWER32; + if( iA1==0 ){ + if( iB1==0 ){ + *pA *= iB; + return 0; + } + r = iA0*iB1; + }else if( iB1==0 ){ + r = iA1*iB0; + }else{ + /* If both iA1 and iB1 are non-zero, overflow will result */ + return 1; + } + testcase( r==(-TWOPOWER31)-1 ); + testcase( r==(-TWOPOWER31) ); + testcase( r==TWOPOWER31 ); + testcase( r==TWOPOWER31-1 ); + if( r<(-TWOPOWER31) || r>=TWOPOWER31 ) return 1; + r *= TWOPOWER32; + if( sqlite3AddInt64(&r, iA0*iB0) ) return 1; + *pA = r; + return 0; +} + +/* +** Compute the absolute value of a 32-bit signed integer, of possible. Or +** if the integer has a value of -2147483648, return +2147483647 +*/ +SQLITE_PRIVATE int sqlite3AbsInt32(int x){ + if( x>=0 ) return x; + if( x==(int)0x80000000 ) return 0x7fffffff; + return -x; +} + +#ifdef SQLITE_ENABLE_8_3_NAMES +/* +** If SQLITE_ENABLE_8_3_NAMES is set at compile-time and if the database +** filename in zBaseFilename is a URI with the "8_3_names=1" parameter and +** if filename in z[] has a suffix (a.k.a. "extension") that is longer than +** three characters, then shorten the suffix on z[] to be the last three +** characters of the original suffix. +** +** If SQLITE_ENABLE_8_3_NAMES is set to 2 at compile-time, then always +** do the suffix shortening regardless of URI parameter. +** +** Examples: +** +** test.db-journal => test.nal +** test.db-wal => test.wal +** test.db-shm => test.shm +** test.db-mj7f3319fa => test.9fa +*/ +SQLITE_PRIVATE void sqlite3FileSuffix3(const char *zBaseFilename, char *z){ +#if SQLITE_ENABLE_8_3_NAMES<2 + if( sqlite3_uri_boolean(zBaseFilename, "8_3_names", 0) ) +#endif + { + int i, sz; + sz = sqlite3Strlen30(z); + for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} + if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4); + } +} +#endif + +/* +** Find (an approximate) sum of two LogEst values. This computation is +** not a simple "+" operator because LogEst is stored as a logarithmic +** value. +** +*/ +SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst a, LogEst b){ + static const unsigned char x[] = { + 10, 10, /* 0,1 */ + 9, 9, /* 2,3 */ + 8, 8, /* 4,5 */ + 7, 7, 7, /* 6,7,8 */ + 6, 6, 6, /* 9,10,11 */ + 5, 5, 5, /* 12-14 */ + 4, 4, 4, 4, /* 15-18 */ + 3, 3, 3, 3, 3, 3, /* 19-24 */ + 2, 2, 2, 2, 2, 2, 2, /* 25-31 */ + }; + if( a>=b ){ + if( a>b+49 ) return a; + if( a>b+31 ) return a+1; + return a+x[a-b]; + }else{ + if( b>a+49 ) return b; + if( b>a+31 ) return b+1; + return b+x[b-a]; + } +} + +/* +** Convert an integer into a LogEst. In other words, compute an +** approximation for 10*log2(x). +*/ +SQLITE_PRIVATE LogEst sqlite3LogEst(u64 x){ + static LogEst a[] = { 0, 2, 3, 5, 6, 7, 8, 9 }; + LogEst y = 40; + if( x<8 ){ + if( x<2 ) return 0; + while( x<8 ){ y -= 10; x <<= 1; } + }else{ + while( x>255 ){ y += 40; x >>= 4; } + while( x>15 ){ y += 10; x >>= 1; } + } + return a[x&7] + y - 10; +} + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Convert a double into a LogEst +** In other words, compute an approximation for 10*log2(x). +*/ +SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double x){ + u64 a; + LogEst e; + assert( sizeof(x)==8 && sizeof(a)==8 ); + if( x<=1 ) return 0; + if( x<=2000000000 ) return sqlite3LogEst((u64)x); + memcpy(&a, &x, 8); + e = (a>>52) - 1022; + return e*10; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +/* +** Convert a LogEst into an integer. +*/ +SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst x){ + u64 n; + if( x<10 ) return 1; + n = x%10; + x /= 10; + if( n>=5 ) n -= 2; + else if( n>=1 ) n -= 1; + if( x>=3 ){ + return x>60 ? (u64)LARGEST_INT64 : (n+8)<<(x-3); + } + return (n+8)>>(3-x); +} + +/************** End of util.c ************************************************/ +/************** Begin file hash.c ********************************************/ +/* +** 2001 September 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 is the implementation of generic hash-tables +** used in SQLite. +*/ +/* #include */ + +/* Turn bulk memory into a hash table object by initializing the +** fields of the Hash structure. +** +** "pNew" is a pointer to the hash table that is to be initialized. +*/ +SQLITE_PRIVATE void sqlite3HashInit(Hash *pNew){ + assert( pNew!=0 ); + pNew->first = 0; + pNew->count = 0; + pNew->htsize = 0; + pNew->ht = 0; +} + +/* Remove all entries from a hash table. Reclaim all memory. +** Call this routine to delete a hash table or to reset a hash table +** to the empty state. +*/ +SQLITE_PRIVATE void sqlite3HashClear(Hash *pH){ + HashElem *elem; /* For looping over all elements of the table */ + + assert( pH!=0 ); + elem = pH->first; + pH->first = 0; + sqlite3_free(pH->ht); + pH->ht = 0; + pH->htsize = 0; + while( elem ){ + HashElem *next_elem = elem->next; + sqlite3_free(elem); + elem = next_elem; + } + pH->count = 0; +} + +/* +** The hashing function. +*/ +static unsigned int strHash(const char *z){ + unsigned int h = 0; + unsigned char c; + while( (c = (unsigned char)*z++)!=0 ){ + h = (h<<3) ^ h ^ sqlite3UpperToLower[c]; + } + return h; +} + + +/* Link pNew element into the hash table pH. If pEntry!=0 then also +** insert pNew into the pEntry hash bucket. +*/ +static void insertElement( + Hash *pH, /* The complete hash table */ + struct _ht *pEntry, /* The entry into which pNew is inserted */ + HashElem *pNew /* The element to be inserted */ +){ + HashElem *pHead; /* First element already in pEntry */ + if( pEntry ){ + pHead = pEntry->count ? pEntry->chain : 0; + pEntry->count++; + pEntry->chain = pNew; + }else{ + pHead = 0; + } + if( pHead ){ + pNew->next = pHead; + pNew->prev = pHead->prev; + if( pHead->prev ){ pHead->prev->next = pNew; } + else { pH->first = pNew; } + pHead->prev = pNew; + }else{ + pNew->next = pH->first; + if( pH->first ){ pH->first->prev = pNew; } + pNew->prev = 0; + pH->first = pNew; + } +} + + +/* Resize the hash table so that it cantains "new_size" buckets. +** +** The hash table might fail to resize if sqlite3_malloc() fails or +** if the new size is the same as the prior size. +** Return TRUE if the resize occurs and false if not. +*/ +static int rehash(Hash *pH, unsigned int new_size){ + struct _ht *new_ht; /* The new hash table */ + HashElem *elem, *next_elem; /* For looping over existing elements */ + +#if SQLITE_MALLOC_SOFT_LIMIT>0 + if( new_size*sizeof(struct _ht)>SQLITE_MALLOC_SOFT_LIMIT ){ + new_size = SQLITE_MALLOC_SOFT_LIMIT/sizeof(struct _ht); + } + if( new_size==pH->htsize ) return 0; +#endif + + /* The inability to allocates space for a larger hash table is + ** a performance hit but it is not a fatal error. So mark the + ** allocation as a benign. Use sqlite3Malloc()/memset(0) instead of + ** sqlite3MallocZero() to make the allocation, as sqlite3MallocZero() + ** only zeroes the requested number of bytes whereas this module will + ** use the actual amount of space allocated for the hash table (which + ** may be larger than the requested amount). + */ + sqlite3BeginBenignMalloc(); + new_ht = (struct _ht *)sqlite3Malloc( new_size*sizeof(struct _ht) ); + sqlite3EndBenignMalloc(); + + if( new_ht==0 ) return 0; + sqlite3_free(pH->ht); + pH->ht = new_ht; + pH->htsize = new_size = sqlite3MallocSize(new_ht)/sizeof(struct _ht); + memset(new_ht, 0, new_size*sizeof(struct _ht)); + for(elem=pH->first, pH->first=0; elem; elem = next_elem){ + unsigned int h = strHash(elem->pKey) % new_size; + next_elem = elem->next; + insertElement(pH, &new_ht[h], elem); + } + return 1; +} + +/* This function (for internal use only) locates an element in an +** hash table that matches the given key. The hash for this key is +** also computed and returned in the *pH parameter. +*/ +static HashElem *findElementWithHash( + const Hash *pH, /* The pH to be searched */ + const char *pKey, /* The key we are searching for */ + unsigned int *pHash /* Write the hash value here */ +){ + HashElem *elem; /* Used to loop thru the element list */ + int count; /* Number of elements left to test */ + unsigned int h; /* The computed hash */ + + if( pH->ht ){ + struct _ht *pEntry; + h = strHash(pKey) % pH->htsize; + pEntry = &pH->ht[h]; + elem = pEntry->chain; + count = pEntry->count; + }else{ + h = 0; + elem = pH->first; + count = pH->count; + } + *pHash = h; + while( count-- ){ + assert( elem!=0 ); + if( sqlite3StrICmp(elem->pKey,pKey)==0 ){ + return elem; + } + elem = elem->next; + } + return 0; +} + +/* Remove a single entry from the hash table given a pointer to that +** element and a hash on the element's key. +*/ +static void removeElementGivenHash( + Hash *pH, /* The pH containing "elem" */ + HashElem* elem, /* The element to be removed from the pH */ + unsigned int h /* Hash value for the element */ +){ + struct _ht *pEntry; + if( elem->prev ){ + elem->prev->next = elem->next; + }else{ + pH->first = elem->next; + } + if( elem->next ){ + elem->next->prev = elem->prev; + } + if( pH->ht ){ + pEntry = &pH->ht[h]; + if( pEntry->chain==elem ){ + pEntry->chain = elem->next; + } + pEntry->count--; + assert( pEntry->count>=0 ); + } + sqlite3_free( 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. Return the data for this element if it is +** found, or NULL if there is no match. +*/ +SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey){ + HashElem *elem; /* The element that matches key */ + unsigned int h; /* A hash on key */ + + assert( pH!=0 ); + assert( pKey!=0 ); + elem = findElementWithHash(pH, pKey, &h); + return elem ? elem->data : 0; +} + +/* Insert an element into the hash table pH. The key is pKey +** and the data is "data". +** +** If no element exists with a matching key, then a new +** element is created and NULL is returned. +** +** If another element already exists with the same key, then the +** new data replaces the old data and the old data is returned. +** The key is not copied in this instance. If a malloc fails, then +** the new data is returned and the hash table is unchanged. +** +** If the "data" parameter to this function is NULL, then the +** element corresponding to "key" is removed from the hash table. +*/ +SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, void *data){ + unsigned int h; /* the hash of the key modulo hash table size */ + HashElem *elem; /* Used to loop thru the element list */ + HashElem *new_elem; /* New element added to the pH */ + + assert( pH!=0 ); + assert( pKey!=0 ); + elem = findElementWithHash(pH,pKey,&h); + if( elem ){ + void *old_data = elem->data; + if( data==0 ){ + removeElementGivenHash(pH,elem,h); + }else{ + elem->data = data; + elem->pKey = pKey; + } + return old_data; + } + if( data==0 ) return 0; + new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) ); + if( new_elem==0 ) return data; + new_elem->pKey = pKey; + new_elem->data = data; + pH->count++; + if( pH->count>=10 && pH->count > 2*pH->htsize ){ + if( rehash(pH, pH->count*2) ){ + assert( pH->htsize>0 ); + h = strHash(pKey) % pH->htsize; + } + } + insertElement(pH, pH->ht ? &pH->ht[h] : 0, new_elem); + return 0; +} + +/************** End of hash.c ************************************************/ +/************** Begin file opcodes.c *****************************************/ +/* Automatically generated. Do not edit */ +/* See the mkopcodec.awk script for details. */ +#if !defined(SQLITE_OMIT_EXPLAIN) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) +#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) || defined(SQLITE_DEBUG) +# define OpHelp(X) "\0" X +#else +# define OpHelp(X) +#endif +SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ + static const char *const azName[] = { "?", + /* 1 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"), + /* 2 */ "Savepoint" OpHelp(""), + /* 3 */ "AutoCommit" OpHelp(""), + /* 4 */ "Transaction" OpHelp(""), + /* 5 */ "SorterNext" OpHelp(""), + /* 6 */ "PrevIfOpen" OpHelp(""), + /* 7 */ "NextIfOpen" OpHelp(""), + /* 8 */ "Prev" OpHelp(""), + /* 9 */ "Next" OpHelp(""), + /* 10 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 11 */ "Checkpoint" OpHelp(""), + /* 12 */ "JournalMode" OpHelp(""), + /* 13 */ "Vacuum" OpHelp(""), + /* 14 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"), + /* 15 */ "VUpdate" OpHelp("data=r[P3@P2]"), + /* 16 */ "Goto" OpHelp(""), + /* 17 */ "Gosub" OpHelp(""), + /* 18 */ "Return" OpHelp(""), + /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"), + /* 20 */ "InitCoroutine" OpHelp(""), + /* 21 */ "EndCoroutine" OpHelp(""), + /* 22 */ "Yield" OpHelp(""), + /* 23 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), + /* 24 */ "Halt" OpHelp(""), + /* 25 */ "Integer" OpHelp("r[P2]=P1"), + /* 26 */ "Int64" OpHelp("r[P2]=P4"), + /* 27 */ "String" OpHelp("r[P2]='P4' (len=P1)"), + /* 28 */ "Null" OpHelp("r[P2..P3]=NULL"), + /* 29 */ "SoftNull" OpHelp("r[P1]=NULL"), + /* 30 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), + /* 31 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), + /* 32 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), + /* 33 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), + /* 34 */ "SCopy" OpHelp("r[P2]=r[P1]"), + /* 35 */ "ResultRow" OpHelp("output=r[P1@P2]"), + /* 36 */ "CollSeq" OpHelp(""), + /* 37 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), + /* 38 */ "MustBeInt" OpHelp(""), + /* 39 */ "RealAffinity" OpHelp(""), + /* 40 */ "Cast" OpHelp("affinity(r[P1])"), + /* 41 */ "Permutation" OpHelp(""), + /* 42 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), + /* 43 */ "Jump" OpHelp(""), + /* 44 */ "Once" OpHelp(""), + /* 45 */ "If" OpHelp(""), + /* 46 */ "IfNot" OpHelp(""), + /* 47 */ "Column" OpHelp("r[P3]=PX"), + /* 48 */ "Affinity" OpHelp("affinity(r[P1@P2])"), + /* 49 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), + /* 50 */ "Count" OpHelp("r[P2]=count()"), + /* 51 */ "ReadCookie" OpHelp(""), + /* 52 */ "SetCookie" OpHelp(""), + /* 53 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), + /* 54 */ "OpenRead" OpHelp("root=P2 iDb=P3"), + /* 55 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), + /* 56 */ "OpenAutoindex" OpHelp("nColumn=P2"), + /* 57 */ "OpenEphemeral" OpHelp("nColumn=P2"), + /* 58 */ "SorterOpen" OpHelp(""), + /* 59 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), + /* 60 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), + /* 61 */ "Close" OpHelp(""), + /* 62 */ "SeekLT" OpHelp("key=r[P3@P4]"), + /* 63 */ "SeekLE" OpHelp("key=r[P3@P4]"), + /* 64 */ "SeekGE" OpHelp("key=r[P3@P4]"), + /* 65 */ "SeekGT" OpHelp("key=r[P3@P4]"), + /* 66 */ "Seek" OpHelp("intkey=r[P2]"), + /* 67 */ "NoConflict" OpHelp("key=r[P3@P4]"), + /* 68 */ "NotFound" OpHelp("key=r[P3@P4]"), + /* 69 */ "Found" OpHelp("key=r[P3@P4]"), + /* 70 */ "NotExists" OpHelp("intkey=r[P3]"), + /* 71 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), + /* 72 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), + /* 73 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), + /* 74 */ "NewRowid" OpHelp("r[P2]=rowid"), + /* 75 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), + /* 76 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), + /* 77 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), + /* 78 */ "Ne" OpHelp("if r[P1]!=r[P3] goto P2"), + /* 79 */ "Eq" OpHelp("if r[P1]==r[P3] goto P2"), + /* 80 */ "Gt" OpHelp("if r[P1]>r[P3] goto P2"), + /* 81 */ "Le" OpHelp("if r[P1]<=r[P3] goto P2"), + /* 82 */ "Lt" OpHelp("if r[P1]=r[P3] goto P2"), + /* 84 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), + /* 85 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), + /* 86 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), + /* 87 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"), + /* 89 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), + /* 90 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), + /* 91 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), + /* 92 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), + /* 93 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), + /* 94 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), + /* 95 */ "Delete" OpHelp(""), + /* 96 */ "BitNot" OpHelp("r[P1]= ~r[P1]"), + /* 97 */ "String8" OpHelp("r[P2]='P4'"), + /* 98 */ "ResetCount" OpHelp(""), + /* 99 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), + /* 100 */ "SorterData" OpHelp("r[P2]=data"), + /* 101 */ "RowKey" OpHelp("r[P2]=key"), + /* 102 */ "RowData" OpHelp("r[P2]=data"), + /* 103 */ "Rowid" OpHelp("r[P2]=rowid"), + /* 104 */ "NullRow" OpHelp(""), + /* 105 */ "Last" OpHelp(""), + /* 106 */ "SorterSort" OpHelp(""), + /* 107 */ "Sort" OpHelp(""), + /* 108 */ "Rewind" OpHelp(""), + /* 109 */ "SorterInsert" OpHelp(""), + /* 110 */ "IdxInsert" OpHelp("key=r[P2]"), + /* 111 */ "IdxDelete" OpHelp("key=r[P2@P3]"), + /* 112 */ "IdxRowid" OpHelp("r[P2]=rowid"), + /* 113 */ "IdxLE" OpHelp("key=r[P3@P4]"), + /* 114 */ "IdxGT" OpHelp("key=r[P3@P4]"), + /* 115 */ "IdxLT" OpHelp("key=r[P3@P4]"), + /* 116 */ "IdxGE" OpHelp("key=r[P3@P4]"), + /* 117 */ "Destroy" OpHelp(""), + /* 118 */ "Clear" OpHelp(""), + /* 119 */ "ResetSorter" OpHelp(""), + /* 120 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"), + /* 121 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"), + /* 122 */ "ParseSchema" OpHelp(""), + /* 123 */ "LoadAnalysis" OpHelp(""), + /* 124 */ "DropTable" OpHelp(""), + /* 125 */ "DropIndex" OpHelp(""), + /* 126 */ "DropTrigger" OpHelp(""), + /* 127 */ "IntegrityCk" OpHelp(""), + /* 128 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), + /* 129 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), + /* 130 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), + /* 131 */ "Program" OpHelp(""), + /* 132 */ "Param" OpHelp(""), + /* 133 */ "Real" OpHelp("r[P2]=P4"), + /* 134 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), + /* 135 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), + /* 136 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), + /* 137 */ "IfPos" OpHelp("if r[P1]>0 goto P2"), + /* 138 */ "IfNeg" OpHelp("r[P1]+=P3, if r[P1]<0 goto P2"), + /* 139 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]+=P3, goto P2"), + /* 140 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), + /* 141 */ "JumpZeroIncr" OpHelp("if (r[P1]++)==0 ) goto P2"), + /* 142 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), + /* 143 */ "IncrVacuum" OpHelp(""), + /* 144 */ "Expire" OpHelp(""), + /* 145 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), + /* 146 */ "VBegin" OpHelp(""), + /* 147 */ "VCreate" OpHelp(""), + /* 148 */ "VDestroy" OpHelp(""), + /* 149 */ "VOpen" OpHelp(""), + /* 150 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), + /* 151 */ "VNext" OpHelp(""), + /* 152 */ "VRename" OpHelp(""), + /* 153 */ "Pagecount" OpHelp(""), + /* 154 */ "MaxPgcnt" OpHelp(""), + /* 155 */ "Init" OpHelp("Start at P2"), + /* 156 */ "Noop" OpHelp(""), + /* 157 */ "Explain" OpHelp(""), + }; + return azName[i]; +} +#endif + +/************** End of opcodes.c *********************************************/ +/************** Begin file os_unix.c *****************************************/ +/* +** 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 file contains the VFS implementation for unix-like operating systems +** include Linux, MacOSX, *BSD, QNX, VxWorks, AIX, HPUX, and others. +** +** There are actually several different VFS implementations in this file. +** The differences are in the way that file locking is done. The default +** implementation uses Posix Advisory Locks. Alternative implementations +** use flock(), dot-files, various proprietary locking schemas, or simply +** skip locking all together. +** +** This source file is organized into divisions where the logic for various +** subfunctions is contained within the appropriate division. PLEASE +** KEEP THE STRUCTURE OF THIS FILE INTACT. New code should be placed +** in the correct division and should be clearly labeled. +** +** The layout of divisions is as follows: +** +** * General-purpose declarations and utility functions. +** * Unique file ID logic used by VxWorks. +** * Various locking primitive implementations (all except proxy locking): +** + for Posix Advisory Locks +** + for no-op locks +** + for dot-file locks +** + for flock() locking +** + for named semaphore locks (VxWorks only) +** + for AFP filesystem locks (MacOSX only) +** * sqlite3_file methods not associated with locking. +** * Definitions of sqlite3_io_methods objects for all locking +** methods plus "finder" functions for each locking method. +** * sqlite3_vfs method implementations. +** * Locking primitives for the proxy uber-locking-method. (MacOSX only) +** * Definitions of sqlite3_vfs objects for all locking methods +** plus implementations of sqlite3_os_init() and sqlite3_os_end(). +*/ +#if SQLITE_OS_UNIX /* This file is used on unix only */ + +/* +** There are various methods for file locking used for concurrency +** control: +** +** 1. POSIX locking (the default), +** 2. No locking, +** 3. Dot-file locking, +** 4. flock() locking, +** 5. AFP locking (OSX only), +** 6. Named POSIX semaphores (VXWorks only), +** 7. proxy locking. (OSX only) +** +** Styles 4, 5, and 7 are only available of SQLITE_ENABLE_LOCKING_STYLE +** is defined to 1. The SQLITE_ENABLE_LOCKING_STYLE also enables automatic +** selection of the appropriate locking style based on the filesystem +** where the database is located. +*/ +#if !defined(SQLITE_ENABLE_LOCKING_STYLE) +# if defined(__APPLE__) +# define SQLITE_ENABLE_LOCKING_STYLE 1 +# else +# define SQLITE_ENABLE_LOCKING_STYLE 0 +# endif +#endif + +/* +** standard include files. +*/ +#include +#include +#include +#include +/* #include */ +#include +#include +#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 +# include +#endif + +#if SQLITE_ENABLE_LOCKING_STYLE +# include +# include +# include +#endif /* SQLITE_ENABLE_LOCKING_STYLE */ + +#if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \ + (__IPHONE_OS_VERSION_MIN_REQUIRED > 2000)) +# if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \ + && (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0)) +# define HAVE_GETHOSTUUID 1 +# else +# warning "gethostuuid() is disabled." +# endif +#endif + + +#if OS_VXWORKS +/* # include */ +# include +# include +#endif /* OS_VXWORKS */ + +#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE +# include +#endif + +#ifdef HAVE_UTIME +# include +#endif + +/* +** Allowed values of unixFile.fsFlags +*/ +#define SQLITE_FSFLAGS_IS_MSDOS 0x1 + +/* +** If we are to be thread-safe, include the pthreads header and define +** the SQLITE_UNIX_THREADS macro. +*/ +#if SQLITE_THREADSAFE +/* # include */ +# 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 + +/* +** Default permissions when creating auto proxy dir +*/ +#ifndef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS +# define SQLITE_DEFAULT_PROXYDIR_PERMISSIONS 0755 +#endif + +/* +** Maximum supported path-length. +*/ +#define MAX_PATHNAME 512 + +/* Always cast the getpid() return type for compatibility with +** kernel modules in VxWorks. */ +#define osGetpid(X) (pid_t)getpid() + +/* +** Only set the lastErrno if the error code is a real error and not +** a normal expected return code of SQLITE_BUSY or SQLITE_OK +*/ +#define IS_LOCK_ERROR(x) ((x != SQLITE_OK) && (x != SQLITE_BUSY)) + +/* Forward references */ +typedef struct unixShm unixShm; /* Connection shared memory */ +typedef struct unixShmNode unixShmNode; /* Shared memory instance */ +typedef struct unixInodeInfo unixInodeInfo; /* An i-node */ +typedef struct UnixUnusedFd UnixUnusedFd; /* An unused file descriptor */ + +/* +** Sometimes, after a file handle is closed by SQLite, the file descriptor +** cannot be closed immediately. In these cases, instances of the following +** structure are used to store the file descriptor while waiting for an +** opportunity to either close or reuse it. +*/ +struct UnixUnusedFd { + int fd; /* File descriptor to close */ + int flags; /* Flags this file descriptor was opened with */ + UnixUnusedFd *pNext; /* Next unused file descriptor on same file */ +}; + +/* +** The unixFile structure is subclass of sqlite3_file specific to the unix +** VFS implementations. +*/ +typedef struct unixFile unixFile; +struct unixFile { + sqlite3_io_methods const *pMethod; /* Always the first entry */ + sqlite3_vfs *pVfs; /* The VFS that created this unixFile */ + unixInodeInfo *pInode; /* Info about locks on this inode */ + int h; /* The file descriptor */ + unsigned char eFileLock; /* The type of lock held on this fd */ + unsigned short int ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ + int lastErrno; /* The unix errno from last I/O error */ + void *lockingContext; /* Locking style specific state */ + UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ + const char *zPath; /* Name of the file */ + unixShm *pShm; /* Shared memory segment information */ + int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ +#if SQLITE_MAX_MMAP_SIZE>0 + int nFetchOut; /* Number of outstanding xFetch refs */ + sqlite3_int64 mmapSize; /* Usable size of mapping at pMapRegion */ + sqlite3_int64 mmapSizeActual; /* Actual size of mapping at pMapRegion */ + sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ + void *pMapRegion; /* Memory mapped region */ +#endif +#ifdef __QNXNTO__ + int sectorSize; /* Device sector size */ + int deviceCharacteristics; /* Precomputed device characteristics */ +#endif +#if SQLITE_ENABLE_LOCKING_STYLE + int openFlags; /* The flags specified at open() */ +#endif +#if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__) + unsigned fsFlags; /* cached details from statfs() */ +#endif +#if OS_VXWORKS + struct vxworksFileId *pId; /* Unique file ID */ +#endif +#ifdef SQLITE_DEBUG + /* The next group of variables are used to track whether or not the + ** transaction counter in bytes 24-27 of database files are updated + ** whenever any part of the database changes. An assertion fault will + ** occur if a file is updated without also updating the transaction + ** counter. This test is made to avoid new problems similar to the + ** one described by ticket #3584. + */ + unsigned char transCntrChng; /* True if the transaction counter changed */ + unsigned char dbUpdate; /* True if any part of database file changed */ + unsigned char inNormalWrite; /* True if in a normal write operation */ + +#endif + +#ifdef SQLITE_TEST + /* In test mode, increase the size of this structure a bit so that + ** it is larger than the struct CrashFile defined in test6.c. + */ + char aPadding[32]; +#endif +}; + +/* This variable holds the process id (pid) from when the xRandomness() +** method was called. If xOpen() is called from a different process id, +** indicating that a fork() has occurred, the PRNG will be reset. +*/ +static pid_t randomnessPid = 0; + +/* +** Allowed values for the unixFile.ctrlFlags bitmask: +*/ +#define UNIXFILE_EXCL 0x01 /* Connections from one process only */ +#define UNIXFILE_RDONLY 0x02 /* Connection is read only */ +#define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ +#ifndef SQLITE_DISABLE_DIRSYNC +# define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */ +#else +# define UNIXFILE_DIRSYNC 0x00 +#endif +#define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ +#define UNIXFILE_DELETE 0x20 /* Delete on close */ +#define UNIXFILE_URI 0x40 /* Filename might have query parameters */ +#define UNIXFILE_NOLOCK 0x80 /* Do no file locking */ +#define UNIXFILE_WARNED 0x0100 /* verifyDbFile() warnings issued */ +#define UNIXFILE_BLOCK 0x0200 /* Next SHM lock might block */ + +/* +** Include code that is common to all os_*.c files +*/ +/************** Include os_common.h in the middle of os_unix.c ***************/ +/************** Begin file os_common.h ***************************************/ +/* +** 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 file contains macros and a little bit of code that is common to +** all of the platform-specific files (os_*.c) and is #included into those +** files. +** +** This file should be #included by the os_*.c files only. It is not a +** general purpose header file. +*/ +#ifndef _OS_COMMON_H_ +#define _OS_COMMON_H_ + +/* +** At least two bugs have slipped in because we changed the MEMORY_DEBUG +** macro to SQLITE_DEBUG and some older makefiles have not yet made the +** 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 + +/* +** Macros for performance tracing. Normally turned off. Only works +** on i486 hardware. +*/ +#ifdef SQLITE_PERFORMANCE_TRACE + +/* +** hwtime.h contains inline assembler code for implementing +** high-performance timing routines. +*/ +/************** Include hwtime.h in the middle of os_common.h ****************/ +/************** Begin file hwtime.h ******************************************/ +/* +** 2008 May 27 +** +** 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 inline asm code for retrieving "high-performance" +** counters for x86 class CPUs. +*/ +#ifndef _HWTIME_H_ +#define _HWTIME_H_ + +/* +** The following routine only works on pentium-class (or newer) processors. +** It uses the RDTSC opcode to read the cycle count value out of the +** processor and returns that value. This can be used for high-res +** profiling. +*/ +#if (defined(__GNUC__) || defined(_MSC_VER)) && \ + (defined(i386) || defined(__i386__) || defined(_M_IX86)) + + #if defined(__GNUC__) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned int lo, hi; + __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); + return (sqlite_uint64)hi << 32 | lo; + } + + #elif defined(_MSC_VER) + + __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ + __asm { + rdtsc + ret ; return value at EDX:EAX + } + } + + #endif + +#elif (defined(__GNUC__) && defined(__x86_64__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned long val; + __asm__ __volatile__ ("rdtsc" : "=A" (val)); + return val; + } + +#elif (defined(__GNUC__) && defined(__ppc__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned long long retval; + unsigned long junk; + __asm__ __volatile__ ("\n\ + 1: mftbu %1\n\ + mftb %L0\n\ + mftbu %0\n\ + cmpw %0,%1\n\ + bne 1b" + : "=r" (retval), "=r" (junk)); + return retval; + } + +#else + + #error Need implementation of sqlite3Hwtime() for your platform. + + /* + ** To compile without implementing sqlite3Hwtime() for your platform, + ** you can remove the above #error and use the following + ** stub function. You will lose timing support for many + ** of the debugging and testing utilities, but it should at + ** least compile and run. + */ +SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } + +#endif + +#endif /* !defined(_HWTIME_H_) */ + +/************** End of hwtime.h **********************************************/ +/************** Continuing where we left off in os_common.h ******************/ + +static sqlite_uint64 g_start; +static sqlite_uint64 g_elapsed; +#define TIMER_START g_start=sqlite3Hwtime() +#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start +#define TIMER_ELAPSED g_elapsed +#else +#define TIMER_START +#define TIMER_END +#define TIMER_ELAPSED ((sqlite_uint64)0) +#endif + +/* +** 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 +SQLITE_API int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */ +SQLITE_API int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */ +SQLITE_API int sqlite3_io_error_pending = 0; /* Count down to first I/O error */ +SQLITE_API int sqlite3_io_error_persist = 0; /* True if I/O errors persist */ +SQLITE_API int sqlite3_io_error_benign = 0; /* True if errors are benign */ +SQLITE_API int sqlite3_diskfull_pending = 0; +SQLITE_API int sqlite3_diskfull = 0; +#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) +#define SimulateIOError(CODE) \ + if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ + || sqlite3_io_error_pending-- == 1 ) \ + { local_ioerr(); CODE; } +static void local_ioerr(){ + IOTRACE(("IOERR\n")); + sqlite3_io_error_hit++; + if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; +} +#define SimulateDiskfullError(CODE) \ + if( sqlite3_diskfull_pending ){ \ + if( sqlite3_diskfull_pending == 1 ){ \ + local_ioerr(); \ + sqlite3_diskfull = 1; \ + sqlite3_io_error_hit = 1; \ + CODE; \ + }else{ \ + sqlite3_diskfull_pending--; \ + } \ + } +#else +#define SimulateIOErrorBenign(X) +#define SimulateIOError(A) +#define SimulateDiskfullError(A) +#endif + +/* +** When testing, keep a count of the number of open files. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_open_file_count = 0; +#define OpenCounter(X) sqlite3_open_file_count+=(X) +#else +#define OpenCounter(X) +#endif + +#endif /* !defined(_OS_COMMON_H_) */ + +/************** End of os_common.h *******************************************/ +/************** Continuing where we left off in os_unix.c ********************/ + +/* +** 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 threadid macro resolves to the thread-id or to 0. Used for +** testing and debugging only. +*/ +#if SQLITE_THREADSAFE +#define threadid pthread_self() +#else +#define threadid 0 +#endif + +/* +** HAVE_MREMAP defaults to true on Linux and false everywhere else. +*/ +#if !defined(HAVE_MREMAP) +# if defined(__linux__) && defined(_GNU_SOURCE) +# define HAVE_MREMAP 1 +# else +# define HAVE_MREMAP 0 +# endif +#endif + +/* +** Explicitly call the 64-bit version of lseek() on Android. Otherwise, lseek() +** is the 32-bit version, even if _FILE_OFFSET_BITS=64 is defined. +*/ +#ifdef __ANDROID__ +# define lseek lseek64 +#endif + +/* +** Different Unix systems declare open() in different ways. Same use +** open(const char*,int,mode_t). Others use open(const char*,int,...). +** The difference is important when using a pointer to the function. +** +** The safest way to deal with the problem is to always use this wrapper +** which always has the same well-defined interface. +*/ +static int posixOpen(const char *zFile, int flags, int mode){ + return open(zFile, flags, mode); +} + +/* +** On some systems, calls to fchown() will trigger a message in a security +** log if they come from non-root processes. So avoid calling fchown() if +** we are not running as root. +*/ +static int posixFchown(int fd, uid_t uid, gid_t gid){ +#if OS_VXWORKS + return 0; +#else + return geteuid() ? 0 : fchown(fd,uid,gid); +#endif +} + +/* Forward reference */ +static int openDirectory(const char*, int*); +static int unixGetpagesize(void); + +/* +** Many system calls are accessed through pointer-to-functions so that +** they may be overridden at runtime to facilitate fault injection during +** testing and sandboxing. The following array holds the names and pointers +** to all overrideable system calls. +*/ +static struct unix_syscall { + const char *zName; /* Name of the system call */ + sqlite3_syscall_ptr pCurrent; /* Current value of the system call */ + sqlite3_syscall_ptr pDefault; /* Default value */ +} aSyscall[] = { + { "open", (sqlite3_syscall_ptr)posixOpen, 0 }, +#define osOpen ((int(*)(const char*,int,int))aSyscall[0].pCurrent) + + { "close", (sqlite3_syscall_ptr)close, 0 }, +#define osClose ((int(*)(int))aSyscall[1].pCurrent) + + { "access", (sqlite3_syscall_ptr)access, 0 }, +#define osAccess ((int(*)(const char*,int))aSyscall[2].pCurrent) + + { "getcwd", (sqlite3_syscall_ptr)getcwd, 0 }, +#define osGetcwd ((char*(*)(char*,size_t))aSyscall[3].pCurrent) + + { "stat", (sqlite3_syscall_ptr)stat, 0 }, +#define osStat ((int(*)(const char*,struct stat*))aSyscall[4].pCurrent) + +/* +** 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 is DOS - what did you expect? +*/ +#ifdef __DJGPP__ + { "fstat", 0, 0 }, +#define osFstat(a,b,c) 0 +#else + { "fstat", (sqlite3_syscall_ptr)fstat, 0 }, +#define osFstat ((int(*)(int,struct stat*))aSyscall[5].pCurrent) +#endif + + { "ftruncate", (sqlite3_syscall_ptr)ftruncate, 0 }, +#define osFtruncate ((int(*)(int,off_t))aSyscall[6].pCurrent) + + { "fcntl", (sqlite3_syscall_ptr)fcntl, 0 }, +#define osFcntl ((int(*)(int,int,...))aSyscall[7].pCurrent) + + { "read", (sqlite3_syscall_ptr)read, 0 }, +#define osRead ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent) + +#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE + { "pread", (sqlite3_syscall_ptr)pread, 0 }, +#else + { "pread", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osPread ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[9].pCurrent) + +#if defined(USE_PREAD64) + { "pread64", (sqlite3_syscall_ptr)pread64, 0 }, +#else + { "pread64", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osPread64 ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[10].pCurrent) + + { "write", (sqlite3_syscall_ptr)write, 0 }, +#define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent) + +#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE + { "pwrite", (sqlite3_syscall_ptr)pwrite, 0 }, +#else + { "pwrite", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osPwrite ((ssize_t(*)(int,const void*,size_t,off_t))\ + aSyscall[12].pCurrent) + +#if defined(USE_PREAD64) + { "pwrite64", (sqlite3_syscall_ptr)pwrite64, 0 }, +#else + { "pwrite64", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\ + aSyscall[13].pCurrent) + + { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 }, +#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent) + +#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE + { "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 }, +#else + { "fallocate", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osFallocate ((int(*)(int,off_t,off_t))aSyscall[15].pCurrent) + + { "unlink", (sqlite3_syscall_ptr)unlink, 0 }, +#define osUnlink ((int(*)(const char*))aSyscall[16].pCurrent) + + { "openDirectory", (sqlite3_syscall_ptr)openDirectory, 0 }, +#define osOpenDirectory ((int(*)(const char*,int*))aSyscall[17].pCurrent) + + { "mkdir", (sqlite3_syscall_ptr)mkdir, 0 }, +#define osMkdir ((int(*)(const char*,mode_t))aSyscall[18].pCurrent) + + { "rmdir", (sqlite3_syscall_ptr)rmdir, 0 }, +#define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) + + { "fchown", (sqlite3_syscall_ptr)posixFchown, 0 }, +#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent) + +#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 + { "mmap", (sqlite3_syscall_ptr)mmap, 0 }, +#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent) + + { "munmap", (sqlite3_syscall_ptr)munmap, 0 }, +#define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent) + +#if HAVE_MREMAP + { "mremap", (sqlite3_syscall_ptr)mremap, 0 }, +#else + { "mremap", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent) + { "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 }, +#define osGetpagesize ((int(*)(void))aSyscall[24].pCurrent) + +#endif + +}; /* End of the overrideable system calls */ + +/* +** This is the xSetSystemCall() method of sqlite3_vfs for all of the +** "unix" VFSes. Return SQLITE_OK opon successfully updating the +** system call pointer, or SQLITE_NOTFOUND if there is no configurable +** system call named zName. +*/ +static int unixSetSystemCall( + sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */ + const char *zName, /* Name of system call to override */ + sqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */ +){ + unsigned int i; + int rc = SQLITE_NOTFOUND; + + UNUSED_PARAMETER(pNotUsed); + if( zName==0 ){ + /* If no zName is given, restore all system calls to their default + ** settings and return NULL + */ + rc = SQLITE_OK; + for(i=0; i=SQLITE_MINIMUM_FILE_DESCRIPTOR ) break; + osClose(fd); + sqlite3_log(SQLITE_WARNING, + "attempt to open \"%s\" as file descriptor %d", z, fd); + fd = -1; + if( osOpen("/dev/null", f, m)<0 ) break; + } + if( fd>=0 ){ + if( m!=0 ){ + struct stat statbuf; + if( osFstat(fd, &statbuf)==0 + && statbuf.st_size==0 + && (statbuf.st_mode&0777)!=m + ){ + osFchmod(fd, m); + } + } +#if defined(FD_CLOEXEC) && (!defined(O_CLOEXEC) || O_CLOEXEC==0) + osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC); +#endif + } + return fd; +} + +/* +** Helper functions to obtain and relinquish the global mutex. The +** global mutex is used to protect the unixInodeInfo and +** vxworksFileId objects used by this file, all of which may be +** shared by multiple threads. +** +** Function unixMutexHeld() is used to assert() that the global mutex +** is held when required. This function is only used as part of assert() +** statements. e.g. +** +** unixEnterMutex() +** assert( unixMutexHeld() ); +** unixEnterLeave() +*/ +static void unixEnterMutex(void){ + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +} +static void unixLeaveMutex(void){ + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +} +#ifdef SQLITE_DEBUG +static int unixMutexHeld(void) { + return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +} +#endif + + +#ifdef SQLITE_HAVE_OS_TRACE +/* +** Helper function for printing out trace information from debugging +** binaries. This returns the string representation of the supplied +** integer lock-type. +*/ +static const char *azFileLock(int eFileLock){ + switch( eFileLock ){ + 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 + +#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 = osFcntl(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 = osFcntl(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==(-1) && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){ + struct flock l2; + l2 = *p; + osFcntl(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; +} +#undef osFcntl +#define osFcntl lockTrace +#endif /* SQLITE_LOCK_TRACE */ + +/* +** Retry ftruncate() calls that fail due to EINTR +** +** All calls to ftruncate() within this file should be made through +** this wrapper. On the Android platform, bypassing the logic below +** could lead to a corrupt database. +*/ +static int robust_ftruncate(int h, sqlite3_int64 sz){ + int rc; +#ifdef __ANDROID__ + /* On Android, ftruncate() always uses 32-bit offsets, even if + ** _FILE_OFFSET_BITS=64 is defined. This means it is unsafe to attempt to + ** truncate a file to any size larger than 2GiB. Silently ignore any + ** such attempts. */ + if( sz>(sqlite3_int64)0x7FFFFFFF ){ + rc = SQLITE_OK; + }else +#endif + do{ rc = osFtruncate(h,sz); }while( rc<0 && errno==EINTR ); + return rc; +} + +/* +** This routine translates a standard POSIX errno code into something +** useful to the clients of the sqlite3 functions. Specifically, it is +** intended to translate a variety of "try again" errors into SQLITE_BUSY +** and a variety of "please close the file descriptor NOW" errors into +** SQLITE_IOERR +** +** Errors during initialization of locks, or file system support for locks, +** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately. +*/ +static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) { + switch (posixError) { +#if 0 + /* At one point this code was not commented out. In theory, this branch + ** should never be hit, as this function should only be called after + ** a locking-related function (i.e. fcntl()) has returned non-zero with + ** the value of errno as the first argument. Since a system call has failed, + ** errno should be non-zero. + ** + ** Despite this, if errno really is zero, we still don't want to return + ** SQLITE_OK. The system call failed, and *some* SQLite error should be + ** propagated back to the caller. Commenting this branch out means errno==0 + ** will be handled by the "default:" case below. + */ + case 0: + return SQLITE_OK; +#endif + + case EAGAIN: + case ETIMEDOUT: + case EBUSY: + case EINTR: + case ENOLCK: + /* random NFS retry error, unless during file system support + * introspection, in which it actually means what it says */ + return SQLITE_BUSY; + + case EACCES: + /* EACCES is like EAGAIN during locking operations, but not any other time*/ + if( (sqliteIOErr == SQLITE_IOERR_LOCK) || + (sqliteIOErr == SQLITE_IOERR_UNLOCK) || + (sqliteIOErr == SQLITE_IOERR_RDLOCK) || + (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){ + return SQLITE_BUSY; + } + /* else fall through */ + case EPERM: + return SQLITE_PERM; + +#if EOPNOTSUPP!=ENOTSUP + case EOPNOTSUPP: + /* something went terribly awry, unless during file system support + * introspection, in which it actually means what it says */ +#endif +#ifdef ENOTSUP + case ENOTSUP: + /* invalid fd, unless during file system support introspection, in which + * it actually means what it says */ +#endif + case EIO: + case EBADF: + case EINVAL: + case ENOTCONN: + case ENODEV: + case ENXIO: + case ENOENT: +#ifdef ESTALE /* ESTALE is not defined on Interix systems */ + case ESTALE: +#endif + case ENOSYS: + /* these should force the client to close the file and reconnect */ + + default: + return sqliteIOErr; + } +} + + +/****************************************************************************** +****************** Begin Unique File ID Utility Used By VxWorks *************** +** +** On most versions of unix, we can get a unique ID for a file by concatenating +** the device number and the inode number. But this does not work on VxWorks. +** On VxWorks, a unique file id must be based on the canonical filename. +** +** A pointer to an instance of the following structure can be used as a +** unique file ID in VxWorks. Each instance of this structure contains +** a copy of the canonical filename. There is also a reference count. +** The structure is reclaimed when the number of pointers to it drops to +** zero. +** +** There are never very many files open at one time and lookups are not +** a performance-critical path, so it is sufficient to put these +** structures on a linked list. +*/ +struct vxworksFileId { + struct vxworksFileId *pNext; /* Next in a list of them all */ + int nRef; /* Number of references to this one */ + int nName; /* Length of the zCanonicalName[] string */ + char *zCanonicalName; /* Canonical filename */ +}; + +#if OS_VXWORKS +/* +** All unique filenames are held on a linked list headed by this +** variable: +*/ +static struct vxworksFileId *vxworksFileList = 0; + +/* +** Simplify a filename into its canonical form +** by making the following changes: +** +** * removing any trailing and duplicate / +** * convert /./ into just / +** * convert /A/../ where A is any simple name into just / +** +** Changes are made in-place. Return the new name length. +** +** The original filename is in z[0..n-1]. Return the number of +** characters in the simplified name. +*/ +static int vxworksSimplifyName(char *z, int n){ + int i, j; + while( n>1 && z[n-1]=='/' ){ n--; } + for(i=j=0; i0 && z[j-1]!='/' ){ j--; } + if( j>0 ){ j--; } + i += 2; + continue; + } + } + z[j++] = z[i]; + } + z[j] = 0; + return j; +} + +/* +** Find a unique file ID for the given absolute pathname. Return +** a pointer to the vxworksFileId object. This pointer is the unique +** file ID. +** +** The nRef field of the vxworksFileId object is incremented before +** the object is returned. A new vxworksFileId object is created +** and added to the global list if necessary. +** +** If a memory allocation error occurs, return NULL. +*/ +static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){ + struct vxworksFileId *pNew; /* search key and new file ID */ + struct vxworksFileId *pCandidate; /* For looping over existing file IDs */ + int n; /* Length of zAbsoluteName string */ + + assert( zAbsoluteName[0]=='/' ); + n = (int)strlen(zAbsoluteName); + pNew = sqlite3_malloc64( sizeof(*pNew) + (n+1) ); + if( pNew==0 ) return 0; + pNew->zCanonicalName = (char*)&pNew[1]; + memcpy(pNew->zCanonicalName, zAbsoluteName, n+1); + n = vxworksSimplifyName(pNew->zCanonicalName, n); + + /* Search for an existing entry that matching the canonical name. + ** If found, increment the reference count and return a pointer to + ** the existing file ID. + */ + unixEnterMutex(); + for(pCandidate=vxworksFileList; pCandidate; pCandidate=pCandidate->pNext){ + if( pCandidate->nName==n + && memcmp(pCandidate->zCanonicalName, pNew->zCanonicalName, n)==0 + ){ + sqlite3_free(pNew); + pCandidate->nRef++; + unixLeaveMutex(); + return pCandidate; + } + } + + /* No match was found. We will make a new file ID */ + pNew->nRef = 1; + pNew->nName = n; + pNew->pNext = vxworksFileList; + vxworksFileList = pNew; + unixLeaveMutex(); + return pNew; +} + +/* +** Decrement the reference count on a vxworksFileId object. Free +** the object when the reference count reaches zero. +*/ +static void vxworksReleaseFileId(struct vxworksFileId *pId){ + unixEnterMutex(); + assert( pId->nRef>0 ); + pId->nRef--; + if( pId->nRef==0 ){ + struct vxworksFileId **pp; + for(pp=&vxworksFileList; *pp && *pp!=pId; pp = &((*pp)->pNext)){} + assert( *pp==pId ); + *pp = pId->pNext; + sqlite3_free(pId); + } + unixLeaveMutex(); +} +#endif /* OS_VXWORKS */ +/*************** End of Unique File ID Utility Used By VxWorks **************** +******************************************************************************/ + + +/****************************************************************************** +*************************** Posix Advisory Locking **************************** +** +** POSIX advisory locks are broken by design. 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 +** that it overrides locks set by the same process using a different +** file descriptor. Consider this test case: +** +** int fd1 = open("./file1", O_RDWR|O_CREAT, 0644); +** int fd2 = open("./file2", O_RDWR|O_CREAT, 0644); +** +** Suppose ./file1 and ./file2 are really the same file (because +** one is a hard or symbolic link to the other) then if you set +** an exclusive lock on fd1, then try to get an exclusive lock +** on fd2, it works. I would have expected the second lock to +** fail since there was already a lock on the file due to fd1. +** But not so. Since both locks came from the same process, the +** second overrides the first, even though they were on different +** file descriptors opened on different file names. +** +** This means that we cannot use POSIX locks to synchronize file access +** among competing threads of the same process. POSIX locks will work fine +** to synchronize access for threads in separate processes, but not +** threads within the same process. +** +** To work around the problem, SQLite has to manage file locks internally +** on its own. Whenever a new database is opened, we have to find the +** specific inode of the database file (the inode is determined by the +** st_dev and st_ino fields of the stat structure that fstat() fills in) +** and check for locks already existing on that inode. When locks are +** created or removed, we have to look at our own internal record of the +** locks to see if another thread has previously set a lock on that same +** inode. +** +** (Aside: The use of inode numbers as unique IDs does not work on VxWorks. +** For VxWorks, we have to use the alternative unique ID system based on +** canonical filename and implemented in the previous division.) +** +** The sqlite3_file structure for POSIX is no longer just an integer file +** descriptor. It is now a structure that holds the integer file +** descriptor and a pointer to a structure that describes the internal +** locks on the corresponding inode. There is one locking structure +** per inode, so if the same inode is opened twice, both unixFile structures +** point to the same locking structure. The locking structure keeps +** a reference count (so we will know when to delete it) and a "cnt" +** field that tells us its internal lock status. cnt==0 means the +** file is unlocked. cnt==-1 means the file has an exclusive lock. +** cnt>0 means there are cnt shared locks on the file. +** +** Any attempt to lock or unlock a file first checks the locking +** structure. The fcntl() system call is only invoked to set a +** POSIX lock if the internal lock structure transitions between +** a locked and an unlocked state. +** +** But wait: there are yet more problems with POSIX advisory locks. +** +** If you close a file descriptor that points to a file that has locks, +** all locks on that file that are owned by the current process are +** released. To work around this problem, each unixInodeInfo object +** maintains a count of the number of pending locks on tha inode. +** When an attempt is made to close an unixFile, if there are +** other unixFile open on the same inode that are holding locks, the call +** to close() the file descriptor is deferred until all of the locks clear. +** The unixInodeInfo structure keeps a list of file descriptors that need to +** be closed and that list is walked (and cleared) when the last lock +** clears. +** +** Yet another problem: LinuxThreads do not play well with posix locks. +** +** Many older versions of linux use the LinuxThreads library which is +** not posix compliant. Under LinuxThreads, a lock created by thread +** A cannot be modified or overridden by a different thread B. +** Only thread A can modify the lock. Locking behavior is correct +** if the appliation uses the newer Native Posix Thread Library (NPTL) +** on linux - with NPTL a lock created by thread A can override locks +** in thread B. But there is no way to know at compile-time which +** threading library is being used. So there is no way to know at +** compile-time whether or not thread A can override locks on thread B. +** One has to do a run-time check to discover the behavior of the +** current process. +** +** SQLite used to support LinuxThreads. But support for LinuxThreads +** was dropped beginning with version 3.7.0. SQLite will still work with +** LinuxThreads provided that (1) there is no more than one connection +** per database file in the same process and (2) database connections +** do not move across threads. +*/ + +/* +** An instance of the following structure serves as the key used +** to locate a particular unixInodeInfo object. +*/ +struct unixFileId { + dev_t dev; /* Device number */ +#if OS_VXWORKS + struct vxworksFileId *pId; /* Unique file ID for vxworks. */ +#else + ino_t ino; /* Inode number */ +#endif +}; + +/* +** An instance of the following structure is allocated for each open +** inode. Or, on LinuxThreads, there is one of these structures for +** each inode opened by each thread. +** +** A single inode can have multiple file descriptors, so each unixFile +** structure contains a pointer to an instance of this object and this +** object keeps a count of the number of unixFile pointing to it. +*/ +struct unixInodeInfo { + struct unixFileId fileId; /* The lookup key */ + int nShared; /* Number of SHARED locks held */ + unsigned char eFileLock; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ + unsigned char bProcessLock; /* An exclusive process lock is held */ + int nRef; /* Number of pointers to this structure */ + unixShmNode *pShmNode; /* Shared memory associated with this inode */ + int nLock; /* Number of outstanding file locks */ + UnixUnusedFd *pUnused; /* Unused file descriptors to close */ + unixInodeInfo *pNext; /* List of all unixInodeInfo objects */ + unixInodeInfo *pPrev; /* .... doubly linked */ +#if SQLITE_ENABLE_LOCKING_STYLE + unsigned long long sharedByte; /* for AFP simulated shared lock */ +#endif +#if OS_VXWORKS + sem_t *pSem; /* Named POSIX semaphore */ + char aSemName[MAX_PATHNAME+2]; /* Name of that semaphore */ +#endif +}; + +/* +** A lists of all unixInodeInfo objects. +*/ +static unixInodeInfo *inodeList = 0; + +/* +** +** This function - unixLogError_x(), is only ever called via the macro +** unixLogError(). +** +** It is invoked after an error occurs in an OS function and errno has been +** set. It logs a message using sqlite3_log() containing the current value of +** errno and, if possible, the human-readable equivalent from strerror() or +** strerror_r(). +** +** The first argument passed to the macro should be the error code that +** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). +** The two subsequent arguments should be the name of the OS function that +** failed (e.g. "unlink", "open") and the associated file-system path, +** if any. +*/ +#define unixLogError(a,b,c) unixLogErrorAtLine(a,b,c,__LINE__) +static int unixLogErrorAtLine( + int errcode, /* SQLite error code */ + const char *zFunc, /* Name of OS function that failed */ + const char *zPath, /* File path associated with error */ + int iLine /* Source line number where error occurred */ +){ + char *zErr; /* Message from strerror() or equivalent */ + int iErrno = errno; /* Saved syscall error number */ + + /* If this is not a threadsafe build (SQLITE_THREADSAFE==0), then use + ** the strerror() function to obtain the human-readable error message + ** equivalent to errno. Otherwise, use strerror_r(). + */ +#if SQLITE_THREADSAFE && defined(HAVE_STRERROR_R) + char aErr[80]; + memset(aErr, 0, sizeof(aErr)); + zErr = aErr; + + /* If STRERROR_R_CHAR_P (set by autoconf scripts) or __USE_GNU is defined, + ** assume that the system provides the GNU version of strerror_r() that + ** returns a pointer to a buffer containing the error message. That pointer + ** may point to aErr[], or it may point to some static storage somewhere. + ** Otherwise, assume that the system provides the POSIX version of + ** strerror_r(), which always writes an error message into aErr[]. + ** + ** If the code incorrectly assumes that it is the POSIX version that is + ** available, the error message will often be an empty string. Not a + ** huge problem. Incorrectly concluding that the GNU version is available + ** could lead to a segfault though. + */ +#if defined(STRERROR_R_CHAR_P) || defined(__USE_GNU) + zErr = +# endif + strerror_r(iErrno, aErr, sizeof(aErr)-1); + +#elif SQLITE_THREADSAFE + /* This is a threadsafe build, but strerror_r() is not available. */ + zErr = ""; +#else + /* Non-threadsafe build, use strerror(). */ + zErr = strerror(iErrno); +#endif + + if( zPath==0 ) zPath = ""; + sqlite3_log(errcode, + "os_unix.c:%d: (%d) %s(%s) - %s", + iLine, iErrno, zFunc, zPath, zErr + ); + + return errcode; +} + +/* +** Close a file descriptor. +** +** We assume that close() almost always works, since it is only in a +** very sick application or on a very sick platform that it might fail. +** If it does fail, simply leak the file descriptor, but do log the +** error. +** +** Note that it is not safe to retry close() after EINTR since the +** file descriptor might have already been reused by another thread. +** So we don't even try to recover from an EINTR. Just log the error +** and move on. +*/ +static void robust_close(unixFile *pFile, int h, int lineno){ + if( osClose(h) ){ + unixLogErrorAtLine(SQLITE_IOERR_CLOSE, "close", + pFile ? pFile->zPath : 0, lineno); + } +} + +/* +** Set the pFile->lastErrno. Do this in a subroutine as that provides +** a convenient place to set a breakpoint. +*/ +static void storeLastErrno(unixFile *pFile, int error){ + pFile->lastErrno = error; +} + +/* +** Close all file descriptors accumuated in the unixInodeInfo->pUnused list. +*/ +static void closePendingFds(unixFile *pFile){ + unixInodeInfo *pInode = pFile->pInode; + UnixUnusedFd *p; + UnixUnusedFd *pNext; + for(p=pInode->pUnused; p; p=pNext){ + pNext = p->pNext; + robust_close(pFile, p->fd, __LINE__); + sqlite3_free(p); + } + pInode->pUnused = 0; +} + +/* +** Release a unixInodeInfo structure previously allocated by findInodeInfo(). +** +** The mutex entered using the unixEnterMutex() function must be held +** when this function is called. +*/ +static void releaseInodeInfo(unixFile *pFile){ + unixInodeInfo *pInode = pFile->pInode; + assert( unixMutexHeld() ); + if( ALWAYS(pInode) ){ + pInode->nRef--; + if( pInode->nRef==0 ){ + assert( pInode->pShmNode==0 ); + closePendingFds(pFile); + if( pInode->pPrev ){ + assert( pInode->pPrev->pNext==pInode ); + pInode->pPrev->pNext = pInode->pNext; + }else{ + assert( inodeList==pInode ); + inodeList = pInode->pNext; + } + if( pInode->pNext ){ + assert( pInode->pNext->pPrev==pInode ); + pInode->pNext->pPrev = pInode->pPrev; + } + sqlite3_free(pInode); + } + } +} + +/* +** Given a file descriptor, locate the unixInodeInfo object that +** describes that file descriptor. Create a new one if necessary. The +** return value might be uninitialized if an error occurs. +** +** The mutex entered using the unixEnterMutex() function must be held +** when this function is called. +** +** Return an appropriate error code. +*/ +static int findInodeInfo( + unixFile *pFile, /* Unix file with file desc used in the key */ + unixInodeInfo **ppInode /* Return the unixInodeInfo object here */ +){ + int rc; /* System call return code */ + int fd; /* The file descriptor for pFile */ + struct unixFileId fileId; /* Lookup key for the unixInodeInfo */ + struct stat statbuf; /* Low-level file information */ + unixInodeInfo *pInode = 0; /* Candidate unixInodeInfo object */ + + assert( unixMutexHeld() ); + + /* Get low-level information about the file that we can used to + ** create a unique name for the file. + */ + fd = pFile->h; + rc = osFstat(fd, &statbuf); + if( rc!=0 ){ + storeLastErrno(pFile, errno); +#ifdef EOVERFLOW + if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS; +#endif + return SQLITE_IOERR; + } + +#ifdef __APPLE__ + /* On OS X on an msdos filesystem, the inode number is reported + ** incorrectly for zero-size files. See ticket #3260. To work + ** around this problem (we consider it a bug in OS X, not SQLite) + ** we always increase the file size to 1 by writing a single byte + ** prior to accessing the inode number. The one byte written is + ** an ASCII 'S' character which also happens to be the first byte + ** in the header of every SQLite database. In this way, if there + ** is a race condition such that another thread has already populated + ** the first page of the database, no damage is done. + */ + if( statbuf.st_size==0 && (pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS)!=0 ){ + do{ rc = osWrite(fd, "S", 1); }while( rc<0 && errno==EINTR ); + if( rc!=1 ){ + storeLastErrno(pFile, errno); + return SQLITE_IOERR; + } + rc = osFstat(fd, &statbuf); + if( rc!=0 ){ + storeLastErrno(pFile, errno); + return SQLITE_IOERR; + } + } +#endif + + memset(&fileId, 0, sizeof(fileId)); + fileId.dev = statbuf.st_dev; +#if OS_VXWORKS + fileId.pId = pFile->pId; +#else + fileId.ino = statbuf.st_ino; +#endif + pInode = inodeList; + while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){ + pInode = pInode->pNext; + } + if( pInode==0 ){ + pInode = sqlite3_malloc64( sizeof(*pInode) ); + if( pInode==0 ){ + return SQLITE_NOMEM; + } + memset(pInode, 0, sizeof(*pInode)); + memcpy(&pInode->fileId, &fileId, sizeof(fileId)); + pInode->nRef = 1; + pInode->pNext = inodeList; + pInode->pPrev = 0; + if( inodeList ) inodeList->pPrev = pInode; + inodeList = pInode; + }else{ + pInode->nRef++; + } + *ppInode = pInode; + return SQLITE_OK; +} + +/* +** Return TRUE if pFile has been renamed or unlinked since it was first opened. +*/ +static int fileHasMoved(unixFile *pFile){ +#if OS_VXWORKS + return pFile->pInode!=0 && pFile->pId!=pFile->pInode->fileId.pId; +#else + struct stat buf; + return pFile->pInode!=0 && + (osStat(pFile->zPath, &buf)!=0 || buf.st_ino!=pFile->pInode->fileId.ino); +#endif +} + + +/* +** Check a unixFile that is a database. Verify the following: +** +** (1) There is exactly one hard link on the file +** (2) The file is not a symbolic link +** (3) The file has not been renamed or unlinked +** +** Issue sqlite3_log(SQLITE_WARNING,...) messages if anything is not right. +*/ +static void verifyDbFile(unixFile *pFile){ + struct stat buf; + int rc; + if( pFile->ctrlFlags & UNIXFILE_WARNED ){ + /* One or more of the following warnings have already been issued. Do not + ** repeat them so as not to clutter the error log */ + return; + } + rc = osFstat(pFile->h, &buf); + if( rc!=0 ){ + sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath); + pFile->ctrlFlags |= UNIXFILE_WARNED; + return; + } + if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){ + sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath); + pFile->ctrlFlags |= UNIXFILE_WARNED; + return; + } + if( buf.st_nlink>1 ){ + sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath); + pFile->ctrlFlags |= UNIXFILE_WARNED; + return; + } + if( fileHasMoved(pFile) ){ + sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath); + pFile->ctrlFlags |= UNIXFILE_WARNED; + return; + } +} + + +/* +** 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, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +*/ +static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ + int rc = SQLITE_OK; + int reserved = 0; + unixFile *pFile = (unixFile*)id; + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + + assert( pFile ); + unixEnterMutex(); /* Because pFile->pInode is shared across threads */ + + /* Check if a thread in this process holds such a lock */ + if( pFile->pInode->eFileLock>SHARED_LOCK ){ + reserved = 1; + } + + /* Otherwise see if some other process holds it. + */ +#ifndef __DJGPP__ + if( !reserved && !pFile->pInode->bProcessLock ){ + struct flock lock; + lock.l_whence = SEEK_SET; + lock.l_start = RESERVED_BYTE; + lock.l_len = 1; + lock.l_type = F_WRLCK; + if( osFcntl(pFile->h, F_GETLK, &lock) ){ + rc = SQLITE_IOERR_CHECKRESERVEDLOCK; + storeLastErrno(pFile, errno); + } else if( lock.l_type!=F_UNLCK ){ + reserved = 1; + } + } +#endif + + unixLeaveMutex(); + OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved)); + + *pResOut = reserved; + return rc; +} + +/* +** Attempt to set a system-lock on the file pFile. The lock is +** described by pLock. +** +** If the pFile was opened read/write from unix-excl, then the only lock +** ever obtained is an exclusive lock, and it is obtained exactly once +** the first time any lock is attempted. All subsequent system locking +** operations become no-ops. Locking operations still happen internally, +** in order to coordinate access between separate database connections +** within this process, but all of that is handled in memory and the +** operating system does not participate. +** +** This function is a pass-through to fcntl(F_SETLK) if pFile is using +** any VFS other than "unix-excl" or if pFile is opened on "unix-excl" +** and is read-only. +** +** Zero is returned if the call completes successfully, or -1 if a call +** to fcntl() fails. In this case, errno is set appropriately (by fcntl()). +*/ +static int unixFileLock(unixFile *pFile, struct flock *pLock){ + int rc; + unixInodeInfo *pInode = pFile->pInode; + assert( unixMutexHeld() ); + assert( pInode!=0 ); + if( ((pFile->ctrlFlags & UNIXFILE_EXCL)!=0 || pInode->bProcessLock) + && ((pFile->ctrlFlags & UNIXFILE_RDONLY)==0) + ){ + if( pInode->bProcessLock==0 ){ + struct flock lock; + assert( pInode->nLock==0 ); + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST; + lock.l_len = SHARED_SIZE; + lock.l_type = F_WRLCK; + rc = osFcntl(pFile->h, F_SETLK, &lock); + if( rc<0 ) return rc; + pInode->bProcessLock = 1; + pInode->nLock++; + }else{ + rc = 0; + } + }else{ + rc = osFcntl(pFile->h, F_SETLK, pLock); + } + return rc; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** 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(sqlite3_file *id, int eFileLock){ + /* 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. + ** + ** Symbols defined in os.h indentify the 'pending byte' and the 'reserved + ** byte', each single bytes at well known offsets, and the 'shared byte + ** range', a range of 510 bytes at a well known offset. + ** + ** To obtain a SHARED lock, a read-lock is obtained on the 'pending + ** byte'. If this is successful, a random byte from the 'shared byte + ** range' is read-locked and the lock on the 'pending byte' released. + ** + ** A process may only obtain a RESERVED lock after it has a SHARED lock. + ** A RESERVED lock is implemented by grabbing a write-lock on the + ** 'reserved byte'. + ** + ** A process may only obtain a PENDING lock after it has obtained a + ** SHARED lock. A PENDING lock is implemented by obtaining a write-lock + ** on the 'pending byte'. This ensures that no new SHARED locks can be + ** obtained, but existing SHARED locks are allowed to persist. A process + ** does not have to obtain a RESERVED lock on the way to a PENDING lock. + ** This property is used by the algorithm for rolling back a journal file + ** after a crash. + ** + ** An EXCLUSIVE lock, obtained after a PENDING lock is held, is + ** implemented by obtaining a write-lock on the entire 'shared byte + ** range'. Since all other locks require a read-lock on one of the bytes + ** within this range, this ensures that no other locks are held on the + ** database. + ** + ** 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; + unixInodeInfo *pInode; + struct flock lock; + int tErrno = 0; + + assert( pFile ); + OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h, + azFileLock(eFileLock), azFileLock(pFile->eFileLock), + azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared, + osGetpid(0))); + + /* If there is already a lock of this type or more restrictive on the + ** unixFile, do nothing. Don't use the end_lock: exit path, as + ** unixEnterMutex() hasn't been called yet. + */ + if( pFile->eFileLock>=eFileLock ){ + OSTRACE(("LOCK %d %s ok (already held) (unix)\n", pFile->h, + azFileLock(eFileLock))); + return SQLITE_OK; + } + + /* Make sure the locking sequence is correct. + ** (1) We never move from unlocked to anything higher than shared lock. + ** (2) SQLite never explicitly requests a pendig lock. + ** (3) A shared lock is always held when a reserve lock is requested. + */ + assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK ); + assert( eFileLock!=PENDING_LOCK ); + assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK ); + + /* This mutex is needed because pFile->pInode is shared across threads + */ + unixEnterMutex(); + pInode = pFile->pInode; + + /* If some thread using this PID has a lock via a different unixFile* + ** handle that precludes the requested lock, return BUSY. + */ + if( (pFile->eFileLock!=pInode->eFileLock && + (pInode->eFileLock>=PENDING_LOCK || eFileLock>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( eFileLock==SHARED_LOCK && + (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){ + assert( eFileLock==SHARED_LOCK ); + assert( pFile->eFileLock==0 ); + assert( pInode->nShared>0 ); + pFile->eFileLock = SHARED_LOCK; + pInode->nShared++; + pInode->nLock++; + goto end_lock; + } + + + /* 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. + */ + lock.l_len = 1L; + lock.l_whence = SEEK_SET; + if( eFileLock==SHARED_LOCK + || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLocknShared==0 ); + assert( pInode->eFileLock==0 ); + assert( rc==SQLITE_OK ); + + /* Now get the read-lock */ + lock.l_start = SHARED_FIRST; + lock.l_len = SHARED_SIZE; + if( unixFileLock(pFile, &lock) ){ + tErrno = errno; + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + } + + /* Drop the temporary PENDING lock */ + lock.l_start = PENDING_BYTE; + lock.l_len = 1L; + lock.l_type = F_UNLCK; + if( unixFileLock(pFile, &lock) && rc==SQLITE_OK ){ + /* This could happen with a network mount */ + tErrno = errno; + rc = SQLITE_IOERR_UNLOCK; + } + + if( rc ){ + if( rc!=SQLITE_BUSY ){ + storeLastErrno(pFile, tErrno); + } + goto end_lock; + }else{ + pFile->eFileLock = SHARED_LOCK; + pInode->nLock++; + pInode->nShared = 1; + } + }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>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->eFileLock ); + lock.l_type = F_WRLCK; + + assert( eFileLock==RESERVED_LOCK || eFileLock==EXCLUSIVE_LOCK ); + if( eFileLock==RESERVED_LOCK ){ + lock.l_start = RESERVED_BYTE; + lock.l_len = 1L; + }else{ + lock.l_start = SHARED_FIRST; + lock.l_len = SHARED_SIZE; + } + + if( unixFileLock(pFile, &lock) ){ + tErrno = errno; + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + if( rc!=SQLITE_BUSY ){ + storeLastErrno(pFile, tErrno); + } + } + } + + +#ifdef SQLITE_DEBUG + /* Set up the transaction-counter change checking flags when + ** transitioning from a SHARED to a RESERVED lock. The change + ** from SHARED to RESERVED marks the beginning of a normal + ** write operation (not a hot journal rollback). + */ + if( rc==SQLITE_OK + && pFile->eFileLock<=SHARED_LOCK + && eFileLock==RESERVED_LOCK + ){ + pFile->transCntrChng = 0; + pFile->dbUpdate = 0; + pFile->inNormalWrite = 1; + } +#endif + + + if( rc==SQLITE_OK ){ + pFile->eFileLock = eFileLock; + pInode->eFileLock = eFileLock; + }else if( eFileLock==EXCLUSIVE_LOCK ){ + pFile->eFileLock = PENDING_LOCK; + pInode->eFileLock = PENDING_LOCK; + } + +end_lock: + unixLeaveMutex(); + OSTRACE(("LOCK %d %s %s (unix)\n", pFile->h, azFileLock(eFileLock), + rc==SQLITE_OK ? "ok" : "failed")); + return rc; +} + +/* +** Add the file descriptor used by file handle pFile to the corresponding +** pUnused list. +*/ +static void setPendingFd(unixFile *pFile){ + unixInodeInfo *pInode = pFile->pInode; + UnixUnusedFd *p = pFile->pUnused; + p->pNext = pInode->pUnused; + pInode->pUnused = p; + pFile->h = -1; + pFile->pUnused = 0; +} + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** 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. +** +** If handleNFSUnlock is true, then on downgrading an EXCLUSIVE_LOCK to SHARED +** the byte range is divided into 2 parts and the first part is unlocked then +** set to a read lock, then the other part is simply unlocked. This works +** around a bug in BSD NFS lockd (also seen on MacOSX 10.3+) that fails to +** remove the write lock on a region when a read lock is set. +*/ +static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ + unixFile *pFile = (unixFile*)id; + unixInodeInfo *pInode; + struct flock lock; + int rc = SQLITE_OK; + + assert( pFile ); + OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, eFileLock, + pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared, + osGetpid(0))); + + assert( eFileLock<=SHARED_LOCK ); + if( pFile->eFileLock<=eFileLock ){ + return SQLITE_OK; + } + unixEnterMutex(); + pInode = pFile->pInode; + assert( pInode->nShared!=0 ); + if( pFile->eFileLock>SHARED_LOCK ){ + assert( pInode->eFileLock==pFile->eFileLock ); + +#ifdef SQLITE_DEBUG + /* When reducing a lock such that other processes can start + ** reading the database file again, make sure that the + ** transaction counter was updated if any part of the database + ** file changed. If the transaction counter is not updated, + ** other connections to the same file might not realize that + ** the file has changed and hence might not know to flush their + ** cache. The use of a stale cache can lead to database corruption. + */ + pFile->inNormalWrite = 0; +#endif + + /* downgrading to a shared lock on NFS involves clearing the write lock + ** before establishing the readlock - to avoid a race condition we downgrade + ** the lock in 2 blocks, so that part of the range will be covered by a + ** write lock until the rest is covered by a read lock: + ** 1: [WWWWW] + ** 2: [....W] + ** 3: [RRRRW] + ** 4: [RRRR.] + */ + if( eFileLock==SHARED_LOCK ){ +#if !defined(__APPLE__) || !SQLITE_ENABLE_LOCKING_STYLE + (void)handleNFSUnlock; + assert( handleNFSUnlock==0 ); +#endif +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE + if( handleNFSUnlock ){ + int tErrno; /* Error code from system call errors */ + off_t divSize = SHARED_SIZE - 1; + + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST; + lock.l_len = divSize; + if( unixFileLock(pFile, &lock)==(-1) ){ + tErrno = errno; + rc = SQLITE_IOERR_UNLOCK; + if( IS_LOCK_ERROR(rc) ){ + storeLastErrno(pFile, tErrno); + } + goto end_unlock; + } + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST; + lock.l_len = divSize; + if( unixFileLock(pFile, &lock)==(-1) ){ + tErrno = errno; + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); + if( IS_LOCK_ERROR(rc) ){ + storeLastErrno(pFile, tErrno); + } + goto end_unlock; + } + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST+divSize; + lock.l_len = SHARED_SIZE-divSize; + if( unixFileLock(pFile, &lock)==(-1) ){ + tErrno = errno; + rc = SQLITE_IOERR_UNLOCK; + if( IS_LOCK_ERROR(rc) ){ + storeLastErrno(pFile, tErrno); + } + goto end_unlock; + } + }else +#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ + { + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST; + lock.l_len = SHARED_SIZE; + if( unixFileLock(pFile, &lock) ){ + /* In theory, the call to unixFileLock() cannot fail because another + ** process is holding an incompatible lock. If it does, this + ** indicates that the other process is not following the locking + ** protocol. If this happens, return SQLITE_IOERR_RDLOCK. Returning + ** SQLITE_BUSY would confuse the upper layer (in practice it causes + ** an assert to fail). */ + rc = SQLITE_IOERR_RDLOCK; + storeLastErrno(pFile, errno); + goto end_unlock; + } + } + } + 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( unixFileLock(pFile, &lock)==0 ){ + pInode->eFileLock = SHARED_LOCK; + }else{ + rc = SQLITE_IOERR_UNLOCK; + storeLastErrno(pFile, errno); + goto end_unlock; + } + } + if( eFileLock==NO_LOCK ){ + /* Decrement the shared lock counter. Release the lock using an + ** OS call only when all threads in this same process have released + ** the lock. + */ + pInode->nShared--; + if( pInode->nShared==0 ){ + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = lock.l_len = 0L; + if( unixFileLock(pFile, &lock)==0 ){ + pInode->eFileLock = NO_LOCK; + }else{ + rc = SQLITE_IOERR_UNLOCK; + storeLastErrno(pFile, errno); + pInode->eFileLock = NO_LOCK; + pFile->eFileLock = 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. + */ + pInode->nLock--; + assert( pInode->nLock>=0 ); + if( pInode->nLock==0 ){ + closePendingFds(pFile); + } + } + +end_unlock: + unixLeaveMutex(); + if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock; + return rc; +} + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** 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(sqlite3_file *id, int eFileLock){ +#if SQLITE_MAX_MMAP_SIZE>0 + assert( eFileLock==SHARED_LOCK || ((unixFile *)id)->nFetchOut==0 ); +#endif + return posixUnlock(id, eFileLock, 0); +} + +#if SQLITE_MAX_MMAP_SIZE>0 +static int unixMapfile(unixFile *pFd, i64 nByte); +static void unixUnmapfile(unixFile *pFd); +#endif + +/* +** This function performs the parts of the "close file" operation +** common to all locking schemes. It closes the directory and file +** handles, if they are valid, and sets all fields of the unixFile +** structure to 0. +** +** It is *not* necessary to hold the mutex when this routine is called, +** even on VxWorks. A mutex will be acquired on VxWorks by the +** vxworksReleaseFileId() routine. +*/ +static int closeUnixFile(sqlite3_file *id){ + unixFile *pFile = (unixFile*)id; +#if SQLITE_MAX_MMAP_SIZE>0 + unixUnmapfile(pFile); +#endif + if( pFile->h>=0 ){ + robust_close(pFile, pFile->h, __LINE__); + pFile->h = -1; + } +#if OS_VXWORKS + if( pFile->pId ){ + if( pFile->ctrlFlags & UNIXFILE_DELETE ){ + osUnlink(pFile->pId->zCanonicalName); + } + vxworksReleaseFileId(pFile->pId); + pFile->pId = 0; + } +#endif +#ifdef SQLITE_UNLINK_AFTER_CLOSE + if( pFile->ctrlFlags & UNIXFILE_DELETE ){ + osUnlink(pFile->zPath); + sqlite3_free(*(char**)&pFile->zPath); + pFile->zPath = 0; + } +#endif + OSTRACE(("CLOSE %-3d\n", pFile->h)); + OpenCounter(-1); + sqlite3_free(pFile->pUnused); + memset(pFile, 0, sizeof(unixFile)); + return SQLITE_OK; +} + +/* +** Close a file. +*/ +static int unixClose(sqlite3_file *id){ + int rc = SQLITE_OK; + unixFile *pFile = (unixFile *)id; + verifyDbFile(pFile); + unixUnlock(id, NO_LOCK); + unixEnterMutex(); + + /* unixFile.pInode is always valid here. Otherwise, a different close + ** routine (e.g. nolockClose()) would be called instead. + */ + assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 ); + if( ALWAYS(pFile->pInode) && pFile->pInode->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 pInode->pUnused list. It will be automatically closed + ** when the last lock is cleared. + */ + setPendingFd(pFile); + } + releaseInodeInfo(pFile); + rc = closeUnixFile(id); + unixLeaveMutex(); + return rc; +} + +/************** End of the posix advisory lock implementation ***************** +******************************************************************************/ + +/****************************************************************************** +****************************** No-op Locking ********************************** +** +** Of the various locking implementations available, this is by far the +** simplest: locking is ignored. No attempt is made to lock the database +** file for reading or writing. +** +** This locking mode is appropriate for use on read-only databases +** (ex: databases that are burned into CD-ROM, for example.) It can +** also be used if the application employs some external mechanism to +** prevent simultaneous access of the same database by two or more +** database connections. But there is a serious risk of database +** corruption if this locking mode is used in situations where multiple +** database connections are accessing the same database file at the same +** time and one or more of those connections are writing. +*/ + +static int nolockCheckReservedLock(sqlite3_file *NotUsed, int *pResOut){ + UNUSED_PARAMETER(NotUsed); + *pResOut = 0; + return SQLITE_OK; +} +static int nolockLock(sqlite3_file *NotUsed, int NotUsed2){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + return SQLITE_OK; +} +static int nolockUnlock(sqlite3_file *NotUsed, int NotUsed2){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + return SQLITE_OK; +} + +/* +** Close the file. +*/ +static int nolockClose(sqlite3_file *id) { + return closeUnixFile(id); +} + +/******************* End of the no-op lock implementation ********************* +******************************************************************************/ + +/****************************************************************************** +************************* Begin dot-file Locking ****************************** +** +** The dotfile locking implementation uses the existence of separate lock +** files (really a directory) to control access to the database. This works +** on just about every filesystem imaginable. But there are serious downsides: +** +** (1) There is zero concurrency. A single reader blocks all other +** connections from reading or writing the database. +** +** (2) An application crash or power loss can leave stale lock files +** sitting around that need to be cleared manually. +** +** Nevertheless, a dotlock is an appropriate locking mode for use if no +** other locking strategy is available. +** +** Dotfile locking works by creating a subdirectory in the same directory as +** the database and with the same name but with a ".lock" extension added. +** The existence of a lock directory implies an EXCLUSIVE lock. All other +** lock types (SHARED, RESERVED, PENDING) are mapped into EXCLUSIVE. +*/ + +/* +** The file suffix added to the data base filename in order to create the +** lock directory. +*/ +#define DOTLOCK_SUFFIX ".lock" + +/* +** 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, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +** +** In dotfile locking, either a lock exists or it does not. So in this +** variation of CheckReservedLock(), *pResOut is set to true if any lock +** is held on the file and false if the file is unlocked. +*/ +static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) { + int rc = SQLITE_OK; + int reserved = 0; + unixFile *pFile = (unixFile*)id; + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + + assert( pFile ); + + /* Check if a thread in this process holds such a lock */ + if( pFile->eFileLock>SHARED_LOCK ){ + /* Either this connection or some other connection in the same process + ** holds a lock on the file. No need to check further. */ + reserved = 1; + }else{ + /* The lock is held if and only if the lockfile exists */ + const char *zLockFile = (const char*)pFile->lockingContext; + reserved = osAccess(zLockFile, 0)==0; + } + OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved)); + *pResOut = reserved; + return rc; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** This routine will only increase a lock. Use the sqlite3OsUnlock() +** routine to lower a locking level. +** +** With dotfile locking, we really only support state (4): EXCLUSIVE. +** But we track the other locking levels internally. +*/ +static int dotlockLock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + char *zLockFile = (char *)pFile->lockingContext; + int rc = SQLITE_OK; + + + /* If we have any lock, then the lock file already exists. All we have + ** to do is adjust our internal record of the lock level. + */ + if( pFile->eFileLock > NO_LOCK ){ + pFile->eFileLock = eFileLock; + /* Always update the timestamp on the old file */ +#ifdef HAVE_UTIME + utime(zLockFile, NULL); +#else + utimes(zLockFile, NULL); +#endif + return SQLITE_OK; + } + + /* grab an exclusive lock */ + rc = osMkdir(zLockFile, 0777); + if( rc<0 ){ + /* failed to open/create the lock directory */ + int tErrno = errno; + if( EEXIST == tErrno ){ + rc = SQLITE_BUSY; + } else { + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + if( IS_LOCK_ERROR(rc) ){ + storeLastErrno(pFile, tErrno); + } + } + return rc; + } + + /* got it, set the type and return ok */ + pFile->eFileLock = eFileLock; + return rc; +} + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** 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. +** +** When the locking level reaches NO_LOCK, delete the lock file. +*/ +static int dotlockUnlock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + char *zLockFile = (char *)pFile->lockingContext; + int rc; + + assert( pFile ); + OSTRACE(("UNLOCK %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock, + pFile->eFileLock, osGetpid(0))); + assert( eFileLock<=SHARED_LOCK ); + + /* no-op if possible */ + if( pFile->eFileLock==eFileLock ){ + return SQLITE_OK; + } + + /* To downgrade to shared, simply update our internal notion of the + ** lock state. No need to mess with the file on disk. + */ + if( eFileLock==SHARED_LOCK ){ + pFile->eFileLock = SHARED_LOCK; + return SQLITE_OK; + } + + /* To fully unlock the database, delete the lock file */ + assert( eFileLock==NO_LOCK ); + rc = osRmdir(zLockFile); + if( rc<0 && errno==ENOTDIR ) rc = osUnlink(zLockFile); + if( rc<0 ){ + int tErrno = errno; + rc = 0; + if( ENOENT != tErrno ){ + rc = SQLITE_IOERR_UNLOCK; + } + if( IS_LOCK_ERROR(rc) ){ + storeLastErrno(pFile, tErrno); + } + return rc; + } + pFile->eFileLock = NO_LOCK; + return SQLITE_OK; +} + +/* +** Close a file. Make sure the lock has been released before closing. +*/ +static int dotlockClose(sqlite3_file *id) { + int rc = SQLITE_OK; + if( id ){ + unixFile *pFile = (unixFile*)id; + dotlockUnlock(id, NO_LOCK); + sqlite3_free(pFile->lockingContext); + rc = closeUnixFile(id); + } + return rc; +} +/****************** End of the dot-file lock implementation ******************* +******************************************************************************/ + +/****************************************************************************** +************************** Begin flock Locking ******************************** +** +** Use the flock() system call to do file locking. +** +** flock() locking is like dot-file locking in that the various +** fine-grain locking levels supported by SQLite are collapsed into +** a single exclusive lock. In other words, SHARED, RESERVED, and +** PENDING locks are the same thing as an EXCLUSIVE lock. SQLite +** still works when you do this, but concurrency is reduced since +** only a single process can be reading the database at a time. +** +** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off +*/ +#if SQLITE_ENABLE_LOCKING_STYLE + +/* +** Retry flock() calls that fail with EINTR +*/ +#ifdef EINTR +static int robust_flock(int fd, int op){ + int rc; + do{ rc = flock(fd,op); }while( rc<0 && errno==EINTR ); + return rc; +} +#else +# define robust_flock(a,b) flock(a,b) +#endif + + +/* +** 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, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +*/ +static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ + int rc = SQLITE_OK; + int reserved = 0; + unixFile *pFile = (unixFile*)id; + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + + assert( pFile ); + + /* Check if a thread in this process holds such a lock */ + if( pFile->eFileLock>SHARED_LOCK ){ + reserved = 1; + } + + /* Otherwise see if some other process holds it. */ + if( !reserved ){ + /* attempt to get the lock */ + int lrc = robust_flock(pFile->h, LOCK_EX | LOCK_NB); + if( !lrc ){ + /* got the lock, unlock it */ + lrc = robust_flock(pFile->h, LOCK_UN); + if ( lrc ) { + int tErrno = errno; + /* unlock failed with an error */ + lrc = SQLITE_IOERR_UNLOCK; + if( IS_LOCK_ERROR(lrc) ){ + storeLastErrno(pFile, tErrno); + rc = lrc; + } + } + } else { + int tErrno = errno; + reserved = 1; + /* someone else might have it reserved */ + lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + if( IS_LOCK_ERROR(lrc) ){ + storeLastErrno(pFile, tErrno); + rc = lrc; + } + } + } + OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved)); + +#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS + if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){ + rc = SQLITE_OK; + reserved=1; + } +#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ + *pResOut = reserved; + return rc; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** flock() only really support EXCLUSIVE locks. We track intermediate +** lock states in the sqlite3_file structure, but all locks SHARED or +** above are really EXCLUSIVE locks and exclude all other processes from +** access the file. +** +** This routine will only increase a lock. Use the sqlite3OsUnlock() +** routine to lower a locking level. +*/ +static int flockLock(sqlite3_file *id, int eFileLock) { + int rc = SQLITE_OK; + unixFile *pFile = (unixFile*)id; + + assert( pFile ); + + /* if we already have a lock, it is exclusive. + ** Just adjust level and punt on outta here. */ + if (pFile->eFileLock > NO_LOCK) { + pFile->eFileLock = eFileLock; + return SQLITE_OK; + } + + /* grab an exclusive lock */ + + if (robust_flock(pFile->h, LOCK_EX | LOCK_NB)) { + int tErrno = errno; + /* didn't get, must be busy */ + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + if( IS_LOCK_ERROR(rc) ){ + storeLastErrno(pFile, tErrno); + } + } else { + /* got it, set the type and return ok */ + pFile->eFileLock = eFileLock; + } + OSTRACE(("LOCK %d %s %s (flock)\n", pFile->h, azFileLock(eFileLock), + rc==SQLITE_OK ? "ok" : "failed")); +#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS + if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){ + rc = SQLITE_BUSY; + } +#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ + return rc; +} + + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** 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 flockUnlock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + + assert( pFile ); + OSTRACE(("UNLOCK %d %d was %d pid=%d (flock)\n", pFile->h, eFileLock, + pFile->eFileLock, osGetpid(0))); + assert( eFileLock<=SHARED_LOCK ); + + /* no-op if possible */ + if( pFile->eFileLock==eFileLock ){ + return SQLITE_OK; + } + + /* shared can just be set because we always have an exclusive */ + if (eFileLock==SHARED_LOCK) { + pFile->eFileLock = eFileLock; + return SQLITE_OK; + } + + /* no, really, unlock. */ + if( robust_flock(pFile->h, LOCK_UN) ){ +#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS + return SQLITE_OK; +#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ + return SQLITE_IOERR_UNLOCK; + }else{ + pFile->eFileLock = NO_LOCK; + return SQLITE_OK; + } +} + +/* +** Close a file. +*/ +static int flockClose(sqlite3_file *id) { + int rc = SQLITE_OK; + if( id ){ + flockUnlock(id, NO_LOCK); + rc = closeUnixFile(id); + } + return rc; +} + +#endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */ + +/******************* End of the flock lock implementation ********************* +******************************************************************************/ + +/****************************************************************************** +************************ Begin Named Semaphore Locking ************************ +** +** Named semaphore locking is only supported on VxWorks. +** +** Semaphore locking is like dot-lock and flock in that it really only +** supports EXCLUSIVE locking. Only a single process can read or write +** the database file at a time. This reduces potential concurrency, but +** makes the lock implementation much easier. +*/ +#if OS_VXWORKS + +/* +** 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, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +*/ +static int semXCheckReservedLock(sqlite3_file *id, int *pResOut) { + int rc = SQLITE_OK; + int reserved = 0; + unixFile *pFile = (unixFile*)id; + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + + assert( pFile ); + + /* Check if a thread in this process holds such a lock */ + if( pFile->eFileLock>SHARED_LOCK ){ + reserved = 1; + } + + /* Otherwise see if some other process holds it. */ + if( !reserved ){ + sem_t *pSem = pFile->pInode->pSem; + + if( sem_trywait(pSem)==-1 ){ + int tErrno = errno; + if( EAGAIN != tErrno ){ + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK); + storeLastErrno(pFile, tErrno); + } else { + /* someone else has the lock when we are in NO_LOCK */ + reserved = (pFile->eFileLock < SHARED_LOCK); + } + }else{ + /* we could have it if we want it */ + sem_post(pSem); + } + } + OSTRACE(("TEST WR-LOCK %d %d %d (sem)\n", pFile->h, rc, reserved)); + + *pResOut = reserved; + return rc; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** Semaphore locks only really support EXCLUSIVE locks. We track intermediate +** lock states in the sqlite3_file structure, but all locks SHARED or +** above are really EXCLUSIVE locks and exclude all other processes from +** access the file. +** +** This routine will only increase a lock. Use the sqlite3OsUnlock() +** routine to lower a locking level. +*/ +static int semXLock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + sem_t *pSem = pFile->pInode->pSem; + int rc = SQLITE_OK; + + /* if we already have a lock, it is exclusive. + ** Just adjust level and punt on outta here. */ + if (pFile->eFileLock > NO_LOCK) { + pFile->eFileLock = eFileLock; + rc = SQLITE_OK; + goto sem_end_lock; + } + + /* lock semaphore now but bail out when already locked. */ + if( sem_trywait(pSem)==-1 ){ + rc = SQLITE_BUSY; + goto sem_end_lock; + } + + /* got it, set the type and return ok */ + pFile->eFileLock = eFileLock; + + sem_end_lock: + return rc; +} + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** 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 semXUnlock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + sem_t *pSem = pFile->pInode->pSem; + + assert( pFile ); + assert( pSem ); + OSTRACE(("UNLOCK %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock, + pFile->eFileLock, osGetpid(0))); + assert( eFileLock<=SHARED_LOCK ); + + /* no-op if possible */ + if( pFile->eFileLock==eFileLock ){ + return SQLITE_OK; + } + + /* shared can just be set because we always have an exclusive */ + if (eFileLock==SHARED_LOCK) { + pFile->eFileLock = eFileLock; + return SQLITE_OK; + } + + /* no, really unlock. */ + if ( sem_post(pSem)==-1 ) { + int rc, tErrno = errno; + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); + if( IS_LOCK_ERROR(rc) ){ + storeLastErrno(pFile, tErrno); + } + return rc; + } + pFile->eFileLock = NO_LOCK; + return SQLITE_OK; +} + +/* + ** Close a file. + */ +static int semXClose(sqlite3_file *id) { + if( id ){ + unixFile *pFile = (unixFile*)id; + semXUnlock(id, NO_LOCK); + assert( pFile ); + unixEnterMutex(); + releaseInodeInfo(pFile); + unixLeaveMutex(); + closeUnixFile(id); + } + return SQLITE_OK; +} + +#endif /* OS_VXWORKS */ +/* +** Named semaphore locking is only available on VxWorks. +** +*************** End of the named semaphore lock implementation **************** +******************************************************************************/ + + +/****************************************************************************** +*************************** Begin AFP Locking ********************************* +** +** AFP is the Apple Filing Protocol. AFP is a network filesystem found +** on Apple Macintosh computers - both OS9 and OSX. +** +** Third-party implementations of AFP are available. But this code here +** only works on OSX. +*/ + +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +/* +** The afpLockingContext structure contains all afp lock specific state +*/ +typedef struct afpLockingContext afpLockingContext; +struct afpLockingContext { + int reserved; + const char *dbPath; /* Name of the open file */ +}; + +struct ByteRangeLockPB2 +{ + unsigned long long offset; /* offset to first byte to lock */ + unsigned long long length; /* nbr of bytes to lock */ + unsigned long long retRangeStart; /* nbr of 1st byte locked if successful */ + unsigned char unLockFlag; /* 1 = unlock, 0 = lock */ + unsigned char startEndFlag; /* 1=rel to end of fork, 0=rel to start */ + int fd; /* file desc to assoc this lock with */ +}; + +#define afpfsByteRangeLock2FSCTL _IOWR('z', 23, struct ByteRangeLockPB2) + +/* +** This is a utility for setting or clearing a bit-range lock on an +** AFP filesystem. +** +** Return SQLITE_OK on success, SQLITE_BUSY on failure. +*/ +static int afpSetLock( + const char *path, /* Name of the file to be locked or unlocked */ + unixFile *pFile, /* Open file descriptor on path */ + unsigned long long offset, /* First byte to be locked */ + unsigned long long length, /* Number of bytes to lock */ + int setLockFlag /* True to set lock. False to clear lock */ +){ + struct ByteRangeLockPB2 pb; + int err; + + pb.unLockFlag = setLockFlag ? 0 : 1; + pb.startEndFlag = 0; + pb.offset = offset; + pb.length = length; + pb.fd = pFile->h; + + OSTRACE(("AFPSETLOCK [%s] for %d%s in range %llx:%llx\n", + (setLockFlag?"ON":"OFF"), pFile->h, (pb.fd==-1?"[testval-1]":""), + offset, length)); + err = fsctl(path, afpfsByteRangeLock2FSCTL, &pb, 0); + if ( err==-1 ) { + int rc; + int tErrno = errno; + OSTRACE(("AFPSETLOCK failed to fsctl() '%s' %d %s\n", + path, tErrno, strerror(tErrno))); +#ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS + rc = SQLITE_BUSY; +#else + rc = sqliteErrorFromPosixError(tErrno, + setLockFlag ? SQLITE_IOERR_LOCK : SQLITE_IOERR_UNLOCK); +#endif /* SQLITE_IGNORE_AFP_LOCK_ERRORS */ + if( IS_LOCK_ERROR(rc) ){ + storeLastErrno(pFile, tErrno); + } + return rc; + } else { + 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, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +*/ +static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){ + int rc = SQLITE_OK; + int reserved = 0; + unixFile *pFile = (unixFile*)id; + afpLockingContext *context; + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + + assert( pFile ); + context = (afpLockingContext *) pFile->lockingContext; + if( context->reserved ){ + *pResOut = 1; + return SQLITE_OK; + } + unixEnterMutex(); /* Because pFile->pInode is shared across threads */ + + /* Check if a thread in this process holds such a lock */ + if( pFile->pInode->eFileLock>SHARED_LOCK ){ + reserved = 1; + } + + /* Otherwise see if some other process holds it. + */ + if( !reserved ){ + /* lock the RESERVED byte */ + int lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1); + if( SQLITE_OK==lrc ){ + /* if we succeeded in taking the reserved lock, unlock it to restore + ** the original state */ + lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1, 0); + } else { + /* if we failed to get the lock then someone else must have it */ + reserved = 1; + } + if( IS_LOCK_ERROR(lrc) ){ + rc=lrc; + } + } + + unixLeaveMutex(); + OSTRACE(("TEST WR-LOCK %d %d %d (afp)\n", pFile->h, rc, reserved)); + + *pResOut = reserved; + return rc; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** 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 afpLock(sqlite3_file *id, int eFileLock){ + int rc = SQLITE_OK; + unixFile *pFile = (unixFile*)id; + unixInodeInfo *pInode = pFile->pInode; + afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; + + assert( pFile ); + OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (afp)\n", pFile->h, + azFileLock(eFileLock), azFileLock(pFile->eFileLock), + azFileLock(pInode->eFileLock), pInode->nShared , osGetpid(0))); + + /* If there is already a lock of this type or more restrictive on the + ** unixFile, do nothing. Don't use the afp_end_lock: exit path, as + ** unixEnterMutex() hasn't been called yet. + */ + if( pFile->eFileLock>=eFileLock ){ + OSTRACE(("LOCK %d %s ok (already held) (afp)\n", pFile->h, + azFileLock(eFileLock))); + return SQLITE_OK; + } + + /* Make sure the locking sequence is correct + ** (1) We never move from unlocked to anything higher than shared lock. + ** (2) SQLite never explicitly requests a pendig lock. + ** (3) A shared lock is always held when a reserve lock is requested. + */ + assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK ); + assert( eFileLock!=PENDING_LOCK ); + assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK ); + + /* This mutex is needed because pFile->pInode is shared across threads + */ + unixEnterMutex(); + pInode = pFile->pInode; + + /* If some thread using this PID has a lock via a different unixFile* + ** handle that precludes the requested lock, return BUSY. + */ + if( (pFile->eFileLock!=pInode->eFileLock && + (pInode->eFileLock>=PENDING_LOCK || eFileLock>SHARED_LOCK)) + ){ + rc = SQLITE_BUSY; + goto afp_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( eFileLock==SHARED_LOCK && + (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){ + assert( eFileLock==SHARED_LOCK ); + assert( pFile->eFileLock==0 ); + assert( pInode->nShared>0 ); + pFile->eFileLock = SHARED_LOCK; + pInode->nShared++; + pInode->nLock++; + goto afp_end_lock; + } + + /* 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( eFileLock==SHARED_LOCK + || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLockdbPath, pFile, PENDING_BYTE, 1, 1); + if (failed) { + rc = failed; + goto afp_end_lock; + } + } + + /* If control gets to this point, then actually go ahead and make + ** operating system calls for the specified lock. + */ + if( eFileLock==SHARED_LOCK ){ + int lrc1, lrc2, lrc1Errno = 0; + long lk, mask; + + assert( pInode->nShared==0 ); + assert( pInode->eFileLock==0 ); + + mask = (sizeof(long)==8) ? LARGEST_INT64 : 0x7fffffff; + /* Now get the read-lock SHARED_LOCK */ + /* note that the quality of the randomness doesn't matter that much */ + lk = random(); + pInode->sharedByte = (lk & mask)%(SHARED_SIZE - 1); + lrc1 = afpSetLock(context->dbPath, pFile, + SHARED_FIRST+pInode->sharedByte, 1, 1); + if( IS_LOCK_ERROR(lrc1) ){ + lrc1Errno = pFile->lastErrno; + } + /* Drop the temporary PENDING lock */ + lrc2 = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0); + + if( IS_LOCK_ERROR(lrc1) ) { + storeLastErrno(pFile, lrc1Errno); + rc = lrc1; + goto afp_end_lock; + } else if( IS_LOCK_ERROR(lrc2) ){ + rc = lrc2; + goto afp_end_lock; + } else if( lrc1 != SQLITE_OK ) { + rc = lrc1; + } else { + pFile->eFileLock = SHARED_LOCK; + pInode->nLock++; + pInode->nShared = 1; + } + }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>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. + */ + int failed = 0; + assert( 0!=pFile->eFileLock ); + if (eFileLock >= RESERVED_LOCK && pFile->eFileLock < RESERVED_LOCK) { + /* Acquire a RESERVED lock */ + failed = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1); + if( !failed ){ + context->reserved = 1; + } + } + if (!failed && eFileLock == EXCLUSIVE_LOCK) { + /* Acquire an EXCLUSIVE lock */ + + /* Remove the shared lock before trying the range. we'll need to + ** reestablish the shared lock if we can't get the afpUnlock + */ + if( !(failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST + + pInode->sharedByte, 1, 0)) ){ + int failed2 = SQLITE_OK; + /* now attemmpt to get the exclusive lock range */ + failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST, + SHARED_SIZE, 1); + if( failed && (failed2 = afpSetLock(context->dbPath, pFile, + SHARED_FIRST + pInode->sharedByte, 1, 1)) ){ + /* Can't reestablish the shared lock. Sqlite can't deal, this is + ** a critical I/O error + */ + rc = ((failed & SQLITE_IOERR) == SQLITE_IOERR) ? failed2 : + SQLITE_IOERR_LOCK; + goto afp_end_lock; + } + }else{ + rc = failed; + } + } + if( failed ){ + rc = failed; + } + } + + if( rc==SQLITE_OK ){ + pFile->eFileLock = eFileLock; + pInode->eFileLock = eFileLock; + }else if( eFileLock==EXCLUSIVE_LOCK ){ + pFile->eFileLock = PENDING_LOCK; + pInode->eFileLock = PENDING_LOCK; + } + +afp_end_lock: + unixLeaveMutex(); + OSTRACE(("LOCK %d %s %s (afp)\n", pFile->h, azFileLock(eFileLock), + rc==SQLITE_OK ? "ok" : "failed")); + return rc; +} + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** 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 afpUnlock(sqlite3_file *id, int eFileLock) { + int rc = SQLITE_OK; + unixFile *pFile = (unixFile*)id; + unixInodeInfo *pInode; + afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; + int skipShared = 0; +#ifdef SQLITE_TEST + int h = pFile->h; +#endif + + assert( pFile ); + OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (afp)\n", pFile->h, eFileLock, + pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared, + osGetpid(0))); + + assert( eFileLock<=SHARED_LOCK ); + if( pFile->eFileLock<=eFileLock ){ + return SQLITE_OK; + } + unixEnterMutex(); + pInode = pFile->pInode; + assert( pInode->nShared!=0 ); + if( pFile->eFileLock>SHARED_LOCK ){ + assert( pInode->eFileLock==pFile->eFileLock ); + SimulateIOErrorBenign(1); + SimulateIOError( h=(-1) ) + SimulateIOErrorBenign(0); + +#ifdef SQLITE_DEBUG + /* When reducing a lock such that other processes can start + ** reading the database file again, make sure that the + ** transaction counter was updated if any part of the database + ** file changed. If the transaction counter is not updated, + ** other connections to the same file might not realize that + ** the file has changed and hence might not know to flush their + ** cache. The use of a stale cache can lead to database corruption. + */ + assert( pFile->inNormalWrite==0 + || pFile->dbUpdate==0 + || pFile->transCntrChng==1 ); + pFile->inNormalWrite = 0; +#endif + + if( pFile->eFileLock==EXCLUSIVE_LOCK ){ + rc = afpSetLock(context->dbPath, pFile, SHARED_FIRST, SHARED_SIZE, 0); + if( rc==SQLITE_OK && (eFileLock==SHARED_LOCK || pInode->nShared>1) ){ + /* only re-establish the shared lock if necessary */ + int sharedLockByte = SHARED_FIRST+pInode->sharedByte; + rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 1); + } else { + skipShared = 1; + } + } + if( rc==SQLITE_OK && pFile->eFileLock>=PENDING_LOCK ){ + rc = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0); + } + if( rc==SQLITE_OK && pFile->eFileLock>=RESERVED_LOCK && context->reserved ){ + rc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1, 0); + if( !rc ){ + context->reserved = 0; + } + } + if( rc==SQLITE_OK && (eFileLock==SHARED_LOCK || pInode->nShared>1)){ + pInode->eFileLock = SHARED_LOCK; + } + } + if( rc==SQLITE_OK && eFileLock==NO_LOCK ){ + + /* Decrement the shared lock counter. Release the lock using an + ** OS call only when all threads in this same process have released + ** the lock. + */ + unsigned long long sharedLockByte = SHARED_FIRST+pInode->sharedByte; + pInode->nShared--; + if( pInode->nShared==0 ){ + SimulateIOErrorBenign(1); + SimulateIOError( h=(-1) ) + SimulateIOErrorBenign(0); + if( !skipShared ){ + rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 0); + } + if( !rc ){ + pInode->eFileLock = NO_LOCK; + pFile->eFileLock = NO_LOCK; + } + } + if( rc==SQLITE_OK ){ + pInode->nLock--; + assert( pInode->nLock>=0 ); + if( pInode->nLock==0 ){ + closePendingFds(pFile); + } + } + } + + unixLeaveMutex(); + if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock; + return rc; +} + +/* +** Close a file & cleanup AFP specific locking context +*/ +static int afpClose(sqlite3_file *id) { + int rc = SQLITE_OK; + if( id ){ + unixFile *pFile = (unixFile*)id; + afpUnlock(id, NO_LOCK); + unixEnterMutex(); + if( pFile->pInode && pFile->pInode->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 pInode->aPending. It will be automatically closed when + ** the last lock is cleared. + */ + setPendingFd(pFile); + } + releaseInodeInfo(pFile); + sqlite3_free(pFile->lockingContext); + rc = closeUnixFile(id); + unixLeaveMutex(); + } + return rc; +} + +#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ +/* +** The code above is the AFP lock implementation. The code is specific +** to MacOSX and does not work on other unix platforms. No alternative +** is available. If you don't compile for a mac, then the "unix-afp" +** VFS is not available. +** +********************* End of the AFP lock implementation ********************** +******************************************************************************/ + +/****************************************************************************** +*************************** Begin NFS Locking ********************************/ + +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +/* + ** Lower the locking level on file descriptor pFile to eFileLock. eFileLock + ** 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 nfsUnlock(sqlite3_file *id, int eFileLock){ + return posixUnlock(id, eFileLock, 1); +} + +#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ +/* +** The code above is the NFS lock implementation. The code is specific +** to MacOSX and does not work on other unix platforms. No alternative +** is available. +** +********************* End of the NFS lock implementation ********************** +******************************************************************************/ + +/****************************************************************************** +**************** Non-locking sqlite3_file methods ***************************** +** +** The next division contains implementations for all methods of the +** sqlite3_file object other than the locking methods. The locking +** methods were defined in divisions above (one locking method per +** division). Those methods that are common to all locking modes +** are gather together into this division. +*/ + +/* +** Seek to the offset passed as the second argument, then read cnt +** bytes into pBuf. Return the number of bytes actually read. +** +** NB: If you define USE_PREAD or USE_PREAD64, then it might also +** be necessary to define _XOPEN_SOURCE to be 500. This varies from +** one system to another. Since SQLite does not define USE_PREAD +** in any form by default, we will not attempt to define _XOPEN_SOURCE. +** See tickets #2741 and #2681. +** +** To avoid stomping the errno value on a failed read the lastErrno value +** is set before returning. +*/ +static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ + int got; + int prior = 0; +#if (!defined(USE_PREAD) && !defined(USE_PREAD64)) + i64 newOffset; +#endif + TIMER_START; + assert( cnt==(cnt&0x1ffff) ); + assert( id->h>2 ); + cnt &= 0x1ffff; + do{ +#if defined(USE_PREAD) + got = osPread(id->h, pBuf, cnt, offset); + SimulateIOError( got = -1 ); +#elif defined(USE_PREAD64) + got = osPread64(id->h, pBuf, cnt, offset); + SimulateIOError( got = -1 ); +#else + newOffset = lseek(id->h, offset, SEEK_SET); + SimulateIOError( newOffset-- ); + if( newOffset!=offset ){ + if( newOffset == -1 ){ + storeLastErrno((unixFile*)id, errno); + }else{ + storeLastErrno((unixFile*)id, 0); + } + return -1; + } + got = osRead(id->h, pBuf, cnt); +#endif + if( got==cnt ) break; + if( got<0 ){ + if( errno==EINTR ){ got = 1; continue; } + prior = 0; + storeLastErrno((unixFile*)id, errno); + break; + }else if( got>0 ){ + cnt -= got; + offset += got; + prior += got; + pBuf = (void*)(got + (char*)pBuf); + } + }while( got>0 ); + TIMER_END; + OSTRACE(("READ %-3d %5d %7lld %llu\n", + id->h, got+prior, offset-prior, TIMER_ELAPSED)); + return got+prior; +} + +/* +** 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( + sqlite3_file *id, + void *pBuf, + int amt, + sqlite3_int64 offset +){ + unixFile *pFile = (unixFile *)id; + int got; + assert( id ); + assert( offset>=0 ); + assert( amt>0 ); + + /* If this is a database file (not a journal, master-journal or temp + ** file), the bytes in the locking range should never be read or written. */ +#if 0 + assert( pFile->pUnused==0 + || offset>=PENDING_BYTE+512 + || offset+amt<=PENDING_BYTE + ); +#endif + +#if SQLITE_MAX_MMAP_SIZE>0 + /* Deal with as much of this read request as possible by transfering + ** data from the memory mapping using memcpy(). */ + if( offsetmmapSize ){ + if( offset+amt <= pFile->mmapSize ){ + memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt); + return SQLITE_OK; + }else{ + int nCopy = pFile->mmapSize - offset; + memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy); + pBuf = &((u8 *)pBuf)[nCopy]; + amt -= nCopy; + offset += nCopy; + } + } +#endif + + got = seekAndRead(pFile, offset, pBuf, amt); + if( got==amt ){ + return SQLITE_OK; + }else if( got<0 ){ + /* lastErrno set by seekAndRead */ + return SQLITE_IOERR_READ; + }else{ + storeLastErrno(pFile, 0); /* not a system error */ + /* Unread parts of the buffer must be zero-filled */ + memset(&((char*)pBuf)[got], 0, amt-got); + return SQLITE_IOERR_SHORT_READ; + } +} + +/* +** Attempt to seek the file-descriptor passed as the first argument to +** absolute offset iOff, then attempt to write nBuf bytes of data from +** pBuf to it. If an error occurs, return -1 and set *piErrno. Otherwise, +** return the actual number of bytes written (which may be less than +** nBuf). +*/ +static int seekAndWriteFd( + int fd, /* File descriptor to write to */ + i64 iOff, /* File offset to begin writing at */ + const void *pBuf, /* Copy data from this buffer to the file */ + int nBuf, /* Size of buffer pBuf in bytes */ + int *piErrno /* OUT: Error number if error occurs */ +){ + int rc = 0; /* Value returned by system call */ + + assert( nBuf==(nBuf&0x1ffff) ); + assert( fd>2 ); + nBuf &= 0x1ffff; + TIMER_START; + +#if defined(USE_PREAD) + do{ rc = (int)osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR ); +#elif defined(USE_PREAD64) + do{ rc = (int)osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR); +#else + do{ + i64 iSeek = lseek(fd, iOff, SEEK_SET); + SimulateIOError( iSeek-- ); + + if( iSeek!=iOff ){ + if( piErrno ) *piErrno = (iSeek==-1 ? errno : 0); + return -1; + } + rc = osWrite(fd, pBuf, nBuf); + }while( rc<0 && errno==EINTR ); +#endif + + TIMER_END; + OSTRACE(("WRITE %-3d %5d %7lld %llu\n", fd, rc, iOff, TIMER_ELAPSED)); + + if( rc<0 && piErrno ) *piErrno = errno; + return rc; +} + + +/* +** Seek to the offset in id->offset then read cnt bytes into pBuf. +** Return the number of bytes actually read. Update the offset. +** +** To avoid stomping the errno value on a failed write the lastErrno value +** is set before returning. +*/ +static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){ + return seekAndWriteFd(id->h, offset, pBuf, cnt, &id->lastErrno); +} + + +/* +** Write data from a buffer into a file. Return SQLITE_OK on success +** or some other error code on failure. +*/ +static int unixWrite( + sqlite3_file *id, + const void *pBuf, + int amt, + sqlite3_int64 offset +){ + unixFile *pFile = (unixFile*)id; + int wrote = 0; + assert( id ); + assert( amt>0 ); + + /* If this is a database file (not a journal, master-journal or temp + ** file), the bytes in the locking range should never be read or written. */ +#if 0 + assert( pFile->pUnused==0 + || offset>=PENDING_BYTE+512 + || offset+amt<=PENDING_BYTE + ); +#endif + +#ifdef SQLITE_DEBUG + /* If we are doing a normal write to a database file (as opposed to + ** doing a hot-journal rollback or a write to some file other than a + ** normal database file) then record the fact that the database + ** has changed. If the transaction counter is modified, record that + ** fact too. + */ + if( pFile->inNormalWrite ){ + pFile->dbUpdate = 1; /* The database has been modified */ + if( offset<=24 && offset+amt>=27 ){ + int rc; + char oldCntr[4]; + SimulateIOErrorBenign(1); + rc = seekAndRead(pFile, 24, oldCntr, 4); + SimulateIOErrorBenign(0); + if( rc!=4 || memcmp(oldCntr, &((char*)pBuf)[24-offset], 4)!=0 ){ + pFile->transCntrChng = 1; /* The transaction counter has changed */ + } + } + } +#endif + +#if SQLITE_MAX_MMAP_SIZE>0 + /* Deal with as much of this write request as possible by transfering + ** data from the memory mapping using memcpy(). */ + if( offsetmmapSize ){ + if( offset+amt <= pFile->mmapSize ){ + memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt); + return SQLITE_OK; + }else{ + int nCopy = pFile->mmapSize - offset; + memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy); + pBuf = &((u8 *)pBuf)[nCopy]; + amt -= nCopy; + offset += nCopy; + } + } +#endif + + while( amt>0 && (wrote = seekAndWrite(pFile, offset, pBuf, amt))>0 ){ + amt -= wrote; + offset += wrote; + pBuf = &((char*)pBuf)[wrote]; + } + SimulateIOError(( wrote=(-1), amt=1 )); + SimulateDiskfullError(( wrote=0, amt=1 )); + + if( amt>0 ){ + if( wrote<0 && pFile->lastErrno!=ENOSPC ){ + /* lastErrno set by seekAndWrite */ + return SQLITE_IOERR_WRITE; + }else{ + storeLastErrno(pFile, 0); /* not a system error */ + return SQLITE_FULL; + } + } + + return SQLITE_OK; +} + +#ifdef SQLITE_TEST +/* +** Count the number of fullsyncs and normal syncs. This is used to test +** that syncs and fullsyncs are occurring at the right times. +*/ +SQLITE_API int sqlite3_sync_count = 0; +SQLITE_API int sqlite3_fullsync_count = 0; +#endif + +/* +** We do not trust systems to provide a working fdatasync(). Some do. +** Others do no. To be safe, we will stick with the (slightly slower) +** fsync(). If you know that your system does support fdatasync() correctly, +** then simply compile with -Dfdatasync=fdatasync or -DHAVE_FDATASYNC +*/ +#if !defined(fdatasync) && !HAVE_FDATASYNC +# define fdatasync fsync +#endif + +/* +** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not +** the F_FULLFSYNC macro is defined. F_FULLFSYNC is currently +** only available on Mac OS X. But that could change. +*/ +#ifdef F_FULLFSYNC +# define HAVE_FULLFSYNC 1 +#else +# define HAVE_FULLFSYNC 0 +#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. +** +** SQLite sets the dataOnly flag if the size of the file is unchanged. +** The idea behind dataOnly is that it should only write the file content +** to disk, not the inode. We only set dataOnly if the file size is +** unchanged since the file size is part of the inode. However, +** Ted Ts'o tells us that fdatasync() will also write the inode if the +** file size has changed. The only real difference between fdatasync() +** and fsync(), Ted tells us, is that fdatasync() will not flush the +** inode if the mtime or owner or other inode attributes have changed. +** We only care about the file size, not the other file attributes, so +** as far as SQLite is concerned, an fdatasync() is always adequate. +** So, we always use fdatasync() if it is available, regardless of +** the value of the dataOnly flag. +*/ +static int full_fsync(int fd, int fullSync, int dataOnly){ + int rc; + + /* The following "ifdef/elif/else/" block has the same structure as + ** the one below. It is replicated here solely to avoid cluttering + ** up the real code with the UNUSED_PARAMETER() macros. + */ +#ifdef SQLITE_NO_SYNC + UNUSED_PARAMETER(fd); + UNUSED_PARAMETER(fullSync); + UNUSED_PARAMETER(dataOnly); +#elif HAVE_FULLFSYNC + UNUSED_PARAMETER(dataOnly); +#else + UNUSED_PARAMETER(fullSync); + UNUSED_PARAMETER(dataOnly); +#endif + + /* 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; +#elif HAVE_FULLFSYNC + if( fullSync ){ + rc = osFcntl(fd, F_FULLFSYNC, 0); + }else{ + rc = 1; + } + /* If the FULLFSYNC failed, fall back to attempting an fsync(). + ** It shouldn't be possible for fullfsync to fail on the local + ** file system (on OSX), so failure indicates that FULLFSYNC + ** isn't supported for this file system. So, attempt an fsync + ** and (for now) ignore the overhead of a superfluous fcntl call. + ** It'd be better to detect fullfsync support once and avoid + ** the fcntl call every time sync is called. + */ + if( rc ) rc = fsync(fd); + +#elif defined(__APPLE__) + /* fdatasync() on HFS+ doesn't yet flush the file size if it changed correctly + ** so currently we default to the macro that redefines fdatasync to fsync + */ + rc = fsync(fd); +#else + rc = fdatasync(fd); +#if OS_VXWORKS + if( rc==-1 && errno==ENOTSUP ){ + rc = fsync(fd); + } +#endif /* OS_VXWORKS */ +#endif /* ifdef SQLITE_NO_SYNC elif HAVE_FULLFSYNC */ + + if( OS_VXWORKS && rc!= -1 ){ + rc = 0; + } + return rc; +} + +/* +** Open a file descriptor to the directory containing file zFilename. +** If successful, *pFd is set to the opened file descriptor and +** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM +** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined +** value. +** +** The directory file descriptor is used for only one thing - to +** fsync() a directory to make sure file creation and deletion events +** are flushed to disk. Such fsyncs are not needed on newer +** journaling filesystems, but are required on older filesystems. +** +** This routine can be overridden using the xSetSysCall interface. +** The ability to override this routine was added in support of the +** chromium sandbox. Opening a directory is a security risk (we are +** told) so making it overrideable allows the chromium sandbox to +** replace this routine with a harmless no-op. To make this routine +** a no-op, replace it with a stub that returns SQLITE_OK but leaves +** *pFd set to a negative number. +** +** If SQLITE_OK is returned, the caller is responsible for closing +** the file descriptor *pFd using close(). +*/ +static int openDirectory(const char *zFilename, int *pFd){ + int ii; + int fd = -1; + char zDirname[MAX_PATHNAME+1]; + + sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename); + for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--); + if( ii>0 ){ + zDirname[ii] = '\0'; + fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0); + if( fd>=0 ){ + OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname)); + } + } + *pFd = fd; + return (fd>=0?SQLITE_OK:unixLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname)); +} + +/* +** 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(sqlite3_file *id, int flags){ + int rc; + unixFile *pFile = (unixFile*)id; + + int isDataOnly = (flags&SQLITE_SYNC_DATAONLY); + int isFullsync = (flags&0x0F)==SQLITE_SYNC_FULL; + + /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */ + assert((flags&0x0F)==SQLITE_SYNC_NORMAL + || (flags&0x0F)==SQLITE_SYNC_FULL + ); + + /* Unix cannot, but some systems may return SQLITE_FULL from here. This + ** line is to test that doing so does not cause any problems. + */ + SimulateDiskfullError( return SQLITE_FULL ); + + assert( pFile ); + OSTRACE(("SYNC %-3d\n", pFile->h)); + rc = full_fsync(pFile->h, isFullsync, isDataOnly); + SimulateIOError( rc=1 ); + if( rc ){ + storeLastErrno(pFile, errno); + return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath); + } + + /* Also fsync the directory containing the file if the DIRSYNC flag + ** is set. This is a one-time occurrence. Many systems (examples: AIX) + ** are unable to fsync a directory, so ignore errors on the fsync. + */ + if( pFile->ctrlFlags & UNIXFILE_DIRSYNC ){ + int dirfd; + OSTRACE(("DIRSYNC %s (have_fullfsync=%d fullsync=%d)\n", pFile->zPath, + HAVE_FULLFSYNC, isFullsync)); + rc = osOpenDirectory(pFile->zPath, &dirfd); + if( rc==SQLITE_OK && dirfd>=0 ){ + full_fsync(dirfd, 0, 0); + robust_close(pFile, dirfd, __LINE__); + }else if( rc==SQLITE_CANTOPEN ){ + rc = SQLITE_OK; + } + pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC; + } + return rc; +} + +/* +** Truncate an open file to a specified size +*/ +static int unixTruncate(sqlite3_file *id, i64 nByte){ + unixFile *pFile = (unixFile *)id; + int rc; + assert( pFile ); + SimulateIOError( return SQLITE_IOERR_TRUNCATE ); + + /* If the user has configured a chunk-size for this file, truncate the + ** file so that it consists of an integer number of chunks (i.e. the + ** actual file size after the operation may be larger than the requested + ** size). + */ + if( pFile->szChunk>0 ){ + nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; + } + + rc = robust_ftruncate(pFile->h, nByte); + if( rc ){ + storeLastErrno(pFile, errno); + return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); + }else{ +#ifdef SQLITE_DEBUG + /* If we are doing a normal write to a database file (as opposed to + ** doing a hot-journal rollback or a write to some file other than a + ** normal database file) and we truncate the file to zero length, + ** that effectively updates the change counter. This might happen + ** when restoring a database using the backup API from a zero-length + ** source. + */ + if( pFile->inNormalWrite && nByte==0 ){ + pFile->transCntrChng = 1; + } +#endif + +#if SQLITE_MAX_MMAP_SIZE>0 + /* If the file was just truncated to a size smaller than the currently + ** mapped region, reduce the effective mapping size as well. SQLite will + ** use read() and write() to access data beyond this point from now on. + */ + if( nBytemmapSize ){ + pFile->mmapSize = nByte; + } +#endif + + return SQLITE_OK; + } +} + +/* +** Determine the current size of a file in bytes +*/ +static int unixFileSize(sqlite3_file *id, i64 *pSize){ + int rc; + struct stat buf; + assert( id ); + rc = osFstat(((unixFile*)id)->h, &buf); + SimulateIOError( rc=1 ); + if( rc!=0 ){ + storeLastErrno((unixFile*)id, errno); + return SQLITE_IOERR_FSTAT; + } + *pSize = buf.st_size; + + /* When opening a zero-size database, the findInodeInfo() procedure + ** writes a single byte into that file in order to work around a bug + ** in the OS-X msdos filesystem. In order to avoid problems with upper + ** layers, we need to report this file size as zero even though it is + ** really 1. Ticket #3260. + */ + if( *pSize==1 ) *pSize = 0; + + + return SQLITE_OK; +} + +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) +/* +** Handler for proxy-locking file-control verbs. Defined below in the +** proxying locking division. +*/ +static int proxyFileControl(sqlite3_file*,int,void*); +#endif + +/* +** This function is called to handle the SQLITE_FCNTL_SIZE_HINT +** file-control operation. Enlarge the database to nBytes in size +** (rounded up to the next chunk-size). If the database is already +** nBytes or larger, this routine is a no-op. +*/ +static int fcntlSizeHint(unixFile *pFile, i64 nByte){ + if( pFile->szChunk>0 ){ + i64 nSize; /* Required file size */ + struct stat buf; /* Used to hold return values of fstat() */ + + if( osFstat(pFile->h, &buf) ){ + return SQLITE_IOERR_FSTAT; + } + + nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk; + if( nSize>(i64)buf.st_size ){ + +#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE + /* The code below is handling the return value of osFallocate() + ** correctly. posix_fallocate() is defined to "returns zero on success, + ** or an error number on failure". See the manpage for details. */ + int err; + do{ + err = osFallocate(pFile->h, buf.st_size, nSize-buf.st_size); + }while( err==EINTR ); + if( err ) return SQLITE_IOERR_WRITE; +#else + /* If the OS does not have posix_fallocate(), fake it. Write a + ** single byte to the last byte in each block that falls entirely + ** within the extended region. Then, if required, a single byte + ** at offset (nSize-1), to set the size of the file correctly. + ** This is a similar technique to that used by glibc on systems + ** that do not have a real fallocate() call. + */ + int nBlk = buf.st_blksize; /* File-system block size */ + int nWrite = 0; /* Number of bytes written by seekAndWrite */ + i64 iWrite; /* Next offset to write to */ + + iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1; + assert( iWrite>=buf.st_size ); + assert( (iWrite/nBlk)==((buf.st_size+nBlk-1)/nBlk) ); + assert( ((iWrite+1)%nBlk)==0 ); + for(/*no-op*/; iWrite0 + if( pFile->mmapSizeMax>0 && nByte>pFile->mmapSize ){ + int rc; + if( pFile->szChunk<=0 ){ + if( robust_ftruncate(pFile->h, nByte) ){ + storeLastErrno(pFile, errno); + return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); + } + } + + rc = unixMapfile(pFile, nByte); + return rc; + } +#endif + + return SQLITE_OK; +} + +/* +** If *pArg is initially negative then this is a query. Set *pArg to +** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set. +** +** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags. +*/ +static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){ + if( *pArg<0 ){ + *pArg = (pFile->ctrlFlags & mask)!=0; + }else if( (*pArg)==0 ){ + pFile->ctrlFlags &= ~mask; + }else{ + pFile->ctrlFlags |= mask; + } +} + +/* Forward declaration */ +static int unixGetTempname(int nBuf, char *zBuf); + +/* +** Information and control of an open file handle. +*/ +static int unixFileControl(sqlite3_file *id, int op, void *pArg){ + unixFile *pFile = (unixFile*)id; + switch( op ){ + case SQLITE_FCNTL_WAL_BLOCK: { + /* pFile->ctrlFlags |= UNIXFILE_BLOCK; // Deferred feature */ + return SQLITE_OK; + } + case SQLITE_FCNTL_LOCKSTATE: { + *(int*)pArg = pFile->eFileLock; + return SQLITE_OK; + } + case SQLITE_FCNTL_LAST_ERRNO: { + *(int*)pArg = pFile->lastErrno; + return SQLITE_OK; + } + case SQLITE_FCNTL_CHUNK_SIZE: { + pFile->szChunk = *(int *)pArg; + return SQLITE_OK; + } + case SQLITE_FCNTL_SIZE_HINT: { + int rc; + SimulateIOErrorBenign(1); + rc = fcntlSizeHint(pFile, *(i64 *)pArg); + SimulateIOErrorBenign(0); + return rc; + } + case SQLITE_FCNTL_PERSIST_WAL: { + unixModeBit(pFile, UNIXFILE_PERSIST_WAL, (int*)pArg); + return SQLITE_OK; + } + case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { + unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg); + return SQLITE_OK; + } + case SQLITE_FCNTL_VFSNAME: { + *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); + return SQLITE_OK; + } + case SQLITE_FCNTL_TEMPFILENAME: { + char *zTFile = sqlite3_malloc64( pFile->pVfs->mxPathname ); + if( zTFile ){ + unixGetTempname(pFile->pVfs->mxPathname, zTFile); + *(char**)pArg = zTFile; + } + return SQLITE_OK; + } + case SQLITE_FCNTL_HAS_MOVED: { + *(int*)pArg = fileHasMoved(pFile); + return SQLITE_OK; + } +#if SQLITE_MAX_MMAP_SIZE>0 + case SQLITE_FCNTL_MMAP_SIZE: { + i64 newLimit = *(i64*)pArg; + int rc = SQLITE_OK; + if( newLimit>sqlite3GlobalConfig.mxMmap ){ + newLimit = sqlite3GlobalConfig.mxMmap; + } + *(i64*)pArg = pFile->mmapSizeMax; + if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){ + pFile->mmapSizeMax = newLimit; + if( pFile->mmapSize>0 ){ + unixUnmapfile(pFile); + rc = unixMapfile(pFile, -1); + } + } + return rc; + } +#endif +#ifdef SQLITE_DEBUG + /* The pager calls this method to signal that it has done + ** a rollback and that the database is therefore unchanged and + ** it hence it is OK for the transaction change counter to be + ** unchanged. + */ + case SQLITE_FCNTL_DB_UNCHANGED: { + ((unixFile*)id)->dbUpdate = 0; + return SQLITE_OK; + } +#endif +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) + case SQLITE_FCNTL_SET_LOCKPROXYFILE: + case SQLITE_FCNTL_GET_LOCKPROXYFILE: { + return proxyFileControl(id,op,pArg); + } +#endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ + } + return SQLITE_NOTFOUND; +} + +/* +** Return the sector size in bytes of the underlying block device for +** the specified file. This is almost always 512 bytes, but may be +** larger for some devices. +** +** SQLite code assumes this function cannot fail. It also assumes that +** if two files are created in the same file-system directory (i.e. +** a database and its journal file) that the sector size will be the +** same for both. +*/ +#ifndef __QNXNTO__ +static int unixSectorSize(sqlite3_file *NotUsed){ + UNUSED_PARAMETER(NotUsed); + return SQLITE_DEFAULT_SECTOR_SIZE; +} +#endif + +/* +** The following version of unixSectorSize() is optimized for QNX. +*/ +#ifdef __QNXNTO__ +#include +#include +static int unixSectorSize(sqlite3_file *id){ + unixFile *pFile = (unixFile*)id; + if( pFile->sectorSize == 0 ){ + struct statvfs fsInfo; + + /* Set defaults for non-supported filesystems */ + pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; + pFile->deviceCharacteristics = 0; + if( fstatvfs(pFile->h, &fsInfo) == -1 ) { + return pFile->sectorSize; + } + + if( !strcmp(fsInfo.f_basetype, "tmp") ) { + pFile->sectorSize = fsInfo.f_bsize; + pFile->deviceCharacteristics = + SQLITE_IOCAP_ATOMIC4K | /* All ram filesystem writes are atomic */ + SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until + ** the write succeeds */ + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind + ** so it is ordered */ + 0; + }else if( strstr(fsInfo.f_basetype, "etfs") ){ + pFile->sectorSize = fsInfo.f_bsize; + pFile->deviceCharacteristics = + /* etfs cluster size writes are atomic */ + (pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) | + SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until + ** the write succeeds */ + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind + ** so it is ordered */ + 0; + }else if( !strcmp(fsInfo.f_basetype, "qnx6") ){ + pFile->sectorSize = fsInfo.f_bsize; + pFile->deviceCharacteristics = + SQLITE_IOCAP_ATOMIC | /* All filesystem writes are atomic */ + SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until + ** the write succeeds */ + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind + ** so it is ordered */ + 0; + }else if( !strcmp(fsInfo.f_basetype, "qnx4") ){ + pFile->sectorSize = fsInfo.f_bsize; + pFile->deviceCharacteristics = + /* full bitset of atomics from max sector size and smaller */ + ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 | + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind + ** so it is ordered */ + 0; + }else if( strstr(fsInfo.f_basetype, "dos") ){ + pFile->sectorSize = fsInfo.f_bsize; + pFile->deviceCharacteristics = + /* full bitset of atomics from max sector size and smaller */ + ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 | + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind + ** so it is ordered */ + 0; + }else{ + pFile->deviceCharacteristics = + SQLITE_IOCAP_ATOMIC512 | /* blocks are atomic */ + SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until + ** the write succeeds */ + 0; + } + } + /* Last chance verification. If the sector size isn't a multiple of 512 + ** then it isn't valid.*/ + if( pFile->sectorSize % 512 != 0 ){ + pFile->deviceCharacteristics = 0; + pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; + } + return pFile->sectorSize; +} +#endif /* __QNXNTO__ */ + +/* +** Return the device characteristics for the file. +** +** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default. +** However, that choice is controversial since technically the underlying +** file system does not always provide powersafe overwrites. (In other +** words, after a power-loss event, parts of the file that were never +** written might end up being altered.) However, non-PSOW behavior is very, +** very rare. And asserting PSOW makes a large reduction in the amount +** of required I/O for journaling, since a lot of padding is eliminated. +** Hence, while POWERSAFE_OVERWRITE is on by default, there is a file-control +** available to turn it off and URI query parameter available to turn it off. +*/ +static int unixDeviceCharacteristics(sqlite3_file *id){ + unixFile *p = (unixFile*)id; + int rc = 0; +#ifdef __QNXNTO__ + if( p->sectorSize==0 ) unixSectorSize(id); + rc = p->deviceCharacteristics; +#endif + if( p->ctrlFlags & UNIXFILE_PSOW ){ + rc |= SQLITE_IOCAP_POWERSAFE_OVERWRITE; + } + return rc; +} + +#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 + +/* +** Return the system page size. +** +** This function should not be called directly by other code in this file. +** Instead, it should be called via macro osGetpagesize(). +*/ +static int unixGetpagesize(void){ +#if OS_VXWORKS + return 1024; +#elif defined(_BSD_SOURCE) + return getpagesize(); +#else + return (int)sysconf(_SC_PAGESIZE); +#endif +} + +#endif /* !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 */ + +#ifndef SQLITE_OMIT_WAL + +/* +** Object used to represent an shared memory buffer. +** +** When multiple threads all reference the same wal-index, each thread +** has its own unixShm object, but they all point to a single instance +** of this unixShmNode object. In other words, each wal-index is opened +** only once per process. +** +** Each unixShmNode object is connected to a single unixInodeInfo object. +** We could coalesce this object into unixInodeInfo, but that would mean +** every open file that does not use shared memory (in other words, most +** open files) would have to carry around this extra information. So +** the unixInodeInfo object contains a pointer to this unixShmNode object +** and the unixShmNode object is created only when needed. +** +** unixMutexHeld() must be true when creating or destroying +** this object or while reading or writing the following fields: +** +** nRef +** +** The following fields are read-only after the object is created: +** +** fid +** zFilename +** +** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and +** unixMutexHeld() is true when reading or writing any other field +** in this structure. +*/ +struct unixShmNode { + unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ + sqlite3_mutex *mutex; /* Mutex to access this object */ + char *zFilename; /* Name of the mmapped file */ + int h; /* Open file descriptor */ + int szRegion; /* Size of shared-memory regions */ + u16 nRegion; /* Size of array apRegion */ + u8 isReadonly; /* True if read-only */ + char **apRegion; /* Array of mapped shared-memory regions */ + int nRef; /* Number of unixShm objects pointing to this */ + unixShm *pFirst; /* All unixShm objects pointing to this */ +#ifdef SQLITE_DEBUG + u8 exclMask; /* Mask of exclusive locks held */ + u8 sharedMask; /* Mask of shared locks held */ + u8 nextShmId; /* Next available unixShm.id value */ +#endif +}; + +/* +** Structure used internally by this VFS to record the state of an +** open shared memory connection. +** +** The following fields are initialized when this object is created and +** are read-only thereafter: +** +** unixShm.pFile +** unixShm.id +** +** All other fields are read/write. The unixShm.pFile->mutex must be held +** while accessing any read/write fields. +*/ +struct unixShm { + unixShmNode *pShmNode; /* The underlying unixShmNode object */ + unixShm *pNext; /* Next unixShm with the same unixShmNode */ + u8 hasMutex; /* True if holding the unixShmNode mutex */ + u8 id; /* Id of this connection within its unixShmNode */ + u16 sharedMask; /* Mask of shared locks held */ + u16 exclMask; /* Mask of exclusive locks held */ +}; + +/* +** Constants used for locking +*/ +#define UNIX_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ +#define UNIX_SHM_DMS (UNIX_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ + +/* +** Apply posix advisory locks for all bytes from ofst through ofst+n-1. +** +** Locks block if the mask is exactly UNIX_SHM_C and are non-blocking +** otherwise. +*/ +static int unixShmSystemLock( + unixFile *pFile, /* Open connection to the WAL file */ + int lockType, /* F_UNLCK, F_RDLCK, or F_WRLCK */ + int ofst, /* First byte of the locking range */ + int n /* Number of bytes to lock */ +){ + unixShmNode *pShmNode; /* Apply locks to this open shared-memory segment */ + struct flock f; /* The posix advisory locking structure */ + int rc = SQLITE_OK; /* Result code form fcntl() */ + + /* Access to the unixShmNode object is serialized by the caller */ + pShmNode = pFile->pInode->pShmNode; + assert( sqlite3_mutex_held(pShmNode->mutex) || pShmNode->nRef==0 ); + + /* Shared locks never span more than one byte */ + assert( n==1 || lockType!=F_RDLCK ); + + /* Locks are within range */ + assert( n>=1 && nh>=0 ){ + int lkType; + /* Initialize the locking parameters */ + memset(&f, 0, sizeof(f)); + f.l_type = lockType; + f.l_whence = SEEK_SET; + f.l_start = ofst; + f.l_len = n; + + lkType = (pFile->ctrlFlags & UNIXFILE_BLOCK)!=0 ? F_SETLKW : F_SETLK; + rc = osFcntl(pShmNode->h, lkType, &f); + rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY; + pFile->ctrlFlags &= ~UNIXFILE_BLOCK; + } + + /* Update the global lock state and do debug tracing */ +#ifdef SQLITE_DEBUG + { u16 mask; + OSTRACE(("SHM-LOCK ")); + mask = ofst>31 ? 0xffff : (1<<(ofst+n)) - (1<exclMask &= ~mask; + pShmNode->sharedMask &= ~mask; + }else if( lockType==F_RDLCK ){ + OSTRACE(("read-lock %d ok", ofst)); + pShmNode->exclMask &= ~mask; + pShmNode->sharedMask |= mask; + }else{ + assert( lockType==F_WRLCK ); + OSTRACE(("write-lock %d ok", ofst)); + pShmNode->exclMask |= mask; + pShmNode->sharedMask &= ~mask; + } + }else{ + if( lockType==F_UNLCK ){ + OSTRACE(("unlock %d failed", ofst)); + }else if( lockType==F_RDLCK ){ + OSTRACE(("read-lock failed")); + }else{ + assert( lockType==F_WRLCK ); + OSTRACE(("write-lock %d failed", ofst)); + } + } + OSTRACE((" - afterwards %03x,%03x\n", + pShmNode->sharedMask, pShmNode->exclMask)); + } +#endif + + return rc; +} + +/* +** Return the minimum number of 32KB shm regions that should be mapped at +** a time, assuming that each mapping must be an integer multiple of the +** current system page-size. +** +** Usually, this is 1. The exception seems to be systems that are configured +** to use 64KB pages - in this case each mapping must cover at least two +** shm regions. +*/ +static int unixShmRegionPerMap(void){ + int shmsz = 32*1024; /* SHM region size */ + int pgsz = osGetpagesize(); /* System page size */ + assert( ((pgsz-1)&pgsz)==0 ); /* Page size must be a power of 2 */ + if( pgszpInode->pShmNode; + assert( unixMutexHeld() ); + if( p && p->nRef==0 ){ + int nShmPerMap = unixShmRegionPerMap(); + int i; + assert( p->pInode==pFd->pInode ); + sqlite3_mutex_free(p->mutex); + for(i=0; inRegion; i+=nShmPerMap){ + if( p->h>=0 ){ + osMunmap(p->apRegion[i], p->szRegion); + }else{ + sqlite3_free(p->apRegion[i]); + } + } + sqlite3_free(p->apRegion); + if( p->h>=0 ){ + robust_close(pFd, p->h, __LINE__); + p->h = -1; + } + p->pInode->pShmNode = 0; + sqlite3_free(p); + } +} + +/* +** Open a shared-memory area associated with open database file pDbFd. +** This particular implementation uses mmapped files. +** +** The file used to implement shared-memory is in the same directory +** as the open database file and has the same name as the open database +** file with the "-shm" suffix added. For example, if the database file +** is "/home/user1/config.db" then the file that is created and mmapped +** for shared memory will be called "/home/user1/config.db-shm". +** +** Another approach to is to use files in /dev/shm or /dev/tmp or an +** some other tmpfs mount. But if a file in a different directory +** from the database file is used, then differing access permissions +** or a chroot() might cause two different processes on the same +** database to end up using different files for shared memory - +** meaning that their memory would not really be shared - resulting +** in database corruption. Nevertheless, this tmpfs file usage +** can be enabled at compile-time using -DSQLITE_SHM_DIRECTORY="/dev/shm" +** or the equivalent. The use of the SQLITE_SHM_DIRECTORY compile-time +** option results in an incompatible build of SQLite; builds of SQLite +** that with differing SQLITE_SHM_DIRECTORY settings attempt to use the +** same database file at the same time, database corruption will likely +** result. The SQLITE_SHM_DIRECTORY compile-time option is considered +** "unsupported" and may go away in a future SQLite release. +** +** When opening a new shared-memory file, if no other instances of that +** file are currently open, in this process or in other processes, then +** the file must be truncated to zero length or have its header cleared. +** +** If the original database file (pDbFd) is using the "unix-excl" VFS +** that means that an exclusive lock is held on the database file and +** that no other processes are able to read or write the database. In +** that case, we do not really need shared memory. No shared memory +** file is created. The shared memory will be simulated with heap memory. +*/ +static int unixOpenSharedMemory(unixFile *pDbFd){ + struct unixShm *p = 0; /* The connection to be opened */ + struct unixShmNode *pShmNode; /* The underlying mmapped file */ + int rc; /* Result code */ + unixInodeInfo *pInode; /* The inode of fd */ + char *zShmFilename; /* Name of the file used for SHM */ + int nShmFilename; /* Size of the SHM filename in bytes */ + + /* Allocate space for the new unixShm object. */ + p = sqlite3_malloc64( sizeof(*p) ); + if( p==0 ) return SQLITE_NOMEM; + memset(p, 0, sizeof(*p)); + assert( pDbFd->pShm==0 ); + + /* Check to see if a unixShmNode object already exists. Reuse an existing + ** one if present. Create a new one if necessary. + */ + unixEnterMutex(); + pInode = pDbFd->pInode; + pShmNode = pInode->pShmNode; + if( pShmNode==0 ){ + struct stat sStat; /* fstat() info for database file */ +#ifndef SQLITE_SHM_DIRECTORY + const char *zBasePath = pDbFd->zPath; +#endif + + /* Call fstat() to figure out the permissions on the database file. If + ** a new *-shm file is created, an attempt will be made to create it + ** with the same permissions. + */ + if( osFstat(pDbFd->h, &sStat) && pInode->bProcessLock==0 ){ + rc = SQLITE_IOERR_FSTAT; + goto shm_open_err; + } + +#ifdef SQLITE_SHM_DIRECTORY + nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31; +#else + nShmFilename = 6 + (int)strlen(zBasePath); +#endif + pShmNode = sqlite3_malloc64( sizeof(*pShmNode) + nShmFilename ); + if( pShmNode==0 ){ + rc = SQLITE_NOMEM; + goto shm_open_err; + } + memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename); + zShmFilename = pShmNode->zFilename = (char*)&pShmNode[1]; +#ifdef SQLITE_SHM_DIRECTORY + sqlite3_snprintf(nShmFilename, zShmFilename, + SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x", + (u32)sStat.st_ino, (u32)sStat.st_dev); +#else + sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", zBasePath); + sqlite3FileSuffix3(pDbFd->zPath, zShmFilename); +#endif + pShmNode->h = -1; + pDbFd->pInode->pShmNode = pShmNode; + pShmNode->pInode = pDbFd->pInode; + pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pShmNode->mutex==0 ){ + rc = SQLITE_NOMEM; + goto shm_open_err; + } + + if( pInode->bProcessLock==0 ){ + int openFlags = O_RDWR | O_CREAT; + if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ + openFlags = O_RDONLY; + pShmNode->isReadonly = 1; + } + pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777)); + if( pShmNode->h<0 ){ + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); + goto shm_open_err; + } + + /* If this process is running as root, make sure that the SHM file + ** is owned by the same user that owns the original database. Otherwise, + ** the original owner will not be able to connect. + */ + osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid); + + /* Check to see if another process is holding the dead-man switch. + ** If not, truncate the file to zero length. + */ + rc = SQLITE_OK; + if( unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ + if( robust_ftruncate(pShmNode->h, 0) ){ + rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); + } + } + if( rc==SQLITE_OK ){ + rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1); + } + if( rc ) goto shm_open_err; + } + } + + /* Make the new connection a child of the unixShmNode */ + p->pShmNode = pShmNode; +#ifdef SQLITE_DEBUG + p->id = pShmNode->nextShmId++; +#endif + pShmNode->nRef++; + pDbFd->pShm = p; + unixLeaveMutex(); + + /* The reference count on pShmNode has already been incremented under + ** the cover of the unixEnterMutex() mutex and the pointer from the + ** new (struct unixShm) object to the pShmNode has been set. All that is + ** left to do is to link the new object into the linked list starting + ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex + ** mutex. + */ + sqlite3_mutex_enter(pShmNode->mutex); + p->pNext = pShmNode->pFirst; + pShmNode->pFirst = p; + sqlite3_mutex_leave(pShmNode->mutex); + return SQLITE_OK; + + /* Jump here on any error */ +shm_open_err: + unixShmPurge(pDbFd); /* This call frees pShmNode if required */ + sqlite3_free(p); + unixLeaveMutex(); + return rc; +} + +/* +** This function is called to obtain a pointer to region iRegion of the +** shared-memory associated with the database file fd. Shared-memory regions +** are numbered starting from zero. Each shared-memory region is szRegion +** bytes in size. +** +** If an error occurs, an error code is returned and *pp is set to NULL. +** +** Otherwise, if the bExtend parameter is 0 and the requested shared-memory +** region has not been allocated (by any client, including one running in a +** separate process), then *pp is set to NULL and SQLITE_OK returned. If +** bExtend is non-zero and the requested shared-memory region has not yet +** been allocated, it is allocated by this function. +** +** If the shared-memory region has already been allocated or is allocated by +** this call as described above, then it is mapped into this processes +** address space (if it is not already), *pp is set to point to the mapped +** memory and SQLITE_OK returned. +*/ +static int unixShmMap( + sqlite3_file *fd, /* Handle open on database file */ + int iRegion, /* Region to retrieve */ + int szRegion, /* Size of regions */ + int bExtend, /* True to extend file if necessary */ + void volatile **pp /* OUT: Mapped memory */ +){ + unixFile *pDbFd = (unixFile*)fd; + unixShm *p; + unixShmNode *pShmNode; + int rc = SQLITE_OK; + int nShmPerMap = unixShmRegionPerMap(); + int nReqRegion; + + /* If the shared-memory file has not yet been opened, open it now. */ + if( pDbFd->pShm==0 ){ + rc = unixOpenSharedMemory(pDbFd); + if( rc!=SQLITE_OK ) return rc; + } + + p = pDbFd->pShm; + pShmNode = p->pShmNode; + sqlite3_mutex_enter(pShmNode->mutex); + assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); + assert( pShmNode->pInode==pDbFd->pInode ); + assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); + assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); + + /* Minimum number of regions required to be mapped. */ + nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap; + + if( pShmNode->nRegionszRegion = szRegion; + + if( pShmNode->h>=0 ){ + /* The requested region is not mapped into this processes address space. + ** Check to see if it has been allocated (i.e. if the wal-index file is + ** large enough to contain the requested region). + */ + if( osFstat(pShmNode->h, &sStat) ){ + rc = SQLITE_IOERR_SHMSIZE; + goto shmpage_out; + } + + if( sStat.st_sizeh, iPg*pgsz + pgsz-1, "", 1, 0)!=1 ){ + const char *zFile = pShmNode->zFilename; + rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile); + goto shmpage_out; + } + } + } + } + } + + /* Map the requested memory region into this processes address space. */ + apNew = (char **)sqlite3_realloc( + pShmNode->apRegion, nReqRegion*sizeof(char *) + ); + if( !apNew ){ + rc = SQLITE_IOERR_NOMEM; + goto shmpage_out; + } + pShmNode->apRegion = apNew; + while( pShmNode->nRegionh>=0 ){ + pMem = osMmap(0, nMap, + pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, + MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion + ); + if( pMem==MAP_FAILED ){ + rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename); + goto shmpage_out; + } + }else{ + pMem = sqlite3_malloc64(szRegion); + if( pMem==0 ){ + rc = SQLITE_NOMEM; + goto shmpage_out; + } + memset(pMem, 0, szRegion); + } + + for(i=0; iapRegion[pShmNode->nRegion+i] = &((char*)pMem)[szRegion*i]; + } + pShmNode->nRegion += nShmPerMap; + } + } + +shmpage_out: + if( pShmNode->nRegion>iRegion ){ + *pp = pShmNode->apRegion[iRegion]; + }else{ + *pp = 0; + } + if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; + sqlite3_mutex_leave(pShmNode->mutex); + return rc; +} + +/* +** Change the lock state for a shared-memory segment. +** +** Note that the relationship between SHAREd and EXCLUSIVE locks is a little +** different here than in posix. In xShmLock(), one can go from unlocked +** to shared and back or from unlocked to exclusive and back. But one may +** not go from shared to exclusive or from exclusive to shared. +*/ +static int unixShmLock( + sqlite3_file *fd, /* Database file holding the shared memory */ + int ofst, /* First lock to acquire or release */ + int n, /* Number of locks to acquire or release */ + int flags /* What to do with the lock */ +){ + unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */ + unixShm *p = pDbFd->pShm; /* The shared memory being locked */ + unixShm *pX; /* For looping over all siblings */ + unixShmNode *pShmNode = p->pShmNode; /* The underlying file iNode */ + int rc = SQLITE_OK; /* Result code */ + u16 mask; /* Mask of locks to take or release */ + + assert( pShmNode==pDbFd->pInode->pShmNode ); + assert( pShmNode->pInode==pDbFd->pInode ); + assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); + assert( n>=1 ); + assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); + assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); + assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); + assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); + + mask = (1<<(ofst+n)) - (1<1 || mask==(1<mutex); + if( flags & SQLITE_SHM_UNLOCK ){ + u16 allMask = 0; /* Mask of locks held by siblings */ + + /* See if any siblings hold this same lock */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( pX==p ) continue; + assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); + allMask |= pX->sharedMask; + } + + /* Unlock the system-level locks */ + if( (mask & allMask)==0 ){ + rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n); + }else{ + rc = SQLITE_OK; + } + + /* Undo the local locks */ + if( rc==SQLITE_OK ){ + p->exclMask &= ~mask; + p->sharedMask &= ~mask; + } + }else if( flags & SQLITE_SHM_SHARED ){ + u16 allShared = 0; /* Union of locks held by connections other than "p" */ + + /* Find out which shared locks are already held by sibling connections. + ** If any sibling already holds an exclusive lock, go ahead and return + ** SQLITE_BUSY. + */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( (pX->exclMask & mask)!=0 ){ + rc = SQLITE_BUSY; + break; + } + allShared |= pX->sharedMask; + } + + /* Get shared locks at the system level, if necessary */ + if( rc==SQLITE_OK ){ + if( (allShared & mask)==0 ){ + rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n); + }else{ + rc = SQLITE_OK; + } + } + + /* Get the local shared locks */ + if( rc==SQLITE_OK ){ + p->sharedMask |= mask; + } + }else{ + /* Make sure no sibling connections hold locks that will block this + ** lock. If any do, return SQLITE_BUSY right away. + */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){ + rc = SQLITE_BUSY; + break; + } + } + + /* Get the exclusive locks at the system level. Then if successful + ** also mark the local connection as being locked. + */ + if( rc==SQLITE_OK ){ + rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n); + if( rc==SQLITE_OK ){ + assert( (p->sharedMask & mask)==0 ); + p->exclMask |= mask; + } + } + } + sqlite3_mutex_leave(pShmNode->mutex); + OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n", + p->id, osGetpid(0), p->sharedMask, p->exclMask)); + return rc; +} + +/* +** Implement a memory barrier or memory fence on shared memory. +** +** All loads and stores begun before the barrier must complete before +** any load or store begun after the barrier. +*/ +static void unixShmBarrier( + sqlite3_file *fd /* Database file holding the shared memory */ +){ + UNUSED_PARAMETER(fd); + unixEnterMutex(); + unixLeaveMutex(); +} + +/* +** Close a connection to shared-memory. Delete the underlying +** storage if deleteFlag is true. +** +** If there is no shared memory associated with the connection then this +** routine is a harmless no-op. +*/ +static int unixShmUnmap( + sqlite3_file *fd, /* The underlying database file */ + int deleteFlag /* Delete shared-memory if true */ +){ + unixShm *p; /* The connection to be closed */ + unixShmNode *pShmNode; /* The underlying shared-memory file */ + unixShm **pp; /* For looping over sibling connections */ + unixFile *pDbFd; /* The underlying database file */ + + pDbFd = (unixFile*)fd; + p = pDbFd->pShm; + if( p==0 ) return SQLITE_OK; + pShmNode = p->pShmNode; + + assert( pShmNode==pDbFd->pInode->pShmNode ); + assert( pShmNode->pInode==pDbFd->pInode ); + + /* Remove connection p from the set of connections associated + ** with pShmNode */ + sqlite3_mutex_enter(pShmNode->mutex); + for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} + *pp = p->pNext; + + /* Free the connection p */ + sqlite3_free(p); + pDbFd->pShm = 0; + sqlite3_mutex_leave(pShmNode->mutex); + + /* If pShmNode->nRef has reached 0, then close the underlying + ** shared-memory file, too */ + unixEnterMutex(); + assert( pShmNode->nRef>0 ); + pShmNode->nRef--; + if( pShmNode->nRef==0 ){ + if( deleteFlag && pShmNode->h>=0 ){ + osUnlink(pShmNode->zFilename); + } + unixShmPurge(pDbFd); + } + unixLeaveMutex(); + + return SQLITE_OK; +} + + +#else +# define unixShmMap 0 +# define unixShmLock 0 +# define unixShmBarrier 0 +# define unixShmUnmap 0 +#endif /* #ifndef SQLITE_OMIT_WAL */ + +#if SQLITE_MAX_MMAP_SIZE>0 +/* +** If it is currently memory mapped, unmap file pFd. +*/ +static void unixUnmapfile(unixFile *pFd){ + assert( pFd->nFetchOut==0 ); + if( pFd->pMapRegion ){ + osMunmap(pFd->pMapRegion, pFd->mmapSizeActual); + pFd->pMapRegion = 0; + pFd->mmapSize = 0; + pFd->mmapSizeActual = 0; + } +} + +/* +** Attempt to set the size of the memory mapping maintained by file +** descriptor pFd to nNew bytes. Any existing mapping is discarded. +** +** If successful, this function sets the following variables: +** +** unixFile.pMapRegion +** unixFile.mmapSize +** unixFile.mmapSizeActual +** +** If unsuccessful, an error message is logged via sqlite3_log() and +** the three variables above are zeroed. In this case SQLite should +** continue accessing the database using the xRead() and xWrite() +** methods. +*/ +static void unixRemapfile( + unixFile *pFd, /* File descriptor object */ + i64 nNew /* Required mapping size */ +){ + const char *zErr = "mmap"; + int h = pFd->h; /* File descriptor open on db file */ + u8 *pOrig = (u8 *)pFd->pMapRegion; /* Pointer to current file mapping */ + i64 nOrig = pFd->mmapSizeActual; /* Size of pOrig region in bytes */ + u8 *pNew = 0; /* Location of new mapping */ + int flags = PROT_READ; /* Flags to pass to mmap() */ + + assert( pFd->nFetchOut==0 ); + assert( nNew>pFd->mmapSize ); + assert( nNew<=pFd->mmapSizeMax ); + assert( nNew>0 ); + assert( pFd->mmapSizeActual>=pFd->mmapSize ); + assert( MAP_FAILED!=0 ); + + if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE; + + if( pOrig ){ +#if HAVE_MREMAP + i64 nReuse = pFd->mmapSize; +#else + const int szSyspage = osGetpagesize(); + i64 nReuse = (pFd->mmapSize & ~(szSyspage-1)); +#endif + u8 *pReq = &pOrig[nReuse]; + + /* Unmap any pages of the existing mapping that cannot be reused. */ + if( nReuse!=nOrig ){ + osMunmap(pReq, nOrig-nReuse); + } + +#if HAVE_MREMAP + pNew = osMremap(pOrig, nReuse, nNew, MREMAP_MAYMOVE); + zErr = "mremap"; +#else + pNew = osMmap(pReq, nNew-nReuse, flags, MAP_SHARED, h, nReuse); + if( pNew!=MAP_FAILED ){ + if( pNew!=pReq ){ + osMunmap(pNew, nNew - nReuse); + pNew = 0; + }else{ + pNew = pOrig; + } + } +#endif + + /* The attempt to extend the existing mapping failed. Free it. */ + if( pNew==MAP_FAILED || pNew==0 ){ + osMunmap(pOrig, nReuse); + } + } + + /* If pNew is still NULL, try to create an entirely new mapping. */ + if( pNew==0 ){ + pNew = osMmap(0, nNew, flags, MAP_SHARED, h, 0); + } + + if( pNew==MAP_FAILED ){ + pNew = 0; + nNew = 0; + unixLogError(SQLITE_OK, zErr, pFd->zPath); + + /* If the mmap() above failed, assume that all subsequent mmap() calls + ** will probably fail too. Fall back to using xRead/xWrite exclusively + ** in this case. */ + pFd->mmapSizeMax = 0; + } + pFd->pMapRegion = (void *)pNew; + pFd->mmapSize = pFd->mmapSizeActual = nNew; +} + +/* +** Memory map or remap the file opened by file-descriptor pFd (if the file +** is already mapped, the existing mapping is replaced by the new). Or, if +** there already exists a mapping for this file, and there are still +** outstanding xFetch() references to it, this function is a no-op. +** +** If parameter nByte is non-negative, then it is the requested size of +** the mapping to create. Otherwise, if nByte is less than zero, then the +** requested size is the size of the file on disk. The actual size of the +** created mapping is either the requested size or the value configured +** using SQLITE_FCNTL_MMAP_LIMIT, whichever is smaller. +** +** SQLITE_OK is returned if no error occurs (even if the mapping is not +** recreated as a result of outstanding references) or an SQLite error +** code otherwise. +*/ +static int unixMapfile(unixFile *pFd, i64 nByte){ + i64 nMap = nByte; + int rc; + + assert( nMap>=0 || pFd->nFetchOut==0 ); + if( pFd->nFetchOut>0 ) return SQLITE_OK; + + if( nMap<0 ){ + struct stat statbuf; /* Low-level file information */ + rc = osFstat(pFd->h, &statbuf); + if( rc!=SQLITE_OK ){ + return SQLITE_IOERR_FSTAT; + } + nMap = statbuf.st_size; + } + if( nMap>pFd->mmapSizeMax ){ + nMap = pFd->mmapSizeMax; + } + + if( nMap!=pFd->mmapSize ){ + if( nMap>0 ){ + unixRemapfile(pFd, nMap); + }else{ + unixUnmapfile(pFd); + } + } + + return SQLITE_OK; +} +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ + +/* +** If possible, return a pointer to a mapping of file fd starting at offset +** iOff. The mapping must be valid for at least nAmt bytes. +** +** If such a pointer can be obtained, store it in *pp and return SQLITE_OK. +** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK. +** Finally, if an error does occur, return an SQLite error code. The final +** value of *pp is undefined in this case. +** +** If this function does return a pointer, the caller must eventually +** release the reference by calling unixUnfetch(). +*/ +static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ +#if SQLITE_MAX_MMAP_SIZE>0 + unixFile *pFd = (unixFile *)fd; /* The underlying database file */ +#endif + *pp = 0; + +#if SQLITE_MAX_MMAP_SIZE>0 + if( pFd->mmapSizeMax>0 ){ + if( pFd->pMapRegion==0 ){ + int rc = unixMapfile(pFd, -1); + if( rc!=SQLITE_OK ) return rc; + } + if( pFd->mmapSize >= iOff+nAmt ){ + *pp = &((u8 *)pFd->pMapRegion)[iOff]; + pFd->nFetchOut++; + } + } +#endif + return SQLITE_OK; +} + +/* +** If the third argument is non-NULL, then this function releases a +** reference obtained by an earlier call to unixFetch(). The second +** argument passed to this function must be the same as the corresponding +** argument that was passed to the unixFetch() invocation. +** +** Or, if the third argument is NULL, then this function is being called +** to inform the VFS layer that, according to POSIX, any existing mapping +** may now be invalid and should be unmapped. +*/ +static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){ +#if SQLITE_MAX_MMAP_SIZE>0 + unixFile *pFd = (unixFile *)fd; /* The underlying database file */ + UNUSED_PARAMETER(iOff); + + /* If p==0 (unmap the entire file) then there must be no outstanding + ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), + ** then there must be at least one outstanding. */ + assert( (p==0)==(pFd->nFetchOut==0) ); + + /* If p!=0, it must match the iOff value. */ + assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] ); + + if( p ){ + pFd->nFetchOut--; + }else{ + unixUnmapfile(pFd); + } + + assert( pFd->nFetchOut>=0 ); +#else + UNUSED_PARAMETER(fd); + UNUSED_PARAMETER(p); + UNUSED_PARAMETER(iOff); +#endif + return SQLITE_OK; +} + +/* +** Here ends the implementation of all sqlite3_file methods. +** +********************** End sqlite3_file Methods ******************************* +******************************************************************************/ + +/* +** This division contains definitions of sqlite3_io_methods objects that +** implement various file locking strategies. It also contains definitions +** of "finder" functions. A finder-function is used to locate the appropriate +** sqlite3_io_methods object for a particular database file. The pAppData +** field of the sqlite3_vfs VFS objects are initialized to be pointers to +** the correct finder-function for that VFS. +** +** Most finder functions return a pointer to a fixed sqlite3_io_methods +** object. The only interesting finder-function is autolockIoFinder, which +** looks at the filesystem type and tries to guess the best locking +** strategy from that. +** +** For finder-function F, two objects are created: +** +** (1) The real finder-function named "FImpt()". +** +** (2) A constant pointer to this function named just "F". +** +** +** A pointer to the F pointer is used as the pAppData value for VFS +** objects. We have to do this instead of letting pAppData point +** directly at the finder-function since C90 rules prevent a void* +** from be cast into a function pointer. +** +** +** Each instance of this macro generates two objects: +** +** * A constant sqlite3_io_methods object call METHOD that has locking +** methods CLOSE, LOCK, UNLOCK, CKRESLOCK. +** +** * An I/O method finder function called FINDER that returns a pointer +** to the METHOD object in the previous bullet. +*/ +#define IOMETHODS(FINDER,METHOD,VERSION,CLOSE,LOCK,UNLOCK,CKLOCK,SHMMAP) \ +static const sqlite3_io_methods METHOD = { \ + VERSION, /* iVersion */ \ + CLOSE, /* xClose */ \ + unixRead, /* xRead */ \ + unixWrite, /* xWrite */ \ + unixTruncate, /* xTruncate */ \ + unixSync, /* xSync */ \ + unixFileSize, /* xFileSize */ \ + LOCK, /* xLock */ \ + UNLOCK, /* xUnlock */ \ + CKLOCK, /* xCheckReservedLock */ \ + unixFileControl, /* xFileControl */ \ + unixSectorSize, /* xSectorSize */ \ + unixDeviceCharacteristics, /* xDeviceCapabilities */ \ + SHMMAP, /* xShmMap */ \ + unixShmLock, /* xShmLock */ \ + unixShmBarrier, /* xShmBarrier */ \ + unixShmUnmap, /* xShmUnmap */ \ + unixFetch, /* xFetch */ \ + unixUnfetch, /* xUnfetch */ \ +}; \ +static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){ \ + UNUSED_PARAMETER(z); UNUSED_PARAMETER(p); \ + return &METHOD; \ +} \ +static const sqlite3_io_methods *(*const FINDER)(const char*,unixFile *p) \ + = FINDER##Impl; + +/* +** Here are all of the sqlite3_io_methods objects for each of the +** locking strategies. Functions that return pointers to these methods +** are also created. +*/ +IOMETHODS( + posixIoFinder, /* Finder function name */ + posixIoMethods, /* sqlite3_io_methods object name */ + 3, /* shared memory and mmap are enabled */ + unixClose, /* xClose method */ + unixLock, /* xLock method */ + unixUnlock, /* xUnlock method */ + unixCheckReservedLock, /* xCheckReservedLock method */ + unixShmMap /* xShmMap method */ +) +IOMETHODS( + nolockIoFinder, /* Finder function name */ + nolockIoMethods, /* sqlite3_io_methods object name */ + 3, /* shared memory is disabled */ + nolockClose, /* xClose method */ + nolockLock, /* xLock method */ + nolockUnlock, /* xUnlock method */ + nolockCheckReservedLock, /* xCheckReservedLock method */ + 0 /* xShmMap method */ +) +IOMETHODS( + dotlockIoFinder, /* Finder function name */ + dotlockIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + dotlockClose, /* xClose method */ + dotlockLock, /* xLock method */ + dotlockUnlock, /* xUnlock method */ + dotlockCheckReservedLock, /* xCheckReservedLock method */ + 0 /* xShmMap method */ +) + +#if SQLITE_ENABLE_LOCKING_STYLE +IOMETHODS( + flockIoFinder, /* Finder function name */ + flockIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + flockClose, /* xClose method */ + flockLock, /* xLock method */ + flockUnlock, /* xUnlock method */ + flockCheckReservedLock, /* xCheckReservedLock method */ + 0 /* xShmMap method */ +) +#endif + +#if OS_VXWORKS +IOMETHODS( + semIoFinder, /* Finder function name */ + semIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + semXClose, /* xClose method */ + semXLock, /* xLock method */ + semXUnlock, /* xUnlock method */ + semXCheckReservedLock, /* xCheckReservedLock method */ + 0 /* xShmMap method */ +) +#endif + +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +IOMETHODS( + afpIoFinder, /* Finder function name */ + afpIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + afpClose, /* xClose method */ + afpLock, /* xLock method */ + afpUnlock, /* xUnlock method */ + afpCheckReservedLock, /* xCheckReservedLock method */ + 0 /* xShmMap method */ +) +#endif + +/* +** The proxy locking method is a "super-method" in the sense that it +** opens secondary file descriptors for the conch and lock files and +** it uses proxy, dot-file, AFP, and flock() locking methods on those +** secondary files. For this reason, the division that implements +** proxy locking is located much further down in the file. But we need +** to go ahead and define the sqlite3_io_methods and finder function +** for proxy locking here. So we forward declare the I/O methods. +*/ +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +static int proxyClose(sqlite3_file*); +static int proxyLock(sqlite3_file*, int); +static int proxyUnlock(sqlite3_file*, int); +static int proxyCheckReservedLock(sqlite3_file*, int*); +IOMETHODS( + proxyIoFinder, /* Finder function name */ + proxyIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + proxyClose, /* xClose method */ + proxyLock, /* xLock method */ + proxyUnlock, /* xUnlock method */ + proxyCheckReservedLock, /* xCheckReservedLock method */ + 0 /* xShmMap method */ +) +#endif + +/* nfs lockd on OSX 10.3+ doesn't clear write locks when a read lock is set */ +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +IOMETHODS( + nfsIoFinder, /* Finder function name */ + nfsIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + unixClose, /* xClose method */ + unixLock, /* xLock method */ + nfsUnlock, /* xUnlock method */ + unixCheckReservedLock, /* xCheckReservedLock method */ + 0 /* xShmMap method */ +) +#endif + +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +/* +** This "finder" function attempts to determine the best locking strategy +** for the database file "filePath". It then returns the sqlite3_io_methods +** object that implements that strategy. +** +** This is for MacOSX only. +*/ +static const sqlite3_io_methods *autolockIoFinderImpl( + const char *filePath, /* name of the database file */ + unixFile *pNew /* open file object for the database file */ +){ + static const struct Mapping { + const char *zFilesystem; /* Filesystem type name */ + const sqlite3_io_methods *pMethods; /* Appropriate locking method */ + } aMap[] = { + { "hfs", &posixIoMethods }, + { "ufs", &posixIoMethods }, + { "afpfs", &afpIoMethods }, + { "smbfs", &afpIoMethods }, + { "webdav", &nolockIoMethods }, + { 0, 0 } + }; + int i; + struct statfs fsInfo; + struct flock lockInfo; + + if( !filePath ){ + /* If filePath==NULL that means we are dealing with a transient file + ** that does not need to be locked. */ + return &nolockIoMethods; + } + if( statfs(filePath, &fsInfo) != -1 ){ + if( fsInfo.f_flags & MNT_RDONLY ){ + return &nolockIoMethods; + } + for(i=0; aMap[i].zFilesystem; i++){ + if( strcmp(fsInfo.f_fstypename, aMap[i].zFilesystem)==0 ){ + return aMap[i].pMethods; + } + } + } + + /* Default case. Handles, amongst others, "nfs". + ** Test byte-range lock using fcntl(). If the call succeeds, + ** assume that the file-system supports POSIX style locks. + */ + lockInfo.l_len = 1; + lockInfo.l_start = 0; + lockInfo.l_whence = SEEK_SET; + lockInfo.l_type = F_RDLCK; + if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { + if( strcmp(fsInfo.f_fstypename, "nfs")==0 ){ + return &nfsIoMethods; + } else { + return &posixIoMethods; + } + }else{ + return &dotlockIoMethods; + } +} +static const sqlite3_io_methods + *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl; + +#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ + +#if OS_VXWORKS +/* +** This "finder" function for VxWorks checks to see if posix advisory +** locking works. If it does, then that is what is used. If it does not +** work, then fallback to named semaphore locking. +*/ +static const sqlite3_io_methods *vxworksIoFinderImpl( + const char *filePath, /* name of the database file */ + unixFile *pNew /* the open file object */ +){ + struct flock lockInfo; + + if( !filePath ){ + /* If filePath==NULL that means we are dealing with a transient file + ** that does not need to be locked. */ + return &nolockIoMethods; + } + + /* Test if fcntl() is supported and use POSIX style locks. + ** Otherwise fall back to the named semaphore method. + */ + lockInfo.l_len = 1; + lockInfo.l_start = 0; + lockInfo.l_whence = SEEK_SET; + lockInfo.l_type = F_RDLCK; + if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { + return &posixIoMethods; + }else{ + return &semIoMethods; + } +} +static const sqlite3_io_methods + *(*const vxworksIoFinder)(const char*,unixFile*) = vxworksIoFinderImpl; + +#endif /* OS_VXWORKS */ + +/* +** An abstract type for a pointer to an IO method finder function: +*/ +typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*); + + +/**************************************************************************** +**************************** sqlite3_vfs methods **************************** +** +** This division contains the implementation of methods on the +** sqlite3_vfs object. +*/ + +/* +** Initialize the contents of the unixFile structure pointed to by pId. +*/ +static int fillInUnixFile( + sqlite3_vfs *pVfs, /* Pointer to vfs object */ + int h, /* Open file descriptor of file being opened */ + sqlite3_file *pId, /* Write to the unixFile structure here */ + const char *zFilename, /* Name of the file being opened */ + int ctrlFlags /* Zero or more UNIXFILE_* values */ +){ + const sqlite3_io_methods *pLockingStyle; + unixFile *pNew = (unixFile *)pId; + int rc = SQLITE_OK; + + assert( pNew->pInode==NULL ); + + /* Usually the path zFilename should not be a relative pathname. The + ** exception is when opening the proxy "conch" file in builds that + ** include the special Apple locking styles. + */ +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE + assert( zFilename==0 || zFilename[0]=='/' + || pVfs->pAppData==(void*)&autolockIoFinder ); +#else + assert( zFilename==0 || zFilename[0]=='/' ); +#endif + + /* No locking occurs in temporary files */ + assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 ); + + OSTRACE(("OPEN %-3d %s\n", h, zFilename)); + pNew->h = h; + pNew->pVfs = pVfs; + pNew->zPath = zFilename; + pNew->ctrlFlags = (u8)ctrlFlags; +#if SQLITE_MAX_MMAP_SIZE>0 + pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap; +#endif + if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0), + "psow", SQLITE_POWERSAFE_OVERWRITE) ){ + pNew->ctrlFlags |= UNIXFILE_PSOW; + } + if( strcmp(pVfs->zName,"unix-excl")==0 ){ + pNew->ctrlFlags |= UNIXFILE_EXCL; + } + +#if OS_VXWORKS + pNew->pId = vxworksFindFileId(zFilename); + if( pNew->pId==0 ){ + ctrlFlags |= UNIXFILE_NOLOCK; + rc = SQLITE_NOMEM; + } +#endif + + if( ctrlFlags & UNIXFILE_NOLOCK ){ + pLockingStyle = &nolockIoMethods; + }else{ + pLockingStyle = (**(finder_type*)pVfs->pAppData)(zFilename, pNew); +#if SQLITE_ENABLE_LOCKING_STYLE + /* Cache zFilename in the locking context (AFP and dotlock override) for + ** proxyLock activation is possible (remote proxy is based on db name) + ** zFilename remains valid until file is closed, to support */ + pNew->lockingContext = (void*)zFilename; +#endif + } + + if( pLockingStyle == &posixIoMethods +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE + || pLockingStyle == &nfsIoMethods +#endif + ){ + unixEnterMutex(); + rc = findInodeInfo(pNew, &pNew->pInode); + if( rc!=SQLITE_OK ){ + /* If an error occurred in findInodeInfo(), close the file descriptor + ** immediately, before releasing the mutex. findInodeInfo() may fail + ** in two scenarios: + ** + ** (a) A call to fstat() failed. + ** (b) A malloc failed. + ** + ** Scenario (b) may only occur if the process is holding no other + ** file descriptors open on the same file. If there were other file + ** descriptors on this file, then no malloc would be required by + ** findInodeInfo(). If this is the case, it is quite safe to close + ** handle h - as it is guaranteed that no posix locks will be released + ** by doing so. + ** + ** If scenario (a) caused the error then things are not so safe. The + ** implicit assumption here is that if fstat() fails, things are in + ** such bad shape that dropping a lock or two doesn't matter much. + */ + robust_close(pNew, h, __LINE__); + h = -1; + } + unixLeaveMutex(); + } + +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) + else if( pLockingStyle == &afpIoMethods ){ + /* AFP locking uses the file path so it needs to be included in + ** the afpLockingContext. + */ + afpLockingContext *pCtx; + pNew->lockingContext = pCtx = sqlite3_malloc64( sizeof(*pCtx) ); + if( pCtx==0 ){ + rc = SQLITE_NOMEM; + }else{ + /* NB: zFilename exists and remains valid until the file is closed + ** according to requirement F11141. So we do not need to make a + ** copy of the filename. */ + pCtx->dbPath = zFilename; + pCtx->reserved = 0; + srandomdev(); + unixEnterMutex(); + rc = findInodeInfo(pNew, &pNew->pInode); + if( rc!=SQLITE_OK ){ + sqlite3_free(pNew->lockingContext); + robust_close(pNew, h, __LINE__); + h = -1; + } + unixLeaveMutex(); + } + } +#endif + + else if( pLockingStyle == &dotlockIoMethods ){ + /* Dotfile locking uses the file path so it needs to be included in + ** the dotlockLockingContext + */ + char *zLockFile; + int nFilename; + assert( zFilename!=0 ); + nFilename = (int)strlen(zFilename) + 6; + zLockFile = (char *)sqlite3_malloc64(nFilename); + if( zLockFile==0 ){ + rc = SQLITE_NOMEM; + }else{ + sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename); + } + pNew->lockingContext = zLockFile; + } + +#if OS_VXWORKS + else if( pLockingStyle == &semIoMethods ){ + /* Named semaphore locking uses the file path so it needs to be + ** included in the semLockingContext + */ + unixEnterMutex(); + rc = findInodeInfo(pNew, &pNew->pInode); + if( (rc==SQLITE_OK) && (pNew->pInode->pSem==NULL) ){ + char *zSemName = pNew->pInode->aSemName; + int n; + sqlite3_snprintf(MAX_PATHNAME, zSemName, "/%s.sem", + pNew->pId->zCanonicalName); + for( n=1; zSemName[n]; n++ ) + if( zSemName[n]=='/' ) zSemName[n] = '_'; + pNew->pInode->pSem = sem_open(zSemName, O_CREAT, 0666, 1); + if( pNew->pInode->pSem == SEM_FAILED ){ + rc = SQLITE_NOMEM; + pNew->pInode->aSemName[0] = '\0'; + } + } + unixLeaveMutex(); + } +#endif + + storeLastErrno(pNew, 0); +#if OS_VXWORKS + if( rc!=SQLITE_OK ){ + if( h>=0 ) robust_close(pNew, h, __LINE__); + h = -1; + osUnlink(zFilename); + pNew->ctrlFlags |= UNIXFILE_DELETE; + } +#endif + if( rc!=SQLITE_OK ){ + if( h>=0 ) robust_close(pNew, h, __LINE__); + }else{ + pNew->pMethod = pLockingStyle; + OpenCounter(+1); + verifyDbFile(pNew); + } + return rc; +} + +/* +** Return the name of a directory in which to put temporary files. +** If no suitable temporary file directory can be found, return NULL. +*/ +static const char *unixTempFileDir(void){ + static const char *azDirs[] = { + 0, + 0, + 0, + "/var/tmp", + "/usr/tmp", + "/tmp", + 0 /* List terminator */ + }; + unsigned int i; + struct stat buf; + const char *zDir = 0; + + azDirs[0] = sqlite3_temp_directory; + if( !azDirs[1] ) azDirs[1] = getenv("SQLITE_TMPDIR"); + if( !azDirs[2] ) azDirs[2] = getenv("TMPDIR"); + for(i=0; imxPathname bytes. +*/ +static int unixGetTempname(int nBuf, char *zBuf){ + static const unsigned char zChars[] = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789"; + unsigned int i, j; + const char *zDir; + + /* It's odd to simulate an io-error here, but really this is just + ** using the io-error infrastructure to test that SQLite handles this + ** function failing. + */ + SimulateIOError( return SQLITE_IOERR ); + + zDir = unixTempFileDir(); + if( zDir==0 ) zDir = "."; + + /* Check that the output buffer is large enough for the temporary file + ** name. If it is not, return SQLITE_ERROR. + */ + if( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 18) >= (size_t)nBuf ){ + return SQLITE_ERROR; + } + + do{ + sqlite3_snprintf(nBuf-18, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir); + j = (int)strlen(zBuf); + sqlite3_randomness(15, &zBuf[j]); + for(i=0; i<15; i++, j++){ + zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; + } + zBuf[j] = 0; + zBuf[j+1] = 0; + }while( osAccess(zBuf,0)==0 ); + return SQLITE_OK; +} + +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) +/* +** Routine to transform a unixFile into a proxy-locking unixFile. +** Implementation in the proxy-lock division, but used by unixOpen() +** if SQLITE_PREFER_PROXY_LOCKING is defined. +*/ +static int proxyTransformUnixFile(unixFile*, const char*); +#endif + +/* +** Search for an unused file descriptor that was opened on the database +** file (not a journal or master-journal file) identified by pathname +** zPath with SQLITE_OPEN_XXX flags matching those passed as the second +** argument to this function. +** +** Such a file descriptor may exist if a database connection was closed +** but the associated file descriptor could not be closed because some +** other file descriptor open on the same file is holding a file-lock. +** Refer to comments in the unixClose() function and the lengthy comment +** describing "Posix Advisory Locking" at the start of this file for +** further details. Also, ticket #4018. +** +** If a suitable file descriptor is found, then it is returned. If no +** such file descriptor is located, -1 is returned. +*/ +static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ + UnixUnusedFd *pUnused = 0; + + /* Do not search for an unused file descriptor on vxworks. Not because + ** vxworks would not benefit from the change (it might, we're not sure), + ** but because no way to test it is currently available. It is better + ** not to risk breaking vxworks support for the sake of such an obscure + ** feature. */ +#if !OS_VXWORKS + struct stat sStat; /* Results of stat() call */ + + /* A stat() call may fail for various reasons. If this happens, it is + ** almost certain that an open() call on the same path will also fail. + ** For this reason, if an error occurs in the stat() call here, it is + ** ignored and -1 is returned. The caller will try to open a new file + ** descriptor on the same path, fail, and return an error to SQLite. + ** + ** Even if a subsequent open() call does succeed, the consequences of + ** not searching for a reusable file descriptor are not dire. */ + if( 0==osStat(zPath, &sStat) ){ + unixInodeInfo *pInode; + + unixEnterMutex(); + pInode = inodeList; + while( pInode && (pInode->fileId.dev!=sStat.st_dev + || pInode->fileId.ino!=sStat.st_ino) ){ + pInode = pInode->pNext; + } + if( pInode ){ + UnixUnusedFd **pp; + for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext)); + pUnused = *pp; + if( pUnused ){ + *pp = pUnused->pNext; + } + } + unixLeaveMutex(); + } +#endif /* if !OS_VXWORKS */ + return pUnused; +} + +/* +** This function is called by unixOpen() to determine the unix permissions +** to create new files with. If no error occurs, then SQLITE_OK is returned +** and a value suitable for passing as the third argument to open(2) is +** written to *pMode. If an IO error occurs, an SQLite error code is +** returned and the value of *pMode is not modified. +** +** In most cases, this routine sets *pMode to 0, which will become +** an indication to robust_open() to create the file using +** SQLITE_DEFAULT_FILE_PERMISSIONS adjusted by the umask. +** But if the file being opened is a WAL or regular journal file, then +** this function queries the file-system for the permissions on the +** corresponding database file and sets *pMode to this value. Whenever +** possible, WAL and journal files are created using the same permissions +** as the associated database file. +** +** If the SQLITE_ENABLE_8_3_NAMES option is enabled, then the +** original filename is unavailable. But 8_3_NAMES is only used for +** FAT filesystems and permissions do not matter there, so just use +** the default permissions. +*/ +static int findCreateFileMode( + const char *zPath, /* Path of file (possibly) being created */ + int flags, /* Flags passed as 4th argument to xOpen() */ + mode_t *pMode, /* OUT: Permissions to open file with */ + uid_t *pUid, /* OUT: uid to set on the file */ + gid_t *pGid /* OUT: gid to set on the file */ +){ + int rc = SQLITE_OK; /* Return Code */ + *pMode = 0; + *pUid = 0; + *pGid = 0; + if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){ + char zDb[MAX_PATHNAME+1]; /* Database file path */ + int nDb; /* Number of valid bytes in zDb */ + struct stat sStat; /* Output of stat() on database file */ + + /* zPath is a path to a WAL or journal file. The following block derives + ** the path to the associated database file from zPath. This block handles + ** the following naming conventions: + ** + ** "-journal" + ** "-wal" + ** "-journalNN" + ** "-walNN" + ** + ** where NN is a decimal number. The NN naming schemes are + ** used by the test_multiplex.c module. + */ + nDb = sqlite3Strlen30(zPath) - 1; +#ifdef SQLITE_ENABLE_8_3_NAMES + while( nDb>0 && sqlite3Isalnum(zPath[nDb]) ) nDb--; + if( nDb==0 || zPath[nDb]!='-' ) return SQLITE_OK; +#else + while( zPath[nDb]!='-' ){ + assert( nDb>0 ); + assert( zPath[nDb]!='\n' ); + nDb--; + } +#endif + memcpy(zDb, zPath, nDb); + zDb[nDb] = '\0'; + + if( 0==osStat(zDb, &sStat) ){ + *pMode = sStat.st_mode & 0777; + *pUid = sStat.st_uid; + *pGid = sStat.st_gid; + }else{ + rc = SQLITE_IOERR_FSTAT; + } + }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){ + *pMode = 0600; + } + return rc; +} + +/* +** Open the file zPath. +** +** Previously, the SQLite OS layer used three functions in place of this +** one: +** +** sqlite3OsOpenReadWrite(); +** sqlite3OsOpenReadOnly(); +** sqlite3OsOpenExclusive(); +** +** These calls correspond to the following combinations of flags: +** +** ReadWrite() -> (READWRITE | CREATE) +** ReadOnly() -> (READONLY) +** OpenExclusive() -> (READWRITE | CREATE | EXCLUSIVE) +** +** The old OpenExclusive() accepted a boolean argument - "delFlag". If +** true, the file was configured to be automatically deleted when the +** file handle closed. To achieve the same effect using this new +** interface, add the DELETEONCLOSE flag to those specified above for +** OpenExclusive(). +*/ +static int unixOpen( + sqlite3_vfs *pVfs, /* The VFS for which this is the xOpen method */ + const char *zPath, /* Pathname of file to be opened */ + sqlite3_file *pFile, /* The file descriptor to be filled in */ + int flags, /* Input flags to control the opening */ + int *pOutFlags /* Output flags returned to SQLite core */ +){ + unixFile *p = (unixFile *)pFile; + int fd = -1; /* File descriptor returned by open() */ + int openFlags = 0; /* Flags to pass to open() */ + int eType = flags&0xFFFFFF00; /* Type of file to open */ + int noLock; /* True to omit locking primitives */ + int rc = SQLITE_OK; /* Function Return Code */ + int ctrlFlags = 0; /* UNIXFILE_* flags */ + + int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); + int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); + int isCreate = (flags & SQLITE_OPEN_CREATE); + int isReadonly = (flags & SQLITE_OPEN_READONLY); + int isReadWrite = (flags & SQLITE_OPEN_READWRITE); +#if SQLITE_ENABLE_LOCKING_STYLE + int isAutoProxy = (flags & SQLITE_OPEN_AUTOPROXY); +#endif +#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE + struct statfs fsInfo; +#endif + + /* If creating a master or main-file journal, this function will open + ** a file-descriptor on the directory too. The first time unixSync() + ** is called the directory file descriptor will be fsync()ed and close()d. + */ + int syncDir = (isCreate && ( + eType==SQLITE_OPEN_MASTER_JOURNAL + || eType==SQLITE_OPEN_MAIN_JOURNAL + || eType==SQLITE_OPEN_WAL + )); + + /* If argument zPath is a NULL pointer, this function is required to open + ** a temporary file. Use this buffer to store the file name in. + */ + char zTmpname[MAX_PATHNAME+2]; + const char *zName = zPath; + + /* Check the following statements are true: + ** + ** (a) Exactly one of the READWRITE and READONLY flags must be set, and + ** (b) if CREATE is set, then READWRITE must also be set, and + ** (c) if EXCLUSIVE is set, then CREATE must also be set. + ** (d) if DELETEONCLOSE is set, then CREATE must also be set. + */ + assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); + assert(isCreate==0 || isReadWrite); + assert(isExclusive==0 || isCreate); + assert(isDelete==0 || isCreate); + + /* The main DB, main journal, WAL file and master journal are never + ** automatically deleted. Nor are they ever temporary files. */ + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); + + /* Assert that the upper layer has set one of the "file-type" flags. */ + assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB + || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL + || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL + || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL + ); + + /* Detect a pid change and reset the PRNG. There is a race condition + ** here such that two or more threads all trying to open databases at + ** the same instant might all reset the PRNG. But multiple resets + ** are harmless. + */ + if( randomnessPid!=osGetpid(0) ){ + randomnessPid = osGetpid(0); + sqlite3_randomness(0,0); + } + + memset(p, 0, sizeof(unixFile)); + + if( eType==SQLITE_OPEN_MAIN_DB ){ + UnixUnusedFd *pUnused; + pUnused = findReusableFd(zName, flags); + if( pUnused ){ + fd = pUnused->fd; + }else{ + pUnused = sqlite3_malloc64(sizeof(*pUnused)); + if( !pUnused ){ + return SQLITE_NOMEM; + } + } + p->pUnused = pUnused; + + /* Database filenames are double-zero terminated if they are not + ** URIs with parameters. Hence, they can always be passed into + ** sqlite3_uri_parameter(). */ + assert( (flags & SQLITE_OPEN_URI) || zName[strlen(zName)+1]==0 ); + + }else if( !zName ){ + /* If zName is NULL, the upper layer is requesting a temp file. */ + assert(isDelete && !syncDir); + rc = unixGetTempname(MAX_PATHNAME+2, zTmpname); + if( rc!=SQLITE_OK ){ + return rc; + } + zName = zTmpname; + + /* Generated temporary filenames are always double-zero terminated + ** for use by sqlite3_uri_parameter(). */ + assert( zName[strlen(zName)+1]==0 ); + } + + /* Determine the value of the flags parameter passed to POSIX function + ** open(). These must be calculated even if open() is not called, as + ** they may be stored as part of the file handle and used by the + ** 'conch file' locking functions later on. */ + if( isReadonly ) openFlags |= O_RDONLY; + if( isReadWrite ) openFlags |= O_RDWR; + if( isCreate ) openFlags |= O_CREAT; + if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW); + openFlags |= (O_LARGEFILE|O_BINARY); + + if( fd<0 ){ + mode_t openMode; /* Permissions to create file with */ + uid_t uid; /* Userid for the file */ + gid_t gid; /* Groupid for the file */ + rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid); + if( rc!=SQLITE_OK ){ + assert( !p->pUnused ); + assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL ); + return rc; + } + fd = robust_open(zName, openFlags, openMode); + OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags)); + if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){ + /* Failed to open the file for read/write access. Try read-only. */ + flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); + openFlags &= ~(O_RDWR|O_CREAT); + flags |= SQLITE_OPEN_READONLY; + openFlags |= O_RDONLY; + isReadonly = 1; + fd = robust_open(zName, openFlags, openMode); + } + if( fd<0 ){ + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName); + goto open_finished; + } + + /* If this process is running as root and if creating a new rollback + ** journal or WAL file, set the ownership of the journal or WAL to be + ** the same as the original database. + */ + if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){ + osFchown(fd, uid, gid); + } + } + assert( fd>=0 ); + if( pOutFlags ){ + *pOutFlags = flags; + } + + if( p->pUnused ){ + p->pUnused->fd = fd; + p->pUnused->flags = flags; + } + + if( isDelete ){ +#if OS_VXWORKS + zPath = zName; +#elif defined(SQLITE_UNLINK_AFTER_CLOSE) + zPath = sqlite3_mprintf("%s", zName); + if( zPath==0 ){ + robust_close(p, fd, __LINE__); + return SQLITE_NOMEM; + } +#else + osUnlink(zName); +#endif + } +#if SQLITE_ENABLE_LOCKING_STYLE + else{ + p->openFlags = openFlags; + } +#endif + + noLock = eType!=SQLITE_OPEN_MAIN_DB; + + +#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE + if( fstatfs(fd, &fsInfo) == -1 ){ + storeLastErrno(p, errno); + robust_close(p, fd, __LINE__); + return SQLITE_IOERR_ACCESS; + } + if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) { + ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS; + } + if (0 == strncmp("exfat", fsInfo.f_fstypename, 5)) { + ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS; + } +#endif + + /* Set up appropriate ctrlFlags */ + if( isDelete ) ctrlFlags |= UNIXFILE_DELETE; + if( isReadonly ) ctrlFlags |= UNIXFILE_RDONLY; + if( noLock ) ctrlFlags |= UNIXFILE_NOLOCK; + if( syncDir ) ctrlFlags |= UNIXFILE_DIRSYNC; + if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI; + +#if SQLITE_ENABLE_LOCKING_STYLE +#if SQLITE_PREFER_PROXY_LOCKING + isAutoProxy = 1; +#endif + if( isAutoProxy && (zPath!=NULL) && (!noLock) && pVfs->xOpen ){ + char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING"); + int useProxy = 0; + + /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means + ** never use proxy, NULL means use proxy for non-local files only. */ + if( envforce!=NULL ){ + useProxy = atoi(envforce)>0; + }else{ + useProxy = !(fsInfo.f_flags&MNT_LOCAL); + } + if( useProxy ){ + rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags); + if( rc==SQLITE_OK ){ + rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:"); + if( rc!=SQLITE_OK ){ + /* Use unixClose to clean up the resources added in fillInUnixFile + ** and clear all the structure's references. Specifically, + ** pFile->pMethods will be NULL so sqlite3OsClose will be a no-op + */ + unixClose(pFile); + return rc; + } + } + goto open_finished; + } + } +#endif + + rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags); + +open_finished: + if( rc!=SQLITE_OK ){ + sqlite3_free(p->pUnused); + } + return rc; +} + + +/* +** Delete the file at zPath. If the dirSync argument is true, fsync() +** the directory after deleting the file. +*/ +static int unixDelete( + sqlite3_vfs *NotUsed, /* VFS containing this as the xDelete method */ + const char *zPath, /* Name of file to be deleted */ + int dirSync /* If true, fsync() directory after deleting file */ +){ + int rc = SQLITE_OK; + UNUSED_PARAMETER(NotUsed); + SimulateIOError(return SQLITE_IOERR_DELETE); + if( osUnlink(zPath)==(-1) ){ + if( errno==ENOENT +#if OS_VXWORKS + || osAccess(zPath,0)!=0 +#endif + ){ + rc = SQLITE_IOERR_DELETE_NOENT; + }else{ + rc = unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath); + } + return rc; + } +#ifndef SQLITE_DISABLE_DIRSYNC + if( (dirSync & 1)!=0 ){ + int fd; + rc = osOpenDirectory(zPath, &fd); + if( rc==SQLITE_OK ){ +#if OS_VXWORKS + if( fsync(fd)==-1 ) +#else + if( fsync(fd) ) +#endif + { + rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath); + } + robust_close(0, fd, __LINE__); + }else if( rc==SQLITE_CANTOPEN ){ + rc = SQLITE_OK; + } + } +#endif + return rc; +} + +/* +** Test the existence of or access permissions of file zPath. The +** test performed depends on the value of flags: +** +** SQLITE_ACCESS_EXISTS: Return 1 if the file exists +** SQLITE_ACCESS_READWRITE: Return 1 if the file is read and writable. +** SQLITE_ACCESS_READONLY: Return 1 if the file is readable. +** +** Otherwise return 0. +*/ +static int unixAccess( + sqlite3_vfs *NotUsed, /* The VFS containing this xAccess method */ + const char *zPath, /* Path of the file to examine */ + int flags, /* What do we want to learn about the zPath file? */ + int *pResOut /* Write result boolean here */ +){ + int amode = 0; + UNUSED_PARAMETER(NotUsed); + SimulateIOError( return SQLITE_IOERR_ACCESS; ); + switch( flags ){ + case SQLITE_ACCESS_EXISTS: + amode = F_OK; + break; + case SQLITE_ACCESS_READWRITE: + amode = W_OK|R_OK; + break; + case SQLITE_ACCESS_READ: + amode = R_OK; + break; + + default: + assert(!"Invalid flags argument"); + } + *pResOut = (osAccess(zPath, amode)==0); + if( flags==SQLITE_ACCESS_EXISTS && *pResOut ){ + struct stat buf; + if( 0==osStat(zPath, &buf) && buf.st_size==0 ){ + *pResOut = 0; + } + } + return SQLITE_OK; +} + + +/* +** Turn a relative pathname into a full pathname. The relative path +** is stored as a nul-terminated string in the buffer pointed to by +** zPath. +** +** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes +** (in this case, MAX_PATHNAME bytes). The full-path is written to +** this buffer before returning. +*/ +static int unixFullPathname( + sqlite3_vfs *pVfs, /* Pointer to vfs object */ + const char *zPath, /* Possibly relative input path */ + int nOut, /* Size of output buffer in bytes */ + char *zOut /* Output buffer */ +){ + + /* It's odd to simulate an io-error here, but really this is just + ** using the io-error infrastructure to test that SQLite handles this + ** function failing. This function could fail if, for example, the + ** current working directory has been unlinked. + */ + SimulateIOError( return SQLITE_ERROR ); + + assert( pVfs->mxPathname==MAX_PATHNAME ); + UNUSED_PARAMETER(pVfs); + + zOut[nOut-1] = '\0'; + if( zPath[0]=='/' ){ + sqlite3_snprintf(nOut, zOut, "%s", zPath); + }else{ + int nCwd; + if( osGetcwd(zOut, nOut-1)==0 ){ + return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath); + } + nCwd = (int)strlen(zOut); + sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath); + } + return SQLITE_OK; +} + + +#ifndef SQLITE_OMIT_LOAD_EXTENSION +/* +** Interfaces for opening a shared library, finding entry points +** within the shared library, and closing the shared library. +*/ +#include +static void *unixDlOpen(sqlite3_vfs *NotUsed, const char *zFilename){ + UNUSED_PARAMETER(NotUsed); + return dlopen(zFilename, RTLD_NOW | RTLD_GLOBAL); +} + +/* +** SQLite calls this function immediately after a call to unixDlSym() or +** unixDlOpen() fails (returns a null pointer). If a more detailed error +** message is available, it is written to zBufOut. If no error message +** is available, zBufOut is left unmodified and SQLite uses a default +** error message. +*/ +static void unixDlError(sqlite3_vfs *NotUsed, int nBuf, char *zBufOut){ + const char *zErr; + UNUSED_PARAMETER(NotUsed); + unixEnterMutex(); + zErr = dlerror(); + if( zErr ){ + sqlite3_snprintf(nBuf, zBufOut, "%s", zErr); + } + unixLeaveMutex(); +} +static void (*unixDlSym(sqlite3_vfs *NotUsed, void *p, const char*zSym))(void){ + /* + ** GCC with -pedantic-errors says that C90 does not allow a void* to be + ** cast into a pointer to a function. And yet the library dlsym() routine + ** returns a void* which is really a pointer to a function. So how do we + ** use dlsym() with -pedantic-errors? + ** + ** Variable x below is defined to be a pointer to a function taking + ** parameters void* and const char* and returning a pointer to a function. + ** We initialize x by assigning it a pointer to the dlsym() function. + ** (That assignment requires a cast.) Then we call the function that + ** x points to. + ** + ** This work-around is unlikely to work correctly on any system where + ** you really cannot cast a function pointer into void*. But then, on the + ** other hand, dlsym() will not work on such a system either, so we have + ** not really lost anything. + */ + void (*(*x)(void*,const char*))(void); + UNUSED_PARAMETER(NotUsed); + x = (void(*(*)(void*,const char*))(void))dlsym; + return (*x)(p, zSym); +} +static void unixDlClose(sqlite3_vfs *NotUsed, void *pHandle){ + UNUSED_PARAMETER(NotUsed); + dlclose(pHandle); +} +#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ + #define unixDlOpen 0 + #define unixDlError 0 + #define unixDlSym 0 + #define unixDlClose 0 +#endif + +/* +** Write nBuf bytes of random data to the supplied buffer zBuf. +*/ +static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){ + UNUSED_PARAMETER(NotUsed); + assert((size_t)nBuf>=(sizeof(time_t)+sizeof(int))); + + /* 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, nBuf); + randomnessPid = osGetpid(0); +#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) + { + int fd, got; + fd = robust_open("/dev/urandom", O_RDONLY, 0); + if( fd<0 ){ + time_t t; + time(&t); + memcpy(zBuf, &t, sizeof(t)); + memcpy(&zBuf[sizeof(t)], &randomnessPid, sizeof(randomnessPid)); + assert( sizeof(t)+sizeof(randomnessPid)<=(size_t)nBuf ); + nBuf = sizeof(t) + sizeof(randomnessPid); + }else{ + do{ got = osRead(fd, zBuf, nBuf); }while( got<0 && errno==EINTR ); + robust_close(0, fd, __LINE__); + } + } +#endif + return nBuf; +} + + +/* +** Sleep for a little while. Return the amount of time slept. +** The argument is the number of microseconds we want to sleep. +** The return value is the number of microseconds of sleep actually +** requested from the underlying operating system, a number which +** might be greater than or equal to the argument, but not less +** than the argument. +*/ +static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){ +#if OS_VXWORKS + struct timespec sp; + + sp.tv_sec = microseconds / 1000000; + sp.tv_nsec = (microseconds % 1000000) * 1000; + nanosleep(&sp, NULL); + UNUSED_PARAMETER(NotUsed); + return microseconds; +#elif defined(HAVE_USLEEP) && HAVE_USLEEP + usleep(microseconds); + UNUSED_PARAMETER(NotUsed); + return microseconds; +#else + int seconds = (microseconds+999999)/1000000; + sleep(seconds); + UNUSED_PARAMETER(NotUsed); + return seconds*1000000; +#endif +} + +/* +** The following variable, if set to a non-zero value, is interpreted as +** the number of seconds since 1970 and is used to set the result of +** sqlite3OsCurrentTime() during testing. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */ +#endif + +/* +** Find the current time (in Universal Coordinated Time). Write into *piNow +** the current time and date as a Julian Day number times 86_400_000. In +** other words, write into *piNow the number of milliseconds since the Julian +** epoch of noon in Greenwich on November 24, 4714 B.C according to the +** proleptic Gregorian calendar. +** +** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date +** cannot be found. +*/ +static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){ + static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; + int rc = SQLITE_OK; +#if defined(NO_GETTOD) + time_t t; + time(&t); + *piNow = ((sqlite3_int64)t)*1000 + unixEpoch; +#elif OS_VXWORKS + struct timespec sNow; + clock_gettime(CLOCK_REALTIME, &sNow); + *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000; +#else + struct timeval sNow; + if( gettimeofday(&sNow, 0)==0 ){ + *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000; + }else{ + rc = SQLITE_ERROR; + } +#endif + +#ifdef SQLITE_TEST + if( sqlite3_current_time ){ + *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; + } +#endif + UNUSED_PARAMETER(NotUsed); + return rc; +} + +/* +** 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. +*/ +static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){ + sqlite3_int64 i = 0; + int rc; + UNUSED_PARAMETER(NotUsed); + rc = unixCurrentTimeInt64(0, &i); + *prNow = i/86400000.0; + return rc; +} + +/* +** We added the xGetLastError() method with the intention of providing +** better low-level error messages when operating-system problems come up +** during SQLite operation. But so far, none of that has been implemented +** in the core. So this routine is never called. For now, it is merely +** a place-holder. +*/ +static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ + UNUSED_PARAMETER(NotUsed); + UNUSED_PARAMETER(NotUsed2); + UNUSED_PARAMETER(NotUsed3); + return 0; +} + + +/* +************************ End of sqlite3_vfs methods *************************** +******************************************************************************/ + +/****************************************************************************** +************************** Begin Proxy Locking ******************************** +** +** Proxy locking is a "uber-locking-method" in this sense: It uses the +** other locking methods on secondary lock files. Proxy locking is a +** meta-layer over top of the primitive locking implemented above. For +** this reason, the division that implements of proxy locking is deferred +** until late in the file (here) after all of the other I/O methods have +** been defined - so that the primitive locking methods are available +** as services to help with the implementation of proxy locking. +** +**** +** +** The default locking schemes in SQLite use byte-range locks on the +** database file to coordinate safe, concurrent access by multiple readers +** and writers [http://sqlite.org/lockingv3.html]. The five file locking +** states (UNLOCKED, PENDING, SHARED, RESERVED, EXCLUSIVE) are implemented +** as POSIX read & write locks over fixed set of locations (via fsctl), +** on AFP and SMB only exclusive byte-range locks are available via fsctl +** with _IOWR('z', 23, struct ByteRangeLockPB2) to track the same 5 states. +** To simulate a F_RDLCK on the shared range, on AFP a randomly selected +** address in the shared range is taken for a SHARED lock, the entire +** shared range is taken for an EXCLUSIVE lock): +** +** PENDING_BYTE 0x40000000 +** RESERVED_BYTE 0x40000001 +** SHARED_RANGE 0x40000002 -> 0x40000200 +** +** This works well on the local file system, but shows a nearly 100x +** slowdown in read performance on AFP because the AFP client disables +** the read cache when byte-range locks are present. Enabling the read +** cache exposes a cache coherency problem that is present on all OS X +** supported network file systems. NFS and AFP both observe the +** close-to-open semantics for ensuring cache coherency +** [http://nfs.sourceforge.net/#faq_a8], which does not effectively +** address the requirements for concurrent database access by multiple +** readers and writers +** [http://www.nabble.com/SQLite-on-NFS-cache-coherency-td15655701.html]. +** +** To address the performance and cache coherency issues, proxy file locking +** changes the way database access is controlled by limiting access to a +** single host at a time and moving file locks off of the database file +** and onto a proxy file on the local file system. +** +** +** Using proxy locks +** ----------------- +** +** C APIs +** +** sqlite3_file_control(db, dbname, SQLITE_FCNTL_SET_LOCKPROXYFILE, +** | ":auto:"); +** sqlite3_file_control(db, dbname, SQLITE_FCNTL_GET_LOCKPROXYFILE, +** &); +** +** +** SQL pragmas +** +** PRAGMA [database.]lock_proxy_file= | :auto: +** PRAGMA [database.]lock_proxy_file +** +** Specifying ":auto:" means that if there is a conch file with a matching +** host ID in it, the proxy path in the conch file will be used, otherwise +** a proxy path based on the user's temp dir +** (via confstr(_CS_DARWIN_USER_TEMP_DIR,...)) will be used and the +** actual proxy file name is generated from the name and path of the +** database file. For example: +** +** For database path "/Users/me/foo.db" +** The lock path will be "/sqliteplocks/_Users_me_foo.db:auto:") +** +** Once a lock proxy is configured for a database connection, it can not +** be removed, however it may be switched to a different proxy path via +** the above APIs (assuming the conch file is not being held by another +** connection or process). +** +** +** How proxy locking works +** ----------------------- +** +** Proxy file locking relies primarily on two new supporting files: +** +** * conch file to limit access to the database file to a single host +** at a time +** +** * proxy file to act as a proxy for the advisory locks normally +** taken on the database +** +** The conch file - to use a proxy file, sqlite must first "hold the conch" +** by taking an sqlite-style shared lock on the conch file, reading the +** contents and comparing the host's unique host ID (see below) and lock +** proxy path against the values stored in the conch. The conch file is +** stored in the same directory as the database file and the file name +** is patterned after the database file name as ".-conch". +** If the conch file does not exist, or its contents do not match the +** host ID and/or proxy path, then the lock is escalated to an exclusive +** lock and the conch file contents is updated with the host ID and proxy +** path and the lock is downgraded to a shared lock again. If the conch +** is held by another process (with a shared lock), the exclusive lock +** will fail and SQLITE_BUSY is returned. +** +** The proxy file - a single-byte file used for all advisory file locks +** normally taken on the database file. This allows for safe sharing +** of the database file for multiple readers and writers on the same +** host (the conch ensures that they all use the same local lock file). +** +** Requesting the lock proxy does not immediately take the conch, it is +** only taken when the first request to lock database file is made. +** This matches the semantics of the traditional locking behavior, where +** opening a connection to a database file does not take a lock on it. +** The shared lock and an open file descriptor are maintained until +** the connection to the database is closed. +** +** The proxy file and the lock file are never deleted so they only need +** to be created the first time they are used. +** +** Configuration options +** --------------------- +** +** SQLITE_PREFER_PROXY_LOCKING +** +** Database files accessed on non-local file systems are +** automatically configured for proxy locking, lock files are +** named automatically using the same logic as +** PRAGMA lock_proxy_file=":auto:" +** +** SQLITE_PROXY_DEBUG +** +** Enables the logging of error messages during host id file +** retrieval and creation +** +** LOCKPROXYDIR +** +** Overrides the default directory used for lock proxy files that +** are named automatically via the ":auto:" setting +** +** SQLITE_DEFAULT_PROXYDIR_PERMISSIONS +** +** Permissions to use when creating a directory for storing the +** lock proxy files, only used when LOCKPROXYDIR is not set. +** +** +** As mentioned above, when compiled with SQLITE_PREFER_PROXY_LOCKING, +** setting the environment variable SQLITE_FORCE_PROXY_LOCKING to 1 will +** force proxy locking to be used for every database file opened, and 0 +** will force automatic proxy locking to be disabled for all database +** files (explicitly calling the SQLITE_FCNTL_SET_LOCKPROXYFILE pragma or +** sqlite_file_control API is not affected by SQLITE_FORCE_PROXY_LOCKING). +*/ + +/* +** Proxy locking is only available on MacOSX +*/ +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE + +/* +** The proxyLockingContext has the path and file structures for the remote +** and local proxy files in it +*/ +typedef struct proxyLockingContext proxyLockingContext; +struct proxyLockingContext { + unixFile *conchFile; /* Open conch file */ + char *conchFilePath; /* Name of the conch file */ + unixFile *lockProxy; /* Open proxy lock file */ + char *lockProxyPath; /* Name of the proxy lock file */ + char *dbPath; /* Name of the open file */ + int conchHeld; /* 1 if the conch is held, -1 if lockless */ + int nFails; /* Number of conch taking failures */ + void *oldLockingContext; /* Original lockingcontext to restore on close */ + sqlite3_io_methods const *pOldMethod; /* Original I/O methods for close */ +}; + +/* +** The proxy lock file path for the database at dbPath is written into lPath, +** which must point to valid, writable memory large enough for a maxLen length +** file path. +*/ +static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){ + int len; + int dbLen; + int i; + +#ifdef LOCKPROXYDIR + len = strlcpy(lPath, LOCKPROXYDIR, maxLen); +#else +# ifdef _CS_DARWIN_USER_TEMP_DIR + { + if( !confstr(_CS_DARWIN_USER_TEMP_DIR, lPath, maxLen) ){ + OSTRACE(("GETLOCKPATH failed %s errno=%d pid=%d\n", + lPath, errno, osGetpid(0))); + return SQLITE_IOERR_LOCK; + } + len = strlcat(lPath, "sqliteplocks", maxLen); + } +# else + len = strlcpy(lPath, "/tmp/", maxLen); +# endif +#endif + + if( lPath[len-1]!='/' ){ + len = strlcat(lPath, "/", maxLen); + } + + /* transform the db path to a unique cache name */ + dbLen = (int)strlen(dbPath); + for( i=0; i 0) ){ + /* only mkdir if leaf dir != "." or "/" or ".." */ + if( i-start>2 || (i-start==1 && buf[start] != '.' && buf[start] != '/') + || (i-start==2 && buf[start] != '.' && buf[start+1] != '.') ){ + buf[i]='\0'; + if( osMkdir(buf, SQLITE_DEFAULT_PROXYDIR_PERMISSIONS) ){ + int err=errno; + if( err!=EEXIST ) { + OSTRACE(("CREATELOCKPATH FAILED creating %s, " + "'%s' proxy lock path=%s pid=%d\n", + buf, strerror(err), lockPath, osGetpid(0))); + return err; + } + } + } + start=i+1; + } + buf[i] = lockPath[i]; + } + OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n", lockPath, osGetpid(0))); + return 0; +} + +/* +** Create a new VFS file descriptor (stored in memory obtained from +** sqlite3_malloc) and open the file named "path" in the file descriptor. +** +** The caller is responsible not only for closing the file descriptor +** but also for freeing the memory associated with the file descriptor. +*/ +static int proxyCreateUnixFile( + const char *path, /* path for the new unixFile */ + unixFile **ppFile, /* unixFile created and returned by ref */ + int islockfile /* if non zero missing dirs will be created */ +) { + int fd = -1; + unixFile *pNew; + int rc = SQLITE_OK; + int openFlags = O_RDWR | O_CREAT; + sqlite3_vfs dummyVfs; + int terrno = 0; + UnixUnusedFd *pUnused = NULL; + + /* 1. first try to open/create the file + ** 2. if that fails, and this is a lock file (not-conch), try creating + ** the parent directories and then try again. + ** 3. if that fails, try to open the file read-only + ** otherwise return BUSY (if lock file) or CANTOPEN for the conch file + */ + pUnused = findReusableFd(path, openFlags); + if( pUnused ){ + fd = pUnused->fd; + }else{ + pUnused = sqlite3_malloc64(sizeof(*pUnused)); + if( !pUnused ){ + return SQLITE_NOMEM; + } + } + if( fd<0 ){ + fd = robust_open(path, openFlags, 0); + terrno = errno; + if( fd<0 && errno==ENOENT && islockfile ){ + if( proxyCreateLockPath(path) == SQLITE_OK ){ + fd = robust_open(path, openFlags, 0); + } + } + } + if( fd<0 ){ + openFlags = O_RDONLY; + fd = robust_open(path, openFlags, 0); + terrno = errno; + } + if( fd<0 ){ + if( islockfile ){ + return SQLITE_BUSY; + } + switch (terrno) { + case EACCES: + return SQLITE_PERM; + case EIO: + return SQLITE_IOERR_LOCK; /* even though it is the conch */ + default: + return SQLITE_CANTOPEN_BKPT; + } + } + + pNew = (unixFile *)sqlite3_malloc64(sizeof(*pNew)); + if( pNew==NULL ){ + rc = SQLITE_NOMEM; + goto end_create_proxy; + } + memset(pNew, 0, sizeof(unixFile)); + pNew->openFlags = openFlags; + memset(&dummyVfs, 0, sizeof(dummyVfs)); + dummyVfs.pAppData = (void*)&autolockIoFinder; + dummyVfs.zName = "dummy"; + pUnused->fd = fd; + pUnused->flags = openFlags; + pNew->pUnused = pUnused; + + rc = fillInUnixFile(&dummyVfs, fd, (sqlite3_file*)pNew, path, 0); + if( rc==SQLITE_OK ){ + *ppFile = pNew; + return SQLITE_OK; + } +end_create_proxy: + robust_close(pNew, fd, __LINE__); + sqlite3_free(pNew); + sqlite3_free(pUnused); + return rc; +} + +#ifdef SQLITE_TEST +/* simulate multiple hosts by creating unique hostid file paths */ +SQLITE_API int sqlite3_hostid_num = 0; +#endif + +#define PROXY_HOSTIDLEN 16 /* conch file host id length */ + +#ifdef HAVE_GETHOSTUUID +/* Not always defined in the headers as it ought to be */ +extern int gethostuuid(uuid_t id, const struct timespec *wait); +#endif + +/* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN +** bytes of writable memory. +*/ +static int proxyGetHostID(unsigned char *pHostID, int *pError){ + assert(PROXY_HOSTIDLEN == sizeof(uuid_t)); + memset(pHostID, 0, PROXY_HOSTIDLEN); +#ifdef HAVE_GETHOSTUUID + { + struct timespec timeout = {1, 0}; /* 1 sec timeout */ + if( gethostuuid(pHostID, &timeout) ){ + int err = errno; + if( pError ){ + *pError = err; + } + return SQLITE_IOERR; + } + } +#else + UNUSED_PARAMETER(pError); +#endif +#ifdef SQLITE_TEST + /* simulate multiple hosts by creating unique hostid file paths */ + if( sqlite3_hostid_num != 0){ + pHostID[0] = (char)(pHostID[0] + (char)(sqlite3_hostid_num & 0xFF)); + } +#endif + + return SQLITE_OK; +} + +/* The conch file contains the header, host id and lock file path + */ +#define PROXY_CONCHVERSION 2 /* 1-byte header, 16-byte host id, path */ +#define PROXY_HEADERLEN 1 /* conch file header length */ +#define PROXY_PATHINDEX (PROXY_HEADERLEN+PROXY_HOSTIDLEN) +#define PROXY_MAXCONCHLEN (PROXY_HEADERLEN+PROXY_HOSTIDLEN+MAXPATHLEN) + +/* +** Takes an open conch file, copies the contents to a new path and then moves +** it back. The newly created file's file descriptor is assigned to the +** conch file structure and finally the original conch file descriptor is +** closed. Returns zero if successful. +*/ +static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + unixFile *conchFile = pCtx->conchFile; + char tPath[MAXPATHLEN]; + char buf[PROXY_MAXCONCHLEN]; + char *cPath = pCtx->conchFilePath; + size_t readLen = 0; + size_t pathLen = 0; + char errmsg[64] = ""; + int fd = -1; + int rc = -1; + UNUSED_PARAMETER(myHostID); + + /* create a new path by replace the trailing '-conch' with '-break' */ + pathLen = strlcpy(tPath, cPath, MAXPATHLEN); + if( pathLen>MAXPATHLEN || pathLen<6 || + (strlcpy(&tPath[pathLen-5], "break", 6) != 5) ){ + sqlite3_snprintf(sizeof(errmsg),errmsg,"path error (len %d)",(int)pathLen); + goto end_breaklock; + } + /* read the conch content */ + readLen = osPread(conchFile->h, buf, PROXY_MAXCONCHLEN, 0); + if( readLenh, __LINE__); + conchFile->h = fd; + conchFile->openFlags = O_RDWR | O_CREAT; + +end_breaklock: + if( rc ){ + if( fd>=0 ){ + osUnlink(tPath); + robust_close(pFile, fd, __LINE__); + } + fprintf(stderr, "failed to break stale lock on %s, %s\n", cPath, errmsg); + } + return rc; +} + +/* Take the requested lock on the conch file and break a stale lock if the +** host id matches. +*/ +static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + unixFile *conchFile = pCtx->conchFile; + int rc = SQLITE_OK; + int nTries = 0; + struct timespec conchModTime; + + memset(&conchModTime, 0, sizeof(conchModTime)); + do { + rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType); + nTries ++; + if( rc==SQLITE_BUSY ){ + /* If the lock failed (busy): + * 1st try: get the mod time of the conch, wait 0.5s and try again. + * 2nd try: fail if the mod time changed or host id is different, wait + * 10 sec and try again + * 3rd try: break the lock unless the mod time has changed. + */ + struct stat buf; + if( osFstat(conchFile->h, &buf) ){ + storeLastErrno(pFile, errno); + return SQLITE_IOERR_LOCK; + } + + if( nTries==1 ){ + conchModTime = buf.st_mtimespec; + usleep(500000); /* wait 0.5 sec and try the lock again*/ + continue; + } + + assert( nTries>1 ); + if( conchModTime.tv_sec != buf.st_mtimespec.tv_sec || + conchModTime.tv_nsec != buf.st_mtimespec.tv_nsec ){ + return SQLITE_BUSY; + } + + if( nTries==2 ){ + char tBuf[PROXY_MAXCONCHLEN]; + int len = osPread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0); + if( len<0 ){ + storeLastErrno(pFile, errno); + return SQLITE_IOERR_LOCK; + } + if( len>PROXY_PATHINDEX && tBuf[0]==(char)PROXY_CONCHVERSION){ + /* don't break the lock if the host id doesn't match */ + if( 0!=memcmp(&tBuf[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN) ){ + return SQLITE_BUSY; + } + }else{ + /* don't break the lock on short read or a version mismatch */ + return SQLITE_BUSY; + } + usleep(10000000); /* wait 10 sec and try the lock again */ + continue; + } + + assert( nTries==3 ); + if( 0==proxyBreakConchLock(pFile, myHostID) ){ + rc = SQLITE_OK; + if( lockType==EXCLUSIVE_LOCK ){ + rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK); + } + if( !rc ){ + rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType); + } + } + } + } while( rc==SQLITE_BUSY && nTries<3 ); + + return rc; +} + +/* Takes the conch by taking a shared lock and read the contents conch, if +** lockPath is non-NULL, the host ID and lock file path must match. A NULL +** lockPath means that the lockPath in the conch file will be used if the +** host IDs match, or a new lock path will be generated automatically +** and written to the conch file. +*/ +static int proxyTakeConch(unixFile *pFile){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + + if( pCtx->conchHeld!=0 ){ + return SQLITE_OK; + }else{ + unixFile *conchFile = pCtx->conchFile; + uuid_t myHostID; + int pError = 0; + char readBuf[PROXY_MAXCONCHLEN]; + char lockPath[MAXPATHLEN]; + char *tempLockPath = NULL; + int rc = SQLITE_OK; + int createConch = 0; + int hostIdMatch = 0; + int readLen = 0; + int tryOldLockPath = 0; + int forceNewLockPath = 0; + + OSTRACE(("TAKECONCH %d for %s pid=%d\n", conchFile->h, + (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), + osGetpid(0))); + + rc = proxyGetHostID(myHostID, &pError); + if( (rc&0xff)==SQLITE_IOERR ){ + storeLastErrno(pFile, pError); + goto end_takeconch; + } + rc = proxyConchLock(pFile, myHostID, SHARED_LOCK); + if( rc!=SQLITE_OK ){ + goto end_takeconch; + } + /* read the existing conch file */ + readLen = seekAndRead((unixFile*)conchFile, 0, readBuf, PROXY_MAXCONCHLEN); + if( readLen<0 ){ + /* I/O error: lastErrno set by seekAndRead */ + storeLastErrno(pFile, conchFile->lastErrno); + rc = SQLITE_IOERR_READ; + goto end_takeconch; + }else if( readLen<=(PROXY_HEADERLEN+PROXY_HOSTIDLEN) || + readBuf[0]!=(char)PROXY_CONCHVERSION ){ + /* a short read or version format mismatch means we need to create a new + ** conch file. + */ + createConch = 1; + } + /* if the host id matches and the lock path already exists in the conch + ** we'll try to use the path there, if we can't open that path, we'll + ** retry with a new auto-generated path + */ + do { /* in case we need to try again for an :auto: named lock file */ + + if( !createConch && !forceNewLockPath ){ + hostIdMatch = !memcmp(&readBuf[PROXY_HEADERLEN], myHostID, + PROXY_HOSTIDLEN); + /* if the conch has data compare the contents */ + if( !pCtx->lockProxyPath ){ + /* for auto-named local lock file, just check the host ID and we'll + ** use the local lock file path that's already in there + */ + if( hostIdMatch ){ + size_t pathLen = (readLen - PROXY_PATHINDEX); + + if( pathLen>=MAXPATHLEN ){ + pathLen=MAXPATHLEN-1; + } + memcpy(lockPath, &readBuf[PROXY_PATHINDEX], pathLen); + lockPath[pathLen] = 0; + tempLockPath = lockPath; + tryOldLockPath = 1; + /* create a copy of the lock path if the conch is taken */ + goto end_takeconch; + } + }else if( hostIdMatch + && !strncmp(pCtx->lockProxyPath, &readBuf[PROXY_PATHINDEX], + readLen-PROXY_PATHINDEX) + ){ + /* conch host and lock path match */ + goto end_takeconch; + } + } + + /* if the conch isn't writable and doesn't match, we can't take it */ + if( (conchFile->openFlags&O_RDWR) == 0 ){ + rc = SQLITE_BUSY; + goto end_takeconch; + } + + /* either the conch didn't match or we need to create a new one */ + if( !pCtx->lockProxyPath ){ + proxyGetLockPath(pCtx->dbPath, lockPath, MAXPATHLEN); + tempLockPath = lockPath; + /* create a copy of the lock path _only_ if the conch is taken */ + } + + /* update conch with host and path (this will fail if other process + ** has a shared lock already), if the host id matches, use the big + ** stick. + */ + futimes(conchFile->h, NULL); + if( hostIdMatch && !createConch ){ + if( conchFile->pInode && conchFile->pInode->nShared>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 { + rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK); + } + }else{ + rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK); + } + if( rc==SQLITE_OK ){ + char writeBuffer[PROXY_MAXCONCHLEN]; + int writeSize = 0; + + writeBuffer[0] = (char)PROXY_CONCHVERSION; + memcpy(&writeBuffer[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN); + if( pCtx->lockProxyPath!=NULL ){ + strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath, + MAXPATHLEN); + }else{ + strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAXPATHLEN); + } + writeSize = PROXY_PATHINDEX + strlen(&writeBuffer[PROXY_PATHINDEX]); + robust_ftruncate(conchFile->h, writeSize); + rc = unixWrite((sqlite3_file *)conchFile, writeBuffer, writeSize, 0); + fsync(conchFile->h); + /* If we created a new conch file (not just updated the contents of a + ** valid conch file), try to match the permissions of the database + */ + if( rc==SQLITE_OK && createConch ){ + struct stat buf; + int err = osFstat(pFile->h, &buf); + if( err==0 ){ + mode_t cmode = buf.st_mode&(S_IRUSR|S_IWUSR | S_IRGRP|S_IWGRP | + S_IROTH|S_IWOTH); + /* try to match the database file R/W permissions, ignore failure */ +#ifndef SQLITE_PROXY_DEBUG + osFchmod(conchFile->h, cmode); +#else + do{ + rc = osFchmod(conchFile->h, cmode); + }while( rc==(-1) && errno==EINTR ); + if( rc!=0 ){ + int code = errno; + fprintf(stderr, "fchmod %o FAILED with %d %s\n", + cmode, code, strerror(code)); + } else { + fprintf(stderr, "fchmod %o SUCCEDED\n",cmode); + } + }else{ + int code = errno; + fprintf(stderr, "STAT FAILED[%d] with %d %s\n", + err, code, strerror(code)); +#endif + } + } + } + conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, SHARED_LOCK); + + end_takeconch: + OSTRACE(("TRANSPROXY: CLOSE %d\n", pFile->h)); + if( rc==SQLITE_OK && pFile->openFlags ){ + int fd; + if( pFile->h>=0 ){ + robust_close(pFile, pFile->h, __LINE__); + } + pFile->h = -1; + fd = robust_open(pCtx->dbPath, pFile->openFlags, 0); + OSTRACE(("TRANSPROXY: OPEN %d\n", fd)); + if( fd>=0 ){ + pFile->h = fd; + }else{ + rc=SQLITE_CANTOPEN_BKPT; /* SQLITE_BUSY? proxyTakeConch called + during locking */ + } + } + if( rc==SQLITE_OK && !pCtx->lockProxy ){ + char *path = tempLockPath ? tempLockPath : pCtx->lockProxyPath; + rc = proxyCreateUnixFile(path, &pCtx->lockProxy, 1); + if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM && tryOldLockPath ){ + /* we couldn't create the proxy lock file with the old lock file path + ** so try again via auto-naming + */ + forceNewLockPath = 1; + tryOldLockPath = 0; + continue; /* go back to the do {} while start point, try again */ + } + } + if( rc==SQLITE_OK ){ + /* Need to make a copy of path if we extracted the value + ** from the conch file or the path was allocated on the stack + */ + if( tempLockPath ){ + pCtx->lockProxyPath = sqlite3DbStrDup(0, tempLockPath); + if( !pCtx->lockProxyPath ){ + rc = SQLITE_NOMEM; + } + } + } + if( rc==SQLITE_OK ){ + pCtx->conchHeld = 1; + + if( pCtx->lockProxy->pMethod == &afpIoMethods ){ + afpLockingContext *afpCtx; + afpCtx = (afpLockingContext *)pCtx->lockProxy->lockingContext; + afpCtx->dbPath = pCtx->lockProxyPath; + } + } else { + conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK); + } + OSTRACE(("TAKECONCH %d %s\n", conchFile->h, + rc==SQLITE_OK?"ok":"failed")); + return rc; + } while (1); /* in case we need to retry the :auto: lock file - + ** we should never get here except via the 'continue' call. */ + } +} + +/* +** If pFile holds a lock on a conch file, then release that lock. +*/ +static int proxyReleaseConch(unixFile *pFile){ + int rc = SQLITE_OK; /* Subroutine return code */ + proxyLockingContext *pCtx; /* The locking context for the proxy lock */ + unixFile *conchFile; /* Name of the conch file */ + + pCtx = (proxyLockingContext *)pFile->lockingContext; + conchFile = pCtx->conchFile; + OSTRACE(("RELEASECONCH %d for %s pid=%d\n", conchFile->h, + (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), + osGetpid(0))); + if( pCtx->conchHeld>0 ){ + rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK); + } + pCtx->conchHeld = 0; + OSTRACE(("RELEASECONCH %d %s\n", conchFile->h, + (rc==SQLITE_OK ? "ok" : "failed"))); + return rc; +} + +/* +** Given the name of a database file, compute the name of its conch file. +** Store the conch filename in memory obtained from sqlite3_malloc64(). +** Make *pConchPath point to the new name. Return SQLITE_OK on success +** or SQLITE_NOMEM if unable to obtain memory. +** +** The caller is responsible for ensuring that the allocated memory +** space is eventually freed. +** +** *pConchPath is set to NULL if a memory allocation error occurs. +*/ +static int proxyCreateConchPathname(char *dbPath, char **pConchPath){ + int i; /* Loop counter */ + int len = (int)strlen(dbPath); /* Length of database filename - dbPath */ + char *conchPath; /* buffer in which to construct conch name */ + + /* Allocate space for the conch filename and initialize the name to + ** the name of the original database file. */ + *pConchPath = conchPath = (char *)sqlite3_malloc64(len + 8); + if( conchPath==0 ){ + return SQLITE_NOMEM; + } + memcpy(conchPath, dbPath, len+1); + + /* now insert a "." before the last / character */ + for( i=(len-1); i>=0; i-- ){ + if( conchPath[i]=='/' ){ + i++; + break; + } + } + conchPath[i]='.'; + while ( ilockingContext; + char *oldPath = pCtx->lockProxyPath; + int rc = SQLITE_OK; + + if( pFile->eFileLock!=NO_LOCK ){ + return SQLITE_BUSY; + } + + /* nothing to do if the path is NULL, :auto: or matches the existing path */ + if( !path || path[0]=='\0' || !strcmp(path, ":auto:") || + (oldPath && !strncmp(oldPath, path, MAXPATHLEN)) ){ + return SQLITE_OK; + }else{ + unixFile *lockProxy = pCtx->lockProxy; + pCtx->lockProxy=NULL; + pCtx->conchHeld = 0; + if( lockProxy!=NULL ){ + rc=lockProxy->pMethod->xClose((sqlite3_file *)lockProxy); + if( rc ) return rc; + sqlite3_free(lockProxy); + } + sqlite3_free(oldPath); + pCtx->lockProxyPath = sqlite3DbStrDup(0, path); + } + + return rc; +} + +/* +** pFile is a file that has been opened by a prior xOpen call. dbPath +** is a string buffer at least MAXPATHLEN+1 characters in size. +** +** This routine find the filename associated with pFile and writes it +** int dbPath. +*/ +static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){ +#if defined(__APPLE__) + if( pFile->pMethod == &afpIoMethods ){ + /* afp style keeps a reference to the db path in the filePath field + ** of the struct */ + assert( (int)strlen((char*)pFile->lockingContext)<=MAXPATHLEN ); + strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath, + MAXPATHLEN); + } else +#endif + if( pFile->pMethod == &dotlockIoMethods ){ + /* dot lock style uses the locking context to store the dot lock + ** file path */ + int len = strlen((char *)pFile->lockingContext) - strlen(DOTLOCK_SUFFIX); + memcpy(dbPath, (char *)pFile->lockingContext, len + 1); + }else{ + /* all other styles use the locking context to store the db file path */ + assert( strlen((char*)pFile->lockingContext)<=MAXPATHLEN ); + strlcpy(dbPath, (char *)pFile->lockingContext, MAXPATHLEN); + } + return SQLITE_OK; +} + +/* +** Takes an already filled in unix file and alters it so all file locking +** will be performed on the local proxy lock file. The following fields +** are preserved in the locking context so that they can be restored and +** the unix structure properly cleaned up at close time: +** ->lockingContext +** ->pMethod +*/ +static int proxyTransformUnixFile(unixFile *pFile, const char *path) { + proxyLockingContext *pCtx; + char dbPath[MAXPATHLEN+1]; /* Name of the database file */ + char *lockPath=NULL; + int rc = SQLITE_OK; + + if( pFile->eFileLock!=NO_LOCK ){ + return SQLITE_BUSY; + } + proxyGetDbPathForUnixFile(pFile, dbPath); + if( !path || path[0]=='\0' || !strcmp(path, ":auto:") ){ + lockPath=NULL; + }else{ + lockPath=(char *)path; + } + + OSTRACE(("TRANSPROXY %d for %s pid=%d\n", pFile->h, + (lockPath ? lockPath : ":auto:"), osGetpid(0))); + + pCtx = sqlite3_malloc64( sizeof(*pCtx) ); + if( pCtx==0 ){ + return SQLITE_NOMEM; + } + memset(pCtx, 0, sizeof(*pCtx)); + + rc = proxyCreateConchPathname(dbPath, &pCtx->conchFilePath); + if( rc==SQLITE_OK ){ + rc = proxyCreateUnixFile(pCtx->conchFilePath, &pCtx->conchFile, 0); + if( rc==SQLITE_CANTOPEN && ((pFile->openFlags&O_RDWR) == 0) ){ + /* if (a) the open flags are not O_RDWR, (b) the conch isn't there, and + ** (c) the file system is read-only, then enable no-locking access. + ** Ugh, since O_RDONLY==0x0000 we test for !O_RDWR since unixOpen asserts + ** that openFlags will have only one of O_RDONLY or O_RDWR. + */ + struct statfs fsInfo; + struct stat conchInfo; + int goLockless = 0; + + if( osStat(pCtx->conchFilePath, &conchInfo) == -1 ) { + int err = errno; + if( (err==ENOENT) && (statfs(dbPath, &fsInfo) != -1) ){ + goLockless = (fsInfo.f_flags&MNT_RDONLY) == MNT_RDONLY; + } + } + if( goLockless ){ + pCtx->conchHeld = -1; /* read only FS/ lockless */ + rc = SQLITE_OK; + } + } + } + if( rc==SQLITE_OK && lockPath ){ + pCtx->lockProxyPath = sqlite3DbStrDup(0, lockPath); + } + + if( rc==SQLITE_OK ){ + pCtx->dbPath = sqlite3DbStrDup(0, dbPath); + if( pCtx->dbPath==NULL ){ + rc = SQLITE_NOMEM; + } + } + if( rc==SQLITE_OK ){ + /* all memory is allocated, proxys are created and assigned, + ** switch the locking context and pMethod then return. + */ + pCtx->oldLockingContext = pFile->lockingContext; + pFile->lockingContext = pCtx; + pCtx->pOldMethod = pFile->pMethod; + pFile->pMethod = &proxyIoMethods; + }else{ + if( pCtx->conchFile ){ + pCtx->conchFile->pMethod->xClose((sqlite3_file *)pCtx->conchFile); + sqlite3_free(pCtx->conchFile); + } + sqlite3DbFree(0, pCtx->lockProxyPath); + sqlite3_free(pCtx->conchFilePath); + sqlite3_free(pCtx); + } + OSTRACE(("TRANSPROXY %d %s\n", pFile->h, + (rc==SQLITE_OK ? "ok" : "failed"))); + return rc; +} + + +/* +** This routine handles sqlite3_file_control() calls that are specific +** to proxy locking. +*/ +static int proxyFileControl(sqlite3_file *id, int op, void *pArg){ + switch( op ){ + case SQLITE_FCNTL_GET_LOCKPROXYFILE: { + unixFile *pFile = (unixFile*)id; + if( pFile->pMethod == &proxyIoMethods ){ + proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext; + proxyTakeConch(pFile); + if( pCtx->lockProxyPath ){ + *(const char **)pArg = pCtx->lockProxyPath; + }else{ + *(const char **)pArg = ":auto: (not held)"; + } + } else { + *(const char **)pArg = NULL; + } + return SQLITE_OK; + } + case SQLITE_FCNTL_SET_LOCKPROXYFILE: { + unixFile *pFile = (unixFile*)id; + int rc = SQLITE_OK; + int isProxyStyle = (pFile->pMethod == &proxyIoMethods); + if( pArg==NULL || (const char *)pArg==0 ){ + if( isProxyStyle ){ + /* turn off proxy locking - not supported. If support is added for + ** switching proxy locking mode off then it will need to fail if + ** the journal mode is WAL mode. + */ + rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/; + }else{ + /* turn off proxy locking - already off - NOOP */ + rc = SQLITE_OK; + } + }else{ + const char *proxyPath = (const char *)pArg; + if( isProxyStyle ){ + proxyLockingContext *pCtx = + (proxyLockingContext*)pFile->lockingContext; + if( !strcmp(pArg, ":auto:") + || (pCtx->lockProxyPath && + !strncmp(pCtx->lockProxyPath, proxyPath, MAXPATHLEN)) + ){ + rc = SQLITE_OK; + }else{ + rc = switchLockProxyPath(pFile, proxyPath); + } + }else{ + /* turn on proxy file locking */ + rc = proxyTransformUnixFile(pFile, proxyPath); + } + } + return rc; + } + default: { + assert( 0 ); /* The call assures that only valid opcodes are sent */ + } + } + /*NOTREACHED*/ + return SQLITE_ERROR; +} + +/* +** Within this division (the proxying locking implementation) the procedures +** above this point are all utilities. The lock-related methods of the +** proxy-locking sqlite3_io_method object follow. +*/ + + +/* +** 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, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +*/ +static int proxyCheckReservedLock(sqlite3_file *id, int *pResOut) { + unixFile *pFile = (unixFile*)id; + int rc = proxyTakeConch(pFile); + if( rc==SQLITE_OK ){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + if( pCtx->conchHeld>0 ){ + unixFile *proxy = pCtx->lockProxy; + return proxy->pMethod->xCheckReservedLock((sqlite3_file*)proxy, pResOut); + }else{ /* conchHeld < 0 is lockless */ + pResOut=0; + } + } + return rc; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** 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 proxyLock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + int rc = proxyTakeConch(pFile); + if( rc==SQLITE_OK ){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + if( pCtx->conchHeld>0 ){ + unixFile *proxy = pCtx->lockProxy; + rc = proxy->pMethod->xLock((sqlite3_file*)proxy, eFileLock); + pFile->eFileLock = proxy->eFileLock; + }else{ + /* conchHeld < 0 is lockless */ + } + } + return rc; +} + + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** 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 proxyUnlock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + int rc = proxyTakeConch(pFile); + if( rc==SQLITE_OK ){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + if( pCtx->conchHeld>0 ){ + unixFile *proxy = pCtx->lockProxy; + rc = proxy->pMethod->xUnlock((sqlite3_file*)proxy, eFileLock); + pFile->eFileLock = proxy->eFileLock; + }else{ + /* conchHeld < 0 is lockless */ + } + } + return rc; +} + +/* +** Close a file that uses proxy locks. +*/ +static int proxyClose(sqlite3_file *id) { + if( id ){ + unixFile *pFile = (unixFile*)id; + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + unixFile *lockProxy = pCtx->lockProxy; + unixFile *conchFile = pCtx->conchFile; + int rc = SQLITE_OK; + + if( lockProxy ){ + rc = lockProxy->pMethod->xUnlock((sqlite3_file*)lockProxy, NO_LOCK); + if( rc ) return rc; + rc = lockProxy->pMethod->xClose((sqlite3_file*)lockProxy); + if( rc ) return rc; + sqlite3_free(lockProxy); + pCtx->lockProxy = 0; + } + if( conchFile ){ + if( pCtx->conchHeld ){ + rc = proxyReleaseConch(pFile); + if( rc ) return rc; + } + rc = conchFile->pMethod->xClose((sqlite3_file*)conchFile); + if( rc ) return rc; + sqlite3_free(conchFile); + } + sqlite3DbFree(0, pCtx->lockProxyPath); + sqlite3_free(pCtx->conchFilePath); + sqlite3DbFree(0, pCtx->dbPath); + /* restore the original locking context and pMethod then close it */ + pFile->lockingContext = pCtx->oldLockingContext; + pFile->pMethod = pCtx->pOldMethod; + sqlite3_free(pCtx); + return pFile->pMethod->xClose(id); + } + return SQLITE_OK; +} + + + +#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ +/* +** The proxy locking style is intended for use with AFP filesystems. +** And since AFP is only supported on MacOSX, the proxy locking is also +** restricted to MacOSX. +** +** +******************* End of the proxy lock implementation ********************** +******************************************************************************/ + +/* +** Initialize the operating system interface. +** +** This routine registers all VFS implementations for unix-like operating +** systems. This routine, and the sqlite3_os_end() routine that follows, +** should be the only routines in this file that are visible from other +** files. +** +** This routine is called once during SQLite initialization and by a +** single thread. The memory allocation and mutex subsystems have not +** necessarily been initialized when this routine is called, and so they +** should not be used. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){ + /* + ** The following macro defines an initializer for an sqlite3_vfs object. + ** The name of the VFS is NAME. The pAppData is a pointer to a pointer + ** to the "finder" function. (pAppData is a pointer to a pointer because + ** silly C90 rules prohibit a void* from being cast to a function pointer + ** and so we have to go through the intermediate pointer to avoid problems + ** when compiling with -pedantic-errors on GCC.) + ** + ** The FINDER parameter to this macro is the name of the pointer to the + ** finder-function. The finder-function returns a pointer to the + ** sqlite_io_methods object that implements the desired locking + ** behaviors. See the division above that contains the IOMETHODS + ** macro for addition information on finder-functions. + ** + ** Most finders simply return a pointer to a fixed sqlite3_io_methods + ** object. But the "autolockIoFinder" available on MacOSX does a little + ** more than that; it looks at the filesystem type that hosts the + ** database file and tries to choose an locking method appropriate for + ** that filesystem time. + */ + #define UNIXVFS(VFSNAME, FINDER) { \ + 3, /* iVersion */ \ + sizeof(unixFile), /* szOsFile */ \ + MAX_PATHNAME, /* mxPathname */ \ + 0, /* pNext */ \ + VFSNAME, /* zName */ \ + (void*)&FINDER, /* pAppData */ \ + unixOpen, /* xOpen */ \ + unixDelete, /* xDelete */ \ + unixAccess, /* xAccess */ \ + unixFullPathname, /* xFullPathname */ \ + unixDlOpen, /* xDlOpen */ \ + unixDlError, /* xDlError */ \ + unixDlSym, /* xDlSym */ \ + unixDlClose, /* xDlClose */ \ + unixRandomness, /* xRandomness */ \ + unixSleep, /* xSleep */ \ + unixCurrentTime, /* xCurrentTime */ \ + unixGetLastError, /* xGetLastError */ \ + unixCurrentTimeInt64, /* xCurrentTimeInt64 */ \ + unixSetSystemCall, /* xSetSystemCall */ \ + unixGetSystemCall, /* xGetSystemCall */ \ + unixNextSystemCall, /* xNextSystemCall */ \ + } + + /* + ** All default VFSes for unix are contained in the following array. + ** + ** Note that the sqlite3_vfs.pNext field of the VFS object is modified + ** by the SQLite core when the VFS is registered. So the following + ** array cannot be const. + */ + static sqlite3_vfs aVfs[] = { +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) + UNIXVFS("unix", autolockIoFinder ), +#elif OS_VXWORKS + UNIXVFS("unix", vxworksIoFinder ), +#else + UNIXVFS("unix", posixIoFinder ), +#endif + UNIXVFS("unix-none", nolockIoFinder ), + UNIXVFS("unix-dotfile", dotlockIoFinder ), + UNIXVFS("unix-excl", posixIoFinder ), +#if OS_VXWORKS + UNIXVFS("unix-namedsem", semIoFinder ), +#endif +#if SQLITE_ENABLE_LOCKING_STYLE || OS_VXWORKS + UNIXVFS("unix-posix", posixIoFinder ), +#endif +#if SQLITE_ENABLE_LOCKING_STYLE + UNIXVFS("unix-flock", flockIoFinder ), +#endif +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) + UNIXVFS("unix-afp", afpIoFinder ), + UNIXVFS("unix-nfs", nfsIoFinder ), + UNIXVFS("unix-proxy", proxyIoFinder ), +#endif + }; + unsigned int i; /* Loop counter */ + + /* Double-check that the aSyscall[] array has been constructed + ** correctly. See ticket [bb3a86e890c8e96ab] */ + assert( ArraySize(aSyscall)==25 ); + + /* Register all VFSes defined in the aVfs[] array */ + for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ + sqlite3_vfs_register(&aVfs[i], i==0); + } + return SQLITE_OK; +} + +/* +** Shutdown the operating system interface. +** +** Some operating systems might need to do some cleanup in this routine, +** to release dynamically allocated objects. But not on unix. +** This routine is a no-op for unix. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void){ + return SQLITE_OK; +} + +#endif /* SQLITE_OS_UNIX */ + +/************** End of os_unix.c *********************************************/ +/************** Begin file os_win.c ******************************************/ +/* +** 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 file contains code that is specific to Windows. +*/ +#if SQLITE_OS_WIN /* This file is used for Windows only */ + +/* +** Include code that is common to all os_*.c files +*/ +/************** Include os_common.h in the middle of os_win.c ****************/ +/************** Begin file os_common.h ***************************************/ +/* +** 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 file contains macros and a little bit of code that is common to +** all of the platform-specific files (os_*.c) and is #included into those +** files. +** +** This file should be #included by the os_*.c files only. It is not a +** general purpose header file. +*/ +#ifndef _OS_COMMON_H_ +#define _OS_COMMON_H_ + +/* +** At least two bugs have slipped in because we changed the MEMORY_DEBUG +** macro to SQLITE_DEBUG and some older makefiles have not yet made the +** 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 + +/* +** Macros for performance tracing. Normally turned off. Only works +** on i486 hardware. +*/ +#ifdef SQLITE_PERFORMANCE_TRACE + +/* +** hwtime.h contains inline assembler code for implementing +** high-performance timing routines. +*/ +/************** Include hwtime.h in the middle of os_common.h ****************/ +/************** Begin file hwtime.h ******************************************/ +/* +** 2008 May 27 +** +** 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 inline asm code for retrieving "high-performance" +** counters for x86 class CPUs. +*/ +#ifndef _HWTIME_H_ +#define _HWTIME_H_ + +/* +** The following routine only works on pentium-class (or newer) processors. +** It uses the RDTSC opcode to read the cycle count value out of the +** processor and returns that value. This can be used for high-res +** profiling. +*/ +#if (defined(__GNUC__) || defined(_MSC_VER)) && \ + (defined(i386) || defined(__i386__) || defined(_M_IX86)) + + #if defined(__GNUC__) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned int lo, hi; + __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); + return (sqlite_uint64)hi << 32 | lo; + } + + #elif defined(_MSC_VER) + + __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ + __asm { + rdtsc + ret ; return value at EDX:EAX + } + } + + #endif + +#elif (defined(__GNUC__) && defined(__x86_64__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned long val; + __asm__ __volatile__ ("rdtsc" : "=A" (val)); + return val; + } + +#elif (defined(__GNUC__) && defined(__ppc__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned long long retval; + unsigned long junk; + __asm__ __volatile__ ("\n\ + 1: mftbu %1\n\ + mftb %L0\n\ + mftbu %0\n\ + cmpw %0,%1\n\ + bne 1b" + : "=r" (retval), "=r" (junk)); + return retval; + } + +#else + + #error Need implementation of sqlite3Hwtime() for your platform. + + /* + ** To compile without implementing sqlite3Hwtime() for your platform, + ** you can remove the above #error and use the following + ** stub function. You will lose timing support for many + ** of the debugging and testing utilities, but it should at + ** least compile and run. + */ +SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } + +#endif + +#endif /* !defined(_HWTIME_H_) */ + +/************** End of hwtime.h **********************************************/ +/************** Continuing where we left off in os_common.h ******************/ + +static sqlite_uint64 g_start; +static sqlite_uint64 g_elapsed; +#define TIMER_START g_start=sqlite3Hwtime() +#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start +#define TIMER_ELAPSED g_elapsed +#else +#define TIMER_START +#define TIMER_END +#define TIMER_ELAPSED ((sqlite_uint64)0) +#endif + +/* +** 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 +SQLITE_API int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */ +SQLITE_API int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */ +SQLITE_API int sqlite3_io_error_pending = 0; /* Count down to first I/O error */ +SQLITE_API int sqlite3_io_error_persist = 0; /* True if I/O errors persist */ +SQLITE_API int sqlite3_io_error_benign = 0; /* True if errors are benign */ +SQLITE_API int sqlite3_diskfull_pending = 0; +SQLITE_API int sqlite3_diskfull = 0; +#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) +#define SimulateIOError(CODE) \ + if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ + || sqlite3_io_error_pending-- == 1 ) \ + { local_ioerr(); CODE; } +static void local_ioerr(){ + IOTRACE(("IOERR\n")); + sqlite3_io_error_hit++; + if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; +} +#define SimulateDiskfullError(CODE) \ + if( sqlite3_diskfull_pending ){ \ + if( sqlite3_diskfull_pending == 1 ){ \ + local_ioerr(); \ + sqlite3_diskfull = 1; \ + sqlite3_io_error_hit = 1; \ + CODE; \ + }else{ \ + sqlite3_diskfull_pending--; \ + } \ + } +#else +#define SimulateIOErrorBenign(X) +#define SimulateIOError(A) +#define SimulateDiskfullError(A) +#endif + +/* +** When testing, keep a count of the number of open files. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_open_file_count = 0; +#define OpenCounter(X) sqlite3_open_file_count+=(X) +#else +#define OpenCounter(X) +#endif + +#endif /* !defined(_OS_COMMON_H_) */ + +/************** End of os_common.h *******************************************/ +/************** Continuing where we left off in os_win.c *********************/ + +/* +** Include the header file for the Windows VFS. +*/ + +/* +** Compiling and using WAL mode requires several APIs that are only +** available in Windows platforms based on the NT kernel. +*/ +#if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL) +# error "WAL mode requires support from the Windows NT kernel, compile\ + with SQLITE_OMIT_WAL." +#endif + +#if !SQLITE_OS_WINNT && SQLITE_MAX_MMAP_SIZE>0 +# error "Memory mapped files require support from the Windows NT kernel,\ + compile with SQLITE_MAX_MMAP_SIZE=0." +#endif + +/* +** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions +** based on the sub-platform)? +*/ +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(SQLITE_WIN32_NO_ANSI) +# define SQLITE_WIN32_HAS_ANSI +#endif + +/* +** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions +** based on the sub-platform)? +*/ +#if (SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT) && \ + !defined(SQLITE_WIN32_NO_WIDE) +# define SQLITE_WIN32_HAS_WIDE +#endif + +/* +** Make sure at least one set of Win32 APIs is available. +*/ +#if !defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_WIN32_HAS_WIDE) +# error "At least one of SQLITE_WIN32_HAS_ANSI and SQLITE_WIN32_HAS_WIDE\ + must be defined." +#endif + +/* +** Define the required Windows SDK version constants if they are not +** already available. +*/ +#ifndef NTDDI_WIN8 +# define NTDDI_WIN8 0x06020000 +#endif + +#ifndef NTDDI_WINBLUE +# define NTDDI_WINBLUE 0x06030000 +#endif + +/* +** Check to see if the GetVersionEx[AW] functions are deprecated on the +** target system. GetVersionEx was first deprecated in Win8.1. +*/ +#ifndef SQLITE_WIN32_GETVERSIONEX +# if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINBLUE +# define SQLITE_WIN32_GETVERSIONEX 0 /* GetVersionEx() is deprecated */ +# else +# define SQLITE_WIN32_GETVERSIONEX 1 /* GetVersionEx() is current */ +# endif +#endif + +/* +** This constant should already be defined (in the "WinDef.h" SDK file). +*/ +#ifndef MAX_PATH +# define MAX_PATH (260) +#endif + +/* +** Maximum pathname length (in chars) for Win32. This should normally be +** MAX_PATH. +*/ +#ifndef SQLITE_WIN32_MAX_PATH_CHARS +# define SQLITE_WIN32_MAX_PATH_CHARS (MAX_PATH) +#endif + +/* +** This constant should already be defined (in the "WinNT.h" SDK file). +*/ +#ifndef UNICODE_STRING_MAX_CHARS +# define UNICODE_STRING_MAX_CHARS (32767) +#endif + +/* +** Maximum pathname length (in chars) for WinNT. This should normally be +** UNICODE_STRING_MAX_CHARS. +*/ +#ifndef SQLITE_WINNT_MAX_PATH_CHARS +# define SQLITE_WINNT_MAX_PATH_CHARS (UNICODE_STRING_MAX_CHARS) +#endif + +/* +** Maximum pathname length (in bytes) for Win32. The MAX_PATH macro is in +** characters, so we allocate 4 bytes per character assuming worst-case of +** 4-bytes-per-character for UTF8. +*/ +#ifndef SQLITE_WIN32_MAX_PATH_BYTES +# define SQLITE_WIN32_MAX_PATH_BYTES (SQLITE_WIN32_MAX_PATH_CHARS*4) +#endif + +/* +** Maximum pathname length (in bytes) for WinNT. This should normally be +** UNICODE_STRING_MAX_CHARS * sizeof(WCHAR). +*/ +#ifndef SQLITE_WINNT_MAX_PATH_BYTES +# define SQLITE_WINNT_MAX_PATH_BYTES \ + (sizeof(WCHAR) * SQLITE_WINNT_MAX_PATH_CHARS) +#endif + +/* +** Maximum error message length (in chars) for WinRT. +*/ +#ifndef SQLITE_WIN32_MAX_ERRMSG_CHARS +# define SQLITE_WIN32_MAX_ERRMSG_CHARS (1024) +#endif + +/* +** Returns non-zero if the character should be treated as a directory +** separator. +*/ +#ifndef winIsDirSep +# define winIsDirSep(a) (((a) == '/') || ((a) == '\\')) +#endif + +/* +** This macro is used when a local variable is set to a value that is +** [sometimes] not used by the code (e.g. via conditional compilation). +*/ +#ifndef UNUSED_VARIABLE_VALUE +# define UNUSED_VARIABLE_VALUE(x) (void)(x) +#endif + +/* +** Returns the character that should be used as the directory separator. +*/ +#ifndef winGetDirSep +# define winGetDirSep() '\\' +#endif + +/* +** Do we need to manually define the Win32 file mapping APIs for use with WAL +** mode or memory mapped files (e.g. these APIs are available in the Windows +** CE SDK; however, they are not present in the header file)? +*/ +#if SQLITE_WIN32_FILEMAPPING_API && \ + (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) +/* +** Two of the file mapping APIs are different under WinRT. Figure out which +** set we need. +*/ +#if SQLITE_OS_WINRT +WINBASEAPI HANDLE WINAPI CreateFileMappingFromApp(HANDLE, \ + LPSECURITY_ATTRIBUTES, ULONG, ULONG64, LPCWSTR); + +WINBASEAPI LPVOID WINAPI MapViewOfFileFromApp(HANDLE, ULONG, ULONG64, SIZE_T); +#else +#if defined(SQLITE_WIN32_HAS_ANSI) +WINBASEAPI HANDLE WINAPI CreateFileMappingA(HANDLE, LPSECURITY_ATTRIBUTES, \ + DWORD, DWORD, DWORD, LPCSTR); +#endif /* defined(SQLITE_WIN32_HAS_ANSI) */ + +#if defined(SQLITE_WIN32_HAS_WIDE) +WINBASEAPI HANDLE WINAPI CreateFileMappingW(HANDLE, LPSECURITY_ATTRIBUTES, \ + DWORD, DWORD, DWORD, LPCWSTR); +#endif /* defined(SQLITE_WIN32_HAS_WIDE) */ + +WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T); +#endif /* SQLITE_OS_WINRT */ + +/* +** These file mapping APIs are common to both Win32 and WinRT. +*/ + +WINBASEAPI BOOL WINAPI FlushViewOfFile(LPCVOID, SIZE_T); +WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID); +#endif /* SQLITE_WIN32_FILEMAPPING_API */ + +/* +** Some Microsoft compilers lack this definition. +*/ +#ifndef INVALID_FILE_ATTRIBUTES +# define INVALID_FILE_ATTRIBUTES ((DWORD)-1) +#endif + +#ifndef FILE_FLAG_MASK +# define FILE_FLAG_MASK (0xFF3C0000) +#endif + +#ifndef FILE_ATTRIBUTE_MASK +# define FILE_ATTRIBUTE_MASK (0x0003FFF7) +#endif + +#ifndef SQLITE_OMIT_WAL +/* Forward references to structures used for WAL */ +typedef struct winShm winShm; /* A connection to shared-memory */ +typedef struct winShmNode winShmNode; /* A region of shared-memory */ +#endif + +/* +** WinCE lacks native support for file locking so we have to fake it +** with some code of our own. +*/ +#if SQLITE_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 sqlite3_file* specific to the win32 +** portability layer. +*/ +typedef struct winFile winFile; +struct winFile { + const sqlite3_io_methods *pMethod; /*** Must be first ***/ + sqlite3_vfs *pVfs; /* The VFS used to open this file */ + HANDLE h; /* Handle for accessing the file */ + u8 locktype; /* Type of lock currently held on this file */ + short sharedLockByte; /* Randomly chosen byte used as a shared lock */ + u8 ctrlFlags; /* Flags. See WINFILE_* below */ + DWORD lastErrno; /* The Windows errno from the last I/O error */ +#ifndef SQLITE_OMIT_WAL + winShm *pShm; /* Instance of shared memory on this file */ +#endif + const char *zPath; /* Full pathname of this file */ + int szChunk; /* Chunk size configured by FCNTL_CHUNK_SIZE */ +#if SQLITE_OS_WINCE + LPWSTR 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 +#if SQLITE_MAX_MMAP_SIZE>0 + int nFetchOut; /* Number of outstanding xFetch references */ + HANDLE hMap; /* Handle for accessing memory mapping */ + void *pMapRegion; /* Area memory mapped */ + sqlite3_int64 mmapSize; /* Usable size of mapped region */ + sqlite3_int64 mmapSizeActual; /* Actual size of mapped region */ + sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ +#endif +}; + +/* +** Allowed values for winFile.ctrlFlags +*/ +#define WINFILE_RDONLY 0x02 /* Connection is read only */ +#define WINFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ +#define WINFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ + +/* + * The size of the buffer used by sqlite3_win32_write_debug(). + */ +#ifndef SQLITE_WIN32_DBG_BUF_SIZE +# define SQLITE_WIN32_DBG_BUF_SIZE ((int)(4096-sizeof(DWORD))) +#endif + +/* + * The value used with sqlite3_win32_set_directory() to specify that + * the data directory should be changed. + */ +#ifndef SQLITE_WIN32_DATA_DIRECTORY_TYPE +# define SQLITE_WIN32_DATA_DIRECTORY_TYPE (1) +#endif + +/* + * The value used with sqlite3_win32_set_directory() to specify that + * the temporary directory should be changed. + */ +#ifndef SQLITE_WIN32_TEMP_DIRECTORY_TYPE +# define SQLITE_WIN32_TEMP_DIRECTORY_TYPE (2) +#endif + +/* + * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the + * various Win32 API heap functions instead of our own. + */ +#ifdef SQLITE_WIN32_MALLOC + +/* + * If this is non-zero, an isolated heap will be created by the native Win32 + * allocator subsystem; otherwise, the default process heap will be used. This + * setting has no effect when compiling for WinRT. By default, this is enabled + * and an isolated heap will be created to store all allocated data. + * + ****************************************************************************** + * WARNING: It is important to note that when this setting is non-zero and the + * winMemShutdown function is called (e.g. by the sqlite3_shutdown + * function), all data that was allocated using the isolated heap will + * be freed immediately and any attempt to access any of that freed + * data will almost certainly result in an immediate access violation. + ****************************************************************************** + */ +#ifndef SQLITE_WIN32_HEAP_CREATE +# define SQLITE_WIN32_HEAP_CREATE (TRUE) +#endif + +/* + * The initial size of the Win32-specific heap. This value may be zero. + */ +#ifndef SQLITE_WIN32_HEAP_INIT_SIZE +# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_DEFAULT_CACHE_SIZE) * \ + (SQLITE_DEFAULT_PAGE_SIZE) + 4194304) +#endif + +/* + * The maximum size of the Win32-specific heap. This value may be zero. + */ +#ifndef SQLITE_WIN32_HEAP_MAX_SIZE +# define SQLITE_WIN32_HEAP_MAX_SIZE (0) +#endif + +/* + * The extra flags to use in calls to the Win32 heap APIs. This value may be + * zero for the default behavior. + */ +#ifndef SQLITE_WIN32_HEAP_FLAGS +# define SQLITE_WIN32_HEAP_FLAGS (0) +#endif + + +/* +** The winMemData structure stores information required by the Win32-specific +** sqlite3_mem_methods implementation. +*/ +typedef struct winMemData winMemData; +struct winMemData { +#ifndef NDEBUG + u32 magic1; /* Magic number to detect structure corruption. */ +#endif + HANDLE hHeap; /* The handle to our heap. */ + BOOL bOwned; /* Do we own the heap (i.e. destroy it on shutdown)? */ +#ifndef NDEBUG + u32 magic2; /* Magic number to detect structure corruption. */ +#endif +}; + +#ifndef NDEBUG +#define WINMEM_MAGIC1 0x42b2830b +#define WINMEM_MAGIC2 0xbd4d7cf4 +#endif + +static struct winMemData win_mem_data = { +#ifndef NDEBUG + WINMEM_MAGIC1, +#endif + NULL, FALSE +#ifndef NDEBUG + ,WINMEM_MAGIC2 +#endif +}; + +#ifndef NDEBUG +#define winMemAssertMagic1() assert( win_mem_data.magic1==WINMEM_MAGIC1 ) +#define winMemAssertMagic2() assert( win_mem_data.magic2==WINMEM_MAGIC2 ) +#define winMemAssertMagic() winMemAssertMagic1(); winMemAssertMagic2(); +#else +#define winMemAssertMagic() +#endif + +#define winMemGetDataPtr() &win_mem_data +#define winMemGetHeap() win_mem_data.hHeap +#define winMemGetOwned() win_mem_data.bOwned + +static void *winMemMalloc(int nBytes); +static void winMemFree(void *pPrior); +static void *winMemRealloc(void *pPrior, int nBytes); +static int winMemSize(void *p); +static int winMemRoundup(int n); +static int winMemInit(void *pAppData); +static void winMemShutdown(void *pAppData); + +SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void); +#endif /* SQLITE_WIN32_MALLOC */ + +/* +** The following variable is (normally) set once and never changes +** thereafter. It records whether the operating system is Win9x +** or WinNT. +** +** 0: Operating system unknown. +** 1: Operating system is Win9x. +** 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. +*/ +#ifdef SQLITE_TEST +SQLITE_API LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; +#else +static LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; +#endif + +#ifndef SYSCALL +# define SYSCALL sqlite3_syscall_ptr +#endif + +/* +** This function is not available on Windows CE or WinRT. + */ + +#if SQLITE_OS_WINCE || SQLITE_OS_WINRT +# define osAreFileApisANSI() 1 +#endif + +/* +** Many system calls are accessed through pointer-to-functions so that +** they may be overridden at runtime to facilitate fault injection during +** testing and sandboxing. The following array holds the names and pointers +** to all overrideable system calls. +*/ +static struct win_syscall { + const char *zName; /* Name of the system call */ + sqlite3_syscall_ptr pCurrent; /* Current value of the system call */ + sqlite3_syscall_ptr pDefault; /* Default value */ +} aSyscall[] = { +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT + { "AreFileApisANSI", (SYSCALL)AreFileApisANSI, 0 }, +#else + { "AreFileApisANSI", (SYSCALL)0, 0 }, +#endif + +#ifndef osAreFileApisANSI +#define osAreFileApisANSI ((BOOL(WINAPI*)(VOID))aSyscall[0].pCurrent) +#endif + +#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) + { "CharLowerW", (SYSCALL)CharLowerW, 0 }, +#else + { "CharLowerW", (SYSCALL)0, 0 }, +#endif + +#define osCharLowerW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[1].pCurrent) + +#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) + { "CharUpperW", (SYSCALL)CharUpperW, 0 }, +#else + { "CharUpperW", (SYSCALL)0, 0 }, +#endif + +#define osCharUpperW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[2].pCurrent) + + { "CloseHandle", (SYSCALL)CloseHandle, 0 }, + +#define osCloseHandle ((BOOL(WINAPI*)(HANDLE))aSyscall[3].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "CreateFileA", (SYSCALL)CreateFileA, 0 }, +#else + { "CreateFileA", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \ + LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent) + +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) + { "CreateFileW", (SYSCALL)CreateFileW, 0 }, +#else + { "CreateFileW", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \ + LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent) + +#if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \ + (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)) + { "CreateFileMappingA", (SYSCALL)CreateFileMappingA, 0 }, +#else + { "CreateFileMappingA", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ + DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent) + +#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ + (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)) + { "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 }, +#else + { "CreateFileMappingW", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ + DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent) + +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) + { "CreateMutexW", (SYSCALL)CreateMutexW, 0 }, +#else + { "CreateMutexW", (SYSCALL)0, 0 }, +#endif + +#define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \ + LPCWSTR))aSyscall[8].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "DeleteFileA", (SYSCALL)DeleteFileA, 0 }, +#else + { "DeleteFileA", (SYSCALL)0, 0 }, +#endif + +#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "DeleteFileW", (SYSCALL)DeleteFileW, 0 }, +#else + { "DeleteFileW", (SYSCALL)0, 0 }, +#endif + +#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent) + +#if SQLITE_OS_WINCE + { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 }, +#else + { "FileTimeToLocalFileTime", (SYSCALL)0, 0 }, +#endif + +#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \ + LPFILETIME))aSyscall[11].pCurrent) + +#if SQLITE_OS_WINCE + { "FileTimeToSystemTime", (SYSCALL)FileTimeToSystemTime, 0 }, +#else + { "FileTimeToSystemTime", (SYSCALL)0, 0 }, +#endif + +#define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \ + LPSYSTEMTIME))aSyscall[12].pCurrent) + + { "FlushFileBuffers", (SYSCALL)FlushFileBuffers, 0 }, + +#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "FormatMessageA", (SYSCALL)FormatMessageA, 0 }, +#else + { "FormatMessageA", (SYSCALL)0, 0 }, +#endif + +#define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \ + DWORD,va_list*))aSyscall[14].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "FormatMessageW", (SYSCALL)FormatMessageW, 0 }, +#else + { "FormatMessageW", (SYSCALL)0, 0 }, +#endif + +#define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \ + DWORD,va_list*))aSyscall[15].pCurrent) + +#if !defined(SQLITE_OMIT_LOAD_EXTENSION) + { "FreeLibrary", (SYSCALL)FreeLibrary, 0 }, +#else + { "FreeLibrary", (SYSCALL)0, 0 }, +#endif + +#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent) + + { "GetCurrentProcessId", (SYSCALL)GetCurrentProcessId, 0 }, + +#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].pCurrent) + +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI) + { "GetDiskFreeSpaceA", (SYSCALL)GetDiskFreeSpaceA, 0 }, +#else + { "GetDiskFreeSpaceA", (SYSCALL)0, 0 }, +#endif + +#define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \ + LPDWORD))aSyscall[18].pCurrent) + +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) + { "GetDiskFreeSpaceW", (SYSCALL)GetDiskFreeSpaceW, 0 }, +#else + { "GetDiskFreeSpaceW", (SYSCALL)0, 0 }, +#endif + +#define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \ + LPDWORD))aSyscall[19].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "GetFileAttributesA", (SYSCALL)GetFileAttributesA, 0 }, +#else + { "GetFileAttributesA", (SYSCALL)0, 0 }, +#endif + +#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent) + +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) + { "GetFileAttributesW", (SYSCALL)GetFileAttributesW, 0 }, +#else + { "GetFileAttributesW", (SYSCALL)0, 0 }, +#endif + +#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "GetFileAttributesExW", (SYSCALL)GetFileAttributesExW, 0 }, +#else + { "GetFileAttributesExW", (SYSCALL)0, 0 }, +#endif + +#define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \ + LPVOID))aSyscall[22].pCurrent) + +#if !SQLITE_OS_WINRT + { "GetFileSize", (SYSCALL)GetFileSize, 0 }, +#else + { "GetFileSize", (SYSCALL)0, 0 }, +#endif + +#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[23].pCurrent) + +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI) + { "GetFullPathNameA", (SYSCALL)GetFullPathNameA, 0 }, +#else + { "GetFullPathNameA", (SYSCALL)0, 0 }, +#endif + +#define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \ + LPSTR*))aSyscall[24].pCurrent) + +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) + { "GetFullPathNameW", (SYSCALL)GetFullPathNameW, 0 }, +#else + { "GetFullPathNameW", (SYSCALL)0, 0 }, +#endif + +#define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \ + LPWSTR*))aSyscall[25].pCurrent) + + { "GetLastError", (SYSCALL)GetLastError, 0 }, + +#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent) + +#if !defined(SQLITE_OMIT_LOAD_EXTENSION) +#if SQLITE_OS_WINCE + /* The GetProcAddressA() routine is only available on Windows CE. */ + { "GetProcAddressA", (SYSCALL)GetProcAddressA, 0 }, +#else + /* All other Windows platforms expect GetProcAddress() to take + ** an ANSI string regardless of the _UNICODE setting */ + { "GetProcAddressA", (SYSCALL)GetProcAddress, 0 }, +#endif +#else + { "GetProcAddressA", (SYSCALL)0, 0 }, +#endif + +#define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \ + LPCSTR))aSyscall[27].pCurrent) + +#if !SQLITE_OS_WINRT + { "GetSystemInfo", (SYSCALL)GetSystemInfo, 0 }, +#else + { "GetSystemInfo", (SYSCALL)0, 0 }, +#endif + +#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[28].pCurrent) + + { "GetSystemTime", (SYSCALL)GetSystemTime, 0 }, + +#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[29].pCurrent) + +#if !SQLITE_OS_WINCE + { "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 }, +#else + { "GetSystemTimeAsFileTime", (SYSCALL)0, 0 }, +#endif + +#define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \ + LPFILETIME))aSyscall[30].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "GetTempPathA", (SYSCALL)GetTempPathA, 0 }, +#else + { "GetTempPathA", (SYSCALL)0, 0 }, +#endif + +#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent) + +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) + { "GetTempPathW", (SYSCALL)GetTempPathW, 0 }, +#else + { "GetTempPathW", (SYSCALL)0, 0 }, +#endif + +#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].pCurrent) + +#if !SQLITE_OS_WINRT + { "GetTickCount", (SYSCALL)GetTickCount, 0 }, +#else + { "GetTickCount", (SYSCALL)0, 0 }, +#endif + +#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_GETVERSIONEX) && \ + SQLITE_WIN32_GETVERSIONEX + { "GetVersionExA", (SYSCALL)GetVersionExA, 0 }, +#else + { "GetVersionExA", (SYSCALL)0, 0 }, +#endif + +#define osGetVersionExA ((BOOL(WINAPI*)( \ + LPOSVERSIONINFOA))aSyscall[34].pCurrent) + +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ + defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX + { "GetVersionExW", (SYSCALL)GetVersionExW, 0 }, +#else + { "GetVersionExW", (SYSCALL)0, 0 }, +#endif + +#define osGetVersionExW ((BOOL(WINAPI*)( \ + LPOSVERSIONINFOW))aSyscall[35].pCurrent) + + { "HeapAlloc", (SYSCALL)HeapAlloc, 0 }, + +#define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \ + SIZE_T))aSyscall[36].pCurrent) + +#if !SQLITE_OS_WINRT + { "HeapCreate", (SYSCALL)HeapCreate, 0 }, +#else + { "HeapCreate", (SYSCALL)0, 0 }, +#endif + +#define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \ + SIZE_T))aSyscall[37].pCurrent) + +#if !SQLITE_OS_WINRT + { "HeapDestroy", (SYSCALL)HeapDestroy, 0 }, +#else + { "HeapDestroy", (SYSCALL)0, 0 }, +#endif + +#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[38].pCurrent) + + { "HeapFree", (SYSCALL)HeapFree, 0 }, + +#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[39].pCurrent) + + { "HeapReAlloc", (SYSCALL)HeapReAlloc, 0 }, + +#define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \ + SIZE_T))aSyscall[40].pCurrent) + + { "HeapSize", (SYSCALL)HeapSize, 0 }, + +#define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \ + LPCVOID))aSyscall[41].pCurrent) + +#if !SQLITE_OS_WINRT + { "HeapValidate", (SYSCALL)HeapValidate, 0 }, +#else + { "HeapValidate", (SYSCALL)0, 0 }, +#endif + +#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \ + LPCVOID))aSyscall[42].pCurrent) + +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT + { "HeapCompact", (SYSCALL)HeapCompact, 0 }, +#else + { "HeapCompact", (SYSCALL)0, 0 }, +#endif + +#define osHeapCompact ((UINT(WINAPI*)(HANDLE,DWORD))aSyscall[43].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION) + { "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 }, +#else + { "LoadLibraryA", (SYSCALL)0, 0 }, +#endif + +#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[44].pCurrent) + +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ + !defined(SQLITE_OMIT_LOAD_EXTENSION) + { "LoadLibraryW", (SYSCALL)LoadLibraryW, 0 }, +#else + { "LoadLibraryW", (SYSCALL)0, 0 }, +#endif + +#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[45].pCurrent) + +#if !SQLITE_OS_WINRT + { "LocalFree", (SYSCALL)LocalFree, 0 }, +#else + { "LocalFree", (SYSCALL)0, 0 }, +#endif + +#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[46].pCurrent) + +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT + { "LockFile", (SYSCALL)LockFile, 0 }, +#else + { "LockFile", (SYSCALL)0, 0 }, +#endif + +#ifndef osLockFile +#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + DWORD))aSyscall[47].pCurrent) +#endif + +#if !SQLITE_OS_WINCE + { "LockFileEx", (SYSCALL)LockFileEx, 0 }, +#else + { "LockFileEx", (SYSCALL)0, 0 }, +#endif + +#ifndef osLockFileEx +#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \ + LPOVERLAPPED))aSyscall[48].pCurrent) +#endif + +#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && \ + (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)) + { "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 }, +#else + { "MapViewOfFile", (SYSCALL)0, 0 }, +#endif + +#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + SIZE_T))aSyscall[49].pCurrent) + + { "MultiByteToWideChar", (SYSCALL)MultiByteToWideChar, 0 }, + +#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \ + int))aSyscall[50].pCurrent) + + { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 }, + +#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \ + LARGE_INTEGER*))aSyscall[51].pCurrent) + + { "ReadFile", (SYSCALL)ReadFile, 0 }, + +#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \ + LPOVERLAPPED))aSyscall[52].pCurrent) + + { "SetEndOfFile", (SYSCALL)SetEndOfFile, 0 }, + +#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[53].pCurrent) + +#if !SQLITE_OS_WINRT + { "SetFilePointer", (SYSCALL)SetFilePointer, 0 }, +#else + { "SetFilePointer", (SYSCALL)0, 0 }, +#endif + +#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \ + DWORD))aSyscall[54].pCurrent) + +#if !SQLITE_OS_WINRT + { "Sleep", (SYSCALL)Sleep, 0 }, +#else + { "Sleep", (SYSCALL)0, 0 }, +#endif + +#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[55].pCurrent) + + { "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 }, + +#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \ + LPFILETIME))aSyscall[56].pCurrent) + +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT + { "UnlockFile", (SYSCALL)UnlockFile, 0 }, +#else + { "UnlockFile", (SYSCALL)0, 0 }, +#endif + +#ifndef osUnlockFile +#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + DWORD))aSyscall[57].pCurrent) +#endif + +#if !SQLITE_OS_WINCE + { "UnlockFileEx", (SYSCALL)UnlockFileEx, 0 }, +#else + { "UnlockFileEx", (SYSCALL)0, 0 }, +#endif + +#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + LPOVERLAPPED))aSyscall[58].pCurrent) + +#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 + { "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 }, +#else + { "UnmapViewOfFile", (SYSCALL)0, 0 }, +#endif + +#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[59].pCurrent) + + { "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 }, + +#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \ + LPCSTR,LPBOOL))aSyscall[60].pCurrent) + + { "WriteFile", (SYSCALL)WriteFile, 0 }, + +#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \ + LPOVERLAPPED))aSyscall[61].pCurrent) + +#if SQLITE_OS_WINRT + { "CreateEventExW", (SYSCALL)CreateEventExW, 0 }, +#else + { "CreateEventExW", (SYSCALL)0, 0 }, +#endif + +#define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \ + DWORD,DWORD))aSyscall[62].pCurrent) + +#if !SQLITE_OS_WINRT + { "WaitForSingleObject", (SYSCALL)WaitForSingleObject, 0 }, +#else + { "WaitForSingleObject", (SYSCALL)0, 0 }, +#endif + +#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \ + DWORD))aSyscall[63].pCurrent) + +#if !SQLITE_OS_WINCE + { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 }, +#else + { "WaitForSingleObjectEx", (SYSCALL)0, 0 }, +#endif + +#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \ + BOOL))aSyscall[64].pCurrent) + +#if SQLITE_OS_WINRT + { "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 }, +#else + { "SetFilePointerEx", (SYSCALL)0, 0 }, +#endif + +#define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \ + PLARGE_INTEGER,DWORD))aSyscall[65].pCurrent) + +#if SQLITE_OS_WINRT + { "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 }, +#else + { "GetFileInformationByHandleEx", (SYSCALL)0, 0 }, +#endif + +#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \ + FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent) + +#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) + { "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 }, +#else + { "MapViewOfFileFromApp", (SYSCALL)0, 0 }, +#endif + +#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \ + SIZE_T))aSyscall[67].pCurrent) + +#if SQLITE_OS_WINRT + { "CreateFile2", (SYSCALL)CreateFile2, 0 }, +#else + { "CreateFile2", (SYSCALL)0, 0 }, +#endif + +#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \ + LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[68].pCurrent) + +#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION) + { "LoadPackagedLibrary", (SYSCALL)LoadPackagedLibrary, 0 }, +#else + { "LoadPackagedLibrary", (SYSCALL)0, 0 }, +#endif + +#define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \ + DWORD))aSyscall[69].pCurrent) + +#if SQLITE_OS_WINRT + { "GetTickCount64", (SYSCALL)GetTickCount64, 0 }, +#else + { "GetTickCount64", (SYSCALL)0, 0 }, +#endif + +#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[70].pCurrent) + +#if SQLITE_OS_WINRT + { "GetNativeSystemInfo", (SYSCALL)GetNativeSystemInfo, 0 }, +#else + { "GetNativeSystemInfo", (SYSCALL)0, 0 }, +#endif + +#define osGetNativeSystemInfo ((VOID(WINAPI*)( \ + LPSYSTEM_INFO))aSyscall[71].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "OutputDebugStringA", (SYSCALL)OutputDebugStringA, 0 }, +#else + { "OutputDebugStringA", (SYSCALL)0, 0 }, +#endif + +#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[72].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "OutputDebugStringW", (SYSCALL)OutputDebugStringW, 0 }, +#else + { "OutputDebugStringW", (SYSCALL)0, 0 }, +#endif + +#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[73].pCurrent) + + { "GetProcessHeap", (SYSCALL)GetProcessHeap, 0 }, + +#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[74].pCurrent) + +#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) + { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 }, +#else + { "CreateFileMappingFromApp", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \ + LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent) + +/* +** NOTE: On some sub-platforms, the InterlockedCompareExchange "function" +** is really just a macro that uses a compiler intrinsic (e.g. x64). +** So do not try to make this is into a redefinable interface. +*/ +#if defined(InterlockedCompareExchange) + { "InterlockedCompareExchange", (SYSCALL)0, 0 }, + +#define osInterlockedCompareExchange InterlockedCompareExchange +#else + { "InterlockedCompareExchange", (SYSCALL)InterlockedCompareExchange, 0 }, + +#define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG \ + SQLITE_WIN32_VOLATILE*, LONG,LONG))aSyscall[76].pCurrent) +#endif /* defined(InterlockedCompareExchange) */ + +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID + { "UuidCreate", (SYSCALL)UuidCreate, 0 }, +#else + { "UuidCreate", (SYSCALL)0, 0 }, +#endif + +#define osUuidCreate ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[77].pCurrent) + +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID + { "UuidCreateSequential", (SYSCALL)UuidCreateSequential, 0 }, +#else + { "UuidCreateSequential", (SYSCALL)0, 0 }, +#endif + +#define osUuidCreateSequential \ + ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[78].pCurrent) + +#if !defined(SQLITE_NO_SYNC) && SQLITE_MAX_MMAP_SIZE>0 + { "FlushViewOfFile", (SYSCALL)FlushViewOfFile, 0 }, +#else + { "FlushViewOfFile", (SYSCALL)0, 0 }, +#endif + +#define osFlushViewOfFile \ + ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent) + +}; /* End of the overrideable system calls */ + +/* +** This is the xSetSystemCall() method of sqlite3_vfs for all of the +** "win32" VFSes. Return SQLITE_OK opon successfully updating the +** system call pointer, or SQLITE_NOTFOUND if there is no configurable +** system call named zName. +*/ +static int winSetSystemCall( + sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */ + const char *zName, /* Name of system call to override */ + sqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */ +){ + unsigned int i; + int rc = SQLITE_NOTFOUND; + + UNUSED_PARAMETER(pNotUsed); + if( zName==0 ){ + /* If no zName is given, restore all system calls to their default + ** settings and return NULL + */ + rc = SQLITE_OK; + for(i=0; i0 ){ + memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE); + memcpy(zDbgBuf, zBuf, nMin); + osOutputDebugStringA(zDbgBuf); + }else{ + osOutputDebugStringA(zBuf); + } +#elif defined(SQLITE_WIN32_HAS_WIDE) + memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE); + if ( osMultiByteToWideChar( + osAreFileApisANSI() ? CP_ACP : CP_OEMCP, 0, zBuf, + nMin, (LPWSTR)zDbgBuf, SQLITE_WIN32_DBG_BUF_SIZE/sizeof(WCHAR))<=0 ){ + return; + } + osOutputDebugStringW((LPCWSTR)zDbgBuf); +#else + if( nMin>0 ){ + memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE); + memcpy(zDbgBuf, zBuf, nMin); + fprintf(stderr, "%s", zDbgBuf); + }else{ + fprintf(stderr, "%s", zBuf); + } +#endif +} + +/* +** The following routine suspends the current thread for at least ms +** milliseconds. This is equivalent to the Win32 Sleep() interface. +*/ +#if SQLITE_OS_WINRT +static HANDLE sleepObj = NULL; +#endif + +SQLITE_API void SQLITE_STDCALL sqlite3_win32_sleep(DWORD milliseconds){ +#if SQLITE_OS_WINRT + if ( sleepObj==NULL ){ + sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET, + SYNCHRONIZE); + } + assert( sleepObj!=NULL ); + osWaitForSingleObjectEx(sleepObj, milliseconds, FALSE); +#else + osSleep(milliseconds); +#endif +} + +#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \ + SQLITE_THREADSAFE>0 +SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){ + DWORD rc; + while( (rc = osWaitForSingleObjectEx(hObject, INFINITE, + TRUE))==WAIT_IO_COMPLETION ){} + return rc; +} +#endif + +/* +** 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 when 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 !defined(SQLITE_WIN32_GETVERSIONEX) || !SQLITE_WIN32_GETVERSIONEX +# define osIsNT() (1) +#elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) +# define osIsNT() (1) +#elif !defined(SQLITE_WIN32_HAS_WIDE) +# define osIsNT() (0) +#else +# define osIsNT() ((sqlite3_os_type==2) || sqlite3_win32_is_nt()) +#endif + +/* +** This function determines if the machine is running a version of Windows +** based on the NT kernel. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_win32_is_nt(void){ +#if SQLITE_OS_WINRT + /* + ** NOTE: The WinRT sub-platform is always assumed to be based on the NT + ** kernel. + */ + return 1; +#elif defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX + if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){ +#if defined(SQLITE_WIN32_HAS_ANSI) + OSVERSIONINFOA sInfo; + sInfo.dwOSVersionInfoSize = sizeof(sInfo); + osGetVersionExA(&sInfo); + osInterlockedCompareExchange(&sqlite3_os_type, + (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); +#elif defined(SQLITE_WIN32_HAS_WIDE) + OSVERSIONINFOW sInfo; + sInfo.dwOSVersionInfoSize = sizeof(sInfo); + osGetVersionExW(&sInfo); + osInterlockedCompareExchange(&sqlite3_os_type, + (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); +#endif + } + return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; +#elif SQLITE_TEST + return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; +#else + /* + ** NOTE: All sub-platforms where the GetVersionEx[AW] functions are + ** deprecated are always assumed to be based on the NT kernel. + */ + return 1; +#endif +} + +#ifdef SQLITE_WIN32_MALLOC +/* +** Allocate nBytes of memory. +*/ +static void *winMemMalloc(int nBytes){ + HANDLE hHeap; + void *p; + + winMemAssertMagic(); + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); +#endif + assert( nBytes>=0 ); + p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); + if( !p ){ + sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%lu), heap=%p", + nBytes, osGetLastError(), (void*)hHeap); + } + return p; +} + +/* +** Free memory. +*/ +static void winMemFree(void *pPrior){ + HANDLE hHeap; + + winMemAssertMagic(); + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); +#endif + if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */ + if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){ + sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%lu), heap=%p", + pPrior, osGetLastError(), (void*)hHeap); + } +} + +/* +** Change the size of an existing memory allocation +*/ +static void *winMemRealloc(void *pPrior, int nBytes){ + HANDLE hHeap; + void *p; + + winMemAssertMagic(); + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); +#endif + assert( nBytes>=0 ); + if( !pPrior ){ + p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); + }else{ + p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes); + } + if( !p ){ + sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%lu), heap=%p", + pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, osGetLastError(), + (void*)hHeap); + } + return p; +} + +/* +** Return the size of an outstanding allocation, in bytes. +*/ +static int winMemSize(void *p){ + HANDLE hHeap; + SIZE_T n; + + winMemAssertMagic(); + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, p) ); +#endif + if( !p ) return 0; + n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p); + if( n==(SIZE_T)-1 ){ + sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%lu), heap=%p", + p, osGetLastError(), (void*)hHeap); + return 0; + } + return (int)n; +} + +/* +** Round up a request size to the next valid allocation size. +*/ +static int winMemRoundup(int n){ + return n; +} + +/* +** Initialize this module. +*/ +static int winMemInit(void *pAppData){ + winMemData *pWinMemData = (winMemData *)pAppData; + + if( !pWinMemData ) return SQLITE_ERROR; + assert( pWinMemData->magic1==WINMEM_MAGIC1 ); + assert( pWinMemData->magic2==WINMEM_MAGIC2 ); + +#if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE + if( !pWinMemData->hHeap ){ + DWORD dwInitialSize = SQLITE_WIN32_HEAP_INIT_SIZE; + DWORD dwMaximumSize = (DWORD)sqlite3GlobalConfig.nHeap; + if( dwMaximumSize==0 ){ + dwMaximumSize = SQLITE_WIN32_HEAP_MAX_SIZE; + }else if( dwInitialSize>dwMaximumSize ){ + dwInitialSize = dwMaximumSize; + } + pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS, + dwInitialSize, dwMaximumSize); + if( !pWinMemData->hHeap ){ + sqlite3_log(SQLITE_NOMEM, + "failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu", + osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize, + dwMaximumSize); + return SQLITE_NOMEM; + } + pWinMemData->bOwned = TRUE; + assert( pWinMemData->bOwned ); + } +#else + pWinMemData->hHeap = osGetProcessHeap(); + if( !pWinMemData->hHeap ){ + sqlite3_log(SQLITE_NOMEM, + "failed to GetProcessHeap (%lu)", osGetLastError()); + return SQLITE_NOMEM; + } + pWinMemData->bOwned = FALSE; + assert( !pWinMemData->bOwned ); +#endif + assert( pWinMemData->hHeap!=0 ); + assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); +#endif + return SQLITE_OK; +} + +/* +** Deinitialize this module. +*/ +static void winMemShutdown(void *pAppData){ + winMemData *pWinMemData = (winMemData *)pAppData; + + if( !pWinMemData ) return; + assert( pWinMemData->magic1==WINMEM_MAGIC1 ); + assert( pWinMemData->magic2==WINMEM_MAGIC2 ); + + if( pWinMemData->hHeap ){ + assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); +#endif + if( pWinMemData->bOwned ){ + if( !osHeapDestroy(pWinMemData->hHeap) ){ + sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%lu), heap=%p", + osGetLastError(), (void*)pWinMemData->hHeap); + } + pWinMemData->bOwned = FALSE; + } + pWinMemData->hHeap = NULL; + } +} + +/* +** Populate the low-level memory allocation function pointers in +** sqlite3GlobalConfig.m with pointers to the routines in this file. The +** arguments specify the block of memory to manage. +** +** This routine is only called by sqlite3_config(), and therefore +** is not required to be threadsafe (it is not). +*/ +SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void){ + static const sqlite3_mem_methods winMemMethods = { + winMemMalloc, + winMemFree, + winMemRealloc, + winMemSize, + winMemRoundup, + winMemInit, + winMemShutdown, + &win_mem_data + }; + return &winMemMethods; +} + +SQLITE_PRIVATE void sqlite3MemSetDefault(void){ + sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetWin32()); +} +#endif /* SQLITE_WIN32_MALLOC */ + +/* +** Convert a UTF-8 string to Microsoft Unicode (UTF-16?). +** +** Space to hold the returned string is obtained from malloc. +*/ +static LPWSTR winUtf8ToUnicode(const char *zFilename){ + int nChar; + LPWSTR zWideFilename; + + nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); + if( nChar==0 ){ + return 0; + } + zWideFilename = sqlite3MallocZero( nChar*sizeof(zWideFilename[0]) ); + if( zWideFilename==0 ){ + return 0; + } + nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, + nChar); + if( nChar==0 ){ + sqlite3_free(zWideFilename); + zWideFilename = 0; + } + return zWideFilename; +} + +/* +** Convert Microsoft Unicode to UTF-8. Space to hold the returned string is +** obtained from sqlite3_malloc(). +*/ +static char *winUnicodeToUtf8(LPCWSTR zWideFilename){ + int nByte; + char *zFilename; + + nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0); + if( nByte == 0 ){ + return 0; + } + zFilename = sqlite3MallocZero( nByte ); + if( zFilename==0 ){ + return 0; + } + nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte, + 0, 0); + if( nByte == 0 ){ + sqlite3_free(zFilename); + zFilename = 0; + } + return zFilename; +} + +/* +** Convert an ANSI string to Microsoft Unicode, based on the +** current codepage settings for file apis. +** +** Space to hold the returned string is obtained +** from sqlite3_malloc. +*/ +static LPWSTR winMbcsToUnicode(const char *zFilename){ + int nByte; + LPWSTR zMbcsFilename; + int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; + + nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL, + 0)*sizeof(WCHAR); + if( nByte==0 ){ + return 0; + } + zMbcsFilename = sqlite3MallocZero( nByte*sizeof(zMbcsFilename[0]) ); + if( zMbcsFilename==0 ){ + return 0; + } + nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, + nByte); + if( nByte==0 ){ + sqlite3_free(zMbcsFilename); + zMbcsFilename = 0; + } + return zMbcsFilename; +} + +/* +** Convert Microsoft Unicode to multi-byte character string, based on the +** user's ANSI codepage. +** +** Space to hold the returned string is obtained from +** sqlite3_malloc(). +*/ +static char *winUnicodeToMbcs(LPCWSTR zWideFilename){ + int nByte; + char *zFilename; + int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; + + nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0); + if( nByte == 0 ){ + return 0; + } + zFilename = sqlite3MallocZero( nByte ); + if( zFilename==0 ){ + return 0; + } + nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, + nByte, 0, 0); + if( nByte == 0 ){ + sqlite3_free(zFilename); + zFilename = 0; + } + return zFilename; +} + +/* +** Convert multibyte character string to UTF-8. Space to hold the +** returned string is obtained from sqlite3_malloc(). +*/ +SQLITE_API char *SQLITE_STDCALL sqlite3_win32_mbcs_to_utf8(const char *zFilename){ + char *zFilenameUtf8; + LPWSTR zTmpWide; + + zTmpWide = winMbcsToUnicode(zFilename); + if( zTmpWide==0 ){ + return 0; + } + zFilenameUtf8 = winUnicodeToUtf8(zTmpWide); + sqlite3_free(zTmpWide); + return zFilenameUtf8; +} + +/* +** Convert UTF-8 to multibyte character string. Space to hold the +** returned string is obtained from sqlite3_malloc(). +*/ +SQLITE_API char *SQLITE_STDCALL sqlite3_win32_utf8_to_mbcs(const char *zFilename){ + char *zFilenameMbcs; + LPWSTR zTmpWide; + + zTmpWide = winUtf8ToUnicode(zFilename); + if( zTmpWide==0 ){ + return 0; + } + zFilenameMbcs = winUnicodeToMbcs(zTmpWide); + sqlite3_free(zTmpWide); + return zFilenameMbcs; +} + +/* +** This function sets the data directory or the temporary directory based on +** the provided arguments. The type argument must be 1 in order to set the +** data directory or 2 in order to set the temporary directory. The zValue +** argument is the name of the directory to use. The return value will be +** SQLITE_OK if successful. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){ + char **ppDirectory = 0; +#ifndef SQLITE_OMIT_AUTOINIT + int rc = sqlite3_initialize(); + if( rc ) return rc; +#endif + if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){ + ppDirectory = &sqlite3_data_directory; + }else if( type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE ){ + ppDirectory = &sqlite3_temp_directory; + } + assert( !ppDirectory || type==SQLITE_WIN32_DATA_DIRECTORY_TYPE + || type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE + ); + assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) ); + if( ppDirectory ){ + char *zValueUtf8 = 0; + if( zValue && zValue[0] ){ + zValueUtf8 = winUnicodeToUtf8(zValue); + if ( zValueUtf8==0 ){ + return SQLITE_NOMEM; + } + } + sqlite3_free(*ppDirectory); + *ppDirectory = zValueUtf8; + return SQLITE_OK; + } + return SQLITE_ERROR; +} + +/* +** The return value of winGetLastErrorMsg +** is zero if the error message fits in the buffer, or non-zero +** otherwise (if the message was truncated). +*/ +static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ + /* FormatMessage returns 0 on failure. Otherwise it + ** returns the number of TCHARs written to the output + ** buffer, excluding the terminating null char. + */ + DWORD dwLen = 0; + char *zOut = 0; + + if( osIsNT() ){ +#if SQLITE_OS_WINRT + WCHAR zTempWide[SQLITE_WIN32_MAX_ERRMSG_CHARS+1]; + dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + lastErrno, + 0, + zTempWide, + SQLITE_WIN32_MAX_ERRMSG_CHARS, + 0); +#else + LPWSTR zTempWide = NULL; + dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + lastErrno, + 0, + (LPWSTR) &zTempWide, + 0, + 0); +#endif + if( dwLen > 0 ){ + /* allocate a buffer and convert to UTF8 */ + sqlite3BeginBenignMalloc(); + zOut = winUnicodeToUtf8(zTempWide); + sqlite3EndBenignMalloc(); +#if !SQLITE_OS_WINRT + /* free the system buffer allocated by FormatMessage */ + osLocalFree(zTempWide); +#endif + } + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + char *zTemp = NULL; + dwLen = osFormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + lastErrno, + 0, + (LPSTR) &zTemp, + 0, + 0); + if( dwLen > 0 ){ + /* allocate a buffer and convert to UTF8 */ + sqlite3BeginBenignMalloc(); + zOut = sqlite3_win32_mbcs_to_utf8(zTemp); + sqlite3EndBenignMalloc(); + /* free the system buffer allocated by FormatMessage */ + osLocalFree(zTemp); + } + } +#endif + if( 0 == dwLen ){ + sqlite3_snprintf(nBuf, zBuf, "OsError 0x%lx (%lu)", lastErrno, lastErrno); + }else{ + /* copy a maximum of nBuf chars to output buffer */ + sqlite3_snprintf(nBuf, zBuf, "%s", zOut); + /* free the UTF8 buffer */ + sqlite3_free(zOut); + } + return 0; +} + +/* +** +** This function - winLogErrorAtLine() - is only ever called via the macro +** winLogError(). +** +** This routine is invoked after an error occurs in an OS function. +** It logs a message using sqlite3_log() containing the current value of +** error code and, if possible, the human-readable equivalent from +** FormatMessage. +** +** The first argument passed to the macro should be the error code that +** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). +** The two subsequent arguments should be the name of the OS function that +** failed and the associated file-system path, if any. +*/ +#define winLogError(a,b,c,d) winLogErrorAtLine(a,b,c,d,__LINE__) +static int winLogErrorAtLine( + int errcode, /* SQLite error code */ + DWORD lastErrno, /* Win32 last error */ + const char *zFunc, /* Name of OS function that failed */ + const char *zPath, /* File path associated with error */ + int iLine /* Source line number where error occurred */ +){ + char zMsg[500]; /* Human readable error text */ + int i; /* Loop counter */ + + zMsg[0] = 0; + winGetLastErrorMsg(lastErrno, sizeof(zMsg), zMsg); + assert( errcode!=SQLITE_OK ); + if( zPath==0 ) zPath = ""; + for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){} + zMsg[i] = 0; + sqlite3_log(errcode, + "os_win.c:%d: (%lu) %s(%s) - %s", + iLine, lastErrno, zFunc, zPath, zMsg + ); + + return errcode; +} + +/* +** The number of times that a ReadFile(), WriteFile(), and DeleteFile() +** will be retried following a locking error - probably caused by +** antivirus software. Also the initial delay before the first retry. +** The delay increases linearly with each retry. +*/ +#ifndef SQLITE_WIN32_IOERR_RETRY +# define SQLITE_WIN32_IOERR_RETRY 10 +#endif +#ifndef SQLITE_WIN32_IOERR_RETRY_DELAY +# define SQLITE_WIN32_IOERR_RETRY_DELAY 25 +#endif +static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY; +static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY; + +/* +** The "winIoerrCanRetry1" macro is used to determine if a particular I/O +** error code obtained via GetLastError() is eligible to be retried. It +** must accept the error code DWORD as its only argument and should return +** non-zero if the error code is transient in nature and the operation +** responsible for generating the original error might succeed upon being +** retried. The argument to this macro should be a variable. +** +** Additionally, a macro named "winIoerrCanRetry2" may be defined. If it +** is defined, it will be consulted only when the macro "winIoerrCanRetry1" +** returns zero. The "winIoerrCanRetry2" macro is completely optional and +** may be used to include additional error codes in the set that should +** result in the failing I/O operation being retried by the caller. If +** defined, the "winIoerrCanRetry2" macro must exhibit external semantics +** identical to those of the "winIoerrCanRetry1" macro. +*/ +#if !defined(winIoerrCanRetry1) +#define winIoerrCanRetry1(a) (((a)==ERROR_ACCESS_DENIED) || \ + ((a)==ERROR_SHARING_VIOLATION) || \ + ((a)==ERROR_LOCK_VIOLATION) || \ + ((a)==ERROR_DEV_NOT_EXIST) || \ + ((a)==ERROR_NETNAME_DELETED) || \ + ((a)==ERROR_SEM_TIMEOUT) || \ + ((a)==ERROR_NETWORK_UNREACHABLE)) +#endif + +/* +** If a ReadFile() or WriteFile() error occurs, invoke this routine +** to see if it should be retried. Return TRUE to retry. Return FALSE +** to give up with an error. +*/ +static int winRetryIoerr(int *pnRetry, DWORD *pError){ + DWORD e = osGetLastError(); + if( *pnRetry>=winIoerrRetry ){ + if( pError ){ + *pError = e; + } + return 0; + } + if( winIoerrCanRetry1(e) ){ + sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); + ++*pnRetry; + return 1; + } +#if defined(winIoerrCanRetry2) + else if( winIoerrCanRetry2(e) ){ + sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); + ++*pnRetry; + return 1; + } +#endif + if( pError ){ + *pError = e; + } + return 0; +} + +/* +** Log a I/O error retry episode. +*/ +static void winLogIoerr(int nRetry, int lineno){ + if( nRetry ){ + sqlite3_log(SQLITE_NOTICE, + "delayed %dms for lock/sharing conflict at line %d", + winIoerrRetryDelay*nRetry*(nRetry+1)/2, lineno + ); + } +} + +#if SQLITE_OS_WINCE +/************************************************************************* +** This section contains code for WinCE only. +*/ +#if !defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API +/* +** The MSVC CRT on Windows CE may not have a localtime() function. So +** create a substitute. +*/ +/* #include */ +struct tm *__cdecl localtime(const time_t *t) +{ + static struct tm y; + FILETIME uTm, lTm; + SYSTEMTIME pTm; + sqlite3_int64 t64; + t64 = *t; + t64 = (t64 + 11644473600)*10000000; + uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF); + uTm.dwHighDateTime= (DWORD)(t64 >> 32); + osFileTimeToLocalFileTime(&uTm,&lTm); + osFileTimeToSystemTime(&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; +} +#endif + +#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)] + +/* +** Acquire a lock on the handle h +*/ +static void winceMutexAcquire(HANDLE h){ + DWORD dwErr; + do { + dwErr = osWaitForSingleObject(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 int winceCreateLock(const char *zFilename, winFile *pFile){ + LPWSTR zTok; + LPWSTR zName; + DWORD lastErrno; + BOOL bLogged = FALSE; + BOOL bInit = TRUE; + + zName = winUtf8ToUnicode(zFilename); + if( zName==0 ){ + /* out of memory */ + return SQLITE_IOERR_NOMEM; + } + + /* Initialize the local lockdata */ + memset(&pFile->local, 0, sizeof(pFile->local)); + + /* Replace the backslashes from the filename and lowercase it + ** to derive a mutex name. */ + zTok = osCharLowerW(zName); + for (;*zTok;zTok++){ + if (*zTok == '\\') *zTok = '_'; + } + + /* Create/open the named mutex */ + pFile->hMutex = osCreateMutexW(NULL, FALSE, zName); + if (!pFile->hMutex){ + pFile->lastErrno = osGetLastError(); + sqlite3_free(zName); + return winLogError(SQLITE_IOERR, pFile->lastErrno, + "winceCreateLock1", zFilename); + } + + /* 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. + */ + osCharUpperW(zName); + pFile->hShared = osCreateFileMappingW(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 */ + lastErrno = osGetLastError(); + if (lastErrno == ERROR_ALREADY_EXISTS){ + bInit = FALSE; + } + + sqlite3_free(zName); + + /* If we succeeded in making the shared memory handle, map it. */ + if( pFile->hShared ){ + pFile->shared = (winceLock*)osMapViewOfFile(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 ){ + pFile->lastErrno = osGetLastError(); + winLogError(SQLITE_IOERR, pFile->lastErrno, + "winceCreateLock2", zFilename); + bLogged = TRUE; + osCloseHandle(pFile->hShared); + pFile->hShared = NULL; + } + } + + /* If shared memory could not be created, then close the mutex and fail */ + if( pFile->hShared==NULL ){ + if( !bLogged ){ + pFile->lastErrno = lastErrno; + winLogError(SQLITE_IOERR, pFile->lastErrno, + "winceCreateLock3", zFilename); + bLogged = TRUE; + } + winceMutexRelease(pFile->hMutex); + osCloseHandle(pFile->hMutex); + pFile->hMutex = NULL; + return SQLITE_IOERR; + } + + /* Initialize the shared memory if we're supposed to */ + if( bInit ){ + memset(pFile->shared, 0, sizeof(winceLock)); + } + + winceMutexRelease(pFile->hMutex); + return SQLITE_OK; +} + +/* +** 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 */ + osUnmapViewOfFile(pFile->shared); + osCloseHandle(pFile->hShared); + + /* Done with the mutex */ + winceMutexRelease(pFile->hMutex); + osCloseHandle(pFile->hMutex); + pFile->hMutex = NULL; + } +} + +/* +** An implementation of the LockFile() API of Windows for CE +*/ +static BOOL winceLockFile( + LPHANDLE phFile, + DWORD dwFileOffsetLow, + DWORD dwFileOffsetHigh, + DWORD nNumberOfBytesToLockLow, + DWORD nNumberOfBytesToLockHigh +){ + winFile *pFile = HANDLE_TO_WINFILE(phFile); + BOOL bReturn = FALSE; + + UNUSED_PARAMETER(dwFileOffsetHigh); + UNUSED_PARAMETER(nNumberOfBytesToLockHigh); + + if (!pFile->hMutex) return TRUE; + winceMutexAcquire(pFile->hMutex); + + /* Wanting an exclusive lock? */ + if (dwFileOffsetLow == (DWORD)SHARED_FIRST + && nNumberOfBytesToLockLow == (DWORD)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 == (DWORD)SHARED_FIRST && + 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 == (DWORD)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 == (DWORD)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 CE +*/ +static BOOL winceUnlockFile( + LPHANDLE phFile, + DWORD dwFileOffsetLow, + DWORD dwFileOffsetHigh, + DWORD nNumberOfBytesToUnlockLow, + DWORD nNumberOfBytesToUnlockHigh +){ + winFile *pFile = HANDLE_TO_WINFILE(phFile); + BOOL bReturn = FALSE; + + UNUSED_PARAMETER(dwFileOffsetHigh); + UNUSED_PARAMETER(nNumberOfBytesToUnlockHigh); + + if (!pFile->hMutex) return TRUE; + winceMutexAcquire(pFile->hMutex); + + /* Releasing a reader lock or an exclusive lock */ + if (dwFileOffsetLow == (DWORD)SHARED_FIRST){ + /* Did we have an exclusive lock? */ + if (pFile->local.bExclusive){ + assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE); + pFile->local.bExclusive = FALSE; + pFile->shared->bExclusive = FALSE; + bReturn = TRUE; + } + + /* Did we just have a reader lock? */ + else if (pFile->local.nReaders){ + assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE + || nNumberOfBytesToUnlockLow == 1); + pFile->local.nReaders --; + if (pFile->local.nReaders == 0) + { + pFile->shared->nReaders --; + } + bReturn = TRUE; + } + } + + /* Releasing a pending lock */ + else if (dwFileOffsetLow == (DWORD)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 == (DWORD)RESERVED_BYTE + && nNumberOfBytesToUnlockLow == 1){ + if (pFile->local.bReserved) { + pFile->local.bReserved = FALSE; + pFile->shared->bReserved = FALSE; + bReturn = TRUE; + } + } + + winceMutexRelease(pFile->hMutex); + return bReturn; +} +/* +** End of the special code for wince +*****************************************************************************/ +#endif /* SQLITE_OS_WINCE */ + +/* +** Lock a file region. +*/ +static BOOL winLockFile( + LPHANDLE phFile, + DWORD flags, + DWORD offsetLow, + DWORD offsetHigh, + DWORD numBytesLow, + DWORD numBytesHigh +){ +#if SQLITE_OS_WINCE + /* + ** NOTE: Windows CE is handled differently here due its lack of the Win32 + ** API LockFile. + */ + return winceLockFile(phFile, offsetLow, offsetHigh, + numBytesLow, numBytesHigh); +#else + if( osIsNT() ){ + OVERLAPPED ovlp; + memset(&ovlp, 0, sizeof(OVERLAPPED)); + ovlp.Offset = offsetLow; + ovlp.OffsetHigh = offsetHigh; + return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp); + }else{ + return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow, + numBytesHigh); + } +#endif +} + +/* +** Unlock a file region. + */ +static BOOL winUnlockFile( + LPHANDLE phFile, + DWORD offsetLow, + DWORD offsetHigh, + DWORD numBytesLow, + DWORD numBytesHigh +){ +#if SQLITE_OS_WINCE + /* + ** NOTE: Windows CE is handled differently here due its lack of the Win32 + ** API UnlockFile. + */ + return winceUnlockFile(phFile, offsetLow, offsetHigh, + numBytesLow, numBytesHigh); +#else + if( osIsNT() ){ + OVERLAPPED ovlp; + memset(&ovlp, 0, sizeof(OVERLAPPED)); + ovlp.Offset = offsetLow; + ovlp.OffsetHigh = offsetHigh; + return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp); + }else{ + return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow, + numBytesHigh); + } +#endif +} + +/***************************************************************************** +** The next group of routines implement the I/O methods specified +** by the sqlite3_io_methods object. +******************************************************************************/ + +/* +** Some Microsoft compilers lack this definition. +*/ +#ifndef INVALID_SET_FILE_POINTER +# define INVALID_SET_FILE_POINTER ((DWORD)-1) +#endif + +/* +** Move the current position of the file handle passed as the first +** argument to offset iOffset within the file. If successful, return 0. +** Otherwise, set pFile->lastErrno and return non-zero. +*/ +static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){ +#if !SQLITE_OS_WINRT + LONG upperBits; /* Most sig. 32 bits of new offset */ + LONG lowerBits; /* Least sig. 32 bits of new offset */ + DWORD dwRet; /* Value returned by SetFilePointer() */ + DWORD lastErrno; /* Value returned by GetLastError() */ + + OSTRACE(("SEEK file=%p, offset=%lld\n", pFile->h, iOffset)); + + upperBits = (LONG)((iOffset>>32) & 0x7fffffff); + lowerBits = (LONG)(iOffset & 0xffffffff); + + /* API oddity: If successful, SetFilePointer() returns a dword + ** containing the lower 32-bits of the new file-offset. Or, if it fails, + ** it returns INVALID_SET_FILE_POINTER. However according to MSDN, + ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine + ** whether an error has actually occurred, it is also necessary to call + ** GetLastError(). + */ + dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); + + if( (dwRet==INVALID_SET_FILE_POINTER + && ((lastErrno = osGetLastError())!=NO_ERROR)) ){ + pFile->lastErrno = lastErrno; + winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, + "winSeekFile", pFile->zPath); + OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); + return 1; + } + + OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); + return 0; +#else + /* + ** Same as above, except that this implementation works for WinRT. + */ + + LARGE_INTEGER x; /* The new offset */ + BOOL bRet; /* Value returned by SetFilePointerEx() */ + + x.QuadPart = iOffset; + bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN); + + if(!bRet){ + pFile->lastErrno = osGetLastError(); + winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, + "winSeekFile", pFile->zPath); + OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); + return 1; + } + + OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); + return 0; +#endif +} + +#if SQLITE_MAX_MMAP_SIZE>0 +/* Forward references to VFS helper methods used for memory mapped files */ +static int winMapfile(winFile*, sqlite3_int64); +static int winUnmapfile(winFile*); +#endif + +/* +** Close a file. +** +** It is reported that an attempt to close a handle might sometimes +** fail. This is a very unreasonable result, but Windows is notorious +** for being unreasonable so I do not doubt that it might happen. If +** the close fails, we pause for 100 milliseconds and try again. As +** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before +** giving up and returning an error. +*/ +#define MX_CLOSE_ATTEMPT 3 +static int winClose(sqlite3_file *id){ + int rc, cnt = 0; + winFile *pFile = (winFile*)id; + + assert( id!=0 ); +#ifndef SQLITE_OMIT_WAL + assert( pFile->pShm==0 ); +#endif + assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE ); + OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p\n", + osGetCurrentProcessId(), pFile, pFile->h)); + +#if SQLITE_MAX_MMAP_SIZE>0 + winUnmapfile(pFile); +#endif + + do{ + rc = osCloseHandle(pFile->h); + /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */ + }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) ); +#if SQLITE_OS_WINCE +#define WINCE_DELETION_ATTEMPTS 3 + winceDestroyLock(pFile); + if( pFile->zDeleteOnClose ){ + int cnt = 0; + while( + osDeleteFileW(pFile->zDeleteOnClose)==0 + && osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff + && cnt++ < WINCE_DELETION_ATTEMPTS + ){ + sqlite3_win32_sleep(100); /* Wait a little before trying again */ + } + sqlite3_free(pFile->zDeleteOnClose); + } +#endif + if( rc ){ + pFile->h = NULL; + } + OpenCounter(-1); + OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p, rc=%s\n", + osGetCurrentProcessId(), pFile, pFile->h, rc ? "ok" : "failed")); + return rc ? SQLITE_OK + : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(), + "winClose", pFile->zPath); +} + +/* +** 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( + sqlite3_file *id, /* File to read from */ + void *pBuf, /* Write content into this buffer */ + int amt, /* Number of bytes to read */ + sqlite3_int64 offset /* Begin reading at this offset */ +){ +#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) + OVERLAPPED overlapped; /* The offset for ReadFile. */ +#endif + winFile *pFile = (winFile*)id; /* file handle */ + DWORD nRead; /* Number of bytes actually read from file */ + int nRetry = 0; /* Number of retrys */ + + assert( id!=0 ); + assert( amt>0 ); + assert( offset>=0 ); + SimulateIOError(return SQLITE_IOERR_READ); + OSTRACE(("READ pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, " + "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile, + pFile->h, pBuf, amt, offset, pFile->locktype)); + +#if SQLITE_MAX_MMAP_SIZE>0 + /* Deal with as much of this read request as possible by transfering + ** data from the memory mapping using memcpy(). */ + if( offsetmmapSize ){ + if( offset+amt <= pFile->mmapSize ){ + memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt); + OSTRACE(("READ-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_OK; + }else{ + int nCopy = (int)(pFile->mmapSize - offset); + memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy); + pBuf = &((u8 *)pBuf)[nCopy]; + amt -= nCopy; + offset += nCopy; + } + } +#endif + +#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED) + if( winSeekFile(pFile, offset) ){ + OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_FULL; + } + while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ +#else + memset(&overlapped, 0, sizeof(OVERLAPPED)); + overlapped.Offset = (LONG)(offset & 0xffffffff); + overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); + while( !osReadFile(pFile->h, pBuf, amt, &nRead, &overlapped) && + osGetLastError()!=ERROR_HANDLE_EOF ){ +#endif + DWORD lastErrno; + if( winRetryIoerr(&nRetry, &lastErrno) ) continue; + pFile->lastErrno = lastErrno; + OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_READ\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, + "winRead", pFile->zPath); + } + winLogIoerr(nRetry, __LINE__); + if( nRead<(DWORD)amt ){ + /* Unread parts of the buffer must be zero-filled */ + memset(&((char*)pBuf)[nRead], 0, amt-nRead); + OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_SHORT_READ\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_IOERR_SHORT_READ; + } + + OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_OK; +} + +/* +** Write data from a buffer into a file. Return SQLITE_OK on success +** or some other error code on failure. +*/ +static int winWrite( + sqlite3_file *id, /* File to write into */ + const void *pBuf, /* The bytes to be written */ + int amt, /* Number of bytes to write */ + sqlite3_int64 offset /* Offset into the file to begin writing at */ +){ + int rc = 0; /* True if error has occurred, else false */ + winFile *pFile = (winFile*)id; /* File handle */ + int nRetry = 0; /* Number of retries */ + + assert( amt>0 ); + assert( pFile ); + SimulateIOError(return SQLITE_IOERR_WRITE); + SimulateDiskfullError(return SQLITE_FULL); + + OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, " + "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile, + pFile->h, pBuf, amt, offset, pFile->locktype)); + +#if SQLITE_MAX_MMAP_SIZE>0 + /* Deal with as much of this write request as possible by transfering + ** data from the memory mapping using memcpy(). */ + if( offsetmmapSize ){ + if( offset+amt <= pFile->mmapSize ){ + memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt); + OSTRACE(("WRITE-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_OK; + }else{ + int nCopy = (int)(pFile->mmapSize - offset); + memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy); + pBuf = &((u8 *)pBuf)[nCopy]; + amt -= nCopy; + offset += nCopy; + } + } +#endif + +#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED) + rc = winSeekFile(pFile, offset); + if( rc==0 ){ +#else + { +#endif +#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) + OVERLAPPED overlapped; /* The offset for WriteFile. */ +#endif + u8 *aRem = (u8 *)pBuf; /* Data yet to be written */ + int nRem = amt; /* Number of bytes yet to be written */ + DWORD nWrite; /* Bytes written by each WriteFile() call */ + DWORD lastErrno = NO_ERROR; /* Value returned by GetLastError() */ + +#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) + memset(&overlapped, 0, sizeof(OVERLAPPED)); + overlapped.Offset = (LONG)(offset & 0xffffffff); + overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); +#endif + + while( nRem>0 ){ +#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED) + if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){ +#else + if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){ +#endif + if( winRetryIoerr(&nRetry, &lastErrno) ) continue; + break; + } + assert( nWrite==0 || nWrite<=(DWORD)nRem ); + if( nWrite==0 || nWrite>(DWORD)nRem ){ + lastErrno = osGetLastError(); + break; + } +#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) + offset += nWrite; + overlapped.Offset = (LONG)(offset & 0xffffffff); + overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); +#endif + aRem += nWrite; + nRem -= nWrite; + } + if( nRem>0 ){ + pFile->lastErrno = lastErrno; + rc = 1; + } + } + + if( rc ){ + if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ) + || ( pFile->lastErrno==ERROR_DISK_FULL )){ + OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return winLogError(SQLITE_FULL, pFile->lastErrno, + "winWrite1", pFile->zPath); + } + OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_WRITE\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno, + "winWrite2", pFile->zPath); + }else{ + winLogIoerr(nRetry, __LINE__); + } + OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_OK; +} + +/* +** Truncate an open file to a specified size +*/ +static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ + winFile *pFile = (winFile*)id; /* File handle object */ + int rc = SQLITE_OK; /* Return code for this function */ + DWORD lastErrno; + + assert( pFile ); + SimulateIOError(return SQLITE_IOERR_TRUNCATE); + OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, size=%lld, lock=%d\n", + osGetCurrentProcessId(), pFile, pFile->h, nByte, pFile->locktype)); + + /* If the user has configured a chunk-size for this file, truncate the + ** file so that it consists of an integer number of chunks (i.e. the + ** actual file size after the operation may be larger than the requested + ** size). + */ + if( pFile->szChunk>0 ){ + nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; + } + + /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ + if( winSeekFile(pFile, nByte) ){ + rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, + "winTruncate1", pFile->zPath); + }else if( 0==osSetEndOfFile(pFile->h) && + ((lastErrno = osGetLastError())!=ERROR_USER_MAPPED_FILE) ){ + pFile->lastErrno = lastErrno; + rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, + "winTruncate2", pFile->zPath); + } + +#if SQLITE_MAX_MMAP_SIZE>0 + /* If the file was truncated to a size smaller than the currently + ** mapped region, reduce the effective mapping size as well. SQLite will + ** use read() and write() to access data beyond this point from now on. + */ + if( pFile->pMapRegion && nBytemmapSize ){ + pFile->mmapSize = nByte; + } +#endif + + OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, rc=%s\n", + osGetCurrentProcessId(), pFile, pFile->h, sqlite3ErrName(rc))); + return rc; +} + +#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. +*/ +SQLITE_API int sqlite3_sync_count = 0; +SQLITE_API int sqlite3_fullsync_count = 0; +#endif + +/* +** Make sure all writes to a particular file are committed to disk. +*/ +static int winSync(sqlite3_file *id, int flags){ +#ifndef SQLITE_NO_SYNC + /* + ** Used only when SQLITE_NO_SYNC is not defined. + */ + BOOL rc; +#endif +#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \ + defined(SQLITE_HAVE_OS_TRACE) + /* + ** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or + ** OSTRACE() macros. + */ + winFile *pFile = (winFile*)id; +#else + UNUSED_PARAMETER(id); +#endif + + assert( pFile ); + /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */ + assert((flags&0x0F)==SQLITE_SYNC_NORMAL + || (flags&0x0F)==SQLITE_SYNC_FULL + ); + + /* Unix cannot, but some systems may return SQLITE_FULL from here. This + ** line is to test that doing so does not cause any problems. + */ + SimulateDiskfullError( return SQLITE_FULL ); + + OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, flags=%x, lock=%d\n", + osGetCurrentProcessId(), pFile, pFile->h, flags, + pFile->locktype)); + +#ifndef SQLITE_TEST + UNUSED_PARAMETER(flags); +#else + if( (flags&0x0F)==SQLITE_SYNC_FULL ){ + 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 + OSTRACE(("SYNC-NOP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_OK; +#else +#if SQLITE_MAX_MMAP_SIZE>0 + if( pFile->pMapRegion ){ + if( osFlushViewOfFile(pFile->pMapRegion, 0) ){ + OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, " + "rc=SQLITE_OK\n", osGetCurrentProcessId(), + pFile, pFile->pMapRegion)); + }else{ + pFile->lastErrno = osGetLastError(); + OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, " + "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), + pFile, pFile->pMapRegion)); + return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, + "winSync1", pFile->zPath); + } + } +#endif + rc = osFlushFileBuffers(pFile->h); + SimulateIOError( rc=FALSE ); + if( rc ){ + OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_OK; + }else{ + pFile->lastErrno = osGetLastError(); + OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_FSYNC\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno, + "winSync2", pFile->zPath); + } +#endif +} + +/* +** Determine the current size of a file in bytes +*/ +static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ + winFile *pFile = (winFile*)id; + int rc = SQLITE_OK; + + assert( id!=0 ); + assert( pSize!=0 ); + SimulateIOError(return SQLITE_IOERR_FSTAT); + OSTRACE(("SIZE file=%p, pSize=%p\n", pFile->h, pSize)); + +#if SQLITE_OS_WINRT + { + FILE_STANDARD_INFO info; + if( osGetFileInformationByHandleEx(pFile->h, FileStandardInfo, + &info, sizeof(info)) ){ + *pSize = info.EndOfFile.QuadPart; + }else{ + pFile->lastErrno = osGetLastError(); + rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, + "winFileSize", pFile->zPath); + } + } +#else + { + DWORD upperBits; + DWORD lowerBits; + DWORD lastErrno; + + lowerBits = osGetFileSize(pFile->h, &upperBits); + *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; + if( (lowerBits == INVALID_FILE_SIZE) + && ((lastErrno = osGetLastError())!=NO_ERROR) ){ + pFile->lastErrno = lastErrno; + rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, + "winFileSize", pFile->zPath); + } + } +#endif + OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n", + pFile->h, pSize, *pSize, sqlite3ErrName(rc))); + return rc; +} + +/* +** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems. +*/ +#ifndef LOCKFILE_FAIL_IMMEDIATELY +# define LOCKFILE_FAIL_IMMEDIATELY 1 +#endif + +#ifndef LOCKFILE_EXCLUSIVE_LOCK +# define LOCKFILE_EXCLUSIVE_LOCK 2 +#endif + +/* +** Historically, SQLite has used both the LockFile and LockFileEx functions. +** When the LockFile function was used, it was always expected to fail +** immediately if the lock could not be obtained. Also, it always expected to +** obtain an exclusive lock. These flags are used with the LockFileEx function +** and reflect those expectations; therefore, they should not be changed. +*/ +#ifndef SQLITE_LOCKFILE_FLAGS +# define SQLITE_LOCKFILE_FLAGS (LOCKFILE_FAIL_IMMEDIATELY | \ + LOCKFILE_EXCLUSIVE_LOCK) +#endif + +/* +** Currently, SQLite never calls the LockFileEx function without wanting the +** call to fail immediately if the lock cannot be obtained. +*/ +#ifndef SQLITE_LOCKFILEEX_FLAGS +# define SQLITE_LOCKFILEEX_FLAGS (LOCKFILE_FAIL_IMMEDIATELY) +#endif + +/* +** Acquire a reader lock. +** Different API routines are called depending on whether or not this +** is Win9x or WinNT. +*/ +static int winGetReadLock(winFile *pFile){ + int res; + OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); + if( osIsNT() ){ +#if SQLITE_OS_WINCE + /* + ** NOTE: Windows CE is handled differently here due its lack of the Win32 + ** API LockFileEx. + */ + res = winceLockFile(&pFile->h, SHARED_FIRST, 0, 1, 0); +#else + res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS, SHARED_FIRST, 0, + SHARED_SIZE, 0); +#endif + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + int lk; + sqlite3_randomness(sizeof(lk), &lk); + pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1)); + res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, + SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); + } +#endif + if( res == 0 ){ + pFile->lastErrno = osGetLastError(); + /* No need to log a failure to lock */ + } + OSTRACE(("READ-LOCK file=%p, result=%d\n", pFile->h, res)); + return res; +} + +/* +** Undo a readlock +*/ +static int winUnlockReadLock(winFile *pFile){ + int res; + DWORD lastErrno; + OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); + if( osIsNT() ){ + res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); + } +#endif + if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ + pFile->lastErrno = lastErrno; + winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, + "winUnlockReadLock", pFile->zPath); + } + OSTRACE(("READ-UNLOCK file=%p, result=%d\n", pFile->h, res)); + return res; +} + +/* +** Lock the file with the lock specified by parameter locktype - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** 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(sqlite3_file *id, int locktype){ + int rc = SQLITE_OK; /* Return code from subroutines */ + int res = 1; /* Result of a Windows lock call */ + int newLocktype; /* Set pFile->locktype to this value before exiting */ + int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ + winFile *pFile = (winFile*)id; + DWORD lastErrno = NO_ERROR; + + assert( id!=0 ); + OSTRACE(("LOCK file=%p, oldLock=%d(%d), newLock=%d\n", + pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); + + /* 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 ){ + OSTRACE(("LOCK-HELD file=%p, rc=SQLITE_OK\n", pFile->h)); + 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 = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, + PENDING_BYTE, 0, 1, 0))==0 ){ + /* Try 3 times to get the pending lock. This is needed to work + ** around problems caused by indexing and/or anti-virus software on + ** Windows systems. + ** If you are using this code as a model for alternative VFSes, do not + ** copy this retry logic. It is a hack intended for Windows only. + */ + lastErrno = osGetLastError(); + OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, result=%d\n", + pFile->h, cnt, res)); + if( lastErrno==ERROR_INVALID_HANDLE ){ + pFile->lastErrno = lastErrno; + rc = SQLITE_IOERR_LOCK; + OSTRACE(("LOCK-FAIL file=%p, count=%d, rc=%s\n", + pFile->h, cnt, sqlite3ErrName(rc))); + return rc; + } + if( cnt ) sqlite3_win32_sleep(1); + } + gotPendingLock = res; + if( !res ){ + lastErrno = osGetLastError(); + } + } + + /* Acquire a shared lock + */ + if( locktype==SHARED_LOCK && res ){ + assert( pFile->locktype==NO_LOCK ); + res = winGetReadLock(pFile); + if( res ){ + newLocktype = SHARED_LOCK; + }else{ + lastErrno = osGetLastError(); + } + } + + /* Acquire a RESERVED lock + */ + if( locktype==RESERVED_LOCK && res ){ + assert( pFile->locktype==SHARED_LOCK ); + res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0); + if( res ){ + newLocktype = RESERVED_LOCK; + }else{ + lastErrno = osGetLastError(); + } + } + + /* 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 = winUnlockReadLock(pFile); + res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, + SHARED_SIZE, 0); + if( res ){ + newLocktype = EXCLUSIVE_LOCK; + }else{ + lastErrno = osGetLastError(); + winGetReadLock(pFile); + } + } + + /* If we are holding a PENDING lock that ought to be released, then + ** release it now. + */ + if( gotPendingLock && locktype==SHARED_LOCK ){ + winUnlockFile(&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{ + pFile->lastErrno = lastErrno; + rc = SQLITE_BUSY; + OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n", + pFile->h, locktype, newLocktype)); + } + pFile->locktype = (u8)newLocktype; + OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n", + pFile->h, pFile->locktype, sqlite3ErrName(rc))); + 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(sqlite3_file *id, int *pResOut){ + int res; + winFile *pFile = (winFile*)id; + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p\n", pFile->h, pResOut)); + + assert( id!=0 ); + if( pFile->locktype>=RESERVED_LOCK ){ + res = 1; + OSTRACE(("TEST-WR-LOCK file=%p, result=%d (local)\n", pFile->h, res)); + }else{ + res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE, 0, 1, 0); + if( res ){ + winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); + } + res = !res; + OSTRACE(("TEST-WR-LOCK file=%p, result=%d (remote)\n", pFile->h, res)); + } + *pResOut = res; + OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", + pFile->h, pResOut, *pResOut)); + return SQLITE_OK; +} + +/* +** 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(sqlite3_file *id, int locktype){ + int type; + winFile *pFile = (winFile*)id; + int rc = SQLITE_OK; + assert( pFile!=0 ); + assert( locktype<=SHARED_LOCK ); + OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n", + pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); + type = pFile->locktype; + if( type>=EXCLUSIVE_LOCK ){ + winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); + if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){ + /* This should never happen. We should always be able to + ** reacquire the read lock */ + rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(), + "winUnlock", pFile->zPath); + } + } + if( type>=RESERVED_LOCK ){ + winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); + } + if( locktype==NO_LOCK && type>=SHARED_LOCK ){ + winUnlockReadLock(pFile); + } + if( type>=PENDING_LOCK ){ + winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0); + } + pFile->locktype = (u8)locktype; + OSTRACE(("UNLOCK file=%p, lock=%d, rc=%s\n", + pFile->h, pFile->locktype, sqlite3ErrName(rc))); + return rc; +} + +/* +** If *pArg is initially negative then this is a query. Set *pArg to +** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set. +** +** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags. +*/ +static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){ + if( *pArg<0 ){ + *pArg = (pFile->ctrlFlags & mask)!=0; + }else if( (*pArg)==0 ){ + pFile->ctrlFlags &= ~mask; + }else{ + pFile->ctrlFlags |= mask; + } +} + +/* Forward references to VFS helper methods used for temporary files */ +static int winGetTempname(sqlite3_vfs *, char **); +static int winIsDir(const void *); +static BOOL winIsDriveLetterAndColon(const char *); + +/* +** Control and query of the open file handle. +*/ +static int winFileControl(sqlite3_file *id, int op, void *pArg){ + winFile *pFile = (winFile*)id; + OSTRACE(("FCNTL file=%p, op=%d, pArg=%p\n", pFile->h, op, pArg)); + switch( op ){ + case SQLITE_FCNTL_LOCKSTATE: { + *(int*)pArg = pFile->locktype; + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_LAST_ERRNO: { + *(int*)pArg = (int)pFile->lastErrno; + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_FCNTL_CHUNK_SIZE: { + pFile->szChunk = *(int *)pArg; + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_FCNTL_SIZE_HINT: { + if( pFile->szChunk>0 ){ + sqlite3_int64 oldSz; + int rc = winFileSize(id, &oldSz); + if( rc==SQLITE_OK ){ + sqlite3_int64 newSz = *(sqlite3_int64*)pArg; + if( newSz>oldSz ){ + SimulateIOErrorBenign(1); + rc = winTruncate(id, newSz); + SimulateIOErrorBenign(0); + } + } + OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); + return rc; + } + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_FCNTL_PERSIST_WAL: { + winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg); + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { + winModeBit(pFile, WINFILE_PSOW, (int*)pArg); + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_FCNTL_VFSNAME: { + *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_FCNTL_WIN32_AV_RETRY: { + int *a = (int*)pArg; + if( a[0]>0 ){ + winIoerrRetry = a[0]; + }else{ + a[0] = winIoerrRetry; + } + if( a[1]>0 ){ + winIoerrRetryDelay = a[1]; + }else{ + a[1] = winIoerrRetryDelay; + } + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } +#ifdef SQLITE_TEST + case SQLITE_FCNTL_WIN32_SET_HANDLE: { + LPHANDLE phFile = (LPHANDLE)pArg; + HANDLE hOldFile = pFile->h; + pFile->h = *phFile; + *phFile = hOldFile; + OSTRACE(("FCNTL oldFile=%p, newFile=%p, rc=SQLITE_OK\n", + hOldFile, pFile->h)); + return SQLITE_OK; + } +#endif + case SQLITE_FCNTL_TEMPFILENAME: { + char *zTFile = 0; + int rc = winGetTempname(pFile->pVfs, &zTFile); + if( rc==SQLITE_OK ){ + *(char**)pArg = zTFile; + } + OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); + return rc; + } +#if SQLITE_MAX_MMAP_SIZE>0 + case SQLITE_FCNTL_MMAP_SIZE: { + i64 newLimit = *(i64*)pArg; + int rc = SQLITE_OK; + if( newLimit>sqlite3GlobalConfig.mxMmap ){ + newLimit = sqlite3GlobalConfig.mxMmap; + } + *(i64*)pArg = pFile->mmapSizeMax; + if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){ + pFile->mmapSizeMax = newLimit; + if( pFile->mmapSize>0 ){ + winUnmapfile(pFile); + rc = winMapfile(pFile, -1); + } + } + OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); + return rc; + } +#endif + } + OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h)); + return SQLITE_NOTFOUND; +} + +/* +** Return the sector size in bytes of the underlying block device for +** the specified file. This is almost always 512 bytes, but may be +** larger for some devices. +** +** SQLite code assumes this function cannot fail. It also assumes that +** if two files are created in the same file-system directory (i.e. +** a database and its journal file) that the sector size will be the +** same for both. +*/ +static int winSectorSize(sqlite3_file *id){ + (void)id; + return SQLITE_DEFAULT_SECTOR_SIZE; +} + +/* +** Return a vector of device characteristics. +*/ +static int winDeviceCharacteristics(sqlite3_file *id){ + winFile *p = (winFile*)id; + return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | + ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); +} + +/* +** Windows will only let you create file view mappings +** on allocation size granularity boundaries. +** During sqlite3_os_init() we do a GetSystemInfo() +** to get the granularity size. +*/ +static SYSTEM_INFO winSysInfo; + +#ifndef SQLITE_OMIT_WAL + +/* +** Helper functions to obtain and relinquish the global mutex. The +** global mutex is used to protect the winLockInfo objects used by +** this file, all of which may be shared by multiple threads. +** +** Function winShmMutexHeld() is used to assert() that the global mutex +** is held when required. This function is only used as part of assert() +** statements. e.g. +** +** winShmEnterMutex() +** assert( winShmMutexHeld() ); +** winShmLeaveMutex() +*/ +static void winShmEnterMutex(void){ + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +} +static void winShmLeaveMutex(void){ + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +} +#ifndef NDEBUG +static int winShmMutexHeld(void) { + return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +} +#endif + +/* +** Object used to represent a single file opened and mmapped to provide +** shared memory. When multiple threads all reference the same +** log-summary, each thread has its own winFile object, but they all +** point to a single instance of this object. In other words, each +** log-summary is opened only once per process. +** +** winShmMutexHeld() must be true when creating or destroying +** this object or while reading or writing the following fields: +** +** nRef +** pNext +** +** The following fields are read-only after the object is created: +** +** fid +** zFilename +** +** Either winShmNode.mutex must be held or winShmNode.nRef==0 and +** winShmMutexHeld() is true when reading or writing any other field +** in this structure. +** +*/ +struct winShmNode { + sqlite3_mutex *mutex; /* Mutex to access this object */ + char *zFilename; /* Name of the file */ + winFile hFile; /* File handle from winOpen */ + + int szRegion; /* Size of shared-memory regions */ + int nRegion; /* Size of array apRegion */ + struct ShmRegion { + HANDLE hMap; /* File handle from CreateFileMapping */ + void *pMap; + } *aRegion; + DWORD lastErrno; /* The Windows errno from the last I/O error */ + + int nRef; /* Number of winShm objects pointing to this */ + winShm *pFirst; /* All winShm objects pointing to this */ + winShmNode *pNext; /* Next in list of all winShmNode objects */ +#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) + u8 nextShmId; /* Next available winShm.id value */ +#endif +}; + +/* +** A global array of all winShmNode objects. +** +** The winShmMutexHeld() must be true while reading or writing this list. +*/ +static winShmNode *winShmNodeList = 0; + +/* +** Structure used internally by this VFS to record the state of an +** open shared memory connection. +** +** The following fields are initialized when this object is created and +** are read-only thereafter: +** +** winShm.pShmNode +** winShm.id +** +** All other fields are read/write. The winShm.pShmNode->mutex must be held +** while accessing any read/write fields. +*/ +struct winShm { + winShmNode *pShmNode; /* The underlying winShmNode object */ + winShm *pNext; /* Next winShm with the same winShmNode */ + u8 hasMutex; /* True if holding the winShmNode mutex */ + u16 sharedMask; /* Mask of shared locks held */ + u16 exclMask; /* Mask of exclusive locks held */ +#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) + u8 id; /* Id of this connection with its winShmNode */ +#endif +}; + +/* +** Constants used for locking +*/ +#define WIN_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ +#define WIN_SHM_DMS (WIN_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ + +/* +** Apply advisory locks for all n bytes beginning at ofst. +*/ +#define _SHM_UNLCK 1 +#define _SHM_RDLCK 2 +#define _SHM_WRLCK 3 +static int winShmSystemLock( + winShmNode *pFile, /* Apply locks to this open shared-memory segment */ + int lockType, /* _SHM_UNLCK, _SHM_RDLCK, or _SHM_WRLCK */ + int ofst, /* Offset to first byte to be locked/unlocked */ + int nByte /* Number of bytes to lock or unlock */ +){ + int rc = 0; /* Result code form Lock/UnlockFileEx() */ + + /* Access to the winShmNode object is serialized by the caller */ + assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 ); + + OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n", + pFile->hFile.h, lockType, ofst, nByte)); + + /* Release/Acquire the system-level lock */ + if( lockType==_SHM_UNLCK ){ + rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0); + }else{ + /* Initialize the locking parameters */ + DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY; + if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK; + rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0); + } + + if( rc!= 0 ){ + rc = SQLITE_OK; + }else{ + pFile->lastErrno = osGetLastError(); + rc = SQLITE_BUSY; + } + + OSTRACE(("SHM-LOCK file=%p, func=%s, errno=%lu, rc=%s\n", + pFile->hFile.h, (lockType == _SHM_UNLCK) ? "winUnlockFile" : + "winLockFile", pFile->lastErrno, sqlite3ErrName(rc))); + + return rc; +} + +/* Forward references to VFS methods */ +static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*); +static int winDelete(sqlite3_vfs *,const char*,int); + +/* +** Purge the winShmNodeList list of all entries with winShmNode.nRef==0. +** +** This is not a VFS shared-memory method; it is a utility function called +** by VFS shared-memory methods. +*/ +static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ + winShmNode **pp; + winShmNode *p; + assert( winShmMutexHeld() ); + OSTRACE(("SHM-PURGE pid=%lu, deleteFlag=%d\n", + osGetCurrentProcessId(), deleteFlag)); + pp = &winShmNodeList; + while( (p = *pp)!=0 ){ + if( p->nRef==0 ){ + int i; + if( p->mutex ){ sqlite3_mutex_free(p->mutex); } + for(i=0; inRegion; i++){ + BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap); + OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n", + osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); + UNUSED_VARIABLE_VALUE(bRc); + bRc = osCloseHandle(p->aRegion[i].hMap); + OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n", + osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); + UNUSED_VARIABLE_VALUE(bRc); + } + if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){ + SimulateIOErrorBenign(1); + winClose((sqlite3_file *)&p->hFile); + SimulateIOErrorBenign(0); + } + if( deleteFlag ){ + SimulateIOErrorBenign(1); + sqlite3BeginBenignMalloc(); + winDelete(pVfs, p->zFilename, 0); + sqlite3EndBenignMalloc(); + SimulateIOErrorBenign(0); + } + *pp = p->pNext; + sqlite3_free(p->aRegion); + sqlite3_free(p); + }else{ + pp = &p->pNext; + } + } +} + +/* +** Open the shared-memory area associated with database file pDbFd. +** +** When opening a new shared-memory file, if no other instances of that +** file are currently open, in this process or in other processes, then +** the file must be truncated to zero length or have its header cleared. +*/ +static int winOpenSharedMemory(winFile *pDbFd){ + struct winShm *p; /* The connection to be opened */ + struct winShmNode *pShmNode = 0; /* The underlying mmapped file */ + int rc; /* Result code */ + struct winShmNode *pNew; /* Newly allocated winShmNode */ + int nName; /* Size of zName in bytes */ + + assert( pDbFd->pShm==0 ); /* Not previously opened */ + + /* Allocate space for the new sqlite3_shm object. Also speculatively + ** allocate space for a new winShmNode and filename. + */ + p = sqlite3MallocZero( sizeof(*p) ); + if( p==0 ) return SQLITE_IOERR_NOMEM; + nName = sqlite3Strlen30(pDbFd->zPath); + pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 ); + if( pNew==0 ){ + sqlite3_free(p); + return SQLITE_IOERR_NOMEM; + } + pNew->zFilename = (char*)&pNew[1]; + sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath); + sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename); + + /* Look to see if there is an existing winShmNode that can be used. + ** If no matching winShmNode currently exists, create a new one. + */ + winShmEnterMutex(); + for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){ + /* TBD need to come up with better match here. Perhaps + ** use FILE_ID_BOTH_DIR_INFO Structure. + */ + if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break; + } + if( pShmNode ){ + sqlite3_free(pNew); + }else{ + pShmNode = pNew; + pNew = 0; + ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE; + pShmNode->pNext = winShmNodeList; + winShmNodeList = pShmNode; + + pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pShmNode->mutex==0 ){ + rc = SQLITE_IOERR_NOMEM; + goto shm_open_err; + } + + rc = winOpen(pDbFd->pVfs, + pShmNode->zFilename, /* Name of the file (UTF-8) */ + (sqlite3_file*)&pShmNode->hFile, /* File handle here */ + SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, + 0); + if( SQLITE_OK!=rc ){ + goto shm_open_err; + } + + /* Check to see if another process is holding the dead-man switch. + ** If not, truncate the file to zero length. + */ + if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){ + rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0); + if( rc!=SQLITE_OK ){ + rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), + "winOpenShm", pDbFd->zPath); + } + } + if( rc==SQLITE_OK ){ + winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1); + rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1); + } + if( rc ) goto shm_open_err; + } + + /* Make the new connection a child of the winShmNode */ + p->pShmNode = pShmNode; +#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) + p->id = pShmNode->nextShmId++; +#endif + pShmNode->nRef++; + pDbFd->pShm = p; + winShmLeaveMutex(); + + /* The reference count on pShmNode has already been incremented under + ** the cover of the winShmEnterMutex() mutex and the pointer from the + ** new (struct winShm) object to the pShmNode has been set. All that is + ** left to do is to link the new object into the linked list starting + ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex + ** mutex. + */ + sqlite3_mutex_enter(pShmNode->mutex); + p->pNext = pShmNode->pFirst; + pShmNode->pFirst = p; + sqlite3_mutex_leave(pShmNode->mutex); + return SQLITE_OK; + + /* Jump here on any error */ +shm_open_err: + winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1); + winShmPurge(pDbFd->pVfs, 0); /* This call frees pShmNode if required */ + sqlite3_free(p); + sqlite3_free(pNew); + winShmLeaveMutex(); + return rc; +} + +/* +** Close a connection to shared-memory. Delete the underlying +** storage if deleteFlag is true. +*/ +static int winShmUnmap( + sqlite3_file *fd, /* Database holding shared memory */ + int deleteFlag /* Delete after closing if true */ +){ + winFile *pDbFd; /* Database holding shared-memory */ + winShm *p; /* The connection to be closed */ + winShmNode *pShmNode; /* The underlying shared-memory file */ + winShm **pp; /* For looping over sibling connections */ + + pDbFd = (winFile*)fd; + p = pDbFd->pShm; + if( p==0 ) return SQLITE_OK; + pShmNode = p->pShmNode; + + /* Remove connection p from the set of connections associated + ** with pShmNode */ + sqlite3_mutex_enter(pShmNode->mutex); + for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} + *pp = p->pNext; + + /* Free the connection p */ + sqlite3_free(p); + pDbFd->pShm = 0; + sqlite3_mutex_leave(pShmNode->mutex); + + /* If pShmNode->nRef has reached 0, then close the underlying + ** shared-memory file, too */ + winShmEnterMutex(); + assert( pShmNode->nRef>0 ); + pShmNode->nRef--; + if( pShmNode->nRef==0 ){ + winShmPurge(pDbFd->pVfs, deleteFlag); + } + winShmLeaveMutex(); + + return SQLITE_OK; +} + +/* +** Change the lock state for a shared-memory segment. +*/ +static int winShmLock( + sqlite3_file *fd, /* Database file holding the shared memory */ + int ofst, /* First lock to acquire or release */ + int n, /* Number of locks to acquire or release */ + int flags /* What to do with the lock */ +){ + winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */ + winShm *p = pDbFd->pShm; /* The shared memory being locked */ + winShm *pX; /* For looping over all siblings */ + winShmNode *pShmNode = p->pShmNode; + int rc = SQLITE_OK; /* Result code */ + u16 mask; /* Mask of locks to take or release */ + + assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); + assert( n>=1 ); + assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); + assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); + + mask = (u16)((1U<<(ofst+n)) - (1U<1 || mask==(1<mutex); + if( flags & SQLITE_SHM_UNLOCK ){ + u16 allMask = 0; /* Mask of locks held by siblings */ + + /* See if any siblings hold this same lock */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( pX==p ) continue; + assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); + allMask |= pX->sharedMask; + } + + /* Unlock the system-level locks */ + if( (mask & allMask)==0 ){ + rc = winShmSystemLock(pShmNode, _SHM_UNLCK, ofst+WIN_SHM_BASE, n); + }else{ + rc = SQLITE_OK; + } + + /* Undo the local locks */ + if( rc==SQLITE_OK ){ + p->exclMask &= ~mask; + p->sharedMask &= ~mask; + } + }else if( flags & SQLITE_SHM_SHARED ){ + u16 allShared = 0; /* Union of locks held by connections other than "p" */ + + /* Find out which shared locks are already held by sibling connections. + ** If any sibling already holds an exclusive lock, go ahead and return + ** SQLITE_BUSY. + */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( (pX->exclMask & mask)!=0 ){ + rc = SQLITE_BUSY; + break; + } + allShared |= pX->sharedMask; + } + + /* Get shared locks at the system level, if necessary */ + if( rc==SQLITE_OK ){ + if( (allShared & mask)==0 ){ + rc = winShmSystemLock(pShmNode, _SHM_RDLCK, ofst+WIN_SHM_BASE, n); + }else{ + rc = SQLITE_OK; + } + } + + /* Get the local shared locks */ + if( rc==SQLITE_OK ){ + p->sharedMask |= mask; + } + }else{ + /* Make sure no sibling connections hold locks that will block this + ** lock. If any do, return SQLITE_BUSY right away. + */ + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){ + rc = SQLITE_BUSY; + break; + } + } + + /* Get the exclusive locks at the system level. Then if successful + ** also mark the local connection as being locked. + */ + if( rc==SQLITE_OK ){ + rc = winShmSystemLock(pShmNode, _SHM_WRLCK, ofst+WIN_SHM_BASE, n); + if( rc==SQLITE_OK ){ + assert( (p->sharedMask & mask)==0 ); + p->exclMask |= mask; + } + } + } + sqlite3_mutex_leave(pShmNode->mutex); + OSTRACE(("SHM-LOCK pid=%lu, id=%d, sharedMask=%03x, exclMask=%03x, rc=%s\n", + osGetCurrentProcessId(), p->id, p->sharedMask, p->exclMask, + sqlite3ErrName(rc))); + return rc; +} + +/* +** Implement a memory barrier or memory fence on shared memory. +** +** All loads and stores begun before the barrier must complete before +** any load or store begun after the barrier. +*/ +static void winShmBarrier( + sqlite3_file *fd /* Database holding the shared memory */ +){ + UNUSED_PARAMETER(fd); + /* MemoryBarrier(); // does not work -- do not know why not */ + winShmEnterMutex(); + winShmLeaveMutex(); +} + +/* +** This function is called to obtain a pointer to region iRegion of the +** shared-memory associated with the database file fd. Shared-memory regions +** are numbered starting from zero. Each shared-memory region is szRegion +** bytes in size. +** +** If an error occurs, an error code is returned and *pp is set to NULL. +** +** Otherwise, if the isWrite parameter is 0 and the requested shared-memory +** region has not been allocated (by any client, including one running in a +** separate process), then *pp is set to NULL and SQLITE_OK returned. If +** isWrite is non-zero and the requested shared-memory region has not yet +** been allocated, it is allocated by this function. +** +** If the shared-memory region has already been allocated or is allocated by +** this call as described above, then it is mapped into this processes +** address space (if it is not already), *pp is set to point to the mapped +** memory and SQLITE_OK returned. +*/ +static int winShmMap( + sqlite3_file *fd, /* Handle open on database file */ + int iRegion, /* Region to retrieve */ + int szRegion, /* Size of regions */ + int isWrite, /* True to extend file if necessary */ + void volatile **pp /* OUT: Mapped memory */ +){ + winFile *pDbFd = (winFile*)fd; + winShm *pShm = pDbFd->pShm; + winShmNode *pShmNode; + int rc = SQLITE_OK; + + if( !pShm ){ + rc = winOpenSharedMemory(pDbFd); + if( rc!=SQLITE_OK ) return rc; + pShm = pDbFd->pShm; + } + pShmNode = pShm->pShmNode; + + sqlite3_mutex_enter(pShmNode->mutex); + assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); + + if( pShmNode->nRegion<=iRegion ){ + struct ShmRegion *apNew; /* New aRegion[] array */ + int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ + sqlite3_int64 sz; /* Current size of wal-index file */ + + pShmNode->szRegion = szRegion; + + /* The requested region is not mapped into this processes address space. + ** Check to see if it has been allocated (i.e. if the wal-index file is + ** large enough to contain the requested region). + */ + rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz); + if( rc!=SQLITE_OK ){ + rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), + "winShmMap1", pDbFd->zPath); + goto shmpage_out; + } + + if( szhFile, nByte); + if( rc!=SQLITE_OK ){ + rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), + "winShmMap2", pDbFd->zPath); + goto shmpage_out; + } + } + + /* Map the requested memory region into this processes address space. */ + apNew = (struct ShmRegion *)sqlite3_realloc64( + pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0]) + ); + if( !apNew ){ + rc = SQLITE_IOERR_NOMEM; + goto shmpage_out; + } + pShmNode->aRegion = apNew; + + while( pShmNode->nRegion<=iRegion ){ + HANDLE hMap = NULL; /* file-mapping handle */ + void *pMap = 0; /* Mapped memory region */ + +#if SQLITE_OS_WINRT + hMap = osCreateFileMappingFromApp(pShmNode->hFile.h, + NULL, PAGE_READWRITE, nByte, NULL + ); +#elif defined(SQLITE_WIN32_HAS_WIDE) + hMap = osCreateFileMappingW(pShmNode->hFile.h, + NULL, PAGE_READWRITE, 0, nByte, NULL + ); +#elif defined(SQLITE_WIN32_HAS_ANSI) + hMap = osCreateFileMappingA(pShmNode->hFile.h, + NULL, PAGE_READWRITE, 0, nByte, NULL + ); +#endif + OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n", + osGetCurrentProcessId(), pShmNode->nRegion, nByte, + hMap ? "ok" : "failed")); + if( hMap ){ + int iOffset = pShmNode->nRegion*szRegion; + int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; +#if SQLITE_OS_WINRT + pMap = osMapViewOfFileFromApp(hMap, FILE_MAP_WRITE | FILE_MAP_READ, + iOffset - iOffsetShift, szRegion + iOffsetShift + ); +#else + pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ, + 0, iOffset - iOffsetShift, szRegion + iOffsetShift + ); +#endif + OSTRACE(("SHM-MAP-MAP pid=%lu, region=%d, offset=%d, size=%d, rc=%s\n", + osGetCurrentProcessId(), pShmNode->nRegion, iOffset, + szRegion, pMap ? "ok" : "failed")); + } + if( !pMap ){ + pShmNode->lastErrno = osGetLastError(); + rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno, + "winShmMap3", pDbFd->zPath); + if( hMap ) osCloseHandle(hMap); + goto shmpage_out; + } + + pShmNode->aRegion[pShmNode->nRegion].pMap = pMap; + pShmNode->aRegion[pShmNode->nRegion].hMap = hMap; + pShmNode->nRegion++; + } + } + +shmpage_out: + if( pShmNode->nRegion>iRegion ){ + int iOffset = iRegion*szRegion; + int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; + char *p = (char *)pShmNode->aRegion[iRegion].pMap; + *pp = (void *)&p[iOffsetShift]; + }else{ + *pp = 0; + } + sqlite3_mutex_leave(pShmNode->mutex); + return rc; +} + +#else +# define winShmMap 0 +# define winShmLock 0 +# define winShmBarrier 0 +# define winShmUnmap 0 +#endif /* #ifndef SQLITE_OMIT_WAL */ + +/* +** Cleans up the mapped region of the specified file, if any. +*/ +#if SQLITE_MAX_MMAP_SIZE>0 +static int winUnmapfile(winFile *pFile){ + assert( pFile!=0 ); + OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, " + "mmapSize=%lld, mmapSizeActual=%lld, mmapSizeMax=%lld\n", + osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion, + pFile->mmapSize, pFile->mmapSizeActual, pFile->mmapSizeMax)); + if( pFile->pMapRegion ){ + if( !osUnmapViewOfFile(pFile->pMapRegion) ){ + pFile->lastErrno = osGetLastError(); + OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, " + "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile, + pFile->pMapRegion)); + return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, + "winUnmapfile1", pFile->zPath); + } + pFile->pMapRegion = 0; + pFile->mmapSize = 0; + pFile->mmapSizeActual = 0; + } + if( pFile->hMap!=NULL ){ + if( !osCloseHandle(pFile->hMap) ){ + pFile->lastErrno = osGetLastError(); + OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n", + osGetCurrentProcessId(), pFile, pFile->hMap)); + return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, + "winUnmapfile2", pFile->zPath); + } + pFile->hMap = NULL; + } + OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile)); + return SQLITE_OK; +} + +/* +** Memory map or remap the file opened by file-descriptor pFd (if the file +** is already mapped, the existing mapping is replaced by the new). Or, if +** there already exists a mapping for this file, and there are still +** outstanding xFetch() references to it, this function is a no-op. +** +** If parameter nByte is non-negative, then it is the requested size of +** the mapping to create. Otherwise, if nByte is less than zero, then the +** requested size is the size of the file on disk. The actual size of the +** created mapping is either the requested size or the value configured +** using SQLITE_FCNTL_MMAP_SIZE, whichever is smaller. +** +** SQLITE_OK is returned if no error occurs (even if the mapping is not +** recreated as a result of outstanding references) or an SQLite error +** code otherwise. +*/ +static int winMapfile(winFile *pFd, sqlite3_int64 nByte){ + sqlite3_int64 nMap = nByte; + int rc; + + assert( nMap>=0 || pFd->nFetchOut==0 ); + OSTRACE(("MAP-FILE pid=%lu, pFile=%p, size=%lld\n", + osGetCurrentProcessId(), pFd, nByte)); + + if( pFd->nFetchOut>0 ) return SQLITE_OK; + + if( nMap<0 ){ + rc = winFileSize((sqlite3_file*)pFd, &nMap); + if( rc ){ + OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_IOERR_FSTAT\n", + osGetCurrentProcessId(), pFd)); + return SQLITE_IOERR_FSTAT; + } + } + if( nMap>pFd->mmapSizeMax ){ + nMap = pFd->mmapSizeMax; + } + nMap &= ~(sqlite3_int64)(winSysInfo.dwPageSize - 1); + + if( nMap==0 && pFd->mmapSize>0 ){ + winUnmapfile(pFd); + } + if( nMap!=pFd->mmapSize ){ + void *pNew = 0; + DWORD protect = PAGE_READONLY; + DWORD flags = FILE_MAP_READ; + + winUnmapfile(pFd); + if( (pFd->ctrlFlags & WINFILE_RDONLY)==0 ){ + protect = PAGE_READWRITE; + flags |= FILE_MAP_WRITE; + } +#if SQLITE_OS_WINRT + pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL); +#elif defined(SQLITE_WIN32_HAS_WIDE) + pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect, + (DWORD)((nMap>>32) & 0xffffffff), + (DWORD)(nMap & 0xffffffff), NULL); +#elif defined(SQLITE_WIN32_HAS_ANSI) + pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect, + (DWORD)((nMap>>32) & 0xffffffff), + (DWORD)(nMap & 0xffffffff), NULL); +#endif + if( pFd->hMap==NULL ){ + pFd->lastErrno = osGetLastError(); + rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, + "winMapfile1", pFd->zPath); + /* Log the error, but continue normal operation using xRead/xWrite */ + OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=%s\n", + osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); + return SQLITE_OK; + } + assert( (nMap % winSysInfo.dwPageSize)==0 ); + assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff ); +#if SQLITE_OS_WINRT + pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap); +#else + pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap); +#endif + if( pNew==NULL ){ + osCloseHandle(pFd->hMap); + pFd->hMap = NULL; + pFd->lastErrno = osGetLastError(); + rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, + "winMapfile2", pFd->zPath); + /* Log the error, but continue normal operation using xRead/xWrite */ + OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=%s\n", + osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); + return SQLITE_OK; + } + pFd->pMapRegion = pNew; + pFd->mmapSize = nMap; + pFd->mmapSizeActual = nMap; + } + + OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFd)); + return SQLITE_OK; +} +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ + +/* +** If possible, return a pointer to a mapping of file fd starting at offset +** iOff. The mapping must be valid for at least nAmt bytes. +** +** If such a pointer can be obtained, store it in *pp and return SQLITE_OK. +** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK. +** Finally, if an error does occur, return an SQLite error code. The final +** value of *pp is undefined in this case. +** +** If this function does return a pointer, the caller must eventually +** release the reference by calling winUnfetch(). +*/ +static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ +#if SQLITE_MAX_MMAP_SIZE>0 + winFile *pFd = (winFile*)fd; /* The underlying database file */ +#endif + *pp = 0; + + OSTRACE(("FETCH pid=%lu, pFile=%p, offset=%lld, amount=%d, pp=%p\n", + osGetCurrentProcessId(), fd, iOff, nAmt, pp)); + +#if SQLITE_MAX_MMAP_SIZE>0 + if( pFd->mmapSizeMax>0 ){ + if( pFd->pMapRegion==0 ){ + int rc = winMapfile(pFd, -1); + if( rc!=SQLITE_OK ){ + OSTRACE(("FETCH pid=%lu, pFile=%p, rc=%s\n", + osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); + return rc; + } + } + if( pFd->mmapSize >= iOff+nAmt ){ + *pp = &((u8 *)pFd->pMapRegion)[iOff]; + pFd->nFetchOut++; + } + } +#endif + + OSTRACE(("FETCH pid=%lu, pFile=%p, pp=%p, *pp=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), fd, pp, *pp)); + return SQLITE_OK; +} + +/* +** If the third argument is non-NULL, then this function releases a +** reference obtained by an earlier call to winFetch(). The second +** argument passed to this function must be the same as the corresponding +** argument that was passed to the winFetch() invocation. +** +** Or, if the third argument is NULL, then this function is being called +** to inform the VFS layer that, according to POSIX, any existing mapping +** may now be invalid and should be unmapped. +*/ +static int winUnfetch(sqlite3_file *fd, i64 iOff, void *p){ +#if SQLITE_MAX_MMAP_SIZE>0 + winFile *pFd = (winFile*)fd; /* The underlying database file */ + + /* If p==0 (unmap the entire file) then there must be no outstanding + ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), + ** then there must be at least one outstanding. */ + assert( (p==0)==(pFd->nFetchOut==0) ); + + /* If p!=0, it must match the iOff value. */ + assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] ); + + OSTRACE(("UNFETCH pid=%lu, pFile=%p, offset=%lld, p=%p\n", + osGetCurrentProcessId(), pFd, iOff, p)); + + if( p ){ + pFd->nFetchOut--; + }else{ + /* FIXME: If Windows truly always prevents truncating or deleting a + ** file while a mapping is held, then the following winUnmapfile() call + ** is unnecessary can be omitted - potentially improving + ** performance. */ + winUnmapfile(pFd); + } + + assert( pFd->nFetchOut>=0 ); +#endif + + OSTRACE(("UNFETCH pid=%lu, pFile=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), fd)); + return SQLITE_OK; +} + +/* +** Here ends the implementation of all sqlite3_file methods. +** +********************** End sqlite3_file Methods ******************************* +******************************************************************************/ + +/* +** This vector defines all the methods that can operate on an +** sqlite3_file for win32. +*/ +static const sqlite3_io_methods winIoMethod = { + 3, /* iVersion */ + winClose, /* xClose */ + winRead, /* xRead */ + winWrite, /* xWrite */ + winTruncate, /* xTruncate */ + winSync, /* xSync */ + winFileSize, /* xFileSize */ + winLock, /* xLock */ + winUnlock, /* xUnlock */ + winCheckReservedLock, /* xCheckReservedLock */ + winFileControl, /* xFileControl */ + winSectorSize, /* xSectorSize */ + winDeviceCharacteristics, /* xDeviceCharacteristics */ + winShmMap, /* xShmMap */ + winShmLock, /* xShmLock */ + winShmBarrier, /* xShmBarrier */ + winShmUnmap, /* xShmUnmap */ + winFetch, /* xFetch */ + winUnfetch /* xUnfetch */ +}; + +/**************************************************************************** +**************************** sqlite3_vfs methods **************************** +** +** This division contains the implementation of methods on the +** sqlite3_vfs object. +*/ + +#if defined(__CYGWIN__) +/* +** Convert a filename from whatever the underlying operating system +** supports for filenames into UTF-8. Space to hold the result is +** obtained from malloc and must be freed by the calling function. +*/ +static char *winConvertToUtf8Filename(const void *zFilename){ + char *zConverted = 0; + if( osIsNT() ){ + zConverted = winUnicodeToUtf8(zFilename); + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + zConverted = sqlite3_win32_mbcs_to_utf8(zFilename); + } +#endif + /* caller will handle out of memory */ + return zConverted; +} +#endif + +/* +** Convert a UTF-8 filename into whatever form the underlying +** operating system wants filenames in. Space to hold the result +** is obtained from malloc and must be freed by the calling +** function. +*/ +static void *winConvertFromUtf8Filename(const char *zFilename){ + void *zConverted = 0; + if( osIsNT() ){ + zConverted = winUtf8ToUnicode(zFilename); + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + zConverted = sqlite3_win32_utf8_to_mbcs(zFilename); + } +#endif + /* caller will handle out of memory */ + return zConverted; +} + +/* +** This function returns non-zero if the specified UTF-8 string buffer +** ends with a directory separator character or one was successfully +** added to it. +*/ +static int winMakeEndInDirSep(int nBuf, char *zBuf){ + if( zBuf ){ + int nLen = sqlite3Strlen30(zBuf); + if( nLen>0 ){ + if( winIsDirSep(zBuf[nLen-1]) ){ + return 1; + }else if( nLen+1mxPathname; nBuf = nMax + 2; + zBuf = sqlite3MallocZero( nBuf ); + if( !zBuf ){ + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); + return SQLITE_IOERR_NOMEM; + } + + /* Figure out the effective temporary directory. First, check if one + ** has been explicitly set by the application; otherwise, use the one + ** configured by the operating system. + */ + nDir = nMax - (nPre + 15); + assert( nDir>0 ); + if( sqlite3_temp_directory ){ + int nDirLen = sqlite3Strlen30(sqlite3_temp_directory); + if( nDirLen>0 ){ + if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){ + nDirLen++; + } + if( nDirLen>nDir ){ + sqlite3_free(zBuf); + OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); + return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0); + } + sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory); + } + } +#if defined(__CYGWIN__) + else{ + static const char *azDirs[] = { + 0, /* getenv("SQLITE_TMPDIR") */ + 0, /* getenv("TMPDIR") */ + 0, /* getenv("TMP") */ + 0, /* getenv("TEMP") */ + 0, /* getenv("USERPROFILE") */ + "/var/tmp", + "/usr/tmp", + "/tmp", + ".", + 0 /* List terminator */ + }; + unsigned int i; + const char *zDir = 0; + + if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR"); + if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); + if( !azDirs[2] ) azDirs[2] = getenv("TMP"); + if( !azDirs[3] ) azDirs[3] = getenv("TEMP"); + if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE"); + for(i=0; i/etilqs_XXXXXXXXXXXXXXX\0\0" + ** + ** If not, return SQLITE_ERROR. The number 17 is used here in order to + ** account for the space used by the 15 character random suffix and the + ** two trailing NUL characters. The final directory separator character + ** has already added if it was not already present. + */ + nLen = sqlite3Strlen30(zBuf); + if( (nLen + nPre + 17) > nBuf ){ + sqlite3_free(zBuf); + OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); + return winLogError(SQLITE_ERROR, 0, "winGetTempname5", 0); + } + + sqlite3_snprintf(nBuf-16-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX); + + j = sqlite3Strlen30(zBuf); + sqlite3_randomness(15, &zBuf[j]); + for(i=0; i<15; i++, j++){ + zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; + } + zBuf[j] = 0; + zBuf[j+1] = 0; + *pzBuf = zBuf; + + OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf)); + return SQLITE_OK; +} + +/* +** Return TRUE if the named file is really a directory. Return false if +** it is something other than a directory, or if there is any kind of memory +** allocation failure. +*/ +static int winIsDir(const void *zConverted){ + DWORD attr; + int rc = 0; + DWORD lastErrno; + + if( osIsNT() ){ + int cnt = 0; + WIN32_FILE_ATTRIBUTE_DATA sAttrData; + memset(&sAttrData, 0, sizeof(sAttrData)); + while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, + GetFileExInfoStandard, + &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} + if( !rc ){ + return 0; /* Invalid name? */ + } + attr = sAttrData.dwFileAttributes; +#if SQLITE_OS_WINCE==0 + }else{ + attr = osGetFileAttributesA((char*)zConverted); +#endif + } + return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY); +} + +/* +** Open a file. +*/ +static int winOpen( + sqlite3_vfs *pVfs, /* Used to get maximum path name length */ + const char *zName, /* Name of the file (UTF-8) */ + sqlite3_file *id, /* Write the SQLite file handle here */ + int flags, /* Open mode flags */ + int *pOutFlags /* Status return flags */ +){ + HANDLE h; + DWORD lastErrno = 0; + DWORD dwDesiredAccess; + DWORD dwShareMode; + DWORD dwCreationDisposition; + DWORD dwFlagsAndAttributes = 0; +#if SQLITE_OS_WINCE + int isTemp = 0; +#endif + winFile *pFile = (winFile*)id; + void *zConverted; /* Filename in OS encoding */ + const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */ + int cnt = 0; + + /* If argument zPath is a NULL pointer, this function is required to open + ** a temporary file. Use this buffer to store the file name in. + */ + char *zTmpname = 0; /* For temporary filename, if necessary. */ + + int rc = SQLITE_OK; /* Function Return Code */ +#if !defined(NDEBUG) || SQLITE_OS_WINCE + int eType = flags&0xFFFFFF00; /* Type of file to open */ +#endif + + int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); + int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); + int isCreate = (flags & SQLITE_OPEN_CREATE); + int isReadonly = (flags & SQLITE_OPEN_READONLY); + int isReadWrite = (flags & SQLITE_OPEN_READWRITE); + +#ifndef NDEBUG + int isOpenJournal = (isCreate && ( + eType==SQLITE_OPEN_MASTER_JOURNAL + || eType==SQLITE_OPEN_MAIN_JOURNAL + || eType==SQLITE_OPEN_WAL + )); +#endif + + OSTRACE(("OPEN name=%s, pFile=%p, flags=%x, pOutFlags=%p\n", + zUtf8Name, id, flags, pOutFlags)); + + /* Check the following statements are true: + ** + ** (a) Exactly one of the READWRITE and READONLY flags must be set, and + ** (b) if CREATE is set, then READWRITE must also be set, and + ** (c) if EXCLUSIVE is set, then CREATE must also be set. + ** (d) if DELETEONCLOSE is set, then CREATE must also be set. + */ + assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); + assert(isCreate==0 || isReadWrite); + assert(isExclusive==0 || isCreate); + assert(isDelete==0 || isCreate); + + /* The main DB, main journal, WAL file and master journal are never + ** automatically deleted. Nor are they ever temporary files. */ + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); + + /* Assert that the upper layer has set one of the "file-type" flags. */ + assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB + || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL + || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL + || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL + ); + + assert( pFile!=0 ); + memset(pFile, 0, sizeof(winFile)); + pFile->h = INVALID_HANDLE_VALUE; + +#if SQLITE_OS_WINRT + if( !zUtf8Name && !sqlite3_temp_directory ){ + sqlite3_log(SQLITE_ERROR, + "sqlite3_temp_directory variable should be set for WinRT"); + } +#endif + + /* If the second argument to this function is NULL, generate a + ** temporary file name to use + */ + if( !zUtf8Name ){ + assert( isDelete && !isOpenJournal ); + rc = winGetTempname(pVfs, &zTmpname); + if( rc!=SQLITE_OK ){ + OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc))); + return rc; + } + zUtf8Name = zTmpname; + } + + /* Database filenames are double-zero terminated if they are not + ** URIs with parameters. Hence, they can always be passed into + ** sqlite3_uri_parameter(). + */ + assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) || + zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 ); + + /* Convert the filename to the system encoding. */ + zConverted = winConvertFromUtf8Filename(zUtf8Name); + if( zConverted==0 ){ + sqlite3_free(zTmpname); + OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name)); + return SQLITE_IOERR_NOMEM; + } + + if( winIsDir(zConverted) ){ + sqlite3_free(zConverted); + sqlite3_free(zTmpname); + OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name)); + return SQLITE_CANTOPEN_ISDIR; + } + + if( isReadWrite ){ + dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; + }else{ + dwDesiredAccess = GENERIC_READ; + } + + /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is + ** created. SQLite doesn't use it to indicate "exclusive access" + ** as it is usually understood. + */ + if( isExclusive ){ + /* Creates a new file, only if it does not already exist. */ + /* If the file exists, it fails. */ + dwCreationDisposition = CREATE_NEW; + }else if( isCreate ){ + /* Open existing file, or create if it doesn't exist */ + dwCreationDisposition = OPEN_ALWAYS; + }else{ + /* Opens a file, only if it exists. */ + dwCreationDisposition = OPEN_EXISTING; + } + + dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; + + if( isDelete ){ +#if SQLITE_OS_WINCE + dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN; + isTemp = 1; +#else + dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY + | FILE_ATTRIBUTE_HIDDEN + | FILE_FLAG_DELETE_ON_CLOSE; +#endif + }else{ + dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; + } + /* Reports from the internet are that performance is always + ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */ +#if SQLITE_OS_WINCE + dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; +#endif + + if( osIsNT() ){ +#if SQLITE_OS_WINRT + CREATEFILE2_EXTENDED_PARAMETERS extendedParameters; + extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); + extendedParameters.dwFileAttributes = + dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK; + extendedParameters.dwFileFlags = dwFlagsAndAttributes & FILE_FLAG_MASK; + extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS; + extendedParameters.lpSecurityAttributes = NULL; + extendedParameters.hTemplateFile = NULL; + while( (h = osCreateFile2((LPCWSTR)zConverted, + dwDesiredAccess, + dwShareMode, + dwCreationDisposition, + &extendedParameters))==INVALID_HANDLE_VALUE && + winRetryIoerr(&cnt, &lastErrno) ){ + /* Noop */ + } +#else + while( (h = osCreateFileW((LPCWSTR)zConverted, + dwDesiredAccess, + dwShareMode, NULL, + dwCreationDisposition, + dwFlagsAndAttributes, + NULL))==INVALID_HANDLE_VALUE && + winRetryIoerr(&cnt, &lastErrno) ){ + /* Noop */ + } +#endif + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + while( (h = osCreateFileA((LPCSTR)zConverted, + dwDesiredAccess, + dwShareMode, NULL, + dwCreationDisposition, + dwFlagsAndAttributes, + NULL))==INVALID_HANDLE_VALUE && + winRetryIoerr(&cnt, &lastErrno) ){ + /* Noop */ + } + } +#endif + winLogIoerr(cnt, __LINE__); + + OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name, + dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); + + if( h==INVALID_HANDLE_VALUE ){ + pFile->lastErrno = lastErrno; + winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); + sqlite3_free(zConverted); + sqlite3_free(zTmpname); + if( isReadWrite && !isExclusive ){ + return winOpen(pVfs, zName, id, + ((flags|SQLITE_OPEN_READONLY) & + ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), + pOutFlags); + }else{ + return SQLITE_CANTOPEN_BKPT; + } + } + + if( pOutFlags ){ + if( isReadWrite ){ + *pOutFlags = SQLITE_OPEN_READWRITE; + }else{ + *pOutFlags = SQLITE_OPEN_READONLY; + } + } + + OSTRACE(("OPEN file=%p, name=%s, access=%lx, pOutFlags=%p, *pOutFlags=%d, " + "rc=%s\n", h, zUtf8Name, dwDesiredAccess, pOutFlags, pOutFlags ? + *pOutFlags : 0, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); + +#if SQLITE_OS_WINCE + if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB + && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK + ){ + osCloseHandle(h); + sqlite3_free(zConverted); + sqlite3_free(zTmpname); + OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc))); + return rc; + } + if( isTemp ){ + pFile->zDeleteOnClose = zConverted; + }else +#endif + { + sqlite3_free(zConverted); + } + + sqlite3_free(zTmpname); + pFile->pMethod = &winIoMethod; + pFile->pVfs = pVfs; + pFile->h = h; + if( isReadonly ){ + pFile->ctrlFlags |= WINFILE_RDONLY; + } + if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){ + pFile->ctrlFlags |= WINFILE_PSOW; + } + pFile->lastErrno = NO_ERROR; + pFile->zPath = zName; +#if SQLITE_MAX_MMAP_SIZE>0 + pFile->hMap = NULL; + pFile->pMapRegion = 0; + pFile->mmapSize = 0; + pFile->mmapSizeActual = 0; + pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap; +#endif + + OpenCounter(+1); + return rc; +} + +/* +** Delete the named file. +** +** Note that Windows does not allow a file to be deleted if some other +** process has it open. Sometimes a virus scanner or indexing program +** will open a journal file shortly after it is created in order to do +** whatever it does. While this other process is holding the +** file open, we will be unable to delete it. To work around this +** problem, we delay 100 milliseconds and try to delete again. Up +** to MX_DELETION_ATTEMPTs deletion attempts are run before giving +** up and returning an error. +*/ +static int winDelete( + sqlite3_vfs *pVfs, /* Not used on win32 */ + const char *zFilename, /* Name of file to delete */ + int syncDir /* Not used on win32 */ +){ + int cnt = 0; + int rc; + DWORD attr; + DWORD lastErrno = 0; + void *zConverted; + UNUSED_PARAMETER(pVfs); + UNUSED_PARAMETER(syncDir); + + SimulateIOError(return SQLITE_IOERR_DELETE); + OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir)); + + zConverted = winConvertFromUtf8Filename(zFilename); + if( zConverted==0 ){ + OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); + return SQLITE_IOERR_NOMEM; + } + if( osIsNT() ){ + do { +#if SQLITE_OS_WINRT + WIN32_FILE_ATTRIBUTE_DATA sAttrData; + memset(&sAttrData, 0, sizeof(sAttrData)); + if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard, + &sAttrData) ){ + attr = sAttrData.dwFileAttributes; + }else{ + lastErrno = osGetLastError(); + if( lastErrno==ERROR_FILE_NOT_FOUND + || lastErrno==ERROR_PATH_NOT_FOUND ){ + rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ + }else{ + rc = SQLITE_ERROR; + } + break; + } +#else + attr = osGetFileAttributesW(zConverted); +#endif + if ( attr==INVALID_FILE_ATTRIBUTES ){ + lastErrno = osGetLastError(); + if( lastErrno==ERROR_FILE_NOT_FOUND + || lastErrno==ERROR_PATH_NOT_FOUND ){ + rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ + }else{ + rc = SQLITE_ERROR; + } + break; + } + if ( attr&FILE_ATTRIBUTE_DIRECTORY ){ + rc = SQLITE_ERROR; /* Files only. */ + break; + } + if ( osDeleteFileW(zConverted) ){ + rc = SQLITE_OK; /* Deleted OK. */ + break; + } + if ( !winRetryIoerr(&cnt, &lastErrno) ){ + rc = SQLITE_ERROR; /* No more retries. */ + break; + } + } while(1); + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + do { + attr = osGetFileAttributesA(zConverted); + if ( attr==INVALID_FILE_ATTRIBUTES ){ + lastErrno = osGetLastError(); + if( lastErrno==ERROR_FILE_NOT_FOUND + || lastErrno==ERROR_PATH_NOT_FOUND ){ + rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ + }else{ + rc = SQLITE_ERROR; + } + break; + } + if ( attr&FILE_ATTRIBUTE_DIRECTORY ){ + rc = SQLITE_ERROR; /* Files only. */ + break; + } + if ( osDeleteFileA(zConverted) ){ + rc = SQLITE_OK; /* Deleted OK. */ + break; + } + if ( !winRetryIoerr(&cnt, &lastErrno) ){ + rc = SQLITE_ERROR; /* No more retries. */ + break; + } + } while(1); + } +#endif + if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){ + rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename); + }else{ + winLogIoerr(cnt, __LINE__); + } + sqlite3_free(zConverted); + OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc))); + return rc; +} + +/* +** Check the existence and status of a file. +*/ +static int winAccess( + sqlite3_vfs *pVfs, /* Not used on win32 */ + const char *zFilename, /* Name of file to check */ + int flags, /* Type of test to make on this file */ + int *pResOut /* OUT: Result */ +){ + DWORD attr; + int rc = 0; + DWORD lastErrno = 0; + void *zConverted; + UNUSED_PARAMETER(pVfs); + + SimulateIOError( return SQLITE_IOERR_ACCESS; ); + OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", + zFilename, flags, pResOut)); + + zConverted = winConvertFromUtf8Filename(zFilename); + if( zConverted==0 ){ + OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); + return SQLITE_IOERR_NOMEM; + } + if( osIsNT() ){ + int cnt = 0; + WIN32_FILE_ATTRIBUTE_DATA sAttrData; + memset(&sAttrData, 0, sizeof(sAttrData)); + while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, + GetFileExInfoStandard, + &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} + if( rc ){ + /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file + ** as if it does not exist. + */ + if( flags==SQLITE_ACCESS_EXISTS + && sAttrData.nFileSizeHigh==0 + && sAttrData.nFileSizeLow==0 ){ + attr = INVALID_FILE_ATTRIBUTES; + }else{ + attr = sAttrData.dwFileAttributes; + } + }else{ + winLogIoerr(cnt, __LINE__); + if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){ + sqlite3_free(zConverted); + return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", + zFilename); + }else{ + attr = INVALID_FILE_ATTRIBUTES; + } + } + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + attr = osGetFileAttributesA((char*)zConverted); + } +#endif + sqlite3_free(zConverted); + switch( flags ){ + case SQLITE_ACCESS_READ: + case SQLITE_ACCESS_EXISTS: + rc = attr!=INVALID_FILE_ATTRIBUTES; + break; + case SQLITE_ACCESS_READWRITE: + rc = attr!=INVALID_FILE_ATTRIBUTES && + (attr & FILE_ATTRIBUTE_READONLY)==0; + break; + default: + assert(!"Invalid flags argument"); + } + *pResOut = rc; + OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", + zFilename, pResOut, *pResOut)); + return SQLITE_OK; +} + +/* +** Returns non-zero if the specified path name starts with a drive letter +** followed by a colon character. +*/ +static BOOL winIsDriveLetterAndColon( + const char *zPathname +){ + return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ); +} + +/* +** Returns non-zero if the specified path name should be used verbatim. If +** non-zero is returned from this function, the calling function must simply +** use the provided path name verbatim -OR- resolve it into a full path name +** using the GetFullPathName Win32 API function (if available). +*/ +static BOOL winIsVerbatimPathname( + const char *zPathname +){ + /* + ** If the path name starts with a forward slash or a backslash, it is either + ** a legal UNC name, a volume relative path, or an absolute path name in the + ** "Unix" format on Windows. There is no easy way to differentiate between + ** the final two cases; therefore, we return the safer return value of TRUE + ** so that callers of this function will simply use it verbatim. + */ + if ( winIsDirSep(zPathname[0]) ){ + return TRUE; + } + + /* + ** If the path name starts with a letter and a colon it is either a volume + ** relative path or an absolute path. Callers of this function must not + ** attempt to treat it as a relative path name (i.e. they should simply use + ** it verbatim). + */ + if ( winIsDriveLetterAndColon(zPathname) ){ + return TRUE; + } + + /* + ** If we get to this point, the path name should almost certainly be a purely + ** relative one (i.e. not a UNC name, not absolute, and not volume relative). + */ + return FALSE; +} + +/* +** Turn a relative pathname into a full pathname. Write the full +** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname +** bytes in size. +*/ +static int winFullPathname( + sqlite3_vfs *pVfs, /* Pointer to vfs object */ + const char *zRelative, /* Possibly relative input path */ + int nFull, /* Size of output buffer in bytes */ + char *zFull /* Output buffer */ +){ + +#if defined(__CYGWIN__) + SimulateIOError( return SQLITE_ERROR ); + UNUSED_PARAMETER(nFull); + assert( nFull>=pVfs->mxPathname ); + if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ + /* + ** NOTE: We are dealing with a relative path name and the data + ** directory has been set. Therefore, use it as the basis + ** for converting the relative path name to an absolute + ** one by prepending the data directory and a slash. + */ + char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); + if( !zOut ){ + return SQLITE_IOERR_NOMEM; + } + if( cygwin_conv_path( + (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) | + CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){ + sqlite3_free(zOut); + return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, + "winFullPathname1", zRelative); + }else{ + char *zUtf8 = winConvertToUtf8Filename(zOut); + if( !zUtf8 ){ + sqlite3_free(zOut); + return SQLITE_IOERR_NOMEM; + } + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", + sqlite3_data_directory, winGetDirSep(), zUtf8); + sqlite3_free(zUtf8); + sqlite3_free(zOut); + } + }else{ + char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); + if( !zOut ){ + return SQLITE_IOERR_NOMEM; + } + if( cygwin_conv_path( + (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A), + zRelative, zOut, pVfs->mxPathname+1)<0 ){ + sqlite3_free(zOut); + return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, + "winFullPathname2", zRelative); + }else{ + char *zUtf8 = winConvertToUtf8Filename(zOut); + if( !zUtf8 ){ + sqlite3_free(zOut); + return SQLITE_IOERR_NOMEM; + } + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8); + sqlite3_free(zUtf8); + sqlite3_free(zOut); + } + } + return SQLITE_OK; +#endif + +#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__) + SimulateIOError( return SQLITE_ERROR ); + /* WinCE has no concept of a relative pathname, or so I am told. */ + /* WinRT has no way to convert a relative path to an absolute one. */ + if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ + /* + ** NOTE: We are dealing with a relative path name and the data + ** directory has been set. Therefore, use it as the basis + ** for converting the relative path name to an absolute + ** one by prepending the data directory and a backslash. + */ + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", + sqlite3_data_directory, winGetDirSep(), zRelative); + }else{ + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative); + } + return SQLITE_OK; +#endif + +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) + DWORD nByte; + void *zConverted; + char *zOut; + + /* If this path name begins with "/X:", where "X" is any alphabetic + ** character, discard the initial "/" from the pathname. + */ + if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){ + zRelative++; + } + + /* It's odd to simulate an io-error here, but really this is just + ** using the io-error infrastructure to test that SQLite handles this + ** function failing. This function could fail if, for example, the + ** current working directory has been unlinked. + */ + SimulateIOError( return SQLITE_ERROR ); + if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ + /* + ** NOTE: We are dealing with a relative path name and the data + ** directory has been set. Therefore, use it as the basis + ** for converting the relative path name to an absolute + ** one by prepending the data directory and a backslash. + */ + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", + sqlite3_data_directory, winGetDirSep(), zRelative); + return SQLITE_OK; + } + zConverted = winConvertFromUtf8Filename(zRelative); + if( zConverted==0 ){ + return SQLITE_IOERR_NOMEM; + } + if( osIsNT() ){ + LPWSTR zTemp; + nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); + if( nByte==0 ){ + sqlite3_free(zConverted); + return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), + "winFullPathname1", zRelative); + } + nByte += 3; + zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); + if( zTemp==0 ){ + sqlite3_free(zConverted); + return SQLITE_IOERR_NOMEM; + } + nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); + if( nByte==0 ){ + sqlite3_free(zConverted); + sqlite3_free(zTemp); + return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), + "winFullPathname2", zRelative); + } + sqlite3_free(zConverted); + zOut = winUnicodeToUtf8(zTemp); + sqlite3_free(zTemp); + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + char *zTemp; + nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0); + if( nByte==0 ){ + sqlite3_free(zConverted); + return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), + "winFullPathname3", zRelative); + } + nByte += 3; + zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); + if( zTemp==0 ){ + sqlite3_free(zConverted); + return SQLITE_IOERR_NOMEM; + } + nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); + if( nByte==0 ){ + sqlite3_free(zConverted); + sqlite3_free(zTemp); + return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), + "winFullPathname4", zRelative); + } + sqlite3_free(zConverted); + zOut = sqlite3_win32_mbcs_to_utf8(zTemp); + sqlite3_free(zTemp); + } +#endif + if( zOut ){ + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut); + sqlite3_free(zOut); + return SQLITE_OK; + }else{ + return SQLITE_IOERR_NOMEM; + } +#endif +} + +#ifndef SQLITE_OMIT_LOAD_EXTENSION +/* +** Interfaces for opening a shared library, finding entry points +** within the shared library, and closing the shared library. +*/ +static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ + HANDLE h; +#if defined(__CYGWIN__) + int nFull = pVfs->mxPathname+1; + char *zFull = sqlite3MallocZero( nFull ); + void *zConverted = 0; + if( zFull==0 ){ + OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); + return 0; + } + if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){ + sqlite3_free(zFull); + OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); + return 0; + } + zConverted = winConvertFromUtf8Filename(zFull); + sqlite3_free(zFull); +#else + void *zConverted = winConvertFromUtf8Filename(zFilename); + UNUSED_PARAMETER(pVfs); +#endif + if( zConverted==0 ){ + OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); + return 0; + } + if( osIsNT() ){ +#if SQLITE_OS_WINRT + h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0); +#else + h = osLoadLibraryW((LPCWSTR)zConverted); +#endif + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + h = osLoadLibraryA((char*)zConverted); + } +#endif + OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)h)); + sqlite3_free(zConverted); + return (void*)h; +} +static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ + UNUSED_PARAMETER(pVfs); + winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut); +} +static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){ + FARPROC proc; + UNUSED_PARAMETER(pVfs); + proc = osGetProcAddressA((HANDLE)pH, zSym); + OSTRACE(("DLSYM handle=%p, symbol=%s, address=%p\n", + (void*)pH, zSym, (void*)proc)); + return (void(*)(void))proc; +} +static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){ + UNUSED_PARAMETER(pVfs); + osFreeLibrary((HANDLE)pHandle); + OSTRACE(("DLCLOSE handle=%p\n", (void*)pHandle)); +} +#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ + #define winDlOpen 0 + #define winDlError 0 + #define winDlSym 0 + #define winDlClose 0 +#endif + + +/* +** Write up to nBuf bytes of randomness into zBuf. +*/ +static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ + int n = 0; + UNUSED_PARAMETER(pVfs); +#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) + n = nBuf; + memset(zBuf, 0, nBuf); +#else + if( sizeof(SYSTEMTIME)<=nBuf-n ){ + SYSTEMTIME x; + osGetSystemTime(&x); + memcpy(&zBuf[n], &x, sizeof(x)); + n += sizeof(x); + } + if( sizeof(DWORD)<=nBuf-n ){ + DWORD pid = osGetCurrentProcessId(); + memcpy(&zBuf[n], &pid, sizeof(pid)); + n += sizeof(pid); + } +#if SQLITE_OS_WINRT + if( sizeof(ULONGLONG)<=nBuf-n ){ + ULONGLONG cnt = osGetTickCount64(); + memcpy(&zBuf[n], &cnt, sizeof(cnt)); + n += sizeof(cnt); + } +#else + if( sizeof(DWORD)<=nBuf-n ){ + DWORD cnt = osGetTickCount(); + memcpy(&zBuf[n], &cnt, sizeof(cnt)); + n += sizeof(cnt); + } +#endif + if( sizeof(LARGE_INTEGER)<=nBuf-n ){ + LARGE_INTEGER i; + osQueryPerformanceCounter(&i); + memcpy(&zBuf[n], &i, sizeof(i)); + n += sizeof(i); + } +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID + if( sizeof(UUID)<=nBuf-n ){ + UUID id; + memset(&id, 0, sizeof(UUID)); + osUuidCreate(&id); + memcpy(zBuf, &id, sizeof(UUID)); + n += sizeof(UUID); + } + if( sizeof(UUID)<=nBuf-n ){ + UUID id; + memset(&id, 0, sizeof(UUID)); + osUuidCreateSequential(&id); + memcpy(zBuf, &id, sizeof(UUID)); + n += sizeof(UUID); + } +#endif +#endif /* defined(SQLITE_TEST) || defined(SQLITE_ZERO_PRNG_SEED) */ + return n; +} + + +/* +** Sleep for a little while. Return the amount of time slept. +*/ +static int winSleep(sqlite3_vfs *pVfs, int microsec){ + sqlite3_win32_sleep((microsec+999)/1000); + UNUSED_PARAMETER(pVfs); + return ((microsec+999)/1000)*1000; +} + +/* +** The following variable, if set to a non-zero value, is interpreted as +** the number of seconds since 1970 and is used to set the result of +** sqlite3OsCurrentTime() during testing. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */ +#endif + +/* +** Find the current time (in Universal Coordinated Time). Write into *piNow +** the current time and date as a Julian Day number times 86_400_000. In +** other words, write into *piNow the number of milliseconds since the Julian +** epoch of noon in Greenwich on November 24, 4714 B.C according to the +** proleptic Gregorian calendar. +** +** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date +** cannot be found. +*/ +static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){ + /* FILETIME structure is a 64-bit value representing the number of + 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). + */ + FILETIME ft; + static const sqlite3_int64 winFiletimeEpoch = 23058135*(sqlite3_int64)8640000; +#ifdef SQLITE_TEST + static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; +#endif + /* 2^32 - to avoid use of LL and warnings in gcc */ + static const sqlite3_int64 max32BitValue = + (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + + (sqlite3_int64)294967296; + +#if SQLITE_OS_WINCE + SYSTEMTIME time; + osGetSystemTime(&time); + /* if SystemTimeToFileTime() fails, it returns zero. */ + if (!osSystemTimeToFileTime(&time,&ft)){ + return SQLITE_ERROR; + } +#else + osGetSystemTimeAsFileTime( &ft ); +#endif + + *piNow = winFiletimeEpoch + + ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) + + (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000; + +#ifdef SQLITE_TEST + if( sqlite3_current_time ){ + *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; + } +#endif + UNUSED_PARAMETER(pVfs); + return SQLITE_OK; +} + +/* +** 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. +*/ +static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ + int rc; + sqlite3_int64 i; + rc = winCurrentTimeInt64(pVfs, &i); + if( !rc ){ + *prNow = i/86400000.0; + } + return rc; +} + +/* +** The idea is that this function works like a combination of +** GetLastError() and FormatMessage() on Windows (or errno and +** strerror_r() on Unix). After an error is returned by an OS +** function, SQLite calls this function with zBuf pointing to +** a buffer of nBuf bytes. The OS layer should populate the +** buffer with a nul-terminated UTF-8 encoded error message +** describing the last IO error to have occurred within the calling +** thread. +** +** If the error message is too large for the supplied buffer, +** it should be truncated. The return value of xGetLastError +** is zero if the error message fits in the buffer, or non-zero +** otherwise (if the message was truncated). If non-zero is returned, +** then it is not necessary to include the nul-terminator character +** in the output buffer. +** +** Not supplying an error message will have no adverse effect +** on SQLite. It is fine to have an implementation that never +** returns an error message: +** +** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ +** assert(zBuf[0]=='\0'); +** return 0; +** } +** +** However if an error message is supplied, it will be incorporated +** by sqlite into the error message available to the user using +** sqlite3_errmsg(), possibly making IO errors easier to debug. +*/ +static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ + UNUSED_PARAMETER(pVfs); + return winGetLastErrorMsg(osGetLastError(), nBuf, zBuf); +} + +/* +** Initialize and deinitialize the operating system interface. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){ + static sqlite3_vfs winVfs = { + 3, /* iVersion */ + sizeof(winFile), /* szOsFile */ + SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ + 0, /* pNext */ + "win32", /* zName */ + 0, /* pAppData */ + winOpen, /* xOpen */ + winDelete, /* xDelete */ + winAccess, /* xAccess */ + winFullPathname, /* xFullPathname */ + winDlOpen, /* xDlOpen */ + winDlError, /* xDlError */ + winDlSym, /* xDlSym */ + winDlClose, /* xDlClose */ + winRandomness, /* xRandomness */ + winSleep, /* xSleep */ + winCurrentTime, /* xCurrentTime */ + winGetLastError, /* xGetLastError */ + winCurrentTimeInt64, /* xCurrentTimeInt64 */ + winSetSystemCall, /* xSetSystemCall */ + winGetSystemCall, /* xGetSystemCall */ + winNextSystemCall, /* xNextSystemCall */ + }; +#if defined(SQLITE_WIN32_HAS_WIDE) + static sqlite3_vfs winLongPathVfs = { + 3, /* iVersion */ + sizeof(winFile), /* szOsFile */ + SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ + 0, /* pNext */ + "win32-longpath", /* zName */ + 0, /* pAppData */ + winOpen, /* xOpen */ + winDelete, /* xDelete */ + winAccess, /* xAccess */ + winFullPathname, /* xFullPathname */ + winDlOpen, /* xDlOpen */ + winDlError, /* xDlError */ + winDlSym, /* xDlSym */ + winDlClose, /* xDlClose */ + winRandomness, /* xRandomness */ + winSleep, /* xSleep */ + winCurrentTime, /* xCurrentTime */ + winGetLastError, /* xGetLastError */ + winCurrentTimeInt64, /* xCurrentTimeInt64 */ + winSetSystemCall, /* xSetSystemCall */ + winGetSystemCall, /* xGetSystemCall */ + winNextSystemCall, /* xNextSystemCall */ + }; +#endif + + /* Double-check that the aSyscall[] array has been constructed + ** correctly. See ticket [bb3a86e890c8e96ab] */ + assert( ArraySize(aSyscall)==80 ); + + /* get memory map allocation granularity */ + memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); +#if SQLITE_OS_WINRT + osGetNativeSystemInfo(&winSysInfo); +#else + osGetSystemInfo(&winSysInfo); +#endif + assert( winSysInfo.dwAllocationGranularity>0 ); + assert( winSysInfo.dwPageSize>0 ); + + sqlite3_vfs_register(&winVfs, 1); + +#if defined(SQLITE_WIN32_HAS_WIDE) + sqlite3_vfs_register(&winLongPathVfs, 0); +#endif + + return SQLITE_OK; +} + +SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void){ +#if SQLITE_OS_WINRT + if( sleepObj!=NULL ){ + osCloseHandle(sleepObj); + sleepObj = NULL; + } +#endif + return SQLITE_OK; +} + +#endif /* SQLITE_OS_WIN */ + +/************** End of os_win.c **********************************************/ +/************** Begin file bitvec.c ******************************************/ +/* +** 2008 February 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 an object that represents a fixed-length +** bitmap. Bits are numbered starting with 1. +** +** A bitmap is used to record which pages of a database file have been +** journalled during a transaction, or which pages have the "dont-write" +** property. Usually only a few pages are meet either condition. +** So the bitmap is usually sparse and has low cardinality. +** But sometimes (for example when during a DROP of a large table) most +** or all of the pages in a database can get journalled. In those cases, +** the bitmap becomes dense with high cardinality. The algorithm needs +** to handle both cases well. +** +** The size of the bitmap is fixed when the object is created. +** +** All bits are clear when the bitmap is created. Individual bits +** may be set or cleared one at a time. +** +** Test operations are about 100 times more common that set operations. +** Clear operations are exceedingly rare. There are usually between +** 5 and 500 set operations per Bitvec object, though the number of sets can +** sometimes grow into tens of thousands or larger. The size of the +** Bitvec object is the number of pages in the database file at the +** start of a transaction, and is thus usually less than a few thousand, +** but can be as large as 2 billion for a really big database. +*/ + +/* Size of the Bitvec structure in bytes. */ +#define BITVEC_SZ 512 + +/* Round the union size down to the nearest pointer boundary, since that's how +** it will be aligned within the Bitvec struct. */ +#define BITVEC_USIZE (((BITVEC_SZ-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*)) + +/* Type of the array "element" for the bitmap representation. +** Should be a power of 2, and ideally, evenly divide into BITVEC_USIZE. +** Setting this to the "natural word" size of your CPU may improve +** performance. */ +#define BITVEC_TELEM u8 +/* Size, in bits, of the bitmap element. */ +#define BITVEC_SZELEM 8 +/* Number of elements in a bitmap array. */ +#define BITVEC_NELEM (BITVEC_USIZE/sizeof(BITVEC_TELEM)) +/* Number of bits in the bitmap array. */ +#define BITVEC_NBIT (BITVEC_NELEM*BITVEC_SZELEM) + +/* Number of u32 values in hash table. */ +#define BITVEC_NINT (BITVEC_USIZE/sizeof(u32)) +/* Maximum number of entries in hash table before +** sub-dividing and re-hashing. */ +#define BITVEC_MXHASH (BITVEC_NINT/2) +/* Hashing function for the aHash representation. +** Empirical testing showed that the *37 multiplier +** (an arbitrary prime)in the hash function provided +** no fewer collisions than the no-op *1. */ +#define BITVEC_HASH(X) (((X)*1)%BITVEC_NINT) + +#define BITVEC_NPTR (BITVEC_USIZE/sizeof(Bitvec *)) + + +/* +** A bitmap is an instance of the following structure. +** +** This bitmap records the existence of zero or more bits +** with values between 1 and iSize, inclusive. +** +** There are three possible representations of the bitmap. +** If iSize<=BITVEC_NBIT, then Bitvec.u.aBitmap[] is a straight +** bitmap. The least significant bit is bit 1. +** +** If iSize>BITVEC_NBIT and iDivisor==0 then Bitvec.u.aHash[] is +** a hash table that will hold up to BITVEC_MXHASH distinct values. +** +** Otherwise, the value i is redirected into one of BITVEC_NPTR +** sub-bitmaps pointed to by Bitvec.u.apSub[]. Each subbitmap +** handles up to iDivisor separate values of i. apSub[0] holds +** values between 1 and iDivisor. apSub[1] holds values between +** iDivisor+1 and 2*iDivisor. apSub[N] holds values between +** N*iDivisor+1 and (N+1)*iDivisor. Each subbitmap is normalized +** to hold deal with values between 1 and iDivisor. +*/ +struct Bitvec { + u32 iSize; /* Maximum bit index. Max iSize is 4,294,967,296. */ + u32 nSet; /* Number of bits that are set - only valid for aHash + ** element. Max is BITVEC_NINT. For BITVEC_SZ of 512, + ** this would be 125. */ + u32 iDivisor; /* Number of bits handled by each apSub[] entry. */ + /* Should >=0 for apSub element. */ + /* Max iDivisor is max(u32) / BITVEC_NPTR + 1. */ + /* For a BITVEC_SZ of 512, this would be 34,359,739. */ + union { + BITVEC_TELEM aBitmap[BITVEC_NELEM]; /* Bitmap representation */ + u32 aHash[BITVEC_NINT]; /* Hash table representation */ + Bitvec *apSub[BITVEC_NPTR]; /* Recursive representation */ + } u; +}; + +/* +** Create a new bitmap object able to handle bits between 0 and iSize, +** inclusive. Return a pointer to the new object. Return NULL if +** malloc fails. +*/ +SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32 iSize){ + Bitvec *p; + assert( sizeof(*p)==BITVEC_SZ ); + p = sqlite3MallocZero( sizeof(*p) ); + if( p ){ + p->iSize = iSize; + } + return p; +} + +/* +** Check to see if the i-th bit is set. Return true or false. +** If p is NULL (if the bitmap has not been created) or if +** i is out of range, then return false. +*/ +SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec *p, u32 i){ + if( p==0 ) return 0; + if( i>p->iSize || i==0 ) return 0; + i--; + while( p->iDivisor ){ + u32 bin = i/p->iDivisor; + i = i%p->iDivisor; + p = p->u.apSub[bin]; + if (!p) { + return 0; + } + } + if( p->iSize<=BITVEC_NBIT ){ + return (p->u.aBitmap[i/BITVEC_SZELEM] & (1<<(i&(BITVEC_SZELEM-1))))!=0; + } else{ + u32 h = BITVEC_HASH(i++); + while( p->u.aHash[h] ){ + if( p->u.aHash[h]==i ) return 1; + h = (h+1) % BITVEC_NINT; + } + return 0; + } +} + +/* +** Set the i-th bit. Return 0 on success and an error code if +** anything goes wrong. +** +** This routine might cause sub-bitmaps to be allocated. Failing +** to get the memory needed to hold the sub-bitmap is the only +** that can go wrong with an insert, assuming p and i are valid. +** +** The calling function must ensure that p is a valid Bitvec object +** and that the value for "i" is within range of the Bitvec object. +** Otherwise the behavior is undefined. +*/ +SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec *p, u32 i){ + u32 h; + if( p==0 ) return SQLITE_OK; + assert( i>0 ); + assert( i<=p->iSize ); + i--; + while((p->iSize > BITVEC_NBIT) && p->iDivisor) { + u32 bin = i/p->iDivisor; + i = i%p->iDivisor; + if( p->u.apSub[bin]==0 ){ + p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor ); + if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM; + } + p = p->u.apSub[bin]; + } + if( p->iSize<=BITVEC_NBIT ){ + p->u.aBitmap[i/BITVEC_SZELEM] |= 1 << (i&(BITVEC_SZELEM-1)); + return SQLITE_OK; + } + h = BITVEC_HASH(i++); + /* if there wasn't a hash collision, and this doesn't */ + /* completely fill the hash, then just add it without */ + /* worring about sub-dividing and re-hashing. */ + if( !p->u.aHash[h] ){ + if (p->nSet<(BITVEC_NINT-1)) { + goto bitvec_set_end; + } else { + goto bitvec_set_rehash; + } + } + /* there was a collision, check to see if it's already */ + /* in hash, if not, try to find a spot for it */ + do { + if( p->u.aHash[h]==i ) return SQLITE_OK; + h++; + if( h>=BITVEC_NINT ) h = 0; + } while( p->u.aHash[h] ); + /* we didn't find it in the hash. h points to the first */ + /* available free spot. check to see if this is going to */ + /* make our hash too "full". */ +bitvec_set_rehash: + if( p->nSet>=BITVEC_MXHASH ){ + unsigned int j; + int rc; + u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash)); + if( aiValues==0 ){ + return SQLITE_NOMEM; + }else{ + memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); + memset(p->u.apSub, 0, sizeof(p->u.apSub)); + p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR; + rc = sqlite3BitvecSet(p, i); + for(j=0; jnSet++; + p->u.aHash[h] = i; + return SQLITE_OK; +} + +/* +** Clear the i-th bit. +** +** pBuf must be a pointer to at least BITVEC_SZ bytes of temporary storage +** that BitvecClear can use to rebuilt its hash table. +*/ +SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec *p, u32 i, void *pBuf){ + if( p==0 ) return; + assert( i>0 ); + i--; + while( p->iDivisor ){ + u32 bin = i/p->iDivisor; + i = i%p->iDivisor; + p = p->u.apSub[bin]; + if (!p) { + return; + } + } + if( p->iSize<=BITVEC_NBIT ){ + p->u.aBitmap[i/BITVEC_SZELEM] &= ~(1 << (i&(BITVEC_SZELEM-1))); + }else{ + unsigned int j; + u32 *aiValues = pBuf; + memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); + memset(p->u.aHash, 0, sizeof(p->u.aHash)); + p->nSet = 0; + for(j=0; jnSet++; + while( p->u.aHash[h] ){ + h++; + if( h>=BITVEC_NINT ) h = 0; + } + p->u.aHash[h] = aiValues[j]; + } + } + } +} + +/* +** Destroy a bitmap object. Reclaim all memory used. +*/ +SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec *p){ + if( p==0 ) return; + if( p->iDivisor ){ + unsigned int i; + for(i=0; iu.apSub[i]); + } + } + sqlite3_free(p); +} + +/* +** Return the value of the iSize parameter specified when Bitvec *p +** was created. +*/ +SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){ + return p->iSize; +} + +#ifndef SQLITE_OMIT_BUILTIN_TEST +/* +** Let V[] be an array of unsigned characters sufficient to hold +** up to N bits. Let I be an integer between 0 and N. 0<=I>3] |= (1<<(I&7)) +#define CLEARBIT(V,I) V[I>>3] &= ~(1<<(I&7)) +#define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0 + +/* +** This routine runs an extensive test of the Bitvec code. +** +** The input is an array of integers that acts as a program +** to test the Bitvec. The integers are opcodes followed +** by 0, 1, or 3 operands, depending on the opcode. Another +** opcode follows immediately after the last operand. +** +** There are 6 opcodes numbered from 0 through 5. 0 is the +** "halt" opcode and causes the test to end. +** +** 0 Halt and return the number of errors +** 1 N S X Set N bits beginning with S and incrementing by X +** 2 N S X Clear N bits beginning with S and incrementing by X +** 3 N Set N randomly chosen bits +** 4 N Clear N randomly chosen bits +** 5 N S X Set N bits from S increment X in array only, not in bitvec +** +** The opcodes 1 through 4 perform set and clear operations are performed +** on both a Bitvec object and on a linear array of bits obtained from malloc. +** Opcode 5 works on the linear array only, not on the Bitvec. +** Opcode 5 is used to deliberately induce a fault in order to +** confirm that error detection works. +** +** At the conclusion of the test the linear array is compared +** against the Bitvec object. If there are any differences, +** an error is returned. If they are the same, zero is returned. +** +** If a memory allocation error occurs, return -1. +*/ +SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){ + Bitvec *pBitvec = 0; + unsigned char *pV = 0; + int rc = -1; + int i, nx, pc, op; + void *pTmpSpace; + + /* Allocate the Bitvec to be tested and a linear array of + ** bits to act as the reference */ + pBitvec = sqlite3BitvecCreate( sz ); + pV = sqlite3MallocZero( (sz+7)/8 + 1 ); + pTmpSpace = sqlite3_malloc64(BITVEC_SZ); + if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end; + + /* NULL pBitvec tests */ + sqlite3BitvecSet(0, 1); + sqlite3BitvecClear(0, 1, pTmpSpace); + + /* Run the program */ + pc = 0; + while( (op = aOp[pc])!=0 ){ + switch( op ){ + case 1: + case 2: + case 5: { + nx = 4; + i = aOp[pc+2] - 1; + aOp[pc+2] += aOp[pc+3]; + break; + } + case 3: + case 4: + default: { + nx = 2; + sqlite3_randomness(sizeof(i), &i); + break; + } + } + if( (--aOp[pc+1]) > 0 ) nx = 0; + pc += nx; + i = (i & 0x7fffffff)%sz; + if( (op & 1)!=0 ){ + SETBIT(pV, (i+1)); + if( op!=5 ){ + if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end; + } + }else{ + CLEARBIT(pV, (i+1)); + sqlite3BitvecClear(pBitvec, i+1, pTmpSpace); + } + } + + /* Test to make sure the linear array exactly matches the + ** Bitvec object. Start with the assumption that they do + ** match (rc==0). Change rc to non-zero if a discrepancy + ** is found. + */ + rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1) + + sqlite3BitvecTest(pBitvec, 0) + + (sqlite3BitvecSize(pBitvec) - sz); + for(i=1; i<=sz; i++){ + if( (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){ + rc = i; + break; + } + } + + /* Free allocated structure */ +bitvec_end: + sqlite3_free(pTmpSpace); + sqlite3_free(pV); + sqlite3BitvecDestroy(pBitvec); + return rc; +} +#endif /* SQLITE_OMIT_BUILTIN_TEST */ + +/************** End of bitvec.c **********************************************/ +/************** Begin file pcache.c ******************************************/ +/* +** 2008 August 05 +** +** 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 that page cache. +*/ + +/* +** A complete page cache is an instance of this structure. +*/ +struct PCache { + PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */ + PgHdr *pSynced; /* Last synced page in dirty page list */ + int nRef; /* Number of referenced pages */ + int szCache; /* Configured cache size */ + int szPage; /* Size of every page in this cache */ + int szExtra; /* Size of extra space for each page */ + u8 bPurgeable; /* True if pages are on backing store */ + u8 eCreate; /* eCreate value for for xFetch() */ + int (*xStress)(void*,PgHdr*); /* Call to try make a page clean */ + void *pStress; /* Argument to xStress */ + sqlite3_pcache *pCache; /* Pluggable cache module */ + PgHdr *pPage1; /* Reference to page 1 */ +}; + +/********************************** Linked List Management ********************/ + +/* Allowed values for second argument to pcacheManageDirtyList() */ +#define PCACHE_DIRTYLIST_REMOVE 1 /* Remove pPage from dirty list */ +#define PCACHE_DIRTYLIST_ADD 2 /* Add pPage to the dirty list */ +#define PCACHE_DIRTYLIST_FRONT 3 /* Move pPage to the front of the list */ + +/* +** Manage pPage's participation on the dirty list. Bits of the addRemove +** argument determines what operation to do. The 0x01 bit means first +** remove pPage from the dirty list. The 0x02 means add pPage back to +** the dirty list. Doing both moves pPage to the front of the dirty list. +*/ +static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){ + PCache *p = pPage->pCache; + + if( addRemove & PCACHE_DIRTYLIST_REMOVE ){ + assert( pPage->pDirtyNext || pPage==p->pDirtyTail ); + assert( pPage->pDirtyPrev || pPage==p->pDirty ); + + /* Update the PCache1.pSynced variable if necessary. */ + if( p->pSynced==pPage ){ + PgHdr *pSynced = pPage->pDirtyPrev; + while( pSynced && (pSynced->flags&PGHDR_NEED_SYNC) ){ + pSynced = pSynced->pDirtyPrev; + } + p->pSynced = pSynced; + } + + if( pPage->pDirtyNext ){ + pPage->pDirtyNext->pDirtyPrev = pPage->pDirtyPrev; + }else{ + assert( pPage==p->pDirtyTail ); + p->pDirtyTail = pPage->pDirtyPrev; + } + if( pPage->pDirtyPrev ){ + pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext; + }else{ + assert( pPage==p->pDirty ); + p->pDirty = pPage->pDirtyNext; + if( p->pDirty==0 && p->bPurgeable ){ + assert( p->eCreate==1 ); + p->eCreate = 2; + } + } + pPage->pDirtyNext = 0; + pPage->pDirtyPrev = 0; + } + if( addRemove & PCACHE_DIRTYLIST_ADD ){ + assert( pPage->pDirtyNext==0 && pPage->pDirtyPrev==0 && p->pDirty!=pPage ); + + pPage->pDirtyNext = p->pDirty; + if( pPage->pDirtyNext ){ + assert( pPage->pDirtyNext->pDirtyPrev==0 ); + pPage->pDirtyNext->pDirtyPrev = pPage; + }else{ + p->pDirtyTail = pPage; + if( p->bPurgeable ){ + assert( p->eCreate==2 ); + p->eCreate = 1; + } + } + p->pDirty = pPage; + if( !p->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) ){ + p->pSynced = pPage; + } + } +} + +/* +** Wrapper around the pluggable caches xUnpin method. If the cache is +** being used for an in-memory database, this function is a no-op. +*/ +static void pcacheUnpin(PgHdr *p){ + if( p->pCache->bPurgeable ){ + if( p->pgno==1 ){ + p->pCache->pPage1 = 0; + } + sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0); + } +} + +/* +** Compute the number of pages of cache requested. p->szCache is the +** cache size requested by the "PRAGMA cache_size" statement. +** +** +*/ +static int numberOfCachePages(PCache *p){ + if( p->szCache>=0 ){ + /* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the + ** suggested cache size is set to N. */ + return p->szCache; + }else{ + /* IMPLEMENTATION-OF: R-61436-13639 If the argument N is negative, then + ** the number of cache pages is adjusted to use approximately abs(N*1024) + ** bytes of memory. */ + return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra)); + } +} + +/*************************************************** General Interfaces ****** +** +** Initialize and shutdown the page cache subsystem. Neither of these +** functions are threadsafe. +*/ +SQLITE_PRIVATE int sqlite3PcacheInitialize(void){ + if( sqlite3GlobalConfig.pcache2.xInit==0 ){ + /* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the + ** built-in default page cache is used instead of the application defined + ** page cache. */ + sqlite3PCacheSetDefault(); + } + return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg); +} +SQLITE_PRIVATE void sqlite3PcacheShutdown(void){ + if( sqlite3GlobalConfig.pcache2.xShutdown ){ + /* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */ + sqlite3GlobalConfig.pcache2.xShutdown(sqlite3GlobalConfig.pcache2.pArg); + } +} + +/* +** Return the size in bytes of a PCache object. +*/ +SQLITE_PRIVATE int sqlite3PcacheSize(void){ return sizeof(PCache); } + +/* +** Create a new PCache object. Storage space to hold the object +** has already been allocated and is passed in as the p pointer. +** The caller discovers how much space needs to be allocated by +** calling sqlite3PcacheSize(). +*/ +SQLITE_PRIVATE int sqlite3PcacheOpen( + int szPage, /* Size of every page */ + int szExtra, /* Extra space associated with each page */ + int bPurgeable, /* True if pages are on backing store */ + int (*xStress)(void*,PgHdr*),/* Call to try to make pages clean */ + void *pStress, /* Argument to xStress */ + PCache *p /* Preallocated space for the PCache */ +){ + memset(p, 0, sizeof(PCache)); + p->szPage = 1; + p->szExtra = szExtra; + p->bPurgeable = bPurgeable; + p->eCreate = 2; + p->xStress = xStress; + p->pStress = pStress; + p->szCache = 100; + return sqlite3PcacheSetPageSize(p, szPage); +} + +/* +** Change the page size for PCache object. The caller must ensure that there +** are no outstanding page references when this function is called. +*/ +SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){ + assert( pCache->nRef==0 && pCache->pDirty==0 ); + if( pCache->szPage ){ + sqlite3_pcache *pNew; + pNew = sqlite3GlobalConfig.pcache2.xCreate( + szPage, pCache->szExtra + ROUND8(sizeof(PgHdr)), + pCache->bPurgeable + ); + if( pNew==0 ) return SQLITE_NOMEM; + sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache)); + if( pCache->pCache ){ + sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); + } + pCache->pCache = pNew; + pCache->pPage1 = 0; + pCache->szPage = szPage; + } + return SQLITE_OK; +} + +/* +** Try to obtain a page from the cache. +** +** This routine returns a pointer to an sqlite3_pcache_page object if +** such an object is already in cache, or if a new one is created. +** This routine returns a NULL pointer if the object was not in cache +** and could not be created. +** +** The createFlags should be 0 to check for existing pages and should +** be 3 (not 1, but 3) to try to create a new page. +** +** If the createFlag is 0, then NULL is always returned if the page +** is not already in the cache. If createFlag is 1, then a new page +** is created only if that can be done without spilling dirty pages +** and without exceeding the cache size limit. +** +** The caller needs to invoke sqlite3PcacheFetchFinish() to properly +** initialize the sqlite3_pcache_page object and convert it into a +** PgHdr object. The sqlite3PcacheFetch() and sqlite3PcacheFetchFinish() +** routines are split this way for performance reasons. When separated +** they can both (usually) operate without having to push values to +** the stack on entry and pop them back off on exit, which saves a +** lot of pushing and popping. +*/ +SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch( + PCache *pCache, /* Obtain the page from this cache */ + Pgno pgno, /* Page number to obtain */ + int createFlag /* If true, create page if it does not exist already */ +){ + int eCreate; + + assert( pCache!=0 ); + assert( pCache->pCache!=0 ); + assert( createFlag==3 || createFlag==0 ); + assert( pgno>0 ); + + /* eCreate defines what to do if the page does not exist. + ** 0 Do not allocate a new page. (createFlag==0) + ** 1 Allocate a new page if doing so is inexpensive. + ** (createFlag==1 AND bPurgeable AND pDirty) + ** 2 Allocate a new page even it doing so is difficult. + ** (createFlag==1 AND !(bPurgeable AND pDirty) + */ + eCreate = createFlag & pCache->eCreate; + assert( eCreate==0 || eCreate==1 || eCreate==2 ); + assert( createFlag==0 || pCache->eCreate==eCreate ); + assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) ); + return sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate); +} + +/* +** If the sqlite3PcacheFetch() routine is unable to allocate a new +** page because new clean pages are available for reuse and the cache +** size limit has been reached, then this routine can be invoked to +** try harder to allocate a page. This routine might invoke the stress +** callback to spill dirty pages to the journal. It will then try to +** allocate the new page and will only fail to allocate a new page on +** an OOM error. +** +** This routine should be invoked only after sqlite3PcacheFetch() fails. +*/ +SQLITE_PRIVATE int sqlite3PcacheFetchStress( + PCache *pCache, /* Obtain the page from this cache */ + Pgno pgno, /* Page number to obtain */ + sqlite3_pcache_page **ppPage /* Write result here */ +){ + PgHdr *pPg; + if( pCache->eCreate==2 ) return 0; + + + /* Find a dirty page to write-out and recycle. First try to find a + ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC + ** cleared), but if that is not possible settle for any other + ** unreferenced dirty page. + */ + for(pPg=pCache->pSynced; + pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); + pPg=pPg->pDirtyPrev + ); + pCache->pSynced = pPg; + if( !pPg ){ + for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev); + } + if( pPg ){ + int rc; +#ifdef SQLITE_LOG_CACHE_SPILL + sqlite3_log(SQLITE_FULL, + "spill page %d making room for %d - cache used: %d/%d", + pPg->pgno, pgno, + sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache), + numberOfCachePages(pCache)); +#endif + rc = pCache->xStress(pCache->pStress, pPg); + if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ + return rc; + } + } + *ppPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2); + return *ppPage==0 ? SQLITE_NOMEM : SQLITE_OK; +} + +/* +** This is a helper routine for sqlite3PcacheFetchFinish() +** +** In the uncommon case where the page being fetched has not been +** initialized, this routine is invoked to do the initialization. +** This routine is broken out into a separate function since it +** requires extra stack manipulation that can be avoided in the common +** case. +*/ +static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit( + PCache *pCache, /* Obtain the page from this cache */ + Pgno pgno, /* Page number obtained */ + sqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */ +){ + PgHdr *pPgHdr; + assert( pPage!=0 ); + pPgHdr = (PgHdr*)pPage->pExtra; + assert( pPgHdr->pPage==0 ); + memset(pPgHdr, 0, sizeof(PgHdr)); + pPgHdr->pPage = pPage; + pPgHdr->pData = pPage->pBuf; + pPgHdr->pExtra = (void *)&pPgHdr[1]; + memset(pPgHdr->pExtra, 0, pCache->szExtra); + pPgHdr->pCache = pCache; + pPgHdr->pgno = pgno; + return sqlite3PcacheFetchFinish(pCache,pgno,pPage); +} + +/* +** This routine converts the sqlite3_pcache_page object returned by +** sqlite3PcacheFetch() into an initialized PgHdr object. This routine +** must be called after sqlite3PcacheFetch() in order to get a usable +** result. +*/ +SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish( + PCache *pCache, /* Obtain the page from this cache */ + Pgno pgno, /* Page number obtained */ + sqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */ +){ + PgHdr *pPgHdr; + + if( pPage==0 ) return 0; + pPgHdr = (PgHdr *)pPage->pExtra; + + if( !pPgHdr->pPage ){ + return pcacheFetchFinishWithInit(pCache, pgno, pPage); + } + if( 0==pPgHdr->nRef ){ + pCache->nRef++; + } + pPgHdr->nRef++; + if( pgno==1 ){ + pCache->pPage1 = pPgHdr; + } + return pPgHdr; +} + +/* +** Decrement the reference count on a page. If the page is clean and the +** reference count drops to 0, then it is made eligible for recycling. +*/ +SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){ + assert( p->nRef>0 ); + p->nRef--; + if( p->nRef==0 ){ + p->pCache->nRef--; + if( (p->flags&PGHDR_DIRTY)==0 ){ + pcacheUnpin(p); + }else if( p->pDirtyPrev!=0 ){ + /* Move the page to the head of the dirty list. */ + pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); + } + } +} + +/* +** Increase the reference count of a supplied page by 1. +*/ +SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr *p){ + assert(p->nRef>0); + p->nRef++; +} + +/* +** Drop a page from the cache. There must be exactly one reference to the +** page. This function deletes that reference, so after it returns the +** page pointed to by p is invalid. +*/ +SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){ + assert( p->nRef==1 ); + if( p->flags&PGHDR_DIRTY ){ + pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); + } + p->pCache->nRef--; + if( p->pgno==1 ){ + p->pCache->pPage1 = 0; + } + sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 1); +} + +/* +** Make sure the page is marked as dirty. If it isn't dirty already, +** make it so. +*/ +SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){ + p->flags &= ~PGHDR_DONT_WRITE; + assert( p->nRef>0 ); + if( 0==(p->flags & PGHDR_DIRTY) ){ + p->flags |= PGHDR_DIRTY; + pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD); + } +} + +/* +** Make sure the page is marked as clean. If it isn't clean already, +** make it so. +*/ +SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){ + if( (p->flags & PGHDR_DIRTY) ){ + pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); + p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC); + if( p->nRef==0 ){ + pcacheUnpin(p); + } + } +} + +/* +** Make every page in the cache clean. +*/ +SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache *pCache){ + PgHdr *p; + while( (p = pCache->pDirty)!=0 ){ + sqlite3PcacheMakeClean(p); + } +} + +/* +** Clear the PGHDR_NEED_SYNC flag from all dirty pages. +*/ +SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *pCache){ + PgHdr *p; + for(p=pCache->pDirty; p; p=p->pDirtyNext){ + p->flags &= ~PGHDR_NEED_SYNC; + } + pCache->pSynced = pCache->pDirtyTail; +} + +/* +** Change the page number of page p to newPgno. +*/ +SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){ + PCache *pCache = p->pCache; + assert( p->nRef>0 ); + assert( newPgno>0 ); + sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno); + p->pgno = newPgno; + if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){ + pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); + } +} + +/* +** Drop every cache entry whose page number is greater than "pgno". The +** caller must ensure that there are no outstanding references to any pages +** other than page 1 with a page number greater than pgno. +** +** If there is a reference to page 1 and the pgno parameter passed to this +** function is 0, then the data area associated with page 1 is zeroed, but +** the page object is not dropped. +*/ +SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){ + if( pCache->pCache ){ + PgHdr *p; + PgHdr *pNext; + for(p=pCache->pDirty; p; p=pNext){ + pNext = p->pDirtyNext; + /* This routine never gets call with a positive pgno except right + ** after sqlite3PcacheCleanAll(). So if there are dirty pages, + ** it must be that pgno==0. + */ + assert( p->pgno>0 ); + if( ALWAYS(p->pgno>pgno) ){ + assert( p->flags&PGHDR_DIRTY ); + sqlite3PcacheMakeClean(p); + } + } + if( pgno==0 && pCache->pPage1 ){ + memset(pCache->pPage1->pData, 0, pCache->szPage); + pgno = 1; + } + sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1); + } +} + +/* +** Close a cache. +*/ +SQLITE_PRIVATE void sqlite3PcacheClose(PCache *pCache){ + assert( pCache->pCache!=0 ); + sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); +} + +/* +** Discard the contents of the cache. +*/ +SQLITE_PRIVATE void sqlite3PcacheClear(PCache *pCache){ + sqlite3PcacheTruncate(pCache, 0); +} + +/* +** Merge two lists of pages connected by pDirty and in pgno order. +** Do not both fixing the pDirtyPrev pointers. +*/ +static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){ + PgHdr result, *pTail; + pTail = &result; + while( pA && pB ){ + if( pA->pgnopgno ){ + pTail->pDirty = pA; + pTail = pA; + pA = pA->pDirty; + }else{ + pTail->pDirty = pB; + pTail = pB; + pB = pB->pDirty; + } + } + if( pA ){ + pTail->pDirty = pA; + }else if( pB ){ + pTail->pDirty = pB; + }else{ + pTail->pDirty = 0; + } + return result.pDirty; +} + +/* +** Sort the list of pages in accending order by pgno. Pages are +** connected by pDirty pointers. The pDirtyPrev pointers are +** corrupted by this sort. +** +** Since there cannot be more than 2^31 distinct pages in a database, +** there cannot be more than 31 buckets required by the merge sorter. +** One extra bucket is added to catch overflow in case something +** ever changes to make the previous sentence incorrect. +*/ +#define N_SORT_BUCKET 32 +static PgHdr *pcacheSortDirtyList(PgHdr *pIn){ + PgHdr *a[N_SORT_BUCKET], *p; + int i; + memset(a, 0, sizeof(a)); + while( pIn ){ + p = pIn; + pIn = p->pDirty; + p->pDirty = 0; + for(i=0; ALWAYS(ipDirty; p; p=p->pDirtyNext){ + p->pDirty = p->pDirtyNext; + } + return pcacheSortDirtyList(pCache->pDirty); +} + +/* +** Return the total number of referenced pages held by the cache. +*/ +SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache *pCache){ + return pCache->nRef; +} + +/* +** Return the number of references to the page supplied as an argument. +*/ +SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr *p){ + return p->nRef; +} + +/* +** Return the total number of pages in the cache. +*/ +SQLITE_PRIVATE int sqlite3PcachePagecount(PCache *pCache){ + assert( pCache->pCache!=0 ); + return sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache); +} + +#ifdef SQLITE_TEST +/* +** Get the suggested cache-size value. +*/ +SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *pCache){ + return numberOfCachePages(pCache); +} +#endif + +/* +** Set the suggested cache-size value. +*/ +SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){ + assert( pCache->pCache!=0 ); + pCache->szCache = mxPage; + sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache, + numberOfCachePages(pCache)); +} + +/* +** Free up as much memory as possible from the page cache. +*/ +SQLITE_PRIVATE void sqlite3PcacheShrink(PCache *pCache){ + assert( pCache->pCache!=0 ); + sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache); +} + +/* +** Return the size of the header added by this middleware layer +** in the page-cache hierarchy. +*/ +SQLITE_PRIVATE int sqlite3HeaderSizePcache(void){ return ROUND8(sizeof(PgHdr)); } + + +#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) +/* +** For all dirty pages currently in the cache, invoke the specified +** callback. This is only used if the SQLITE_CHECK_PAGES macro is +** defined. +*/ +SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)){ + PgHdr *pDirty; + for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext){ + xIter(pDirty); + } +} +#endif + +/************** End of pcache.c **********************************************/ +/************** Begin file pcache1.c *****************************************/ +/* +** 2008 November 05 +** +** 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 the default page cache implementation (the +** sqlite3_pcache interface). It also contains part of the implementation +** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features. +** If the default page cache implementation is overridden, then neither of +** these two features are available. +*/ + + +typedef struct PCache1 PCache1; +typedef struct PgHdr1 PgHdr1; +typedef struct PgFreeslot PgFreeslot; +typedef struct PGroup PGroup; + +/* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set +** of one or more PCaches that are able to recycle each other's unpinned +** pages when they are under memory pressure. A PGroup is an instance of +** the following object. +** +** This page cache implementation works in one of two modes: +** +** (1) Every PCache is the sole member of its own PGroup. There is +** one PGroup per PCache. +** +** (2) There is a single global PGroup that all PCaches are a member +** of. +** +** Mode 1 uses more memory (since PCache instances are not able to rob +** unused pages from other PCaches) but it also operates without a mutex, +** and is therefore often faster. Mode 2 requires a mutex in order to be +** threadsafe, but recycles pages more efficiently. +** +** For mode (1), PGroup.mutex is NULL. For mode (2) there is only a single +** PGroup which is the pcache1.grp global variable and its mutex is +** SQLITE_MUTEX_STATIC_LRU. +*/ +struct PGroup { + sqlite3_mutex *mutex; /* MUTEX_STATIC_LRU or NULL */ + unsigned int nMaxPage; /* Sum of nMax for purgeable caches */ + unsigned int nMinPage; /* Sum of nMin for purgeable caches */ + unsigned int mxPinned; /* nMaxpage + 10 - nMinPage */ + unsigned int nCurrentPage; /* Number of purgeable pages allocated */ + PgHdr1 *pLruHead, *pLruTail; /* LRU list of unpinned pages */ +}; + +/* Each page cache is an instance of the following object. Every +** open database file (including each in-memory database and each +** temporary or transient database) has a single page cache which +** is an instance of this object. +** +** Pointers to structures of this type are cast and returned as +** opaque sqlite3_pcache* handles. +*/ +struct PCache1 { + /* Cache configuration parameters. Page size (szPage) and the purgeable + ** flag (bPurgeable) are set when the cache is created. nMax may be + ** modified at any time by a call to the pcache1Cachesize() method. + ** The PGroup mutex must be held when accessing nMax. + */ + PGroup *pGroup; /* PGroup this cache belongs to */ + int szPage; /* Size of allocated pages in bytes */ + int szExtra; /* Size of extra space in bytes */ + int bPurgeable; /* True if cache is purgeable */ + unsigned int nMin; /* Minimum number of pages reserved */ + unsigned int nMax; /* Configured "cache_size" value */ + unsigned int n90pct; /* nMax*9/10 */ + unsigned int iMaxKey; /* Largest key seen since xTruncate() */ + + /* Hash table of all pages. The following variables may only be accessed + ** when the accessor is holding the PGroup mutex. + */ + unsigned int nRecyclable; /* Number of pages in the LRU list */ + unsigned int nPage; /* Total number of pages in apHash */ + unsigned int nHash; /* Number of slots in apHash[] */ + PgHdr1 **apHash; /* Hash table for fast lookup by key */ +}; + +/* +** Each cache entry is represented by an instance of the following +** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of +** PgHdr1.pCache->szPage bytes is allocated directly before this structure +** in memory. +*/ +struct PgHdr1 { + sqlite3_pcache_page page; + unsigned int iKey; /* Key value (page number) */ + u8 isPinned; /* Page in use, not on the LRU list */ + PgHdr1 *pNext; /* Next in hash table chain */ + PCache1 *pCache; /* Cache that currently owns this page */ + PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */ + PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */ +}; + +/* +** Free slots in the allocator used to divide up the buffer provided using +** the SQLITE_CONFIG_PAGECACHE mechanism. +*/ +struct PgFreeslot { + PgFreeslot *pNext; /* Next free slot */ +}; + +/* +** Global data used by this cache. +*/ +static SQLITE_WSD struct PCacheGlobal { + PGroup grp; /* The global PGroup for mode (2) */ + + /* Variables related to SQLITE_CONFIG_PAGECACHE settings. The + ** szSlot, nSlot, pStart, pEnd, nReserve, and isInit values are all + ** fixed at sqlite3_initialize() time and do not require mutex protection. + ** The nFreeSlot and pFree values do require mutex protection. + */ + int isInit; /* True if initialized */ + int szSlot; /* Size of each free slot */ + int nSlot; /* The number of pcache slots */ + int nReserve; /* Try to keep nFreeSlot above this */ + void *pStart, *pEnd; /* Bounds of pagecache malloc range */ + /* Above requires no mutex. Use mutex below for variable that follow. */ + sqlite3_mutex *mutex; /* Mutex for accessing the following: */ + PgFreeslot *pFree; /* Free page blocks */ + int nFreeSlot; /* Number of unused pcache slots */ + /* The following value requires a mutex to change. We skip the mutex on + ** reading because (1) most platforms read a 32-bit integer atomically and + ** (2) even if an incorrect value is read, no great harm is done since this + ** is really just an optimization. */ + int bUnderPressure; /* True if low on PAGECACHE memory */ +} pcache1_g; + +/* +** All code in this file should access the global structure above via the +** alias "pcache1". This ensures that the WSD emulation is used when +** compiling for systems that do not support real WSD. +*/ +#define pcache1 (GLOBAL(struct PCacheGlobal, pcache1_g)) + +/* +** Macros to enter and leave the PCache LRU mutex. +*/ +#define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex) +#define pcache1LeaveMutex(X) sqlite3_mutex_leave((X)->mutex) + +/******************************************************************************/ +/******** Page Allocation/SQLITE_CONFIG_PCACHE Related Functions **************/ + +/* +** This function is called during initialization if a static buffer is +** supplied to use for the page-cache by passing the SQLITE_CONFIG_PAGECACHE +** verb to sqlite3_config(). Parameter pBuf points to an allocation large +** enough to contain 'n' buffers of 'sz' bytes each. +** +** This routine is called from sqlite3_initialize() and so it is guaranteed +** to be serialized already. There is no need for further mutexing. +*/ +SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){ + if( pcache1.isInit ){ + PgFreeslot *p; + sz = ROUNDDOWN8(sz); + pcache1.szSlot = sz; + pcache1.nSlot = pcache1.nFreeSlot = n; + pcache1.nReserve = n>90 ? 10 : (n/10 + 1); + pcache1.pStart = pBuf; + pcache1.pFree = 0; + pcache1.bUnderPressure = 0; + while( n-- ){ + p = (PgFreeslot*)pBuf; + p->pNext = pcache1.pFree; + pcache1.pFree = p; + pBuf = (void*)&((char*)pBuf)[sz]; + } + pcache1.pEnd = pBuf; + } +} + +/* +** Malloc function used within this file to allocate space from the buffer +** configured using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no +** such buffer exists or there is no space left in it, this function falls +** back to sqlite3Malloc(). +** +** Multiple threads can run this routine at the same time. Global variables +** in pcache1 need to be protected via mutex. +*/ +static void *pcache1Alloc(int nByte){ + void *p = 0; + assert( sqlite3_mutex_notheld(pcache1.grp.mutex) ); + if( nByte<=pcache1.szSlot ){ + sqlite3_mutex_enter(pcache1.mutex); + p = (PgHdr1 *)pcache1.pFree; + if( p ){ + pcache1.pFree = pcache1.pFree->pNext; + pcache1.nFreeSlot--; + pcache1.bUnderPressure = pcache1.nFreeSlot=0 ); + sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte); + sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1); + } + sqlite3_mutex_leave(pcache1.mutex); + } + if( p==0 ){ + /* Memory is not available in the SQLITE_CONFIG_PAGECACHE pool. Get + ** it from sqlite3Malloc instead. + */ + p = sqlite3Malloc(nByte); +#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS + if( p ){ + int sz = sqlite3MallocSize(p); + sqlite3_mutex_enter(pcache1.mutex); + sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte); + sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz); + sqlite3_mutex_leave(pcache1.mutex); + } +#endif + sqlite3MemdebugSetType(p, MEMTYPE_PCACHE); + } + return p; +} + +/* +** Free an allocated buffer obtained from pcache1Alloc(). +*/ +static int pcache1Free(void *p){ + int nFreed = 0; + if( p==0 ) return 0; + if( p>=pcache1.pStart && ppNext = pcache1.pFree; + pcache1.pFree = pSlot; + pcache1.nFreeSlot++; + pcache1.bUnderPressure = pcache1.nFreeSlot=pcache1.pStart && ppGroup->mutex) ); + pcache1LeaveMutex(pCache->pGroup); +#ifdef SQLITE_PCACHE_SEPARATE_HEADER + pPg = pcache1Alloc(pCache->szPage); + p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra); + if( !pPg || !p ){ + pcache1Free(pPg); + sqlite3_free(p); + pPg = 0; + } +#else + pPg = pcache1Alloc(ROUND8(sizeof(PgHdr1)) + pCache->szPage + pCache->szExtra); + p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage]; +#endif + pcache1EnterMutex(pCache->pGroup); + + if( pPg ){ + p->page.pBuf = pPg; + p->page.pExtra = &p[1]; + if( pCache->bPurgeable ){ + pCache->pGroup->nCurrentPage++; + } + return p; + } + return 0; +} + +/* +** Free a page object allocated by pcache1AllocPage(). +** +** The pointer is allowed to be NULL, which is prudent. But it turns out +** that the current implementation happens to never call this routine +** with a NULL pointer, so we mark the NULL test with ALWAYS(). +*/ +static void pcache1FreePage(PgHdr1 *p){ + if( ALWAYS(p) ){ + PCache1 *pCache = p->pCache; + assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) ); + pcache1Free(p->page.pBuf); +#ifdef SQLITE_PCACHE_SEPARATE_HEADER + sqlite3_free(p); +#endif + if( pCache->bPurgeable ){ + pCache->pGroup->nCurrentPage--; + } + } +} + +/* +** Malloc function used by SQLite to obtain space from the buffer configured +** using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no such buffer +** exists, this function falls back to sqlite3Malloc(). +*/ +SQLITE_PRIVATE void *sqlite3PageMalloc(int sz){ + return pcache1Alloc(sz); +} + +/* +** Free an allocated buffer obtained from sqlite3PageMalloc(). +*/ +SQLITE_PRIVATE void sqlite3PageFree(void *p){ + pcache1Free(p); +} + + +/* +** Return true if it desirable to avoid allocating a new page cache +** entry. +** +** If memory was allocated specifically to the page cache using +** SQLITE_CONFIG_PAGECACHE but that memory has all been used, then +** it is desirable to avoid allocating a new page cache entry because +** presumably SQLITE_CONFIG_PAGECACHE was suppose to be sufficient +** for all page cache needs and we should not need to spill the +** allocation onto the heap. +** +** Or, the heap is used for all page cache memory but the heap is +** under memory pressure, then again it is desirable to avoid +** allocating a new page cache entry in order to avoid stressing +** the heap even further. +*/ +static int pcache1UnderMemoryPressure(PCache1 *pCache){ + if( pcache1.nSlot && (pCache->szPage+pCache->szExtra)<=pcache1.szSlot ){ + return pcache1.bUnderPressure; + }else{ + return sqlite3HeapNearlyFull(); + } +} + +/******************************************************************************/ +/******** General Implementation Functions ************************************/ + +/* +** This function is used to resize the hash table used by the cache passed +** as the first argument. +** +** The PCache mutex must be held when this function is called. +*/ +static void pcache1ResizeHash(PCache1 *p){ + PgHdr1 **apNew; + unsigned int nNew; + unsigned int i; + + assert( sqlite3_mutex_held(p->pGroup->mutex) ); + + nNew = p->nHash*2; + if( nNew<256 ){ + nNew = 256; + } + + pcache1LeaveMutex(p->pGroup); + if( p->nHash ){ sqlite3BeginBenignMalloc(); } + apNew = (PgHdr1 **)sqlite3MallocZero(sizeof(PgHdr1 *)*nNew); + if( p->nHash ){ sqlite3EndBenignMalloc(); } + pcache1EnterMutex(p->pGroup); + if( apNew ){ + for(i=0; inHash; i++){ + PgHdr1 *pPage; + PgHdr1 *pNext = p->apHash[i]; + while( (pPage = pNext)!=0 ){ + unsigned int h = pPage->iKey % nNew; + pNext = pPage->pNext; + pPage->pNext = apNew[h]; + apNew[h] = pPage; + } + } + sqlite3_free(p->apHash); + p->apHash = apNew; + p->nHash = nNew; + } +} + +/* +** This function is used internally to remove the page pPage from the +** PGroup LRU list, if is part of it. If pPage is not part of the PGroup +** LRU list, then this function is a no-op. +** +** The PGroup mutex must be held when this function is called. +*/ +static void pcache1PinPage(PgHdr1 *pPage){ + PCache1 *pCache; + PGroup *pGroup; + + assert( pPage!=0 ); + assert( pPage->isPinned==0 ); + pCache = pPage->pCache; + pGroup = pCache->pGroup; + assert( pPage->pLruNext || pPage==pGroup->pLruTail ); + assert( pPage->pLruPrev || pPage==pGroup->pLruHead ); + assert( sqlite3_mutex_held(pGroup->mutex) ); + if( pPage->pLruPrev ){ + pPage->pLruPrev->pLruNext = pPage->pLruNext; + }else{ + pGroup->pLruHead = pPage->pLruNext; + } + if( pPage->pLruNext ){ + pPage->pLruNext->pLruPrev = pPage->pLruPrev; + }else{ + pGroup->pLruTail = pPage->pLruPrev; + } + pPage->pLruNext = 0; + pPage->pLruPrev = 0; + pPage->isPinned = 1; + pCache->nRecyclable--; +} + + +/* +** Remove the page supplied as an argument from the hash table +** (PCache1.apHash structure) that it is currently stored in. +** +** The PGroup mutex must be held when this function is called. +*/ +static void pcache1RemoveFromHash(PgHdr1 *pPage){ + unsigned int h; + PCache1 *pCache = pPage->pCache; + PgHdr1 **pp; + + assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); + h = pPage->iKey % pCache->nHash; + for(pp=&pCache->apHash[h]; (*pp)!=pPage; pp=&(*pp)->pNext); + *pp = (*pp)->pNext; + + pCache->nPage--; +} + +/* +** If there are currently more than nMaxPage pages allocated, try +** to recycle pages to reduce the number allocated to nMaxPage. +*/ +static void pcache1EnforceMaxPage(PGroup *pGroup){ + assert( sqlite3_mutex_held(pGroup->mutex) ); + while( pGroup->nCurrentPage>pGroup->nMaxPage && pGroup->pLruTail ){ + PgHdr1 *p = pGroup->pLruTail; + assert( p->pCache->pGroup==pGroup ); + assert( p->isPinned==0 ); + pcache1PinPage(p); + pcache1RemoveFromHash(p); + pcache1FreePage(p); + } +} + +/* +** Discard all pages from cache pCache with a page number (key value) +** greater than or equal to iLimit. Any pinned pages that meet this +** criteria are unpinned before they are discarded. +** +** The PCache mutex must be held when this function is called. +*/ +static void pcache1TruncateUnsafe( + PCache1 *pCache, /* The cache to truncate */ + unsigned int iLimit /* Drop pages with this pgno or larger */ +){ + TESTONLY( unsigned int nPage = 0; ) /* To assert pCache->nPage is correct */ + unsigned int h; + assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); + for(h=0; hnHash; h++){ + PgHdr1 **pp = &pCache->apHash[h]; + PgHdr1 *pPage; + while( (pPage = *pp)!=0 ){ + if( pPage->iKey>=iLimit ){ + pCache->nPage--; + *pp = pPage->pNext; + if( !pPage->isPinned ) pcache1PinPage(pPage); + pcache1FreePage(pPage); + }else{ + pp = &pPage->pNext; + TESTONLY( nPage++; ) + } + } + } + assert( pCache->nPage==nPage ); +} + +/******************************************************************************/ +/******** sqlite3_pcache Methods **********************************************/ + +/* +** Implementation of the sqlite3_pcache.xInit method. +*/ +static int pcache1Init(void *NotUsed){ + UNUSED_PARAMETER(NotUsed); + assert( pcache1.isInit==0 ); + memset(&pcache1, 0, sizeof(pcache1)); + if( sqlite3GlobalConfig.bCoreMutex ){ + pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU); + pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PMEM); + } + pcache1.grp.mxPinned = 10; + pcache1.isInit = 1; + return SQLITE_OK; +} + +/* +** Implementation of the sqlite3_pcache.xShutdown method. +** Note that the static mutex allocated in xInit does +** not need to be freed. +*/ +static void pcache1Shutdown(void *NotUsed){ + UNUSED_PARAMETER(NotUsed); + assert( pcache1.isInit!=0 ); + memset(&pcache1, 0, sizeof(pcache1)); +} + +/* forward declaration */ +static void pcache1Destroy(sqlite3_pcache *p); + +/* +** Implementation of the sqlite3_pcache.xCreate method. +** +** Allocate a new cache. +*/ +static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){ + PCache1 *pCache; /* The newly created page cache */ + PGroup *pGroup; /* The group the new page cache will belong to */ + int sz; /* Bytes of memory required to allocate the new cache */ + + /* + ** The separateCache variable is true if each PCache has its own private + ** PGroup. In other words, separateCache is true for mode (1) where no + ** mutexing is required. + ** + ** * Always use a unified cache (mode-2) if ENABLE_MEMORY_MANAGEMENT + ** + ** * Always use a unified cache in single-threaded applications + ** + ** * Otherwise (if multi-threaded and ENABLE_MEMORY_MANAGEMENT is off) + ** use separate caches (mode-1) + */ +#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || SQLITE_THREADSAFE==0 + const int separateCache = 0; +#else + int separateCache = sqlite3GlobalConfig.bCoreMutex>0; +#endif + + assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 ); + assert( szExtra < 300 ); + + sz = sizeof(PCache1) + sizeof(PGroup)*separateCache; + pCache = (PCache1 *)sqlite3MallocZero(sz); + if( pCache ){ + if( separateCache ){ + pGroup = (PGroup*)&pCache[1]; + pGroup->mxPinned = 10; + }else{ + pGroup = &pcache1.grp; + } + pCache->pGroup = pGroup; + pCache->szPage = szPage; + pCache->szExtra = szExtra; + pCache->bPurgeable = (bPurgeable ? 1 : 0); + pcache1EnterMutex(pGroup); + pcache1ResizeHash(pCache); + if( bPurgeable ){ + pCache->nMin = 10; + pGroup->nMinPage += pCache->nMin; + pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; + } + pcache1LeaveMutex(pGroup); + if( pCache->nHash==0 ){ + pcache1Destroy((sqlite3_pcache*)pCache); + pCache = 0; + } + } + return (sqlite3_pcache *)pCache; +} + +/* +** Implementation of the sqlite3_pcache.xCachesize method. +** +** Configure the cache_size limit for a cache. +*/ +static void pcache1Cachesize(sqlite3_pcache *p, int nMax){ + PCache1 *pCache = (PCache1 *)p; + if( pCache->bPurgeable ){ + PGroup *pGroup = pCache->pGroup; + pcache1EnterMutex(pGroup); + pGroup->nMaxPage += (nMax - pCache->nMax); + pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; + pCache->nMax = nMax; + pCache->n90pct = pCache->nMax*9/10; + pcache1EnforceMaxPage(pGroup); + pcache1LeaveMutex(pGroup); + } +} + +/* +** Implementation of the sqlite3_pcache.xShrink method. +** +** Free up as much memory as possible. +*/ +static void pcache1Shrink(sqlite3_pcache *p){ + PCache1 *pCache = (PCache1*)p; + if( pCache->bPurgeable ){ + PGroup *pGroup = pCache->pGroup; + int savedMaxPage; + pcache1EnterMutex(pGroup); + savedMaxPage = pGroup->nMaxPage; + pGroup->nMaxPage = 0; + pcache1EnforceMaxPage(pGroup); + pGroup->nMaxPage = savedMaxPage; + pcache1LeaveMutex(pGroup); + } +} + +/* +** Implementation of the sqlite3_pcache.xPagecount method. +*/ +static int pcache1Pagecount(sqlite3_pcache *p){ + int n; + PCache1 *pCache = (PCache1*)p; + pcache1EnterMutex(pCache->pGroup); + n = pCache->nPage; + pcache1LeaveMutex(pCache->pGroup); + return n; +} + + +/* +** Implement steps 3, 4, and 5 of the pcache1Fetch() algorithm described +** in the header of the pcache1Fetch() procedure. +** +** This steps are broken out into a separate procedure because they are +** usually not needed, and by avoiding the stack initialization required +** for these steps, the main pcache1Fetch() procedure can run faster. +*/ +static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2( + PCache1 *pCache, + unsigned int iKey, + int createFlag +){ + unsigned int nPinned; + PGroup *pGroup = pCache->pGroup; + PgHdr1 *pPage = 0; + + /* Step 3: Abort if createFlag is 1 but the cache is nearly full */ + assert( pCache->nPage >= pCache->nRecyclable ); + nPinned = pCache->nPage - pCache->nRecyclable; + assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage ); + assert( pCache->n90pct == pCache->nMax*9/10 ); + if( createFlag==1 && ( + nPinned>=pGroup->mxPinned + || nPinned>=pCache->n90pct + || (pcache1UnderMemoryPressure(pCache) && pCache->nRecyclablenPage>=pCache->nHash ) pcache1ResizeHash(pCache); + assert( pCache->nHash>0 && pCache->apHash ); + + /* Step 4. Try to recycle a page. */ + if( pCache->bPurgeable && pGroup->pLruTail && ( + (pCache->nPage+1>=pCache->nMax) + || pGroup->nCurrentPage>=pGroup->nMaxPage + || pcache1UnderMemoryPressure(pCache) + )){ + PCache1 *pOther; + pPage = pGroup->pLruTail; + assert( pPage->isPinned==0 ); + pcache1RemoveFromHash(pPage); + pcache1PinPage(pPage); + pOther = pPage->pCache; + + /* We want to verify that szPage and szExtra are the same for pOther + ** and pCache. Assert that we can verify this by comparing sums. */ + assert( (pCache->szPage & (pCache->szPage-1))==0 && pCache->szPage>=512 ); + assert( pCache->szExtra<512 ); + assert( (pOther->szPage & (pOther->szPage-1))==0 && pOther->szPage>=512 ); + assert( pOther->szExtra<512 ); + + if( pOther->szPage+pOther->szExtra != pCache->szPage+pCache->szExtra ){ + pcache1FreePage(pPage); + pPage = 0; + }else{ + pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable); + } + } + + /* Step 5. If a usable page buffer has still not been found, + ** attempt to allocate a new one. + */ + if( !pPage ){ + if( createFlag==1 ) sqlite3BeginBenignMalloc(); + pPage = pcache1AllocPage(pCache); + if( createFlag==1 ) sqlite3EndBenignMalloc(); + } + + if( pPage ){ + unsigned int h = iKey % pCache->nHash; + pCache->nPage++; + pPage->iKey = iKey; + pPage->pNext = pCache->apHash[h]; + pPage->pCache = pCache; + pPage->pLruPrev = 0; + pPage->pLruNext = 0; + pPage->isPinned = 1; + *(void **)pPage->page.pExtra = 0; + pCache->apHash[h] = pPage; + if( iKey>pCache->iMaxKey ){ + pCache->iMaxKey = iKey; + } + } + return pPage; +} + +/* +** Implementation of the sqlite3_pcache.xFetch method. +** +** Fetch a page by key value. +** +** Whether or not a new page may be allocated by this function depends on +** the value of the createFlag argument. 0 means do not allocate a new +** page. 1 means allocate a new page if space is easily available. 2 +** means to try really hard to allocate a new page. +** +** For a non-purgeable cache (a cache used as the storage for an in-memory +** database) there is really no difference between createFlag 1 and 2. So +** the calling function (pcache.c) will never have a createFlag of 1 on +** a non-purgeable cache. +** +** There are three different approaches to obtaining space for a page, +** depending on the value of parameter createFlag (which may be 0, 1 or 2). +** +** 1. Regardless of the value of createFlag, the cache is searched for a +** copy of the requested page. If one is found, it is returned. +** +** 2. If createFlag==0 and the page is not already in the cache, NULL is +** returned. +** +** 3. If createFlag is 1, and the page is not already in the cache, then +** return NULL (do not allocate a new page) if any of the following +** conditions are true: +** +** (a) the number of pages pinned by the cache is greater than +** PCache1.nMax, or +** +** (b) the number of pages pinned by the cache is greater than +** the sum of nMax for all purgeable caches, less the sum of +** nMin for all other purgeable caches, or +** +** 4. If none of the first three conditions apply and the cache is marked +** as purgeable, and if one of the following is true: +** +** (a) The number of pages allocated for the cache is already +** PCache1.nMax, or +** +** (b) The number of pages allocated for all purgeable caches is +** already equal to or greater than the sum of nMax for all +** purgeable caches, +** +** (c) The system is under memory pressure and wants to avoid +** unnecessary pages cache entry allocations +** +** then attempt to recycle a page from the LRU list. If it is the right +** size, return the recycled buffer. Otherwise, free the buffer and +** proceed to step 5. +** +** 5. Otherwise, allocate and return a new page buffer. +*/ +static sqlite3_pcache_page *pcache1Fetch( + sqlite3_pcache *p, + unsigned int iKey, + int createFlag +){ + PCache1 *pCache = (PCache1 *)p; + PgHdr1 *pPage = 0; + + assert( offsetof(PgHdr1,page)==0 ); + assert( pCache->bPurgeable || createFlag!=1 ); + assert( pCache->bPurgeable || pCache->nMin==0 ); + assert( pCache->bPurgeable==0 || pCache->nMin==10 ); + assert( pCache->nMin==0 || pCache->bPurgeable ); + assert( pCache->nHash>0 ); + pcache1EnterMutex(pCache->pGroup); + + /* Step 1: Search the hash table for an existing entry. */ + pPage = pCache->apHash[iKey % pCache->nHash]; + while( pPage && pPage->iKey!=iKey ){ pPage = pPage->pNext; } + + /* Step 2: Abort if no existing page is found and createFlag is 0 */ + if( pPage ){ + if( !pPage->isPinned ) pcache1PinPage(pPage); + }else if( createFlag ){ + /* Steps 3, 4, and 5 implemented by this subroutine */ + pPage = pcache1FetchStage2(pCache, iKey, createFlag); + } + assert( pPage==0 || pCache->iMaxKey>=iKey ); + pcache1LeaveMutex(pCache->pGroup); + return (sqlite3_pcache_page*)pPage; +} + + +/* +** Implementation of the sqlite3_pcache.xUnpin method. +** +** Mark a page as unpinned (eligible for asynchronous recycling). +*/ +static void pcache1Unpin( + sqlite3_pcache *p, + sqlite3_pcache_page *pPg, + int reuseUnlikely +){ + PCache1 *pCache = (PCache1 *)p; + PgHdr1 *pPage = (PgHdr1 *)pPg; + PGroup *pGroup = pCache->pGroup; + + assert( pPage->pCache==pCache ); + pcache1EnterMutex(pGroup); + + /* It is an error to call this function if the page is already + ** part of the PGroup LRU list. + */ + assert( pPage->pLruPrev==0 && pPage->pLruNext==0 ); + assert( pGroup->pLruHead!=pPage && pGroup->pLruTail!=pPage ); + assert( pPage->isPinned==1 ); + + if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){ + pcache1RemoveFromHash(pPage); + pcache1FreePage(pPage); + }else{ + /* Add the page to the PGroup LRU list. */ + if( pGroup->pLruHead ){ + pGroup->pLruHead->pLruPrev = pPage; + pPage->pLruNext = pGroup->pLruHead; + pGroup->pLruHead = pPage; + }else{ + pGroup->pLruTail = pPage; + pGroup->pLruHead = pPage; + } + pCache->nRecyclable++; + pPage->isPinned = 0; + } + + pcache1LeaveMutex(pCache->pGroup); +} + +/* +** Implementation of the sqlite3_pcache.xRekey method. +*/ +static void pcache1Rekey( + sqlite3_pcache *p, + sqlite3_pcache_page *pPg, + unsigned int iOld, + unsigned int iNew +){ + PCache1 *pCache = (PCache1 *)p; + PgHdr1 *pPage = (PgHdr1 *)pPg; + PgHdr1 **pp; + unsigned int h; + assert( pPage->iKey==iOld ); + assert( pPage->pCache==pCache ); + + pcache1EnterMutex(pCache->pGroup); + + h = iOld%pCache->nHash; + pp = &pCache->apHash[h]; + while( (*pp)!=pPage ){ + pp = &(*pp)->pNext; + } + *pp = pPage->pNext; + + h = iNew%pCache->nHash; + pPage->iKey = iNew; + pPage->pNext = pCache->apHash[h]; + pCache->apHash[h] = pPage; + if( iNew>pCache->iMaxKey ){ + pCache->iMaxKey = iNew; + } + + pcache1LeaveMutex(pCache->pGroup); +} + +/* +** Implementation of the sqlite3_pcache.xTruncate method. +** +** Discard all unpinned pages in the cache with a page number equal to +** or greater than parameter iLimit. Any pinned pages with a page number +** equal to or greater than iLimit are implicitly unpinned. +*/ +static void pcache1Truncate(sqlite3_pcache *p, unsigned int iLimit){ + PCache1 *pCache = (PCache1 *)p; + pcache1EnterMutex(pCache->pGroup); + if( iLimit<=pCache->iMaxKey ){ + pcache1TruncateUnsafe(pCache, iLimit); + pCache->iMaxKey = iLimit-1; + } + pcache1LeaveMutex(pCache->pGroup); +} + +/* +** Implementation of the sqlite3_pcache.xDestroy method. +** +** Destroy a cache allocated using pcache1Create(). +*/ +static void pcache1Destroy(sqlite3_pcache *p){ + PCache1 *pCache = (PCache1 *)p; + PGroup *pGroup = pCache->pGroup; + assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) ); + pcache1EnterMutex(pGroup); + pcache1TruncateUnsafe(pCache, 0); + assert( pGroup->nMaxPage >= pCache->nMax ); + pGroup->nMaxPage -= pCache->nMax; + assert( pGroup->nMinPage >= pCache->nMin ); + pGroup->nMinPage -= pCache->nMin; + pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; + pcache1EnforceMaxPage(pGroup); + pcache1LeaveMutex(pGroup); + sqlite3_free(pCache->apHash); + sqlite3_free(pCache); +} + +/* +** This function is called during initialization (sqlite3_initialize()) to +** install the default pluggable cache module, assuming the user has not +** already provided an alternative. +*/ +SQLITE_PRIVATE void sqlite3PCacheSetDefault(void){ + static const sqlite3_pcache_methods2 defaultMethods = { + 1, /* iVersion */ + 0, /* pArg */ + pcache1Init, /* xInit */ + pcache1Shutdown, /* xShutdown */ + pcache1Create, /* xCreate */ + pcache1Cachesize, /* xCachesize */ + pcache1Pagecount, /* xPagecount */ + pcache1Fetch, /* xFetch */ + pcache1Unpin, /* xUnpin */ + pcache1Rekey, /* xRekey */ + pcache1Truncate, /* xTruncate */ + pcache1Destroy, /* xDestroy */ + pcache1Shrink /* xShrink */ + }; + sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods); +} + +/* +** Return the size of the header on each page of this PCACHE implementation. +*/ +SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void){ return ROUND8(sizeof(PgHdr1)); } + +/* +** Return the global mutex used by this PCACHE implementation. The +** sqlite3_status() routine needs access to this mutex. +*/ +SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void){ + return pcache1.mutex; +} + +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT +/* +** 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 sqlite3_free()ed. +** +** nReq is the number of bytes of memory required. Once this much has +** been released, the function returns. The return value is the total number +** of bytes of memory released. +*/ +SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){ + int nFree = 0; + assert( sqlite3_mutex_notheld(pcache1.grp.mutex) ); + assert( sqlite3_mutex_notheld(pcache1.mutex) ); + if( pcache1.pStart==0 ){ + PgHdr1 *p; + pcache1EnterMutex(&pcache1.grp); + while( (nReq<0 || nFreepage.pBuf); +#ifdef SQLITE_PCACHE_SEPARATE_HEADER + nFree += sqlite3MemSize(p); +#endif + assert( p->isPinned==0 ); + pcache1PinPage(p); + pcache1RemoveFromHash(p); + pcache1FreePage(p); + } + pcache1LeaveMutex(&pcache1.grp); + } + return nFree; +} +#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */ + +#ifdef SQLITE_TEST +/* +** This function is used by test procedures to inspect the internal state +** of the global cache. +*/ +SQLITE_PRIVATE void sqlite3PcacheStats( + int *pnCurrent, /* OUT: Total number of pages cached */ + int *pnMax, /* OUT: Global maximum cache size */ + int *pnMin, /* OUT: Sum of PCache1.nMin for purgeable caches */ + int *pnRecyclable /* OUT: Total number of pages available for recycling */ +){ + PgHdr1 *p; + int nRecyclable = 0; + for(p=pcache1.grp.pLruHead; p; p=p->pLruNext){ + assert( p->isPinned==0 ); + nRecyclable++; + } + *pnCurrent = pcache1.grp.nCurrentPage; + *pnMax = (int)pcache1.grp.nMaxPage; + *pnMin = (int)pcache1.grp.nMinPage; + *pnRecyclable = nRecyclable; +} +#endif + +/************** End of pcache1.c *********************************************/ +/************** Begin file rowset.c ******************************************/ +/* +** 2008 December 3 +** +** 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 module implements an object we call a "RowSet". +** +** The RowSet object is a collection of rowids. Rowids +** are inserted into the RowSet in an arbitrary order. Inserts +** can be intermixed with tests to see if a given rowid has been +** previously inserted into the RowSet. +** +** After all inserts are finished, it is possible to extract the +** elements of the RowSet in sorted order. Once this extraction +** process has started, no new elements may be inserted. +** +** Hence, the primitive operations for a RowSet are: +** +** CREATE +** INSERT +** TEST +** SMALLEST +** DESTROY +** +** The CREATE and DESTROY primitives are the constructor and destructor, +** obviously. The INSERT primitive adds a new element to the RowSet. +** TEST checks to see if an element is already in the RowSet. SMALLEST +** extracts the least value from the RowSet. +** +** The INSERT primitive might allocate additional memory. Memory is +** allocated in chunks so most INSERTs do no allocation. There is an +** upper bound on the size of allocated memory. No memory is freed +** until DESTROY. +** +** The TEST primitive includes a "batch" number. The TEST primitive +** will only see elements that were inserted before the last change +** in the batch number. In other words, if an INSERT occurs between +** two TESTs where the TESTs have the same batch nubmer, then the +** value added by the INSERT will not be visible to the second TEST. +** The initial batch number is zero, so if the very first TEST contains +** a non-zero batch number, it will see all prior INSERTs. +** +** No INSERTs may occurs after a SMALLEST. An assertion will fail if +** that is attempted. +** +** The cost of an INSERT is roughly constant. (Sometimes new memory +** has to be allocated on an INSERT.) The cost of a TEST with a new +** batch number is O(NlogN) where N is the number of elements in the RowSet. +** The cost of a TEST using the same batch number is O(logN). The cost +** of the first SMALLEST is O(NlogN). Second and subsequent SMALLEST +** primitives are constant time. The cost of DESTROY is O(N). +** +** There is an added cost of O(N) when switching between TEST and +** SMALLEST primitives. +*/ + + +/* +** Target size for allocation chunks. +*/ +#define ROWSET_ALLOCATION_SIZE 1024 + +/* +** The number of rowset entries per allocation chunk. +*/ +#define ROWSET_ENTRY_PER_CHUNK \ + ((ROWSET_ALLOCATION_SIZE-8)/sizeof(struct RowSetEntry)) + +/* +** Each entry in a RowSet is an instance of the following object. +** +** This same object is reused to store a linked list of trees of RowSetEntry +** objects. In that alternative use, pRight points to the next entry +** in the list, pLeft points to the tree, and v is unused. The +** RowSet.pForest value points to the head of this forest list. +*/ +struct RowSetEntry { + i64 v; /* ROWID value for this entry */ + struct RowSetEntry *pRight; /* Right subtree (larger entries) or list */ + struct RowSetEntry *pLeft; /* Left subtree (smaller entries) */ +}; + +/* +** RowSetEntry objects are allocated in large chunks (instances of the +** following structure) to reduce memory allocation overhead. The +** chunks are kept on a linked list so that they can be deallocated +** when the RowSet is destroyed. +*/ +struct RowSetChunk { + struct RowSetChunk *pNextChunk; /* Next chunk on list of them all */ + struct RowSetEntry aEntry[ROWSET_ENTRY_PER_CHUNK]; /* Allocated entries */ +}; + +/* +** A RowSet in an instance of the following structure. +** +** A typedef of this structure if found in sqliteInt.h. +*/ +struct RowSet { + struct RowSetChunk *pChunk; /* List of all chunk allocations */ + sqlite3 *db; /* The database connection */ + struct RowSetEntry *pEntry; /* List of entries using pRight */ + struct RowSetEntry *pLast; /* Last entry on the pEntry list */ + struct RowSetEntry *pFresh; /* Source of new entry objects */ + struct RowSetEntry *pForest; /* List of binary trees of entries */ + u16 nFresh; /* Number of objects on pFresh */ + u16 rsFlags; /* Various flags */ + int iBatch; /* Current insert batch */ +}; + +/* +** Allowed values for RowSet.rsFlags +*/ +#define ROWSET_SORTED 0x01 /* True if RowSet.pEntry is sorted */ +#define ROWSET_NEXT 0x02 /* True if sqlite3RowSetNext() has been called */ + +/* +** Turn bulk memory into a RowSet object. N bytes of memory +** are available at pSpace. The db pointer is used as a memory context +** for any subsequent allocations that need to occur. +** Return a pointer to the new RowSet object. +** +** It must be the case that N is sufficient to make a Rowset. If not +** an assertion fault occurs. +** +** If N is larger than the minimum, use the surplus as an initial +** allocation of entries available to be filled. +*/ +SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){ + RowSet *p; + assert( N >= ROUND8(sizeof(*p)) ); + p = pSpace; + p->pChunk = 0; + p->db = db; + p->pEntry = 0; + p->pLast = 0; + p->pForest = 0; + p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p); + p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry)); + p->rsFlags = ROWSET_SORTED; + p->iBatch = 0; + return p; +} + +/* +** Deallocate all chunks from a RowSet. This frees all memory that +** the RowSet has allocated over its lifetime. This routine is +** the destructor for the RowSet. +*/ +SQLITE_PRIVATE void sqlite3RowSetClear(RowSet *p){ + struct RowSetChunk *pChunk, *pNextChunk; + for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){ + pNextChunk = pChunk->pNextChunk; + sqlite3DbFree(p->db, pChunk); + } + p->pChunk = 0; + p->nFresh = 0; + p->pEntry = 0; + p->pLast = 0; + p->pForest = 0; + p->rsFlags = ROWSET_SORTED; +} + +/* +** Allocate a new RowSetEntry object that is associated with the +** given RowSet. Return a pointer to the new and completely uninitialized +** objected. +** +** In an OOM situation, the RowSet.db->mallocFailed flag is set and this +** routine returns NULL. +*/ +static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){ + assert( p!=0 ); + if( p->nFresh==0 ){ + struct RowSetChunk *pNew; + pNew = sqlite3DbMallocRaw(p->db, sizeof(*pNew)); + if( pNew==0 ){ + return 0; + } + pNew->pNextChunk = p->pChunk; + p->pChunk = pNew; + p->pFresh = pNew->aEntry; + p->nFresh = ROWSET_ENTRY_PER_CHUNK; + } + p->nFresh--; + return p->pFresh++; +} + +/* +** Insert a new value into a RowSet. +** +** The mallocFailed flag of the database connection is set if a +** memory allocation fails. +*/ +SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet *p, i64 rowid){ + struct RowSetEntry *pEntry; /* The new entry */ + struct RowSetEntry *pLast; /* The last prior entry */ + + /* This routine is never called after sqlite3RowSetNext() */ + assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 ); + + pEntry = rowSetEntryAlloc(p); + if( pEntry==0 ) return; + pEntry->v = rowid; + pEntry->pRight = 0; + pLast = p->pLast; + if( pLast ){ + if( (p->rsFlags & ROWSET_SORTED)!=0 && rowid<=pLast->v ){ + p->rsFlags &= ~ROWSET_SORTED; + } + pLast->pRight = pEntry; + }else{ + p->pEntry = pEntry; + } + p->pLast = pEntry; +} + +/* +** Merge two lists of RowSetEntry objects. Remove duplicates. +** +** The input lists are connected via pRight pointers and are +** assumed to each already be in sorted order. +*/ +static struct RowSetEntry *rowSetEntryMerge( + struct RowSetEntry *pA, /* First sorted list to be merged */ + struct RowSetEntry *pB /* Second sorted list to be merged */ +){ + struct RowSetEntry head; + struct RowSetEntry *pTail; + + pTail = &head; + while( pA && pB ){ + assert( pA->pRight==0 || pA->v<=pA->pRight->v ); + assert( pB->pRight==0 || pB->v<=pB->pRight->v ); + if( pA->vv ){ + pTail->pRight = pA; + pA = pA->pRight; + pTail = pTail->pRight; + }else if( pB->vv ){ + pTail->pRight = pB; + pB = pB->pRight; + pTail = pTail->pRight; + }else{ + pA = pA->pRight; + } + } + if( pA ){ + assert( pA->pRight==0 || pA->v<=pA->pRight->v ); + pTail->pRight = pA; + }else{ + assert( pB==0 || pB->pRight==0 || pB->v<=pB->pRight->v ); + pTail->pRight = pB; + } + return head.pRight; +} + +/* +** Sort all elements on the list of RowSetEntry objects into order of +** increasing v. +*/ +static struct RowSetEntry *rowSetEntrySort(struct RowSetEntry *pIn){ + unsigned int i; + struct RowSetEntry *pNext, *aBucket[40]; + + memset(aBucket, 0, sizeof(aBucket)); + while( pIn ){ + pNext = pIn->pRight; + pIn->pRight = 0; + for(i=0; aBucket[i]; i++){ + pIn = rowSetEntryMerge(aBucket[i], pIn); + aBucket[i] = 0; + } + aBucket[i] = pIn; + pIn = pNext; + } + pIn = 0; + for(i=0; ipLeft ){ + struct RowSetEntry *p; + rowSetTreeToList(pIn->pLeft, ppFirst, &p); + p->pRight = pIn; + }else{ + *ppFirst = pIn; + } + if( pIn->pRight ){ + rowSetTreeToList(pIn->pRight, &pIn->pRight, ppLast); + }else{ + *ppLast = pIn; + } + assert( (*ppLast)->pRight==0 ); +} + + +/* +** Convert a sorted list of elements (connected by pRight) into a binary +** tree with depth of iDepth. A depth of 1 means the tree contains a single +** node taken from the head of *ppList. A depth of 2 means a tree with +** three nodes. And so forth. +** +** Use as many entries from the input list as required and update the +** *ppList to point to the unused elements of the list. If the input +** list contains too few elements, then construct an incomplete tree +** and leave *ppList set to NULL. +** +** Return a pointer to the root of the constructed binary tree. +*/ +static struct RowSetEntry *rowSetNDeepTree( + struct RowSetEntry **ppList, + int iDepth +){ + struct RowSetEntry *p; /* Root of the new tree */ + struct RowSetEntry *pLeft; /* Left subtree */ + if( *ppList==0 ){ + return 0; + } + if( iDepth==1 ){ + p = *ppList; + *ppList = p->pRight; + p->pLeft = p->pRight = 0; + return p; + } + pLeft = rowSetNDeepTree(ppList, iDepth-1); + p = *ppList; + if( p==0 ){ + return pLeft; + } + p->pLeft = pLeft; + *ppList = p->pRight; + p->pRight = rowSetNDeepTree(ppList, iDepth-1); + return p; +} + +/* +** Convert a sorted list of elements into a binary tree. Make the tree +** as deep as it needs to be in order to contain the entire list. +*/ +static struct RowSetEntry *rowSetListToTree(struct RowSetEntry *pList){ + int iDepth; /* Depth of the tree so far */ + struct RowSetEntry *p; /* Current tree root */ + struct RowSetEntry *pLeft; /* Left subtree */ + + assert( pList!=0 ); + p = pList; + pList = p->pRight; + p->pLeft = p->pRight = 0; + for(iDepth=1; pList; iDepth++){ + pLeft = p; + p = pList; + pList = p->pRight; + p->pLeft = pLeft; + p->pRight = rowSetNDeepTree(&pList, iDepth); + } + return p; +} + +/* +** Take all the entries on p->pEntry and on the trees in p->pForest and +** sort them all together into one big ordered list on p->pEntry. +** +** This routine should only be called once in the life of a RowSet. +*/ +static void rowSetToList(RowSet *p){ + + /* This routine is called only once */ + assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 ); + + if( (p->rsFlags & ROWSET_SORTED)==0 ){ + p->pEntry = rowSetEntrySort(p->pEntry); + } + + /* While this module could theoretically support it, sqlite3RowSetNext() + ** is never called after sqlite3RowSetText() for the same RowSet. So + ** there is never a forest to deal with. Should this change, simply + ** remove the assert() and the #if 0. */ + assert( p->pForest==0 ); +#if 0 + while( p->pForest ){ + struct RowSetEntry *pTree = p->pForest->pLeft; + if( pTree ){ + struct RowSetEntry *pHead, *pTail; + rowSetTreeToList(pTree, &pHead, &pTail); + p->pEntry = rowSetEntryMerge(p->pEntry, pHead); + } + p->pForest = p->pForest->pRight; + } +#endif + p->rsFlags |= ROWSET_NEXT; /* Verify this routine is never called again */ +} + +/* +** Extract the smallest element from the RowSet. +** Write the element into *pRowid. Return 1 on success. Return +** 0 if the RowSet is already empty. +** +** After this routine has been called, the sqlite3RowSetInsert() +** routine may not be called again. +*/ +SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){ + assert( p!=0 ); + + /* Merge the forest into a single sorted list on first call */ + if( (p->rsFlags & ROWSET_NEXT)==0 ) rowSetToList(p); + + /* Return the next entry on the list */ + if( p->pEntry ){ + *pRowid = p->pEntry->v; + p->pEntry = p->pEntry->pRight; + if( p->pEntry==0 ){ + sqlite3RowSetClear(p); + } + return 1; + }else{ + return 0; + } +} + +/* +** Check to see if element iRowid was inserted into the rowset as +** part of any insert batch prior to iBatch. Return 1 or 0. +** +** If this is the first test of a new batch and if there exist entries +** on pRowSet->pEntry, then sort those entries into the forest at +** pRowSet->pForest so that they can be tested. +*/ +SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){ + struct RowSetEntry *p, *pTree; + + /* This routine is never called after sqlite3RowSetNext() */ + assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 ); + + /* Sort entries into the forest on the first test of a new batch + */ + if( iBatch!=pRowSet->iBatch ){ + p = pRowSet->pEntry; + if( p ){ + struct RowSetEntry **ppPrevTree = &pRowSet->pForest; + if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){ + p = rowSetEntrySort(p); + } + for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){ + ppPrevTree = &pTree->pRight; + if( pTree->pLeft==0 ){ + pTree->pLeft = rowSetListToTree(p); + break; + }else{ + struct RowSetEntry *pAux, *pTail; + rowSetTreeToList(pTree->pLeft, &pAux, &pTail); + pTree->pLeft = 0; + p = rowSetEntryMerge(pAux, p); + } + } + if( pTree==0 ){ + *ppPrevTree = pTree = rowSetEntryAlloc(pRowSet); + if( pTree ){ + pTree->v = 0; + pTree->pRight = 0; + pTree->pLeft = rowSetListToTree(p); + } + } + pRowSet->pEntry = 0; + pRowSet->pLast = 0; + pRowSet->rsFlags |= ROWSET_SORTED; + } + pRowSet->iBatch = iBatch; + } + + /* Test to see if the iRowid value appears anywhere in the forest. + ** Return 1 if it does and 0 if not. + */ + for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){ + p = pTree->pLeft; + while( p ){ + if( p->vpRight; + }else if( p->v>iRowid ){ + p = p->pLeft; + }else{ + return 1; + } + } + } + return 0; +} + +/************** End of rowset.c **********************************************/ +/************** Begin file pager.c *******************************************/ +/* +** 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. +** +************************************************************************* +** This is the implementation of the page cache subsystem or "pager". +** +** 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. +*/ +#ifndef SQLITE_OMIT_DISKIO +/************** Include wal.h in the middle of pager.c ***********************/ +/************** Begin file wal.h *********************************************/ +/* +** 2010 February 1 +** +** 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 the interface to the write-ahead logging +** system. Refer to the comments below and the header comment attached to +** the implementation of each function in log.c for further details. +*/ + +#ifndef _WAL_H_ +#define _WAL_H_ + + +/* Additional values that can be added to the sync_flags argument of +** sqlite3WalFrames(): +*/ +#define WAL_SYNC_TRANSACTIONS 0x20 /* Sync at the end of each transaction */ +#define SQLITE_SYNC_MASK 0x13 /* Mask off the SQLITE_SYNC_* values */ + +#ifdef SQLITE_OMIT_WAL +# define sqlite3WalOpen(x,y,z) 0 +# define sqlite3WalLimit(x,y) +# define sqlite3WalClose(w,x,y,z) 0 +# define sqlite3WalBeginReadTransaction(y,z) 0 +# define sqlite3WalEndReadTransaction(z) +# define sqlite3WalDbsize(y) 0 +# define sqlite3WalBeginWriteTransaction(y) 0 +# define sqlite3WalEndWriteTransaction(x) 0 +# define sqlite3WalUndo(x,y,z) 0 +# define sqlite3WalSavepoint(y,z) +# define sqlite3WalSavepointUndo(y,z) 0 +# define sqlite3WalFrames(u,v,w,x,y,z) 0 +# define sqlite3WalCheckpoint(r,s,t,u,v,w,x,y,z) 0 +# define sqlite3WalCallback(z) 0 +# define sqlite3WalExclusiveMode(y,z) 0 +# define sqlite3WalHeapMemory(z) 0 +# define sqlite3WalFramesize(z) 0 +# define sqlite3WalFindFrame(x,y,z) 0 +#else + +#define WAL_SAVEPOINT_NDATA 4 + +/* Connection to a write-ahead log (WAL) file. +** There is one object of this type for each pager. +*/ +typedef struct Wal Wal; + +/* Open and close a connection to a write-ahead log. */ +SQLITE_PRIVATE int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**); +SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, int sync_flags, int, u8 *); + +/* Set the limiting size of a WAL file. */ +SQLITE_PRIVATE void sqlite3WalLimit(Wal*, i64); + +/* Used by readers to open (lock) and close (unlock) a snapshot. A +** snapshot is like a read-transaction. It is the state of the database +** at an instant in time. sqlite3WalOpenSnapshot gets a read lock and +** preserves the current state even if the other threads or processes +** write to or checkpoint the WAL. sqlite3WalCloseSnapshot() closes the +** transaction and releases the lock. +*/ +SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *); +SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal); + +/* Read a page from the write-ahead log, if it is present. */ +SQLITE_PRIVATE int sqlite3WalFindFrame(Wal *, Pgno, u32 *); +SQLITE_PRIVATE int sqlite3WalReadFrame(Wal *, u32, int, u8 *); + +/* If the WAL is not empty, return the size of the database. */ +SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal); + +/* Obtain or release the WRITER lock. */ +SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal); +SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal); + +/* Undo any frames written (but not committed) to the log */ +SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx); + +/* Return an integer that records the current (uncommitted) write +** position in the WAL */ +SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData); + +/* Move the write position of the WAL back to iFrame. Called in +** response to a ROLLBACK TO command. */ +SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData); + +/* Write a frame or frames to the log. */ +SQLITE_PRIVATE int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int); + +/* Copy pages from the log to the database file */ +SQLITE_PRIVATE int sqlite3WalCheckpoint( + Wal *pWal, /* Write-ahead log connection */ + int eMode, /* One of PASSIVE, FULL and RESTART */ + int (*xBusy)(void*), /* Function to call when busy */ + void *pBusyArg, /* Context argument for xBusyHandler */ + int sync_flags, /* Flags to sync db file with (or 0) */ + int nBuf, /* Size of buffer nBuf */ + u8 *zBuf, /* Temporary buffer to use */ + int *pnLog, /* OUT: Number of frames in WAL */ + int *pnCkpt /* OUT: Number of backfilled frames in WAL */ +); + +/* Return the value to pass to a sqlite3_wal_hook callback, the +** number of frames in the WAL at the point of the last commit since +** sqlite3WalCallback() was called. If no commits have occurred since +** the last call, then return 0. +*/ +SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal); + +/* Tell the wal layer that an EXCLUSIVE lock has been obtained (or released) +** by the pager layer on the database file. +*/ +SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op); + +/* Return true if the argument is non-NULL and the WAL module is using +** heap-memory for the wal-index. Otherwise, if the argument is NULL or the +** WAL module is using shared-memory, return false. +*/ +SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal); + +#ifdef SQLITE_ENABLE_ZIPVFS +/* If the WAL file is not empty, return the number of bytes of content +** stored in each frame (i.e. the db page-size when the WAL was created). +*/ +SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal); +#endif + +#endif /* ifndef SQLITE_OMIT_WAL */ +#endif /* _WAL_H_ */ + +/************** End of wal.h *************************************************/ +/************** Continuing where we left off in pager.c **********************/ + + +/******************* NOTES ON THE DESIGN OF THE PAGER ************************ +** +** This comment block describes invariants that hold when using a rollback +** journal. These invariants do not apply for journal_mode=WAL, +** journal_mode=MEMORY, or journal_mode=OFF. +** +** Within this comment block, a page is deemed to have been synced +** automatically as soon as it is written when PRAGMA synchronous=OFF. +** Otherwise, the page is not synced until the xSync method of the VFS +** is called successfully on the file containing the page. +** +** Definition: A page of the database file is said to be "overwriteable" if +** one or more of the following are true about the page: +** +** (a) The original content of the page as it was at the beginning of +** the transaction has been written into the rollback journal and +** synced. +** +** (b) The page was a freelist leaf page at the start of the transaction. +** +** (c) The page number is greater than the largest page that existed in +** the database file at the start of the transaction. +** +** (1) A page of the database file is never overwritten unless one of the +** following are true: +** +** (a) The page and all other pages on the same sector are overwriteable. +** +** (b) The atomic page write optimization is enabled, and the entire +** transaction other than the update of the transaction sequence +** number consists of a single page change. +** +** (2) The content of a page written into the rollback journal exactly matches +** both the content in the database when the rollback journal was written +** and the content in the database at the beginning of the current +** transaction. +** +** (3) Writes to the database file are an integer multiple of the page size +** in length and are aligned on a page boundary. +** +** (4) Reads from the database file are either aligned on a page boundary and +** an integer multiple of the page size in length or are taken from the +** first 100 bytes of the database file. +** +** (5) All writes to the database file are synced prior to the rollback journal +** being deleted, truncated, or zeroed. +** +** (6) If a master journal file is used, then all writes to the database file +** are synced prior to the master journal being deleted. +** +** Definition: Two databases (or the same database at two points it time) +** are said to be "logically equivalent" if they give the same answer to +** all queries. Note in particular the content of freelist leaf +** pages can be changed arbitrarily without affecting the logical equivalence +** of the database. +** +** (7) At any time, if any subset, including the empty set and the total set, +** of the unsynced changes to a rollback journal are removed and the +** journal is rolled back, the resulting database file will be logically +** equivalent to the database file at the beginning of the transaction. +** +** (8) When a transaction is rolled back, the xTruncate method of the VFS +** is called to restore the database file to the same size it was at +** the beginning of the transaction. (In some VFSes, the xTruncate +** method is a no-op, but that does not change the fact the SQLite will +** invoke it.) +** +** (9) Whenever the database file is modified, at least one bit in the range +** of bytes from 24 through 39 inclusive will be changed prior to releasing +** the EXCLUSIVE lock, thus signaling other connections on the same +** database to flush their caches. +** +** (10) The pattern of bits in bytes 24 through 39 shall not repeat in less +** than one billion transactions. +** +** (11) A database file is well-formed at the beginning and at the conclusion +** of every transaction. +** +** (12) An EXCLUSIVE lock is held on the database file when writing to +** the database file. +** +** (13) A SHARED lock is held on the database file while reading any +** content out of the database file. +** +******************************************************************************/ + +/* +** Macros for troubleshooting. Normally turned off +*/ +#if 0 +int sqlite3PagerTrace=1; /* True to enable tracing */ +#define sqlite3DebugPrintf printf +#define PAGERTRACE(X) if( sqlite3PagerTrace ){ sqlite3DebugPrintf X; } +#else +#define PAGERTRACE(X) +#endif + +/* +** The following two macros are used within the PAGERTRACE() macros above +** to print out file-descriptors. +** +** PAGERID() takes a pointer to a Pager struct as its argument. The +** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file +** struct as its argument. +*/ +#define PAGERID(p) ((int)(p->fd)) +#define FILEHANDLEID(fd) ((int)fd) + +/* +** The Pager.eState variable stores the current 'state' of a pager. A +** pager may be in any one of the seven states shown in the following +** state diagram. +** +** OPEN <------+------+ +** | | | +** V | | +** +---------> READER-------+ | +** | | | +** | V | +** |<-------WRITER_LOCKED------> ERROR +** | | ^ +** | V | +** |<------WRITER_CACHEMOD-------->| +** | | | +** | V | +** |<-------WRITER_DBMOD---------->| +** | | | +** | V | +** +<------WRITER_FINISHED-------->+ +** +** +** List of state transitions and the C [function] that performs each: +** +** OPEN -> READER [sqlite3PagerSharedLock] +** READER -> OPEN [pager_unlock] +** +** READER -> WRITER_LOCKED [sqlite3PagerBegin] +** WRITER_LOCKED -> WRITER_CACHEMOD [pager_open_journal] +** WRITER_CACHEMOD -> WRITER_DBMOD [syncJournal] +** WRITER_DBMOD -> WRITER_FINISHED [sqlite3PagerCommitPhaseOne] +** WRITER_*** -> READER [pager_end_transaction] +** +** WRITER_*** -> ERROR [pager_error] +** ERROR -> OPEN [pager_unlock] +** +** +** OPEN: +** +** The pager starts up in this state. Nothing is guaranteed in this +** state - the file may or may not be locked and the database size is +** unknown. The database may not be read or written. +** +** * No read or write transaction is active. +** * Any lock, or no lock at all, may be held on the database file. +** * The dbSize, dbOrigSize and dbFileSize variables may not be trusted. +** +** READER: +** +** In this state all the requirements for reading the database in +** rollback (non-WAL) mode are met. Unless the pager is (or recently +** was) in exclusive-locking mode, a user-level read transaction is +** open. The database size is known in this state. +** +** A connection running with locking_mode=normal enters this state when +** it opens a read-transaction on the database and returns to state +** OPEN after the read-transaction is completed. However a connection +** running in locking_mode=exclusive (including temp databases) remains in +** this state even after the read-transaction is closed. The only way +** a locking_mode=exclusive connection can transition from READER to OPEN +** is via the ERROR state (see below). +** +** * A read transaction may be active (but a write-transaction cannot). +** * A SHARED or greater lock is held on the database file. +** * The dbSize variable may be trusted (even if a user-level read +** transaction is not active). The dbOrigSize and dbFileSize variables +** may not be trusted at this point. +** * If the database is a WAL database, then the WAL connection is open. +** * Even if a read-transaction is not open, it is guaranteed that +** there is no hot-journal in the file-system. +** +** WRITER_LOCKED: +** +** The pager moves to this state from READER when a write-transaction +** is first opened on the database. In WRITER_LOCKED state, all locks +** required to start a write-transaction are held, but no actual +** modifications to the cache or database have taken place. +** +** In rollback mode, a RESERVED or (if the transaction was opened with +** BEGIN EXCLUSIVE) EXCLUSIVE lock is obtained on the database file when +** moving to this state, but the journal file is not written to or opened +** to in this state. If the transaction is committed or rolled back while +** in WRITER_LOCKED state, all that is required is to unlock the database +** file. +** +** IN WAL mode, WalBeginWriteTransaction() is called to lock the log file. +** If the connection is running with locking_mode=exclusive, an attempt +** is made to obtain an EXCLUSIVE lock on the database file. +** +** * A write transaction is active. +** * If the connection is open in rollback-mode, a RESERVED or greater +** lock is held on the database file. +** * If the connection is open in WAL-mode, a WAL write transaction +** is open (i.e. sqlite3WalBeginWriteTransaction() has been successfully +** called). +** * The dbSize, dbOrigSize and dbFileSize variables are all valid. +** * The contents of the pager cache have not been modified. +** * The journal file may or may not be open. +** * Nothing (not even the first header) has been written to the journal. +** +** WRITER_CACHEMOD: +** +** A pager moves from WRITER_LOCKED state to this state when a page is +** first modified by the upper layer. In rollback mode the journal file +** is opened (if it is not already open) and a header written to the +** start of it. The database file on disk has not been modified. +** +** * A write transaction is active. +** * A RESERVED or greater lock is held on the database file. +** * The journal file is open and the first header has been written +** to it, but the header has not been synced to disk. +** * The contents of the page cache have been modified. +** +** WRITER_DBMOD: +** +** The pager transitions from WRITER_CACHEMOD into WRITER_DBMOD state +** when it modifies the contents of the database file. WAL connections +** never enter this state (since they do not modify the database file, +** just the log file). +** +** * A write transaction is active. +** * An EXCLUSIVE or greater lock is held on the database file. +** * The journal file is open and the first header has been written +** and synced to disk. +** * The contents of the page cache have been modified (and possibly +** written to disk). +** +** WRITER_FINISHED: +** +** It is not possible for a WAL connection to enter this state. +** +** A rollback-mode pager changes to WRITER_FINISHED state from WRITER_DBMOD +** state after the entire transaction has been successfully written into the +** database file. In this state the transaction may be committed simply +** by finalizing the journal file. Once in WRITER_FINISHED state, it is +** not possible to modify the database further. At this point, the upper +** layer must either commit or rollback the transaction. +** +** * A write transaction is active. +** * An EXCLUSIVE or greater lock is held on the database file. +** * All writing and syncing of journal and database data has finished. +** If no error occurred, all that remains is to finalize the journal to +** commit the transaction. If an error did occur, the caller will need +** to rollback the transaction. +** +** ERROR: +** +** The ERROR state is entered when an IO or disk-full error (including +** SQLITE_IOERR_NOMEM) occurs at a point in the code that makes it +** difficult to be sure that the in-memory pager state (cache contents, +** db size etc.) are consistent with the contents of the file-system. +** +** Temporary pager files may enter the ERROR state, but in-memory pagers +** cannot. +** +** For example, if an IO error occurs while performing a rollback, +** the contents of the page-cache may be left in an inconsistent state. +** At this point it would be dangerous to change back to READER state +** (as usually happens after a rollback). Any subsequent readers might +** report database corruption (due to the inconsistent cache), and if +** they upgrade to writers, they may inadvertently corrupt the database +** file. To avoid this hazard, the pager switches into the ERROR state +** instead of READER following such an error. +** +** Once it has entered the ERROR state, any attempt to use the pager +** to read or write data returns an error. Eventually, once all +** outstanding transactions have been abandoned, the pager is able to +** transition back to OPEN state, discarding the contents of the +** page-cache and any other in-memory state at the same time. Everything +** is reloaded from disk (and, if necessary, hot-journal rollback peformed) +** when a read-transaction is next opened on the pager (transitioning +** the pager into READER state). At that point the system has recovered +** from the error. +** +** Specifically, the pager jumps into the ERROR state if: +** +** 1. An error occurs while attempting a rollback. This happens in +** function sqlite3PagerRollback(). +** +** 2. An error occurs while attempting to finalize a journal file +** following a commit in function sqlite3PagerCommitPhaseTwo(). +** +** 3. An error occurs while attempting to write to the journal or +** database file in function pagerStress() in order to free up +** memory. +** +** In other cases, the error is returned to the b-tree layer. The b-tree +** layer then attempts a rollback operation. If the error condition +** persists, the pager enters the ERROR state via condition (1) above. +** +** Condition (3) is necessary because it can be triggered by a read-only +** statement executed within a transaction. In this case, if the error +** code were simply returned to the user, the b-tree layer would not +** automatically attempt a rollback, as it assumes that an error in a +** read-only statement cannot leave the pager in an internally inconsistent +** state. +** +** * The Pager.errCode variable is set to something other than SQLITE_OK. +** * There are one or more outstanding references to pages (after the +** last reference is dropped the pager should move back to OPEN state). +** * The pager is not an in-memory pager. +** +** +** Notes: +** +** * A pager is never in WRITER_DBMOD or WRITER_FINISHED state if the +** connection is open in WAL mode. A WAL connection is always in one +** of the first four states. +** +** * Normally, a connection open in exclusive mode is never in PAGER_OPEN +** state. There are two exceptions: immediately after exclusive-mode has +** been turned on (and before any read or write transactions are +** executed), and when the pager is leaving the "error state". +** +** * See also: assert_pager_state(). +*/ +#define PAGER_OPEN 0 +#define PAGER_READER 1 +#define PAGER_WRITER_LOCKED 2 +#define PAGER_WRITER_CACHEMOD 3 +#define PAGER_WRITER_DBMOD 4 +#define PAGER_WRITER_FINISHED 5 +#define PAGER_ERROR 6 + +/* +** The Pager.eLock variable is almost always set to one of the +** following locking-states, according to the lock currently held on +** the database file: NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK. +** This variable is kept up to date as locks are taken and released by +** the pagerLockDb() and pagerUnlockDb() wrappers. +** +** If the VFS xLock() or xUnlock() returns an error other than SQLITE_BUSY +** (i.e. one of the SQLITE_IOERR subtypes), it is not clear whether or not +** the operation was successful. In these circumstances pagerLockDb() and +** pagerUnlockDb() take a conservative approach - eLock is always updated +** when unlocking the file, and only updated when locking the file if the +** VFS call is successful. This way, the Pager.eLock variable may be set +** to a less exclusive (lower) value than the lock that is actually held +** at the system level, but it is never set to a more exclusive value. +** +** This is usually safe. If an xUnlock fails or appears to fail, there may +** be a few redundant xLock() calls or a lock may be held for longer than +** required, but nothing really goes wrong. +** +** The exception is when the database file is unlocked as the pager moves +** from ERROR to OPEN state. At this point there may be a hot-journal file +** in the file-system that needs to be rolled back (as part of an OPEN->SHARED +** transition, by the same pager or any other). If the call to xUnlock() +** fails at this point and the pager is left holding an EXCLUSIVE lock, this +** can confuse the call to xCheckReservedLock() call made later as part +** of hot-journal detection. +** +** xCheckReservedLock() is defined as returning true "if there is a RESERVED +** lock held by this process or any others". So xCheckReservedLock may +** return true because the caller itself is holding an EXCLUSIVE lock (but +** doesn't know it because of a previous error in xUnlock). If this happens +** a hot-journal may be mistaken for a journal being created by an active +** transaction in another process, causing SQLite to read from the database +** without rolling it back. +** +** To work around this, if a call to xUnlock() fails when unlocking the +** database in the ERROR state, Pager.eLock is set to UNKNOWN_LOCK. It +** is only changed back to a real locking state after a successful call +** to xLock(EXCLUSIVE). Also, the code to do the OPEN->SHARED state transition +** omits the check for a hot-journal if Pager.eLock is set to UNKNOWN_LOCK +** lock. Instead, it assumes a hot-journal exists and obtains an EXCLUSIVE +** lock on the database file before attempting to roll it back. See function +** PagerSharedLock() for more detail. +** +** Pager.eLock may only be set to UNKNOWN_LOCK when the pager is in +** PAGER_OPEN state. +*/ +#define UNKNOWN_LOCK (EXCLUSIVE_LOCK+1) + +/* +** A macro used for invoking the codec if there is one +*/ +#ifdef SQLITE_HAS_CODEC +# define CODEC1(P,D,N,X,E) \ + if( P->xCodec && P->xCodec(P->pCodec,D,N,X)==0 ){ E; } +# define CODEC2(P,D,N,X,E,O) \ + if( P->xCodec==0 ){ O=(char*)D; }else \ + if( (O=(char*)(P->xCodec(P->pCodec,D,N,X)))==0 ){ E; } +#else +# define CODEC1(P,D,N,X,E) /* NO-OP */ +# define CODEC2(P,D,N,X,E,O) O=(char*)D +#endif + +/* +** The maximum allowed sector size. 64KiB. If the xSectorsize() method +** returns a value larger than this, then MAX_SECTOR_SIZE is used instead. +** This could conceivably cause corruption following a power failure on +** such a system. This is currently an undocumented limit. +*/ +#define MAX_SECTOR_SIZE 0x10000 + +/* +** An instance of the following structure is allocated for each active +** savepoint and statement transaction in the system. All such structures +** are stored in the Pager.aSavepoint[] array, which is allocated and +** resized using sqlite3Realloc(). +** +** When a savepoint is created, the PagerSavepoint.iHdrOffset field is +** set to 0. If a journal-header is written into the main journal while +** the savepoint is active, then iHdrOffset is set to the byte offset +** immediately following the last journal record written into the main +** journal before the journal-header. This is required during savepoint +** rollback (see pagerPlaybackSavepoint()). +*/ +typedef struct PagerSavepoint PagerSavepoint; +struct PagerSavepoint { + i64 iOffset; /* Starting offset in main journal */ + i64 iHdrOffset; /* See above */ + Bitvec *pInSavepoint; /* Set of pages in this savepoint */ + Pgno nOrig; /* Original number of pages in file */ + Pgno iSubRec; /* Index of first record in sub-journal */ +#ifndef SQLITE_OMIT_WAL + u32 aWalData[WAL_SAVEPOINT_NDATA]; /* WAL savepoint context */ +#endif +}; + +/* +** Bits of the Pager.doNotSpill flag. See further description below. +*/ +#define SPILLFLAG_OFF 0x01 /* Never spill cache. Set via pragma */ +#define SPILLFLAG_ROLLBACK 0x02 /* Current rolling back, so do not spill */ +#define SPILLFLAG_NOSYNC 0x04 /* Spill is ok, but do not sync */ + +/* +** An open page cache is an instance of struct Pager. A description of +** some of the more important member variables follows: +** +** eState +** +** The current 'state' of the pager object. See the comment and state +** diagram above for a description of the pager state. +** +** eLock +** +** For a real on-disk database, the current lock held on the database file - +** NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK. +** +** For a temporary or in-memory database (neither of which require any +** locks), this variable is always set to EXCLUSIVE_LOCK. Since such +** databases always have Pager.exclusiveMode==1, this tricks the pager +** logic into thinking that it already has all the locks it will ever +** need (and no reason to release them). +** +** In some (obscure) circumstances, this variable may also be set to +** UNKNOWN_LOCK. See the comment above the #define of UNKNOWN_LOCK for +** details. +** +** changeCountDone +** +** This boolean variable is used to make sure that the change-counter +** (the 4-byte header field at byte offset 24 of the database file) is +** not updated more often than necessary. +** +** It is set to true when the change-counter field is updated, which +** can only happen if an exclusive lock is held on the database file. +** It is cleared (set to false) whenever an exclusive lock is +** relinquished on the database file. Each time a transaction is committed, +** The changeCountDone flag is inspected. If it is true, the work of +** updating the change-counter is omitted for the current transaction. +** +** This mechanism means that when running in exclusive mode, a connection +** need only update the change-counter once, for the first transaction +** committed. +** +** setMaster +** +** When PagerCommitPhaseOne() is called to commit a transaction, it may +** (or may not) specify a master-journal name to be written into the +** journal file before it is synced to disk. +** +** Whether or not a journal file contains a master-journal pointer affects +** the way in which the journal file is finalized after the transaction is +** committed or rolled back when running in "journal_mode=PERSIST" mode. +** If a journal file does not contain a master-journal pointer, it is +** finalized by overwriting the first journal header with zeroes. If +** it does contain a master-journal pointer the journal file is finalized +** by truncating it to zero bytes, just as if the connection were +** running in "journal_mode=truncate" mode. +** +** Journal files that contain master journal pointers cannot be finalized +** simply by overwriting the first journal-header with zeroes, as the +** master journal pointer could interfere with hot-journal rollback of any +** subsequently interrupted transaction that reuses the journal file. +** +** The flag is cleared as soon as the journal file is finalized (either +** by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the +** journal file from being successfully finalized, the setMaster flag +** is cleared anyway (and the pager will move to ERROR state). +** +** doNotSpill +** +** This variables control the behavior of cache-spills (calls made by +** the pcache module to the pagerStress() routine to write cached data +** to the file-system in order to free up memory). +** +** When bits SPILLFLAG_OFF or SPILLFLAG_ROLLBACK of doNotSpill are set, +** writing to the database from pagerStress() is disabled altogether. +** The SPILLFLAG_ROLLBACK case is done in a very obscure case that +** comes up during savepoint rollback that requires the pcache module +** to allocate a new page to prevent the journal file from being written +** while it is being traversed by code in pager_playback(). The SPILLFLAG_OFF +** case is a user preference. +** +** If the SPILLFLAG_NOSYNC bit is set, writing to the database from pagerStress() +** is permitted, but syncing the journal file is not. This flag is set +** by sqlite3PagerWrite() when the file-system sector-size is larger than +** the database page-size in order to prevent a journal sync from happening +** in between the journalling of two pages on the same sector. +** +** subjInMemory +** +** This is a boolean variable. If true, then any required sub-journal +** is opened as an in-memory journal file. If false, then in-memory +** sub-journals are only used for in-memory pager files. +** +** This variable is updated by the upper layer each time a new +** write-transaction is opened. +** +** dbSize, dbOrigSize, dbFileSize +** +** Variable dbSize is set to the number of pages in the database file. +** It is valid in PAGER_READER and higher states (all states except for +** OPEN and ERROR). +** +** dbSize is set based on the size of the database file, which may be +** larger than the size of the database (the value stored at offset +** 28 of the database header by the btree). If the size of the file +** is not an integer multiple of the page-size, the value stored in +** dbSize is rounded down (i.e. a 5KB file with 2K page-size has dbSize==2). +** Except, any file that is greater than 0 bytes in size is considered +** to have at least one page. (i.e. a 1KB file with 2K page-size leads +** to dbSize==1). +** +** During a write-transaction, if pages with page-numbers greater than +** dbSize are modified in the cache, dbSize is updated accordingly. +** Similarly, if the database is truncated using PagerTruncateImage(), +** dbSize is updated. +** +** Variables dbOrigSize and dbFileSize are valid in states +** PAGER_WRITER_LOCKED and higher. dbOrigSize is a copy of the dbSize +** variable at the start of the transaction. It is used during rollback, +** and to determine whether or not pages need to be journalled before +** being modified. +** +** Throughout a write-transaction, dbFileSize contains the size of +** the file on disk in pages. It is set to a copy of dbSize when the +** write-transaction is first opened, and updated when VFS calls are made +** to write or truncate the database file on disk. +** +** The only reason the dbFileSize variable is required is to suppress +** unnecessary calls to xTruncate() after committing a transaction. If, +** when a transaction is committed, the dbFileSize variable indicates +** that the database file is larger than the database image (Pager.dbSize), +** pager_truncate() is called. The pager_truncate() call uses xFilesize() +** to measure the database file on disk, and then truncates it if required. +** dbFileSize is not used when rolling back a transaction. In this case +** pager_truncate() is called unconditionally (which means there may be +** a call to xFilesize() that is not strictly required). In either case, +** pager_truncate() may cause the file to become smaller or larger. +** +** dbHintSize +** +** The dbHintSize variable is used to limit the number of calls made to +** the VFS xFileControl(FCNTL_SIZE_HINT) method. +** +** dbHintSize is set to a copy of the dbSize variable when a +** write-transaction is opened (at the same time as dbFileSize and +** dbOrigSize). If the xFileControl(FCNTL_SIZE_HINT) method is called, +** dbHintSize is increased to the number of pages that correspond to the +** size-hint passed to the method call. See pager_write_pagelist() for +** details. +** +** errCode +** +** The Pager.errCode variable is only ever used in PAGER_ERROR state. It +** is set to zero in all other states. In PAGER_ERROR state, Pager.errCode +** is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX +** sub-codes. +*/ +struct Pager { + sqlite3_vfs *pVfs; /* OS functions to use for IO */ + u8 exclusiveMode; /* Boolean. True if locking_mode==EXCLUSIVE */ + u8 journalMode; /* One of the PAGER_JOURNALMODE_* values */ + u8 useJournal; /* Use a rollback journal on this file */ + u8 noSync; /* Do not sync the journal if true */ + u8 fullSync; /* Do extra syncs of the journal for robustness */ + u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */ + u8 walSyncFlags; /* SYNC_NORMAL or SYNC_FULL for wal writes */ + u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ + u8 tempFile; /* zFilename is a temporary or immutable file */ + u8 noLock; /* Do not lock (except in WAL mode) */ + u8 readOnly; /* True for a read-only database */ + u8 memDb; /* True to inhibit all file I/O */ + + /************************************************************************** + ** The following block contains those class members that change during + ** routine operation. Class members not in this block are either fixed + ** when the pager is first created or else only change when there is a + ** significant mode change (such as changing the page_size, locking_mode, + ** or the journal_mode). From another view, these class members describe + ** the "state" of the pager, while other class members describe the + ** "configuration" of the pager. + */ + u8 eState; /* Pager state (OPEN, READER, WRITER_LOCKED..) */ + u8 eLock; /* Current lock held on database file */ + u8 changeCountDone; /* Set after incrementing the change-counter */ + u8 setMaster; /* True if a m-j name has been written to jrnl */ + u8 doNotSpill; /* Do not spill the cache when non-zero */ + u8 subjInMemory; /* True to use in-memory sub-journals */ + u8 bUseFetch; /* True to use xFetch() */ + u8 hasBeenUsed; /* True if any content previously read from this pager*/ + Pgno dbSize; /* Number of pages in the database */ + Pgno dbOrigSize; /* dbSize before the current transaction */ + Pgno dbFileSize; /* Number of pages in the database file */ + Pgno dbHintSize; /* Value passed to FCNTL_SIZE_HINT call */ + int errCode; /* One of several kinds of errors */ + int nRec; /* Pages journalled since last j-header written */ + u32 cksumInit; /* Quasi-random value added to every checksum */ + u32 nSubRec; /* Number of records written to sub-journal */ + Bitvec *pInJournal; /* One bit for each page in the database file */ + sqlite3_file *fd; /* File descriptor for database */ + sqlite3_file *jfd; /* File descriptor for main journal */ + sqlite3_file *sjfd; /* File descriptor for sub-journal */ + i64 journalOff; /* Current write offset in the journal file */ + i64 journalHdr; /* Byte offset to previous journal header */ + sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */ + PagerSavepoint *aSavepoint; /* Array of active savepoints */ + int nSavepoint; /* Number of elements in aSavepoint[] */ + u32 iDataVersion; /* Changes whenever database content changes */ + char dbFileVers[16]; /* Changes whenever database file changes */ + + int nMmapOut; /* Number of mmap pages currently outstanding */ + sqlite3_int64 szMmap; /* Desired maximum mmap size */ + PgHdr *pMmapFreelist; /* List of free mmap page headers (pDirty) */ + /* + ** End of the routinely-changing class members + ***************************************************************************/ + + u16 nExtra; /* Add this many bytes to each in-memory page */ + i16 nReserve; /* Number of unused bytes at end of each page */ + u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */ + u32 sectorSize; /* Assumed sector size during rollback */ + int pageSize; /* Number of bytes in a page */ + Pgno mxPgno; /* Maximum allowed size of the database */ + i64 journalSizeLimit; /* Size limit for persistent journal files */ + char *zFilename; /* Name of the database file */ + char *zJournal; /* Name of the journal file */ + int (*xBusyHandler)(void*); /* Function to call when busy */ + void *pBusyHandlerArg; /* Context argument for xBusyHandler */ + int aStat[3]; /* Total cache hits, misses and writes */ +#ifdef SQLITE_TEST + int nRead; /* Database pages read */ +#endif + void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */ +#ifdef SQLITE_HAS_CODEC + void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */ + void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */ + void (*xCodecFree)(void*); /* Destructor for the codec */ + void *pCodec; /* First argument to xCodec... methods */ +#endif + char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ + PCache *pPCache; /* Pointer to page cache object */ +#ifndef SQLITE_OMIT_WAL + Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ + char *zWal; /* File name for write-ahead log */ +#endif +}; + +/* +** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains +** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS +** or CACHE_WRITE to sqlite3_db_status(). +*/ +#define PAGER_STAT_HIT 0 +#define PAGER_STAT_MISS 1 +#define PAGER_STAT_WRITE 2 + +/* +** The following global variables hold counters used for +** testing purposes only. These variables do not exist in +** a non-testing build. These variables are not thread-safe. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_pager_readdb_count = 0; /* Number of full pages read from DB */ +SQLITE_API int sqlite3_pager_writedb_count = 0; /* Number of full pages written to DB */ +SQLITE_API int sqlite3_pager_writej_count = 0; /* Number of pages written to journal */ +# define PAGER_INCR(v) v++ +#else +# define PAGER_INCR(v) +#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 being +** written, semi-random garbage data might appear in the journal +** file after power is restored. If an attempt is then made +** to roll the journal back, the database could be corrupted. The additional +** sanity checking data is an attempt to discover the garbage in the +** journal and ignore it. +** +** The sanity checking information for the new journal format consists +** of a 32-bit checksum on each page of data. The checksum covers both +** the page number and the pPager->pageSize bytes of data for the page. +** This cksum is initialized to a 32-bit random value that appears in the +** journal file right after the header. The random initializer is important, +** because garbage data that appears at the end of a journal is likely +** data that was once in other files that have now been deleted. If the +** garbage data came from an obsolete journal file, the checksums might +** be correct. But by initializing the checksum to random value which +** is different for every journal, we minimize that risk. +*/ +static const unsigned char aJournalMagic[] = { + 0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd7, +}; + +/* +** The size of the of each page record in the journal is given by +** the following macro. +*/ +#define JOURNAL_PG_SZ(pPager) ((pPager->pageSize) + 8) + +/* +** The journal header size for this pager. This is usually the same +** size as a single disk sector. See also setSectorSize(). +*/ +#define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize) + +/* +** The macro MEMDB is true if we are dealing with an in-memory database. +** We do this as a macro so that if the SQLITE_OMIT_MEMORYDB macro is set, +** the value of MEMDB will be a constant and the compiler will optimize +** out code that would never execute. +*/ +#ifdef SQLITE_OMIT_MEMORYDB +# define MEMDB 0 +#else +# define MEMDB pPager->memDb +#endif + +/* +** The macro USEFETCH is true if we are allowed to use the xFetch and xUnfetch +** interfaces to access the database using memory-mapped I/O. +*/ +#if SQLITE_MAX_MMAP_SIZE>0 +# define USEFETCH(x) ((x)->bUseFetch) +#else +# define USEFETCH(x) 0 +#endif + +/* +** The maximum legal page number is (2^31 - 1). +*/ +#define PAGER_MAX_PGNO 2147483647 + +/* +** The argument to this macro is a file descriptor (type sqlite3_file*). +** Return 0 if it is not open, or non-zero (but not 1) if it is. +** +** This is so that expressions can be written as: +** +** if( isOpen(pPager->jfd) ){ ... +** +** instead of +** +** if( pPager->jfd->pMethods ){ ... +*/ +#define isOpen(pFd) ((pFd)->pMethods) + +/* +** Return true if this pager uses a write-ahead log instead of the usual +** rollback journal. Otherwise false. +*/ +#ifndef SQLITE_OMIT_WAL +static int pagerUseWal(Pager *pPager){ + return (pPager->pWal!=0); +} +#else +# define pagerUseWal(x) 0 +# define pagerRollbackWal(x) 0 +# define pagerWalFrames(v,w,x,y) 0 +# define pagerOpenWalIfPresent(z) SQLITE_OK +# define pagerBeginReadTransaction(z) SQLITE_OK +#endif + +#ifndef NDEBUG +/* +** Usage: +** +** assert( assert_pager_state(pPager) ); +** +** This function runs many asserts to try to find inconsistencies in +** the internal state of the Pager object. +*/ +static int assert_pager_state(Pager *p){ + Pager *pPager = p; + + /* State must be valid. */ + assert( p->eState==PAGER_OPEN + || p->eState==PAGER_READER + || p->eState==PAGER_WRITER_LOCKED + || p->eState==PAGER_WRITER_CACHEMOD + || p->eState==PAGER_WRITER_DBMOD + || p->eState==PAGER_WRITER_FINISHED + || p->eState==PAGER_ERROR + ); + + /* Regardless of the current state, a temp-file connection always behaves + ** as if it has an exclusive lock on the database file. It never updates + ** the change-counter field, so the changeCountDone flag is always set. + */ + assert( p->tempFile==0 || p->eLock==EXCLUSIVE_LOCK ); + assert( p->tempFile==0 || pPager->changeCountDone ); + + /* If the useJournal flag is clear, the journal-mode must be "OFF". + ** And if the journal-mode is "OFF", the journal file must not be open. + */ + assert( p->journalMode==PAGER_JOURNALMODE_OFF || p->useJournal ); + assert( p->journalMode!=PAGER_JOURNALMODE_OFF || !isOpen(p->jfd) ); + + /* Check that MEMDB implies noSync. And an in-memory journal. Since + ** this means an in-memory pager performs no IO at all, it cannot encounter + ** either SQLITE_IOERR or SQLITE_FULL during rollback or while finalizing + ** a journal file. (although the in-memory journal implementation may + ** return SQLITE_IOERR_NOMEM while the journal file is being written). It + ** is therefore not possible for an in-memory pager to enter the ERROR + ** state. + */ + if( MEMDB ){ + assert( p->noSync ); + assert( p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_MEMORY + ); + assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN ); + assert( pagerUseWal(p)==0 ); + } + + /* If changeCountDone is set, a RESERVED lock or greater must be held + ** on the file. + */ + assert( pPager->changeCountDone==0 || pPager->eLock>=RESERVED_LOCK ); + assert( p->eLock!=PENDING_LOCK ); + + switch( p->eState ){ + case PAGER_OPEN: + assert( !MEMDB ); + assert( pPager->errCode==SQLITE_OK ); + assert( sqlite3PcacheRefCount(pPager->pPCache)==0 || pPager->tempFile ); + break; + + case PAGER_READER: + assert( pPager->errCode==SQLITE_OK ); + assert( p->eLock!=UNKNOWN_LOCK ); + assert( p->eLock>=SHARED_LOCK ); + break; + + case PAGER_WRITER_LOCKED: + assert( p->eLock!=UNKNOWN_LOCK ); + assert( pPager->errCode==SQLITE_OK ); + if( !pagerUseWal(pPager) ){ + assert( p->eLock>=RESERVED_LOCK ); + } + assert( pPager->dbSize==pPager->dbOrigSize ); + assert( pPager->dbOrigSize==pPager->dbFileSize ); + assert( pPager->dbOrigSize==pPager->dbHintSize ); + assert( pPager->setMaster==0 ); + break; + + case PAGER_WRITER_CACHEMOD: + assert( p->eLock!=UNKNOWN_LOCK ); + assert( pPager->errCode==SQLITE_OK ); + if( !pagerUseWal(pPager) ){ + /* It is possible that if journal_mode=wal here that neither the + ** journal file nor the WAL file are open. This happens during + ** a rollback transaction that switches from journal_mode=off + ** to journal_mode=wal. + */ + assert( p->eLock>=RESERVED_LOCK ); + assert( isOpen(p->jfd) + || p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_WAL + ); + } + assert( pPager->dbOrigSize==pPager->dbFileSize ); + assert( pPager->dbOrigSize==pPager->dbHintSize ); + break; + + case PAGER_WRITER_DBMOD: + assert( p->eLock==EXCLUSIVE_LOCK ); + assert( pPager->errCode==SQLITE_OK ); + assert( !pagerUseWal(pPager) ); + assert( p->eLock>=EXCLUSIVE_LOCK ); + assert( isOpen(p->jfd) + || p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_WAL + ); + assert( pPager->dbOrigSize<=pPager->dbHintSize ); + break; + + case PAGER_WRITER_FINISHED: + assert( p->eLock==EXCLUSIVE_LOCK ); + assert( pPager->errCode==SQLITE_OK ); + assert( !pagerUseWal(pPager) ); + assert( isOpen(p->jfd) + || p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_WAL + ); + break; + + case PAGER_ERROR: + /* There must be at least one outstanding reference to the pager if + ** in ERROR state. Otherwise the pager should have already dropped + ** back to OPEN state. + */ + assert( pPager->errCode!=SQLITE_OK ); + assert( sqlite3PcacheRefCount(pPager->pPCache)>0 ); + break; + } + + return 1; +} +#endif /* ifndef NDEBUG */ + +#ifdef SQLITE_DEBUG +/* +** Return a pointer to a human readable string in a static buffer +** containing the state of the Pager object passed as an argument. This +** is intended to be used within debuggers. For example, as an alternative +** to "print *pPager" in gdb: +** +** (gdb) printf "%s", print_pager_state(pPager) +*/ +static char *print_pager_state(Pager *p){ + static char zRet[1024]; + + sqlite3_snprintf(1024, zRet, + "Filename: %s\n" + "State: %s errCode=%d\n" + "Lock: %s\n" + "Locking mode: locking_mode=%s\n" + "Journal mode: journal_mode=%s\n" + "Backing store: tempFile=%d memDb=%d useJournal=%d\n" + "Journal: journalOff=%lld journalHdr=%lld\n" + "Size: dbsize=%d dbOrigSize=%d dbFileSize=%d\n" + , p->zFilename + , p->eState==PAGER_OPEN ? "OPEN" : + p->eState==PAGER_READER ? "READER" : + p->eState==PAGER_WRITER_LOCKED ? "WRITER_LOCKED" : + p->eState==PAGER_WRITER_CACHEMOD ? "WRITER_CACHEMOD" : + p->eState==PAGER_WRITER_DBMOD ? "WRITER_DBMOD" : + p->eState==PAGER_WRITER_FINISHED ? "WRITER_FINISHED" : + p->eState==PAGER_ERROR ? "ERROR" : "?error?" + , (int)p->errCode + , p->eLock==NO_LOCK ? "NO_LOCK" : + p->eLock==RESERVED_LOCK ? "RESERVED" : + p->eLock==EXCLUSIVE_LOCK ? "EXCLUSIVE" : + p->eLock==SHARED_LOCK ? "SHARED" : + p->eLock==UNKNOWN_LOCK ? "UNKNOWN" : "?error?" + , p->exclusiveMode ? "exclusive" : "normal" + , p->journalMode==PAGER_JOURNALMODE_MEMORY ? "memory" : + p->journalMode==PAGER_JOURNALMODE_OFF ? "off" : + p->journalMode==PAGER_JOURNALMODE_DELETE ? "delete" : + p->journalMode==PAGER_JOURNALMODE_PERSIST ? "persist" : + p->journalMode==PAGER_JOURNALMODE_TRUNCATE ? "truncate" : + p->journalMode==PAGER_JOURNALMODE_WAL ? "wal" : "?error?" + , (int)p->tempFile, (int)p->memDb, (int)p->useJournal + , p->journalOff, p->journalHdr + , (int)p->dbSize, (int)p->dbOrigSize, (int)p->dbFileSize + ); + + return zRet; +} +#endif + +/* +** Return true if it is necessary to write page *pPg into the sub-journal. +** A page needs to be written into the sub-journal if there exists one +** or more open savepoints for which: +** +** * The page-number is less than or equal to PagerSavepoint.nOrig, and +** * The bit corresponding to the page-number is not set in +** PagerSavepoint.pInSavepoint. +*/ +static int subjRequiresPage(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + PagerSavepoint *p; + Pgno pgno = pPg->pgno; + int i; + for(i=0; inSavepoint; i++){ + p = &pPager->aSavepoint[i]; + if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){ + return 1; + } + } + return 0; +} + +/* +** Return true if the page is already in the journal file. +*/ +static int pageInJournal(Pager *pPager, PgHdr *pPg){ + return sqlite3BitvecTest(pPager->pInJournal, pPg->pgno); +} + +/* +** 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(sqlite3_file *fd, i64 offset, u32 *pRes){ + unsigned char ac[4]; + int rc = sqlite3OsRead(fd, ac, sizeof(ac), offset); + if( rc==SQLITE_OK ){ + *pRes = sqlite3Get4byte(ac); + } + return rc; +} + +/* +** Write a 32-bit integer into a string buffer in big-endian byte order. +*/ +#define put32bits(A,B) sqlite3Put4byte((u8*)A,B) + + +/* +** 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(sqlite3_file *fd, i64 offset, u32 val){ + char ac[4]; + put32bits(ac, val); + return sqlite3OsWrite(fd, ac, 4, offset); +} + +/* +** Unlock the database file to level eLock, which must be either NO_LOCK +** or SHARED_LOCK. Regardless of whether or not the call to xUnlock() +** succeeds, set the Pager.eLock variable to match the (attempted) new lock. +** +** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is +** called, do not modify it. See the comment above the #define of +** UNKNOWN_LOCK for an explanation of this. +*/ +static int pagerUnlockDb(Pager *pPager, int eLock){ + int rc = SQLITE_OK; + + assert( !pPager->exclusiveMode || pPager->eLock==eLock ); + assert( eLock==NO_LOCK || eLock==SHARED_LOCK ); + assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 ); + if( isOpen(pPager->fd) ){ + assert( pPager->eLock>=eLock ); + rc = pPager->noLock ? SQLITE_OK : sqlite3OsUnlock(pPager->fd, eLock); + if( pPager->eLock!=UNKNOWN_LOCK ){ + pPager->eLock = (u8)eLock; + } + IOTRACE(("UNLOCK %p %d\n", pPager, eLock)) + } + return rc; +} + +/* +** Lock the database file to level eLock, which must be either SHARED_LOCK, +** RESERVED_LOCK or EXCLUSIVE_LOCK. If the caller is successful, set the +** Pager.eLock variable to the new locking state. +** +** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is +** called, do not modify it unless the new locking state is EXCLUSIVE_LOCK. +** See the comment above the #define of UNKNOWN_LOCK for an explanation +** of this. +*/ +static int pagerLockDb(Pager *pPager, int eLock){ + int rc = SQLITE_OK; + + assert( eLock==SHARED_LOCK || eLock==RESERVED_LOCK || eLock==EXCLUSIVE_LOCK ); + if( pPager->eLockeLock==UNKNOWN_LOCK ){ + rc = pPager->noLock ? SQLITE_OK : sqlite3OsLock(pPager->fd, eLock); + if( rc==SQLITE_OK && (pPager->eLock!=UNKNOWN_LOCK||eLock==EXCLUSIVE_LOCK) ){ + pPager->eLock = (u8)eLock; + IOTRACE(("LOCK %p %d\n", pPager, eLock)) + } + } + return rc; +} + +/* +** This function determines whether or not the atomic-write optimization +** can be used with this pager. The optimization can be used if: +** +** (a) the value returned by OsDeviceCharacteristics() indicates that +** a database page may be written atomically, and +** (b) the value returned by OsSectorSize() is less than or equal +** to the page size. +** +** The optimization is also always enabled for temporary files. It is +** an error to call this function if pPager is opened on an in-memory +** database. +** +** If the optimization cannot be used, 0 is returned. If it can be used, +** then the value returned is the size of the journal file when it +** contains rollback data for exactly one page. +*/ +#ifdef SQLITE_ENABLE_ATOMIC_WRITE +static int jrnlBufferSize(Pager *pPager){ + assert( !MEMDB ); + if( !pPager->tempFile ){ + int dc; /* Device characteristics */ + int nSector; /* Sector size */ + int szPage; /* Page size */ + + assert( isOpen(pPager->fd) ); + dc = sqlite3OsDeviceCharacteristics(pPager->fd); + nSector = pPager->sectorSize; + szPage = pPager->pageSize; + + assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); + assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); + if( 0==(dc&(SQLITE_IOCAP_ATOMIC|(szPage>>8)) || nSector>szPage) ){ + return 0; + } + } + + return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager); +} +#endif + +/* +** If SQLITE_CHECK_PAGES is defined then we do some sanity checking +** on the cache using a hash function. This is used for testing +** and debugging only. +*/ +#ifdef SQLITE_CHECK_PAGES +/* +** Return a 32-bit hash of the page data for pPage. +*/ +static u32 pager_datahash(int nByte, unsigned char *pData){ + u32 hash = 0; + int i; + for(i=0; ipPager->pageSize, (unsigned char *)pPage->pData); +} +static void pager_set_pagehash(PgHdr *pPage){ + pPage->pageHash = pager_pagehash(pPage); +} + +/* +** 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( pPager->eState!=PAGER_ERROR ); + assert( (pPg->flags&PGHDR_DIRTY) || pPg->pageHash==pager_pagehash(pPg) ); +} + +#else +#define pager_datahash(X,Y) 0 +#define pager_pagehash(X) 0 +#define pager_set_pagehash(X) +#define CHECK_PAGE(x) +#endif /* SQLITE_CHECK_PAGES */ + +/* +** When this is called the journal file for pager pPager must be open. +** This function attempts to read a master journal file name from the +** end of the file and, if successful, copies it into memory supplied +** by the caller. See comments above writeMasterJournal() for the format +** used to store a master journal file name at the end of a journal file. +** +** zMaster must point to a buffer of at least nMaster bytes allocated by +** the caller. This should be sqlite3_vfs.mxPathname+1 (to ensure there is +** enough space to write the master journal name). If the master journal +** name in the journal is longer than nMaster bytes (including a +** nul-terminator), then this is handled as if no master journal name +** were present in the journal. +** +** If a master journal file name is present at the end of the journal +** file, then it is copied into the buffer pointed to by zMaster. A +** nul-terminator byte is appended to the buffer following the master +** journal file name. +** +** If it is determined that no master journal file name is present +** zMaster[0] is set to 0 and SQLITE_OK returned. +** +** If an error occurs while reading from the journal file, an SQLite +** error code is returned. +*/ +static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){ + int rc; /* Return code */ + u32 len; /* Length in bytes of master journal name */ + i64 szJ; /* Total size in bytes of journal file pJrnl */ + u32 cksum; /* MJ checksum value read from journal */ + u32 u; /* Unsigned loop counter */ + unsigned char aMagic[8]; /* A buffer to hold the magic header */ + zMaster[0] = '\0'; + + if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ)) + || szJ<16 + || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len)) + || len>=nMaster + || len==0 + || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum)) + || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8)) + || memcmp(aMagic, aJournalMagic, 8) + || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, zMaster, len, szJ-16-len)) + ){ + return rc; + } + + /* See if the checksum matches the master journal name */ + for(u=0; ujournalOff, assuming a sector +** size of pPager->sectorSize bytes. +** +** i.e for a sector size of 512: +** +** Pager.journalOff Return value +** --------------------------------------- +** 0 0 +** 512 512 +** 100 512 +** 2000 2048 +** +*/ +static i64 journalHdrOffset(Pager *pPager){ + i64 offset = 0; + i64 c = pPager->journalOff; + 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)jfd) ); + if( pPager->journalOff ){ + const i64 iLimit = pPager->journalSizeLimit; /* Local cache of jsl */ + + IOTRACE(("JZEROHDR %p\n", pPager)) + if( doTruncate || iLimit==0 ){ + rc = sqlite3OsTruncate(pPager->jfd, 0); + }else{ + static const char zeroHdr[28] = {0}; + rc = sqlite3OsWrite(pPager->jfd, zeroHdr, sizeof(zeroHdr), 0); + } + if( rc==SQLITE_OK && !pPager->noSync ){ + rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_DATAONLY|pPager->syncFlags); + } + + /* At this point the transaction is committed but the write lock + ** is still held on the file. If there is a size limit configured for + ** the persistent journal and the journal file currently consumes more + ** space than that limit allows for, truncate it now. There is no need + ** to sync the file following this operation. + */ + if( rc==SQLITE_OK && iLimit>0 ){ + i64 sz; + rc = sqlite3OsFileSize(pPager->jfd, &sz); + if( rc==SQLITE_OK && sz>iLimit ){ + rc = sqlite3OsTruncate(pPager->jfd, iLimit); + } + } + } + return rc; +} + +/* +** 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. +** - 4 bytes: Database page size. +** +** Followed by (JOURNAL_HDR_SZ - 28) bytes of unused space. +*/ +static int writeJournalHdr(Pager *pPager){ + int rc = SQLITE_OK; /* Return code */ + char *zHeader = pPager->pTmpSpace; /* Temporary space used to build header */ + u32 nHeader = (u32)pPager->pageSize;/* Size of buffer pointed to by zHeader */ + u32 nWrite; /* Bytes of header sector written */ + int ii; /* Loop counter */ + + assert( isOpen(pPager->jfd) ); /* Journal file must be open. */ + + if( nHeader>JOURNAL_HDR_SZ(pPager) ){ + nHeader = JOURNAL_HDR_SZ(pPager); + } + + /* If there are active savepoints and any of them were created + ** since the most recent journal header was written, update the + ** PagerSavepoint.iHdrOffset fields now. + */ + for(ii=0; iinSavepoint; ii++){ + if( pPager->aSavepoint[ii].iHdrOffset==0 ){ + pPager->aSavepoint[ii].iHdrOffset = pPager->journalOff; + } + } + + pPager->journalHdr = pPager->journalOff = journalHdrOffset(pPager); + + /* + ** Write the nRec Field - the number of page records that follow this + ** journal header. Normally, zero is written to this value at this time. + ** After the records are added to the journal (and the journal synced, + ** if in full-sync mode), the zero is overwritten with the true number + ** of records (see syncJournal()). + ** + ** A faster alternative is to write 0xFFFFFFFF to the nRec field. When + ** reading the journal this value tells SQLite to assume that the + ** rest of the journal file contains valid page records. This assumption + ** is dangerous, as if a failure occurred whilst writing to the journal + ** file it may contain some garbage data. There are two scenarios + ** where this risk can be ignored: + ** + ** * When the pager is in no-sync mode. Corruption can follow a + ** power failure in this case anyway. + ** + ** * When the SQLITE_IOCAP_SAFE_APPEND flag is set. This guarantees + ** that garbage data is never appended to the journal file. + */ + assert( isOpen(pPager->fd) || pPager->noSync ); + if( pPager->noSync || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY) + || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) + ){ + memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); + put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff); + }else{ + memset(zHeader, 0, sizeof(aJournalMagic)+4); + } + + /* The random check-hash initializer */ + sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); + put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit); + /* The initial database size */ + put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbOrigSize); + /* The assumed sector size for this process */ + put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize); + + /* The page size */ + put32bits(&zHeader[sizeof(aJournalMagic)+16], pPager->pageSize); + + /* Initializing the tail of the buffer is not necessary. Everything + ** works find if the following memset() is omitted. But initializing + ** the memory prevents valgrind from complaining, so we are willing to + ** take the performance hit. + */ + memset(&zHeader[sizeof(aJournalMagic)+20], 0, + nHeader-(sizeof(aJournalMagic)+20)); + + /* In theory, it is only necessary to write the 28 bytes that the + ** journal header consumes to the journal file here. Then increment the + ** Pager.journalOff variable by JOURNAL_HDR_SZ so that the next + ** record is written to the following sector (leaving a gap in the file + ** that will be implicitly filled in by the OS). + ** + ** However it has been discovered that on some systems this pattern can + ** be significantly slower than contiguously writing data to the file, + ** even if that means explicitly writing data to the block of + ** (JOURNAL_HDR_SZ - 28) bytes that will not be used. So that is what + ** is done. + ** + ** The loop is required here in case the sector-size is larger than the + ** database page size. Since the zHeader buffer is only Pager.pageSize + ** bytes in size, more than one call to sqlite3OsWrite() may be required + ** to populate the entire journal header sector. + */ + for(nWrite=0; rc==SQLITE_OK&&nWritejournalHdr, nHeader)) + rc = sqlite3OsWrite(pPager->jfd, zHeader, nHeader, pPager->journalOff); + assert( pPager->journalHdr <= pPager->journalOff ); + pPager->journalOff += nHeader; + } + + 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 +** file. The current location in the journal file is given by +** pPager->journalOff. See comments above function writeJournalHdr() for +** a description of the journal header format. +** +** If the header is read successfully, *pNRec is set to the number of +** page records following this header and *pDbSize is set to the size of the +** database before the transaction began, in pages. Also, pPager->cksumInit +** is set to the value read from the journal header. SQLITE_OK is returned +** in this case. +** +** If the journal header file appears to be corrupted, SQLITE_DONE is +** returned and *pNRec and *PDbSize are undefined. If JOURNAL_HDR_SZ bytes +** cannot be read from the journal file an error code is returned. +*/ +static int readJournalHdr( + Pager *pPager, /* Pager object */ + int isHot, + i64 journalSize, /* Size of the open journal file in bytes */ + u32 *pNRec, /* OUT: Value read from the nRec field */ + u32 *pDbSize /* OUT: Value of original database size field */ +){ + int rc; /* Return code */ + unsigned char aMagic[8]; /* A buffer to hold the magic header */ + i64 iHdrOff; /* Offset of journal header being read */ + + assert( isOpen(pPager->jfd) ); /* Journal file must be open. */ + + /* Advance Pager.journalOff to the start of the next sector. If the + ** journal file is too small for there to be a header stored at this + ** point, return SQLITE_DONE. + */ + pPager->journalOff = journalHdrOffset(pPager); + if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){ + return SQLITE_DONE; + } + iHdrOff = pPager->journalOff; + + /* Read in the first 8 bytes of the journal header. If they do not match + ** the magic string found at the start of each journal header, return + ** SQLITE_DONE. If an IO error occurs, return an error code. Otherwise, + ** proceed. + */ + if( isHot || iHdrOff!=pPager->journalHdr ){ + rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic), iHdrOff); + if( rc ){ + return rc; + } + if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){ + return SQLITE_DONE; + } + } + + /* Read the first three 32-bit fields of the journal header: The nRec + ** field, the checksum-initializer and the database size at the start + ** of the transaction. Return an error code if anything goes wrong. + */ + if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+8, pNRec)) + || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+12, &pPager->cksumInit)) + || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+16, pDbSize)) + ){ + return rc; + } + + if( pPager->journalOff==0 ){ + u32 iPageSize; /* Page-size field of journal header */ + u32 iSectorSize; /* Sector-size field of journal header */ + + /* Read the page-size and sector-size journal header fields. */ + if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+20, &iSectorSize)) + || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+24, &iPageSize)) + ){ + return rc; + } + + /* Versions of SQLite prior to 3.5.8 set the page-size field of the + ** journal header to zero. In this case, assume that the Pager.pageSize + ** variable is already set to the correct page size. + */ + if( iPageSize==0 ){ + iPageSize = pPager->pageSize; + } + + /* Check that the values read from the page-size and sector-size fields + ** are within range. To be 'in range', both values need to be a power + ** of two greater than or equal to 512 or 32, and not greater than their + ** respective compile time maximum limits. + */ + if( iPageSize<512 || iSectorSize<32 + || iPageSize>SQLITE_MAX_PAGE_SIZE || iSectorSize>MAX_SECTOR_SIZE + || ((iPageSize-1)&iPageSize)!=0 || ((iSectorSize-1)&iSectorSize)!=0 + ){ + /* If the either the page-size or sector-size in the journal-header is + ** invalid, then the process that wrote the journal-header must have + ** crashed before the header was synced. In this case stop reading + ** the journal file here. + */ + return SQLITE_DONE; + } + + /* Update the page-size to match the value read from the journal. + ** Use a testcase() macro to make sure that malloc failure within + ** PagerSetPagesize() is tested. + */ + rc = sqlite3PagerSetPagesize(pPager, &iPageSize, -1); + testcase( rc!=SQLITE_OK ); + + /* 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. + */ + pPager->sectorSize = iSectorSize; + } + + pPager->journalOff += JOURNAL_HDR_SZ(pPager); + 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: Master journal filename in utf-8. +** + 4 bytes: N (length of master journal name in bytes, no nul-terminator). +** + 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, where each byte is interpreted as a signed 8-bit integer. +** +** 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; /* Return code */ + int nMaster; /* Length of string zMaster */ + i64 iHdrOff; /* Offset of header in journal file */ + i64 jrnlSize; /* Size of journal file on disk */ + u32 cksum = 0; /* Checksum of string zMaster */ + + assert( pPager->setMaster==0 ); + assert( !pagerUseWal(pPager) ); + + if( !zMaster + || pPager->journalMode==PAGER_JOURNALMODE_MEMORY + || !isOpen(pPager->jfd) + ){ + return SQLITE_OK; + } + pPager->setMaster = 1; + assert( pPager->journalHdr <= pPager->journalOff ); + + /* Calculate the length in bytes and the checksum of zMaster */ + for(nMaster=0; zMaster[nMaster]; nMaster++){ + cksum += zMaster[nMaster]; + } + + /* 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 ){ + pPager->journalOff = journalHdrOffset(pPager); + } + iHdrOff = pPager->journalOff; + + /* Write the master journal data to the end of the journal file. If + ** an error occurs, return the error code to the caller. + */ + if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_MJ_PGNO(pPager)))) + || (0 != (rc = sqlite3OsWrite(pPager->jfd, zMaster, nMaster, iHdrOff+4))) + || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster, nMaster))) + || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster+4, cksum))) + || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, iHdrOff+4+nMaster+8))) + ){ + return rc; + } + pPager->journalOff += (nMaster+20); + + /* If the pager is in peristent-journal mode, then the physical + ** journal-file may extend past the end of the master-journal name + ** and 8 bytes of magic data just written to the file. This is + ** dangerous because the code to rollback a hot-journal file + ** will not be able to find the master-journal name to determine + ** whether or not the journal is hot. + ** + ** Easiest thing to do in this scenario is to truncate the journal + ** file to the required size. + */ + if( SQLITE_OK==(rc = sqlite3OsFileSize(pPager->jfd, &jrnlSize)) + && jrnlSize>pPager->journalOff + ){ + rc = sqlite3OsTruncate(pPager->jfd, pPager->journalOff); + } + return rc; +} + +/* +** Discard the entire contents of the in-memory page-cache. +*/ +static void pager_reset(Pager *pPager){ + pPager->iDataVersion++; + sqlite3BackupRestart(pPager->pBackup); + sqlite3PcacheClear(pPager->pPCache); +} + +/* +** Return the pPager->iDataVersion value +*/ +SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager *pPager){ + assert( pPager->eState>PAGER_OPEN ); + return pPager->iDataVersion; +} + +/* +** Free all structures in the Pager.aSavepoint[] array and set both +** Pager.aSavepoint and Pager.nSavepoint to zero. Close the sub-journal +** if it is open and the pager is not in exclusive mode. +*/ +static void releaseAllSavepoints(Pager *pPager){ + int ii; /* Iterator for looping through Pager.aSavepoint */ + for(ii=0; iinSavepoint; ii++){ + sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint); + } + if( !pPager->exclusiveMode || sqlite3IsMemJournal(pPager->sjfd) ){ + sqlite3OsClose(pPager->sjfd); + } + sqlite3_free(pPager->aSavepoint); + pPager->aSavepoint = 0; + pPager->nSavepoint = 0; + pPager->nSubRec = 0; +} + +/* +** Set the bit number pgno in the PagerSavepoint.pInSavepoint +** bitvecs of all open savepoints. Return SQLITE_OK if successful +** or SQLITE_NOMEM if a malloc failure occurs. +*/ +static int addToSavepointBitvecs(Pager *pPager, Pgno pgno){ + int ii; /* Loop counter */ + int rc = SQLITE_OK; /* Result code */ + + for(ii=0; iinSavepoint; ii++){ + PagerSavepoint *p = &pPager->aSavepoint[ii]; + if( pgno<=p->nOrig ){ + rc |= sqlite3BitvecSet(p->pInSavepoint, pgno); + testcase( rc==SQLITE_NOMEM ); + assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); + } + } + return rc; +} + +/* +** This function is a no-op if the pager is in exclusive mode and not +** in the ERROR state. Otherwise, it switches the pager to PAGER_OPEN +** state. +** +** If the pager is not in exclusive-access mode, the database file is +** completely unlocked. If the file is unlocked and the file-system does +** not exhibit the UNDELETABLE_WHEN_OPEN property, the journal file is +** closed (if it is open). +** +** If the pager is in ERROR state when this function is called, the +** contents of the pager cache are discarded before switching back to +** the OPEN state. Regardless of whether the pager is in exclusive-mode +** or not, any journal file left in the file-system will be treated +** as a hot-journal and rolled back the next time a read-transaction +** is opened (by this or by any other connection). +*/ +static void pager_unlock(Pager *pPager){ + + assert( pPager->eState==PAGER_READER + || pPager->eState==PAGER_OPEN + || pPager->eState==PAGER_ERROR + ); + + sqlite3BitvecDestroy(pPager->pInJournal); + pPager->pInJournal = 0; + releaseAllSavepoints(pPager); + + if( pagerUseWal(pPager) ){ + assert( !isOpen(pPager->jfd) ); + sqlite3WalEndReadTransaction(pPager->pWal); + pPager->eState = PAGER_OPEN; + }else if( !pPager->exclusiveMode ){ + int rc; /* Error code returned by pagerUnlockDb() */ + int iDc = isOpen(pPager->fd)?sqlite3OsDeviceCharacteristics(pPager->fd):0; + + /* If the operating system support deletion of open files, then + ** close the journal file when dropping the database lock. Otherwise + ** another connection with journal_mode=delete might delete the file + ** out from under us. + */ + assert( (PAGER_JOURNALMODE_MEMORY & 5)!=1 ); + assert( (PAGER_JOURNALMODE_OFF & 5)!=1 ); + assert( (PAGER_JOURNALMODE_WAL & 5)!=1 ); + assert( (PAGER_JOURNALMODE_DELETE & 5)!=1 ); + assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 ); + assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 ); + if( 0==(iDc & SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN) + || 1!=(pPager->journalMode & 5) + ){ + sqlite3OsClose(pPager->jfd); + } + + /* If the pager is in the ERROR state and the call to unlock the database + ** file fails, set the current lock to UNKNOWN_LOCK. See the comment + ** above the #define for UNKNOWN_LOCK for an explanation of why this + ** is necessary. + */ + rc = pagerUnlockDb(pPager, NO_LOCK); + if( rc!=SQLITE_OK && pPager->eState==PAGER_ERROR ){ + pPager->eLock = UNKNOWN_LOCK; + } + + /* The pager state may be changed from PAGER_ERROR to PAGER_OPEN here + ** without clearing the error code. This is intentional - the error + ** code is cleared and the cache reset in the block below. + */ + assert( pPager->errCode || pPager->eState!=PAGER_ERROR ); + pPager->changeCountDone = 0; + pPager->eState = PAGER_OPEN; + } + + /* If Pager.errCode is set, the contents of the pager cache cannot be + ** trusted. Now that there are no outstanding references to the pager, + ** it can safely move back to PAGER_OPEN state. This happens in both + ** normal and exclusive-locking mode. + */ + if( pPager->errCode ){ + assert( !MEMDB ); + pager_reset(pPager); + pPager->changeCountDone = pPager->tempFile; + pPager->eState = PAGER_OPEN; + pPager->errCode = SQLITE_OK; + if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0); + } + + pPager->journalOff = 0; + pPager->journalHdr = 0; + pPager->setMaster = 0; +} + +/* +** This function is called whenever an IOERR or FULL error that requires +** the pager to transition into the ERROR state may ahve occurred. +** 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_FULL, SQLITE_IOERR or one of the +** IOERR sub-codes, the pager enters the ERROR state and the error code +** is stored in Pager.errCode. While the pager remains in the ERROR state, +** all major API calls on the Pager will immediately return Pager.errCode. +** +** The ERROR state indicates that the contents of the pager-cache +** cannot be trusted. This state can be cleared by completely discarding +** the contents of the pager-cache. If a transaction was active when +** the persistent error occurred, then the rollback journal may need +** to be replayed to restore the contents of the database file (as if +** it were a hot-journal). +*/ +static int pager_error(Pager *pPager, int rc){ + int rc2 = rc & 0xff; + assert( rc==SQLITE_OK || !MEMDB ); + assert( + pPager->errCode==SQLITE_FULL || + pPager->errCode==SQLITE_OK || + (pPager->errCode & 0xff)==SQLITE_IOERR + ); + if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){ + pPager->errCode = rc; + pPager->eState = PAGER_ERROR; + } + return rc; +} + +static int pager_truncate(Pager *pPager, Pgno nPage); + +/* +** This routine ends a transaction. A transaction is usually ended by +** either a COMMIT or a ROLLBACK operation. This routine may be called +** after rollback of a hot-journal, or if an error occurs while opening +** the journal file or writing the very first journal-header of a +** database transaction. +** +** This routine is never called in PAGER_ERROR state. If it is called +** in PAGER_NONE or PAGER_SHARED state and the lock held is less +** exclusive than a RESERVED lock, it is a no-op. +** +** Otherwise, any active savepoints are released. +** +** If the journal file is open, then it is "finalized". Once a journal +** file has been finalized it is not possible to use it to roll back a +** transaction. Nor will it be considered to be a hot-journal by this +** or any other database connection. Exactly how a journal is finalized +** depends on whether or not the pager is running in exclusive mode and +** the current journal-mode (Pager.journalMode value), as follows: +** +** journalMode==MEMORY +** Journal file descriptor is simply closed. This destroys an +** in-memory journal. +** +** journalMode==TRUNCATE +** Journal file is truncated to zero bytes in size. +** +** journalMode==PERSIST +** The first 28 bytes of the journal file are zeroed. This invalidates +** the first journal header in the file, and hence the entire journal +** file. An invalid journal file cannot be rolled back. +** +** journalMode==DELETE +** The journal file is closed and deleted using sqlite3OsDelete(). +** +** If the pager is running in exclusive mode, this method of finalizing +** the journal file is never used. Instead, if the journalMode is +** DELETE and the pager is in exclusive mode, the method described under +** journalMode==PERSIST is used instead. +** +** After the journal is finalized, the pager moves to PAGER_READER state. +** If running in non-exclusive rollback mode, the lock on the file is +** downgraded to a SHARED_LOCK. +** +** SQLITE_OK is returned if no error occurs. If an error occurs during +** any of the IO operations to finalize the journal file or unlock the +** database then the IO error code is returned to the user. If the +** operation to finalize the journal file fails, then the code still +** tries to unlock the database file if not in exclusive mode. If the +** unlock operation fails as well, then the first error code related +** to the first error encountered (the journal finalization one) is +** returned. +*/ +static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ + int rc = SQLITE_OK; /* Error code from journal finalization operation */ + int rc2 = SQLITE_OK; /* Error code from db file unlock operation */ + + /* Do nothing if the pager does not have an open write transaction + ** or at least a RESERVED lock. This function may be called when there + ** is no write-transaction active but a RESERVED or greater lock is + ** held under two circumstances: + ** + ** 1. After a successful hot-journal rollback, it is called with + ** eState==PAGER_NONE and eLock==EXCLUSIVE_LOCK. + ** + ** 2. If a connection with locking_mode=exclusive holding an EXCLUSIVE + ** lock switches back to locking_mode=normal and then executes a + ** read-transaction, this function is called with eState==PAGER_READER + ** and eLock==EXCLUSIVE_LOCK when the read-transaction is closed. + */ + assert( assert_pager_state(pPager) ); + assert( pPager->eState!=PAGER_ERROR ); + if( pPager->eStateeLockjfd) || pPager->pInJournal==0 ); + if( isOpen(pPager->jfd) ){ + assert( !pagerUseWal(pPager) ); + + /* Finalize the journal file. */ + if( sqlite3IsMemJournal(pPager->jfd) ){ + assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ); + sqlite3OsClose(pPager->jfd); + }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){ + if( pPager->journalOff==0 ){ + rc = SQLITE_OK; + }else{ + rc = sqlite3OsTruncate(pPager->jfd, 0); + if( rc==SQLITE_OK && pPager->fullSync ){ + /* Make sure the new file size is written into the inode right away. + ** Otherwise the journal might resurrect following a power loss and + ** cause the last transaction to roll back. See + ** https://bugzilla.mozilla.org/show_bug.cgi?id=1072773 + */ + rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags); + } + } + pPager->journalOff = 0; + }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST + || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL) + ){ + rc = zeroJournalHdr(pPager, hasMaster); + pPager->journalOff = 0; + }else{ + /* This branch may be executed with Pager.journalMode==MEMORY if + ** a hot-journal was just rolled back. In this case the journal + ** file should be closed and deleted. If this connection writes to + ** the database file, it will do so using an in-memory journal. + */ + int bDelete = (!pPager->tempFile && sqlite3JournalExists(pPager->jfd)); + assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE + || pPager->journalMode==PAGER_JOURNALMODE_MEMORY + || pPager->journalMode==PAGER_JOURNALMODE_WAL + ); + sqlite3OsClose(pPager->jfd); + if( bDelete ){ + rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); + } + } + } + +#ifdef SQLITE_CHECK_PAGES + sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash); + if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){ + PgHdr *p = sqlite3PagerLookup(pPager, 1); + if( p ){ + p->pageHash = 0; + sqlite3PagerUnrefNotNull(p); + } + } +#endif + + sqlite3BitvecDestroy(pPager->pInJournal); + pPager->pInJournal = 0; + pPager->nRec = 0; + sqlite3PcacheCleanAll(pPager->pPCache); + sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize); + + if( pagerUseWal(pPager) ){ + /* Drop the WAL write-lock, if any. Also, if the connection was in + ** locking_mode=exclusive mode but is no longer, drop the EXCLUSIVE + ** lock held on the database file. + */ + rc2 = sqlite3WalEndWriteTransaction(pPager->pWal); + assert( rc2==SQLITE_OK ); + }else if( rc==SQLITE_OK && bCommit && pPager->dbFileSize>pPager->dbSize ){ + /* This branch is taken when committing a transaction in rollback-journal + ** mode if the database file on disk is larger than the database image. + ** At this point the journal has been finalized and the transaction + ** successfully committed, but the EXCLUSIVE lock is still held on the + ** file. So it is safe to truncate the database file to its minimum + ** required size. */ + assert( pPager->eLock==EXCLUSIVE_LOCK ); + rc = pager_truncate(pPager, pPager->dbSize); + } + + if( rc==SQLITE_OK && bCommit && isOpen(pPager->fd) ){ + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_COMMIT_PHASETWO, 0); + if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; + } + + if( !pPager->exclusiveMode + && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0)) + ){ + rc2 = pagerUnlockDb(pPager, SHARED_LOCK); + pPager->changeCountDone = 0; + } + pPager->eState = PAGER_READER; + pPager->setMaster = 0; + + return (rc==SQLITE_OK?rc2:rc); +} + +/* +** Execute a rollback if a transaction is active and unlock the +** database file. +** +** If the pager has already entered the ERROR state, do not attempt +** the rollback at this time. Instead, pager_unlock() is called. The +** call to pager_unlock() will discard all in-memory pages, unlock +** the database file and move the pager back to OPEN state. If this +** means that there is a hot-journal left in the file-system, the next +** connection to obtain a shared lock on the pager (which may be this one) +** will roll it back. +** +** If the pager has not already entered the ERROR state, but an IO or +** malloc error occurs during a rollback, then this will itself cause +** the pager to enter the ERROR state. Which will be cleared by the +** call to pager_unlock(), as described above. +*/ +static void pagerUnlockAndRollback(Pager *pPager){ + if( pPager->eState!=PAGER_ERROR && pPager->eState!=PAGER_OPEN ){ + assert( assert_pager_state(pPager) ); + if( pPager->eState>=PAGER_WRITER_LOCKED ){ + sqlite3BeginBenignMalloc(); + sqlite3PagerRollback(pPager); + sqlite3EndBenignMalloc(); + }else if( !pPager->exclusiveMode ){ + assert( pPager->eState==PAGER_READER ); + pager_end_transaction(pPager, 0, 0); + } + } + pager_unlock(pPager); +} + +/* +** Parameter aData must point to a buffer of pPager->pageSize bytes +** of data. Compute and return a checksum based ont the contents of the +** page of data and the current value of pPager->cksumInit. +** +** This is not a real checksum. It is really just the sum of the +** random initial value (pPager->cksumInit) and every 200th byte +** of the page data, starting with byte offset (pPager->pageSize%200). +** Each byte is interpreted as an 8-bit unsigned integer. +** +** Changing the formula used to compute this checksum results in an +** incompatible journal file format. +** +** If journal corruption occurs due to a power failure, the most likely +** scenario is that one end or the other of the record will be changed. +** It is much less likely that the two ends of the journal record will be +** correct and the middle be corrupt. Thus, this "checksum" scheme, +** though fast and simple, catches the mostly likely kind of corruption. +*/ +static u32 pager_cksum(Pager *pPager, const u8 *aData){ + u32 cksum = pPager->cksumInit; /* Checksum value to return */ + int i = pPager->pageSize-200; /* Loop counter */ + while( i>0 ){ + cksum += aData[i]; + i -= 200; + } + return cksum; +} + +/* +** Report the current page size and number of reserved bytes back +** to the codec. +*/ +#ifdef SQLITE_HAS_CODEC +static void pagerReportSize(Pager *pPager){ + if( pPager->xCodecSizeChng ){ + pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize, + (int)pPager->nReserve); + } +} +#else +# define pagerReportSize(X) /* No-op if we do not support a codec */ +#endif + +/* +** Read a single page from either the journal file (if isMainJrnl==1) or +** from the sub-journal (if isMainJrnl==0) and playback that page. +** The page begins at offset *pOffset into the file. The *pOffset +** value is increased to the start of the next page in the journal. +** +** The main rollback journal uses checksums - the statement journal does +** not. +** +** If the page number of the page record read from the (sub-)journal file +** is greater than the current value of Pager.dbSize, then playback is +** skipped and SQLITE_OK is returned. +** +** If pDone is not NULL, then it is a record of pages that have already +** been played back. If the page at *pOffset has already been played back +** (if the corresponding pDone bit is set) then skip the playback. +** Make sure the pDone bit corresponding to the *pOffset page is set +** prior to returning. +** +** If the page record is successfully read from the (sub-)journal file +** and played back, then SQLITE_OK is returned. If an IO error occurs +** while reading the record from the (sub-)journal file or while writing +** to the database file, then the IO error code is returned. If data +** is successfully read from the (sub-)journal file but appears to be +** corrupted, SQLITE_DONE is returned. Data is considered corrupted in +** two circumstances: +** +** * If the record page-number is illegal (0 or PAGER_MJ_PGNO), or +** * If the record is being rolled back from the main journal file +** and the checksum field does not match the record content. +** +** Neither of these two scenarios are possible during a savepoint rollback. +** +** If this is a savepoint rollback, then memory may have to be dynamically +** allocated by this function. If this is the case and an allocation fails, +** SQLITE_NOMEM is returned. +*/ +static int pager_playback_one_page( + Pager *pPager, /* The pager being played back */ + i64 *pOffset, /* Offset of record to playback */ + Bitvec *pDone, /* Bitvec of pages already played back */ + int isMainJrnl, /* 1 -> main journal. 0 -> sub-journal. */ + int isSavepnt /* True for a savepoint rollback */ +){ + 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 */ + char *aData; /* Temporary storage for the page */ + sqlite3_file *jfd; /* The file descriptor for the journal file */ + int isSynced; /* True if journal page is synced */ + + assert( (isMainJrnl&~1)==0 ); /* isMainJrnl is 0 or 1 */ + assert( (isSavepnt&~1)==0 ); /* isSavepnt is 0 or 1 */ + assert( isMainJrnl || pDone ); /* pDone always used on sub-journals */ + assert( isSavepnt || pDone==0 ); /* pDone never used on non-savepoint */ + + aData = pPager->pTmpSpace; + assert( aData ); /* Temp storage must have already been allocated */ + assert( pagerUseWal(pPager)==0 || (!isMainJrnl && isSavepnt) ); + + /* Either the state is greater than PAGER_WRITER_CACHEMOD (a transaction + ** or savepoint rollback done at the request of the caller) or this is + ** a hot-journal rollback. If it is a hot-journal rollback, the pager + ** is in state OPEN and holds an EXCLUSIVE lock. Hot-journal rollback + ** only reads from the main journal, not the sub-journal. + */ + assert( pPager->eState>=PAGER_WRITER_CACHEMOD + || (pPager->eState==PAGER_OPEN && pPager->eLock==EXCLUSIVE_LOCK) + ); + assert( pPager->eState>=PAGER_WRITER_CACHEMOD || isMainJrnl ); + + /* Read the page number and page data from the journal or sub-journal + ** file. Return an error code to the caller if an IO error occurs. + */ + jfd = isMainJrnl ? pPager->jfd : pPager->sjfd; + rc = read32bits(jfd, *pOffset, &pgno); + if( rc!=SQLITE_OK ) return rc; + rc = sqlite3OsRead(jfd, (u8*)aData, pPager->pageSize, (*pOffset)+4); + if( rc!=SQLITE_OK ) return rc; + *pOffset += pPager->pageSize + 4 + isMainJrnl*4; + + /* Sanity checking on the page. This is more important that I originally + ** thought. If a power failure occurs while the journal is being written, + ** it could cause invalid data to be written into the journal. We need to + ** detect this invalid data (with high probability) and ignore it. + */ + if( pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){ + assert( !isSavepnt ); + return SQLITE_DONE; + } + if( pgno>(Pgno)pPager->dbSize || sqlite3BitvecTest(pDone, pgno) ){ + return SQLITE_OK; + } + if( isMainJrnl ){ + rc = read32bits(jfd, (*pOffset)-4, &cksum); + if( rc ) return rc; + if( !isSavepnt && pager_cksum(pPager, (u8*)aData)!=cksum ){ + return SQLITE_DONE; + } + } + + /* If this page has already been played by before during the current + ** rollback, then don't bother to play it back again. + */ + if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){ + return rc; + } + + /* When playing back page 1, restore the nReserve setting + */ + if( pgno==1 && pPager->nReserve!=((u8*)aData)[20] ){ + pPager->nReserve = ((u8*)aData)[20]; + pagerReportSize(pPager); + } + + /* If the pager is in CACHEMOD 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. + ** + ** An exception to the above rule: If the database is in no-sync mode + ** and a page is moved during an incremental vacuum then the page may + ** not be in the pager cache. Later: if a malloc() or IO error occurs + ** during a Movepage() call, then the page may not be in the cache + ** either. So the condition described in the above paragraph is not + ** assert()able. + ** + ** If in WRITER_DBMOD, WRITER_FINISHED or OPEN state, then we update the + ** pager cache if it exists and the main file. The page is then marked + ** not dirty. Since this code is only executed in PAGER_OPEN state for + ** a hot-journal rollback, it is guaranteed that the page-cache is empty + ** if the pager is in OPEN state. + ** + ** 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 synced into the main rollback + ** journal. Otherwise, a power loss might leave modified data in the + ** database file without an entry in the rollback journal that can + ** restore the database to its original form. 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 fully synced + ** in the main journal either because the page is not in cache or else + ** the page is marked as needSync==0. + ** + ** 2008-04-14: When attempting to vacuum a corrupt database file, it + ** is possible to fail a statement on a database that does not yet exist. + ** Do not attempt to write if database file has never been opened. + */ + if( pagerUseWal(pPager) ){ + pPg = 0; + }else{ + pPg = sqlite3PagerLookup(pPager, pgno); + } + assert( pPg || !MEMDB ); + assert( pPager->eState!=PAGER_OPEN || pPg==0 ); + PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n", + PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, (u8*)aData), + (isMainJrnl?"main-journal":"sub-journal") + )); + if( isMainJrnl ){ + isSynced = pPager->noSync || (*pOffset <= pPager->journalHdr); + }else{ + isSynced = (pPg==0 || 0==(pPg->flags & PGHDR_NEED_SYNC)); + } + if( isOpen(pPager->fd) + && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) + && isSynced + ){ + i64 ofst = (pgno-1)*(i64)pPager->pageSize; + testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 ); + assert( !pagerUseWal(pPager) ); + rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst); + if( pgno>pPager->dbFileSize ){ + pPager->dbFileSize = pgno; + } + if( pPager->pBackup ){ + CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM); + sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData); + CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM, aData); + } + }else if( !isMainJrnl && pPg==0 ){ + /* If this is a rollback of a savepoint and data was not written to + ** the database and the page is not in-memory, there is a potential + ** problem. When the page is next fetched by the b-tree layer, it + ** will be read from the database file, which may or may not be + ** current. + ** + ** There are a couple of different ways this can happen. All are quite + ** obscure. When running in synchronous mode, this can only happen + ** if the page is on the free-list at the start of the transaction, then + ** populated, then moved using sqlite3PagerMovepage(). + ** + ** The solution is to add an in-memory page to the cache containing + ** the data just read from the sub-journal. Mark the page as dirty + ** and if the pager requires a journal-sync, then mark the page as + ** requiring a journal-sync before it is written. + */ + assert( isSavepnt ); + assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 ); + pPager->doNotSpill |= SPILLFLAG_ROLLBACK; + rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1); + assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 ); + pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK; + if( rc!=SQLITE_OK ) return rc; + pPg->flags &= ~PGHDR_NEED_READ; + sqlite3PcacheMakeDirty(pPg); + } + 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 + ** sqlite3PagerRollback(). + */ + void *pData; + pData = pPg->pData; + memcpy(pData, (u8*)aData, pPager->pageSize); + pPager->xReiniter(pPg); + if( isMainJrnl && (!isSavepnt || *pOffset<=pPager->journalHdr) ){ + /* If the contents of this page were just restored from the main + ** journal file, then its content must be as they were when the + ** transaction was first opened. In this case we can mark the page + ** as clean, since there will be no need to write it out to the + ** database. + ** + ** There is one exception to this rule. If the page is being rolled + ** back as part of a savepoint (or statement) rollback from an + ** unsynced portion of the main journal file, then it is not safe + ** to mark the page as clean. This is because marking the page as + ** clean will clear the PGHDR_NEED_SYNC flag. Since the page is + ** already in the journal file (recorded in Pager.pInJournal) and + ** the PGHDR_NEED_SYNC flag is cleared, if the page is written to + ** again within this transaction, it will be marked as dirty but + ** the PGHDR_NEED_SYNC flag will not be set. It could then potentially + ** be written out into the database file before its journal file + ** segment is synced. If a crash occurs during or following this, + ** database corruption may ensue. + */ + assert( !pagerUseWal(pPager) ); + sqlite3PcacheMakeClean(pPg); + } + pager_set_pagehash(pPg); + + /* If this was page 1, then restore the value of Pager.dbFileVers. + ** Do this before any decoding. */ + if( pgno==1 ){ + memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers)); + } + + /* Decode the page just read from disk */ + CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM); + sqlite3PcacheRelease(pPg); + } + 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. +** +** Argument zMaster may point to Pager.pTmpSpace. So that buffer is not +** available for use within this function. +** +** When a master journal file is created, it is populated with the names +** of all of its child journals, one after another, formatted as utf-8 +** encoded text. The end of each child journal file is marked with a +** nul-terminator byte (0x00). i.e. the entire contents of a master journal +** file for a transaction involving two databases might be: +** +** "/home/bill/a.db-journal\x00/home/bill/b.db-journal\x00" +** +** A master journal file may only be deleted once all of its child +** journals have been rolled back. +** +** This function reads the contents of the master-journal file into +** memory and loops through each of the child journal names. For +** each child journal, it checks if: +** +** * if the child journal exists, and if so +** * if the child journal contains a reference to master journal +** file zMaster +** +** If a child journal can be found that matches both of the criteria +** above, this function returns without doing anything. Otherwise, if +** no such child journal can be found, file zMaster is deleted from +** the file-system using sqlite3OsDelete(). +** +** If an IO error within this function, an error code is returned. This +** function allocates memory by calling sqlite3Malloc(). If an allocation +** fails, SQLITE_NOMEM is returned. Otherwise, if no IO or malloc errors +** occur, SQLITE_OK is returned. +** +** TODO: This function allocates a single block of memory to load +** the entire contents of the master journal file. This could be +** a couple of kilobytes or so - potentially larger than the page +** size. +*/ +static int pager_delmaster(Pager *pPager, const char *zMaster){ + sqlite3_vfs *pVfs = pPager->pVfs; + int rc; /* Return code */ + sqlite3_file *pMaster; /* Malloc'd master-journal file descriptor */ + sqlite3_file *pJournal; /* Malloc'd child-journal file descriptor */ + char *zMasterJournal = 0; /* Contents of master journal file */ + i64 nMasterJournal; /* Size of master journal file */ + char *zJournal; /* Pointer to one journal within MJ file */ + char *zMasterPtr; /* Space to hold MJ filename from a journal file */ + int nMasterPtr; /* Amount of space allocated to zMasterPtr[] */ + + /* Allocate space for both the pJournal and pMaster file descriptors. + ** If successful, open the master journal file for reading. + */ + pMaster = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2); + pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile); + if( !pMaster ){ + rc = SQLITE_NOMEM; + }else{ + const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL); + rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0); + } + if( rc!=SQLITE_OK ) goto delmaster_out; + + /* Load the entire master journal file into space obtained from + ** sqlite3_malloc() and pointed to by zMasterJournal. Also obtain + ** sufficient space (in zMasterPtr) to hold the names of master + ** journal files extracted from regular rollback-journals. + */ + rc = sqlite3OsFileSize(pMaster, &nMasterJournal); + if( rc!=SQLITE_OK ) goto delmaster_out; + nMasterPtr = pVfs->mxPathname+1; + zMasterJournal = sqlite3Malloc(nMasterJournal + nMasterPtr + 1); + if( !zMasterJournal ){ + rc = SQLITE_NOMEM; + goto delmaster_out; + } + zMasterPtr = &zMasterJournal[nMasterJournal+1]; + rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0); + if( rc!=SQLITE_OK ) goto delmaster_out; + zMasterJournal[nMasterJournal] = 0; + + zJournal = zMasterJournal; + while( (zJournal-zMasterJournal)pageSize bytes). +** If the file on disk is currently larger than nPage pages, then use the VFS +** xTruncate() method to truncate it. +** +** Or, it might be the case that the file on disk is smaller than +** nPage pages. Some operating system implementations can get confused if +** you try to truncate a file to some size that is larger than it +** currently is, so detect this case and write a single zero byte to +** the end of the new file instead. +** +** If successful, return SQLITE_OK. If an IO error occurs while modifying +** the database file, return the error code to the caller. +*/ +static int pager_truncate(Pager *pPager, Pgno nPage){ + int rc = SQLITE_OK; + assert( pPager->eState!=PAGER_ERROR ); + assert( pPager->eState!=PAGER_READER ); + + if( isOpen(pPager->fd) + && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) + ){ + i64 currentSize, newSize; + int szPage = pPager->pageSize; + assert( pPager->eLock==EXCLUSIVE_LOCK ); + /* TODO: Is it safe to use Pager.dbFileSize here? */ + rc = sqlite3OsFileSize(pPager->fd, ¤tSize); + newSize = szPage*(i64)nPage; + if( rc==SQLITE_OK && currentSize!=newSize ){ + if( currentSize>newSize ){ + rc = sqlite3OsTruncate(pPager->fd, newSize); + }else if( (currentSize+szPage)<=newSize ){ + char *pTmp = pPager->pTmpSpace; + memset(pTmp, 0, szPage); + testcase( (newSize-szPage) == currentSize ); + testcase( (newSize-szPage) > currentSize ); + rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, newSize-szPage); + } + if( rc==SQLITE_OK ){ + pPager->dbFileSize = nPage; + } + } + } + return rc; +} + +/* +** Return a sanitized version of the sector-size of OS file pFile. The +** return value is guaranteed to lie between 32 and MAX_SECTOR_SIZE. +*/ +SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *pFile){ + int iRet = sqlite3OsSectorSize(pFile); + if( iRet<32 ){ + iRet = 512; + }else if( iRet>MAX_SECTOR_SIZE ){ + assert( MAX_SECTOR_SIZE>=512 ); + iRet = MAX_SECTOR_SIZE; + } + return iRet; +} + +/* +** Set the value of the Pager.sectorSize variable for the given +** pager based on the value returned by the xSectorSize method +** of the open database file. The sector size will be used +** to determine the size and alignment of journal header and +** master journal pointers within created journal files. +** +** For temporary files the effective sector size is always 512 bytes. +** +** Otherwise, for non-temporary files, the effective sector size is +** the value returned by the xSectorSize() method rounded up to 32 if +** it is less than 32, or rounded down to MAX_SECTOR_SIZE if it +** is greater than MAX_SECTOR_SIZE. +** +** If the file has the SQLITE_IOCAP_POWERSAFE_OVERWRITE property, then set +** the effective sector size to its minimum value (512). The purpose of +** pPager->sectorSize is to define the "blast radius" of bytes that +** might change if a crash occurs while writing to a single byte in +** that range. But with POWERSAFE_OVERWRITE, the blast radius is zero +** (that is what POWERSAFE_OVERWRITE means), so we minimize the sector +** size. For backwards compatibility of the rollback journal file format, +** we cannot reduce the effective sector size below 512. +*/ +static void setSectorSize(Pager *pPager){ + assert( isOpen(pPager->fd) || pPager->tempFile ); + + if( pPager->tempFile + || (sqlite3OsDeviceCharacteristics(pPager->fd) & + SQLITE_IOCAP_POWERSAFE_OVERWRITE)!=0 + ){ + /* Sector size doesn't matter for temporary files. Also, the file + ** may not have been opened yet, in which case the OsSectorSize() + ** call will segfault. */ + pPager->sectorSize = 512; + }else{ + pPager->sectorSize = sqlite3SectorSize(pPager->fd); + } +} + +/* +** 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: +** +** (1) 8 byte prefix. A copy of aJournalMagic[]. +** (2) 4 byte big-endian integer which is the number of valid page records +** in the journal. If this value is 0xffffffff, then compute the +** number of page records from the journal size. +** (3) 4 byte big-endian integer which is the initial value for the +** sanity checksum. +** (4) 4 byte integer which is the number of pages to truncate the +** database to during a rollback. +** (5) 4 byte big-endian integer which is the sector size. The header +** is this many bytes in size. +** (6) 4 byte big-endian integer which is the page size. +** (7) zero padding out to the next sector size. +** (8) Zero or more pages instances, each as follows: +** + 4 byte page number. +** + pPager->pageSize bytes of data. +** + 4 byte checksum +** +** When we speak of the journal header, we mean the first 7 items above. +** Each entry in the journal is an instance of the 8th item. +** +** Call the value from the second bullet "nRec". nRec is the number of +** valid page entries in the journal. In most cases, you can compute the +** value of nRec from the size of the journal file. But if a power +** failure occurred while the journal was being written, it could be the +** case that the size of the journal file had already been increased but +** the extra entries had not yet made it safely to disk. In such a case, +** the value of nRec computed from the file size would be too large. For +** that reason, we always use the nRec value in the header. +** +** If the nRec value is 0xffffffff it means that nRec should be computed +** from the file size. This value is used when the user selects the +** no-sync option for the journal. A power failure could lead to corruption +** in this case. But for things like temporary table (which will be +** deleted when the power is restored) we don't care. +** +** If the file opened as the journal file is not a well-formed +** journal file then all pages up to the first corrupted page are rolled +** back (or no pages if the journal header is corrupted). The journal file +** is then deleted and SQLITE_OK returned, just as if no corruption had +** been encountered. +** +** If an I/O or malloc() error occurs, the journal-file is not deleted +** and an error code is returned. +** +** The isHot parameter indicates that we are trying to rollback a journal +** that might be a hot journal. Or, it could be that the journal is +** preserved because of JOURNALMODE_PERSIST or JOURNALMODE_TRUNCATE. +** If the journal really is hot, reset the pager cache prior rolling +** back any content. If the journal is merely persistent, no reset is +** needed. +*/ +static int pager_playback(Pager *pPager, int isHot){ + sqlite3_vfs *pVfs = pPager->pVfs; + i64 szJ; /* Size of the journal file in bytes */ + u32 nRec; /* Number of Records in the journal */ + u32 u; /* Unsigned loop counter */ + Pgno mxPg = 0; /* Size of the original file in pages */ + int rc; /* Result code of a subroutine */ + int res = 1; /* Value returned by sqlite3OsAccess() */ + char *zMaster = 0; /* Name of master journal file if any */ + int needPagerReset; /* True to reset page prior to first page rollback */ + int nPlayback = 0; /* Total number of pages restored from journal */ + + /* Figure out how many records are in the journal. Abort early if + ** the journal is empty. + */ + assert( isOpen(pPager->jfd) ); + 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. + ** + ** TODO: Technically the following is an error because it assumes that + ** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that + ** (pPager->pageSize >= pPager->pVfs->mxPathname+1). Using os_unix.c, + ** mxPathname is 512, which is the same as the minimum allowable value + ** for pageSize. + */ + zMaster = pPager->pTmpSpace; + rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1); + if( rc==SQLITE_OK && zMaster[0] ){ + rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res); + } + zMaster = 0; + if( rc!=SQLITE_OK || !res ){ + goto end_playback; + } + pPager->journalOff = 0; + needPagerReset = isHot; + + /* This loop terminates either when a readJournalHdr() or + ** pager_playback_one_page() call returns SQLITE_DONE or an IO error + ** occurs. + */ + while( 1 ){ + /* Read the next journal header from the journal file. If there are + ** not enough bytes left in the journal file for a complete header, or + ** it is corrupted, then a process must have failed while writing it. + ** This indicates nothing more needs to be rolled back. + */ + rc = readJournalHdr(pPager, isHot, szJ, &nRec, &mxPg); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_DONE ){ + rc = SQLITE_OK; + } + goto end_playback; + } + + /* If nRec is 0xffffffff, then this journal was created by a process + ** working in no-sync mode. This means that the rest of the journal + ** file consists of pages, there are no more journal headers. Compute + ** the value of nRec based on this assumption. + */ + if( nRec==0xffffffff ){ + assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ); + nRec = (int)((szJ - JOURNAL_HDR_SZ(pPager))/JOURNAL_PG_SZ(pPager)); + } + + /* If nRec is 0 and this rollback is of a transaction created by this + ** process and if this is the final header in the journal, then it means + ** that this part of the journal was being filled but has not yet been + ** synced to disk. Compute the number of pages based on the remaining + ** size of the file. + ** + ** The third term of the test was added to fix ticket #2565. + ** When rolling back a hot journal, nRec==0 always means that the next + ** chunk of the journal contains zero pages to be rolled back. But + ** when doing a ROLLBACK and the nRec==0 chunk is the last chunk in + ** the journal, it means that the journal might contain additional + ** pages that need to be rolled back and that the number of pages + ** should be computed based on the journal file size. + */ + if( nRec==0 && !isHot && + pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){ + nRec = (int)((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager)); + } + + /* If this is the first header read from the journal, truncate the + ** database file back to its original size. + */ + if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){ + rc = pager_truncate(pPager, mxPg); + if( rc!=SQLITE_OK ){ + goto end_playback; + } + pPager->dbSize = mxPg; + } + + /* Copy original pages out of the journal and back into the + ** database file and/or page cache. + */ + for(u=0; ujournalOff,0,1,0); + if( rc==SQLITE_OK ){ + nPlayback++; + }else{ + if( rc==SQLITE_DONE ){ + pPager->journalOff = szJ; + break; + }else if( rc==SQLITE_IOERR_SHORT_READ ){ + /* If the journal has been truncated, simply stop reading and + ** processing the journal. This might happen if the journal was + ** not completely written and synced prior to a crash. In that + ** case, the database should have never been written in the + ** first place so it is OK to simply abandon the rollback. */ + rc = SQLITE_OK; + goto end_playback; + }else{ + /* If we are unable to rollback, quit and return the error + ** code. This will cause the pager to enter the error state + ** so that no further harm will be done. Perhaps the next + ** process to come along will be able to rollback the database. + */ + goto end_playback; + } + } + } + } + /*NOTREACHED*/ + assert( 0 ); + +end_playback: + /* Following a rollback, the database file should be back in its original + ** state prior to the start of the transaction, so invoke the + ** SQLITE_FCNTL_DB_UNCHANGED file-control method to disable the + ** assertion that the transaction counter was modified. + */ +#ifdef SQLITE_DEBUG + if( pPager->fd->pMethods ){ + sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0); + } +#endif + + /* If this playback is happening automatically as a result of an IO or + ** malloc error that occurred after the change-counter was updated but + ** before the transaction was committed, then the change-counter + ** modification may just have been reverted. If this happens in exclusive + ** mode, then subsequent transactions performed by the connection will not + ** update the change-counter at all. This may lead to cache inconsistency + ** problems for other processes at some point in the future. So, just + ** in case this has happened, clear the changeCountDone flag now. + */ + pPager->changeCountDone = pPager->tempFile; + + if( rc==SQLITE_OK ){ + zMaster = pPager->pTmpSpace; + rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1); + testcase( rc!=SQLITE_OK ); + } + if( rc==SQLITE_OK + && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) + ){ + rc = sqlite3PagerSync(pPager, 0); + } + if( rc==SQLITE_OK ){ + rc = pager_end_transaction(pPager, zMaster[0]!='\0', 0); + testcase( rc!=SQLITE_OK ); + } + if( rc==SQLITE_OK && zMaster[0] && res ){ + /* If there was a master journal and this routine will return success, + ** see if it is possible to delete the master journal. + */ + rc = pager_delmaster(pPager, zMaster); + testcase( rc!=SQLITE_OK ); + } + if( isHot && nPlayback ){ + sqlite3_log(SQLITE_NOTICE_RECOVER_ROLLBACK, "recovered %d pages from %s", + nPlayback, pPager->zJournal); + } + + /* The Pager.sectorSize variable may have been updated while rolling + ** back a journal created by a process with a different sector size + ** value. Reset it to the correct value for this process. + */ + setSectorSize(pPager); + return rc; +} + + +/* +** Read the content for page pPg out of the database file and into +** pPg->pData. A shared lock or greater must be held on the database +** file before this function is called. +** +** If page 1 is read, then the value of Pager.dbFileVers[] is set to +** the value read from the database file. +** +** If an IO error occurs, then the IO error is returned to the caller. +** Otherwise, SQLITE_OK is returned. +*/ +static int readDbPage(PgHdr *pPg, u32 iFrame){ + Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */ + Pgno pgno = pPg->pgno; /* Page number to read */ + int rc = SQLITE_OK; /* Return code */ + int pgsz = pPager->pageSize; /* Number of bytes to read */ + + assert( pPager->eState>=PAGER_READER && !MEMDB ); + assert( isOpen(pPager->fd) ); + +#ifndef SQLITE_OMIT_WAL + if( iFrame ){ + /* Try to pull the page from the write-ahead log. */ + rc = sqlite3WalReadFrame(pPager->pWal, iFrame, pgsz, pPg->pData); + }else +#endif + { + i64 iOffset = (pgno-1)*(i64)pPager->pageSize; + rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset); + if( rc==SQLITE_IOERR_SHORT_READ ){ + rc = SQLITE_OK; + } + } + + if( pgno==1 ){ + if( rc ){ + /* If the read is unsuccessful, set the dbFileVers[] to something + ** that will never be a valid file version. dbFileVers[] is a copy + ** of bytes 24..39 of the database. Bytes 28..31 should always be + ** zero or the size of the database in page. Bytes 32..35 and 35..39 + ** should be page numbers which are never 0xffffffff. So filling + ** pPager->dbFileVers[] with all 0xff bytes should suffice. + ** + ** For an encrypted database, the situation is more complex: bytes + ** 24..39 of the database are white noise. But the probability of + ** white noise equaling 16 bytes of 0xff is vanishingly small so + ** we should still be ok. + */ + memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers)); + }else{ + u8 *dbFileVers = &((u8*)pPg->pData)[24]; + memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers)); + } + } + CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM); + + PAGER_INCR(sqlite3_pager_readdb_count); + PAGER_INCR(pPager->nRead); + IOTRACE(("PGIN %p %d\n", pPager, pgno)); + PAGERTRACE(("FETCH %d page %d hash(%08x)\n", + PAGERID(pPager), pgno, pager_pagehash(pPg))); + + return rc; +} + +/* +** Update the value of the change-counter at offsets 24 and 92 in +** the header and the sqlite version number at offset 96. +** +** This is an unconditional update. See also the pager_incr_changecounter() +** routine which only updates the change-counter if the update is actually +** needed, as determined by the pPager->changeCountDone state variable. +*/ +static void pager_write_changecounter(PgHdr *pPg){ + u32 change_counter; + + /* Increment the value just read and write it back to byte 24. */ + change_counter = sqlite3Get4byte((u8*)pPg->pPager->dbFileVers)+1; + put32bits(((char*)pPg->pData)+24, change_counter); + + /* Also store the SQLite version number in bytes 96..99 and in + ** bytes 92..95 store the change counter for which the version number + ** is valid. */ + put32bits(((char*)pPg->pData)+92, change_counter); + put32bits(((char*)pPg->pData)+96, SQLITE_VERSION_NUMBER); +} + +#ifndef SQLITE_OMIT_WAL +/* +** This function is invoked once for each page that has already been +** written into the log file when a WAL transaction is rolled back. +** Parameter iPg is the page number of said page. The pCtx argument +** is actually a pointer to the Pager structure. +** +** If page iPg is present in the cache, and has no outstanding references, +** it is discarded. Otherwise, if there are one or more outstanding +** references, the page content is reloaded from the database. If the +** attempt to reload content from the database is required and fails, +** return an SQLite error code. Otherwise, SQLITE_OK. +*/ +static int pagerUndoCallback(void *pCtx, Pgno iPg){ + int rc = SQLITE_OK; + Pager *pPager = (Pager *)pCtx; + PgHdr *pPg; + + assert( pagerUseWal(pPager) ); + pPg = sqlite3PagerLookup(pPager, iPg); + if( pPg ){ + if( sqlite3PcachePageRefcount(pPg)==1 ){ + sqlite3PcacheDrop(pPg); + }else{ + u32 iFrame = 0; + rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame); + if( rc==SQLITE_OK ){ + rc = readDbPage(pPg, iFrame); + } + if( rc==SQLITE_OK ){ + pPager->xReiniter(pPg); + } + sqlite3PagerUnrefNotNull(pPg); + } + } + + /* Normally, if a transaction is rolled back, any backup processes are + ** updated as data is copied out of the rollback journal and into the + ** database. This is not generally possible with a WAL database, as + ** rollback involves simply truncating the log file. Therefore, if one + ** or more frames have already been written to the log (and therefore + ** also copied into the backup databases) as part of this transaction, + ** the backups must be restarted. + */ + sqlite3BackupRestart(pPager->pBackup); + + return rc; +} + +/* +** This function is called to rollback a transaction on a WAL database. +*/ +static int pagerRollbackWal(Pager *pPager){ + int rc; /* Return Code */ + PgHdr *pList; /* List of dirty pages to revert */ + + /* For all pages in the cache that are currently dirty or have already + ** been written (but not committed) to the log file, do one of the + ** following: + ** + ** + Discard the cached page (if refcount==0), or + ** + Reload page content from the database (if refcount>0). + */ + pPager->dbSize = pPager->dbOrigSize; + rc = sqlite3WalUndo(pPager->pWal, pagerUndoCallback, (void *)pPager); + pList = sqlite3PcacheDirtyList(pPager->pPCache); + while( pList && rc==SQLITE_OK ){ + PgHdr *pNext = pList->pDirty; + rc = pagerUndoCallback((void *)pPager, pList->pgno); + pList = pNext; + } + + return rc; +} + +/* +** This function is a wrapper around sqlite3WalFrames(). As well as logging +** the contents of the list of pages headed by pList (connected by pDirty), +** this function notifies any active backup processes that the pages have +** changed. +** +** The list of pages passed into this routine is always sorted by page number. +** Hence, if page 1 appears anywhere on the list, it will be the first page. +*/ +static int pagerWalFrames( + Pager *pPager, /* Pager object */ + PgHdr *pList, /* List of frames to log */ + Pgno nTruncate, /* Database size after this commit */ + int isCommit /* True if this is a commit */ +){ + int rc; /* Return code */ + int nList; /* Number of pages in pList */ + PgHdr *p; /* For looping over pages */ + + assert( pPager->pWal ); + assert( pList ); +#ifdef SQLITE_DEBUG + /* Verify that the page list is in accending order */ + for(p=pList; p && p->pDirty; p=p->pDirty){ + assert( p->pgno < p->pDirty->pgno ); + } +#endif + + assert( pList->pDirty==0 || isCommit ); + if( isCommit ){ + /* If a WAL transaction is being committed, there is no point in writing + ** any pages with page numbers greater than nTruncate into the WAL file. + ** They will never be read by any client. So remove them from the pDirty + ** list here. */ + PgHdr **ppNext = &pList; + nList = 0; + for(p=pList; (*ppNext = p)!=0; p=p->pDirty){ + if( p->pgno<=nTruncate ){ + ppNext = &p->pDirty; + nList++; + } + } + assert( pList ); + }else{ + nList = 1; + } + pPager->aStat[PAGER_STAT_WRITE] += nList; + + if( pList->pgno==1 ) pager_write_changecounter(pList); + rc = sqlite3WalFrames(pPager->pWal, + pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags + ); + if( rc==SQLITE_OK && pPager->pBackup ){ + for(p=pList; p; p=p->pDirty){ + sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData); + } + } + +#ifdef SQLITE_CHECK_PAGES + pList = sqlite3PcacheDirtyList(pPager->pPCache); + for(p=pList; p; p=p->pDirty){ + pager_set_pagehash(p); + } +#endif + + return rc; +} + +/* +** Begin a read transaction on the WAL. +** +** This routine used to be called "pagerOpenSnapshot()" because it essentially +** makes a snapshot of the database at the current point in time and preserves +** that snapshot for use by the reader in spite of concurrently changes by +** other writers or checkpointers. +*/ +static int pagerBeginReadTransaction(Pager *pPager){ + int rc; /* Return code */ + int changed = 0; /* True if cache must be reset */ + + assert( pagerUseWal(pPager) ); + assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER ); + + /* sqlite3WalEndReadTransaction() was not called for the previous + ** transaction in locking_mode=EXCLUSIVE. So call it now. If we + ** are in locking_mode=NORMAL and EndRead() was previously called, + ** the duplicate call is harmless. + */ + sqlite3WalEndReadTransaction(pPager->pWal); + + rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed); + if( rc!=SQLITE_OK || changed ){ + pager_reset(pPager); + if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0); + } + + return rc; +} +#endif + +/* +** This function is called as part of the transition from PAGER_OPEN +** to PAGER_READER state to determine the size of the database file +** in pages (assuming the page size currently stored in Pager.pageSize). +** +** If no error occurs, SQLITE_OK is returned and the size of the database +** in pages is stored in *pnPage. Otherwise, an error code (perhaps +** SQLITE_IOERR_FSTAT) is returned and *pnPage is left unmodified. +*/ +static int pagerPagecount(Pager *pPager, Pgno *pnPage){ + Pgno nPage; /* Value to return via *pnPage */ + + /* Query the WAL sub-system for the database size. The WalDbsize() + ** function returns zero if the WAL is not open (i.e. Pager.pWal==0), or + ** if the database size is not available. The database size is not + ** available from the WAL sub-system if the log file is empty or + ** contains no valid committed transactions. + */ + assert( pPager->eState==PAGER_OPEN ); + assert( pPager->eLock>=SHARED_LOCK ); + nPage = sqlite3WalDbsize(pPager->pWal); + + /* If the database size was not available from the WAL sub-system, + ** determine it based on the size of the database file. If the size + ** of the database file is not an integer multiple of the page-size, + ** round down to the nearest page. Except, any file larger than 0 + ** bytes in size is considered to contain at least one page. + */ + if( nPage==0 ){ + i64 n = 0; /* Size of db file in bytes */ + assert( isOpen(pPager->fd) || pPager->tempFile ); + if( isOpen(pPager->fd) ){ + int rc = sqlite3OsFileSize(pPager->fd, &n); + if( rc!=SQLITE_OK ){ + return rc; + } + } + nPage = (Pgno)((n+pPager->pageSize-1) / pPager->pageSize); + } + + /* If the current number of pages in the file is greater than the + ** configured maximum pager number, increase the allowed limit so + ** that the file can be read. + */ + if( nPage>pPager->mxPgno ){ + pPager->mxPgno = (Pgno)nPage; + } + + *pnPage = nPage; + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_WAL +/* +** Check if the *-wal file that corresponds to the database opened by pPager +** exists if the database is not empy, or verify that the *-wal file does +** not exist (by deleting it) if the database file is empty. +** +** If the database is not empty and the *-wal file exists, open the pager +** in WAL mode. If the database is empty or if no *-wal file exists and +** if no error occurs, make sure Pager.journalMode is not set to +** PAGER_JOURNALMODE_WAL. +** +** Return SQLITE_OK or an error code. +** +** The caller must hold a SHARED lock on the database file to call this +** function. Because an EXCLUSIVE lock on the db file is required to delete +** a WAL on a none-empty database, this ensures there is no race condition +** between the xAccess() below and an xDelete() being executed by some +** other connection. +*/ +static int pagerOpenWalIfPresent(Pager *pPager){ + int rc = SQLITE_OK; + assert( pPager->eState==PAGER_OPEN ); + assert( pPager->eLock>=SHARED_LOCK ); + + if( !pPager->tempFile ){ + int isWal; /* True if WAL file exists */ + Pgno nPage; /* Size of the database file */ + + rc = pagerPagecount(pPager, &nPage); + if( rc ) return rc; + if( nPage==0 ){ + rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0); + if( rc==SQLITE_IOERR_DELETE_NOENT ) rc = SQLITE_OK; + isWal = 0; + }else{ + rc = sqlite3OsAccess( + pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal + ); + } + if( rc==SQLITE_OK ){ + if( isWal ){ + testcase( sqlite3PcachePagecount(pPager->pPCache)==0 ); + rc = sqlite3PagerOpenWal(pPager, 0); + }else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){ + pPager->journalMode = PAGER_JOURNALMODE_DELETE; + } + } + } + return rc; +} +#endif + +/* +** Playback savepoint pSavepoint. Or, if pSavepoint==NULL, then playback +** the entire master journal file. The case pSavepoint==NULL occurs when +** a ROLLBACK TO command is invoked on a SAVEPOINT that is a transaction +** savepoint. +** +** When pSavepoint is not NULL (meaning a non-transaction savepoint is +** being rolled back), then the rollback consists of up to three stages, +** performed in the order specified: +** +** * Pages are played back from the main journal starting at byte +** offset PagerSavepoint.iOffset and continuing to +** PagerSavepoint.iHdrOffset, or to the end of the main journal +** file if PagerSavepoint.iHdrOffset is zero. +** +** * If PagerSavepoint.iHdrOffset is not zero, then pages are played +** back starting from the journal header immediately following +** PagerSavepoint.iHdrOffset to the end of the main journal file. +** +** * Pages are then played back from the sub-journal file, starting +** with the PagerSavepoint.iSubRec and continuing to the end of +** the journal file. +** +** Throughout the rollback process, each time a page is rolled back, the +** corresponding bit is set in a bitvec structure (variable pDone in the +** implementation below). This is used to ensure that a page is only +** rolled back the first time it is encountered in either journal. +** +** If pSavepoint is NULL, then pages are only played back from the main +** journal file. There is no need for a bitvec in this case. +** +** In either case, before playback commences the Pager.dbSize variable +** is reset to the value that it held at the start of the savepoint +** (or transaction). No page with a page-number greater than this value +** is played back. If one is encountered it is simply skipped. +*/ +static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ + i64 szJ; /* Effective size of the main journal */ + i64 iHdrOff; /* End of first segment of main-journal records */ + int rc = SQLITE_OK; /* Return code */ + Bitvec *pDone = 0; /* Bitvec to ensure pages played back only once */ + + assert( pPager->eState!=PAGER_ERROR ); + assert( pPager->eState>=PAGER_WRITER_LOCKED ); + + /* Allocate a bitvec to use to store the set of pages rolled back */ + if( pSavepoint ){ + pDone = sqlite3BitvecCreate(pSavepoint->nOrig); + if( !pDone ){ + return SQLITE_NOMEM; + } + } + + /* Set the database size back to the value it was before the savepoint + ** being reverted was opened. + */ + pPager->dbSize = pSavepoint ? pSavepoint->nOrig : pPager->dbOrigSize; + pPager->changeCountDone = pPager->tempFile; + + if( !pSavepoint && pagerUseWal(pPager) ){ + return pagerRollbackWal(pPager); + } + + /* Use pPager->journalOff as the effective size of the main rollback + ** journal. The actual file might be larger than this in + ** PAGER_JOURNALMODE_TRUNCATE or PAGER_JOURNALMODE_PERSIST. But anything + ** past pPager->journalOff is off-limits to us. + */ + szJ = pPager->journalOff; + assert( pagerUseWal(pPager)==0 || szJ==0 ); + + /* Begin by rolling back records from the main journal starting at + ** PagerSavepoint.iOffset and continuing to the next journal header. + ** There might be records in the main journal that have a page number + ** greater than the current database size (pPager->dbSize) but those + ** will be skipped automatically. Pages are added to pDone as they + ** are played back. + */ + if( pSavepoint && !pagerUseWal(pPager) ){ + iHdrOff = pSavepoint->iHdrOffset ? pSavepoint->iHdrOffset : szJ; + pPager->journalOff = pSavepoint->iOffset; + while( rc==SQLITE_OK && pPager->journalOffjournalOff, pDone, 1, 1); + } + assert( rc!=SQLITE_DONE ); + }else{ + pPager->journalOff = 0; + } + + /* Continue rolling back records out of the main journal starting at + ** the first journal header seen and continuing until the effective end + ** of the main journal file. Continue to skip out-of-range pages and + ** continue adding pages rolled back to pDone. + */ + while( rc==SQLITE_OK && pPager->journalOffjournalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff" + ** test is related to ticket #2565. See the discussion in the + ** pager_playback() function for additional information. + */ + if( nJRec==0 + && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff + ){ + nJRec = (u32)((szJ - pPager->journalOff)/JOURNAL_PG_SZ(pPager)); + } + for(ii=0; rc==SQLITE_OK && iijournalOffjournalOff, pDone, 1, 1); + } + assert( rc!=SQLITE_DONE ); + } + assert( rc!=SQLITE_OK || pPager->journalOff>=szJ ); + + /* Finally, rollback pages from the sub-journal. Page that were + ** previously rolled back out of the main journal (and are hence in pDone) + ** will be skipped. Out-of-range pages are also skipped. + */ + if( pSavepoint ){ + u32 ii; /* Loop counter */ + i64 offset = (i64)pSavepoint->iSubRec*(4+pPager->pageSize); + + if( pagerUseWal(pPager) ){ + rc = sqlite3WalSavepointUndo(pPager->pWal, pSavepoint->aWalData); + } + for(ii=pSavepoint->iSubRec; rc==SQLITE_OK && iinSubRec; ii++){ + assert( offset==(i64)ii*(4+pPager->pageSize) ); + rc = pager_playback_one_page(pPager, &offset, pDone, 0, 1); + } + assert( rc!=SQLITE_DONE ); + } + + sqlite3BitvecDestroy(pDone); + if( rc==SQLITE_OK ){ + pPager->journalOff = szJ; + } + + return rc; +} + +/* +** Change the maximum number of in-memory pages that are allowed. +*/ +SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){ + sqlite3PcacheSetCachesize(pPager->pPCache, mxPage); +} + +/* +** Invoke SQLITE_FCNTL_MMAP_SIZE based on the current value of szMmap. +*/ +static void pagerFixMaplimit(Pager *pPager){ +#if SQLITE_MAX_MMAP_SIZE>0 + sqlite3_file *fd = pPager->fd; + if( isOpen(fd) && fd->pMethods->iVersion>=3 ){ + sqlite3_int64 sz; + sz = pPager->szMmap; + pPager->bUseFetch = (sz>0); + sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz); + } +#endif +} + +/* +** Change the maximum size of any memory mapping made of the database file. +*/ +SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *pPager, sqlite3_int64 szMmap){ + pPager->szMmap = szMmap; + pagerFixMaplimit(pPager); +} + +/* +** Free as much memory as possible from the pager. +*/ +SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){ + sqlite3PcacheShrink(pPager->pPCache); +} + +/* +** Adjust settings of the pager to those specified in the pgFlags parameter. +** +** The "level" in pgFlags & PAGER_SYNCHRONOUS_MASK sets the robustness +** of the database to damage due to OS crashes or power failures by +** changing the number of syncs()s when writing the journals. +** There are three levels: +** +** OFF sqlite3OsSync() is never called. This is the default +** for temporary and transient files. +** +** NORMAL The journal is synced once before writes begin on the +** database. This is normally adequate protection, but +** it is theoretically possible, though very unlikely, +** that an inopertune power failure could leave the journal +** in a state which would cause damage to the database +** when it is rolled back. +** +** FULL The journal is synced twice before writes begin on the +** database (with some additional information - the nRec field +** of the journal header - being written in between the two +** syncs). If we assume that writing a +** single disk sector is atomic, then this mode provides +** assurance that the journal will not be corrupted to the +** point of causing damage to the database during rollback. +** +** The above is for a rollback-journal mode. For WAL mode, OFF continues +** to mean that no syncs ever occur. NORMAL means that the WAL is synced +** prior to the start of checkpoint and that the database file is synced +** at the conclusion of the checkpoint if the entire content of the WAL +** was written back into the database. But no sync operations occur for +** an ordinary commit in NORMAL mode with WAL. FULL means that the WAL +** file is synced following each commit operation, in addition to the +** syncs associated with NORMAL. +** +** Do not confuse synchronous=FULL with SQLITE_SYNC_FULL. The +** SQLITE_SYNC_FULL macro means to use the MacOSX-style full-fsync +** using fcntl(F_FULLFSYNC). SQLITE_SYNC_NORMAL means to do an +** ordinary fsync() call. There is no difference between SQLITE_SYNC_FULL +** and SQLITE_SYNC_NORMAL on platforms other than MacOSX. But the +** synchronous=FULL versus synchronous=NORMAL setting determines when +** the xSync primitive is called and is relevant to all platforms. +** +** Numeric values associated with these states are OFF==1, NORMAL=2, +** and FULL=3. +*/ +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +SQLITE_PRIVATE void sqlite3PagerSetFlags( + Pager *pPager, /* The pager to set safety level for */ + unsigned pgFlags /* Various flags */ +){ + unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK; + assert( level>=1 && level<=3 ); + pPager->noSync = (level==1 || pPager->tempFile) ?1:0; + pPager->fullSync = (level==3 && !pPager->tempFile) ?1:0; + if( pPager->noSync ){ + pPager->syncFlags = 0; + pPager->ckptSyncFlags = 0; + }else if( pgFlags & PAGER_FULLFSYNC ){ + pPager->syncFlags = SQLITE_SYNC_FULL; + pPager->ckptSyncFlags = SQLITE_SYNC_FULL; + }else if( pgFlags & PAGER_CKPT_FULLFSYNC ){ + pPager->syncFlags = SQLITE_SYNC_NORMAL; + pPager->ckptSyncFlags = SQLITE_SYNC_FULL; + }else{ + pPager->syncFlags = SQLITE_SYNC_NORMAL; + pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; + } + pPager->walSyncFlags = pPager->syncFlags; + if( pPager->fullSync ){ + pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS; + } + if( pgFlags & PAGER_CACHESPILL ){ + pPager->doNotSpill &= ~SPILLFLAG_OFF; + }else{ + pPager->doNotSpill |= SPILLFLAG_OFF; + } +} +#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. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_opentemp_count = 0; +#endif + +/* +** Open a temporary file. +** +** Write the file descriptor into *pFile. 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. +** +** The flags passed to the VFS layer xOpen() call are those specified +** by parameter vfsFlags ORed with the following: +** +** SQLITE_OPEN_READWRITE +** SQLITE_OPEN_CREATE +** SQLITE_OPEN_EXCLUSIVE +** SQLITE_OPEN_DELETEONCLOSE +*/ +static int pagerOpentemp( + Pager *pPager, /* The pager object */ + sqlite3_file *pFile, /* Write the file descriptor here */ + int vfsFlags /* Flags passed through to the VFS */ +){ + int rc; /* Return code */ + +#ifdef SQLITE_TEST + sqlite3_opentemp_count++; /* Used for testing and analysis only */ +#endif + + vfsFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | + SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE; + rc = sqlite3OsOpen(pPager->pVfs, 0, pFile, vfsFlags, 0); + assert( rc!=SQLITE_OK || isOpen(pFile) ); + return rc; +} + +/* +** Set the busy handler function. +** +** The pager invokes the busy-handler if sqlite3OsLock() returns +** SQLITE_BUSY when trying to upgrade from no-lock to a SHARED lock, +** or when trying to upgrade from a RESERVED lock to an EXCLUSIVE +** lock. It does *not* invoke the busy handler when upgrading from +** SHARED to RESERVED, or when upgrading from SHARED to EXCLUSIVE +** (which occurs during hot-journal rollback). Summary: +** +** Transition | Invokes xBusyHandler +** -------------------------------------------------------- +** NO_LOCK -> SHARED_LOCK | Yes +** SHARED_LOCK -> RESERVED_LOCK | No +** SHARED_LOCK -> EXCLUSIVE_LOCK | No +** RESERVED_LOCK -> EXCLUSIVE_LOCK | Yes +** +** If the busy-handler callback returns non-zero, the lock is +** retried. If it returns zero, then the SQLITE_BUSY error is +** returned to the caller of the pager API function. +*/ +SQLITE_PRIVATE void sqlite3PagerSetBusyhandler( + Pager *pPager, /* Pager object */ + int (*xBusyHandler)(void *), /* Pointer to busy-handler function */ + void *pBusyHandlerArg /* Argument to pass to xBusyHandler */ +){ + pPager->xBusyHandler = xBusyHandler; + pPager->pBusyHandlerArg = pBusyHandlerArg; + + if( isOpen(pPager->fd) ){ + void **ap = (void **)&pPager->xBusyHandler; + assert( ((int(*)(void *))(ap[0]))==xBusyHandler ); + assert( ap[1]==pBusyHandlerArg ); + sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap); + } +} + +/* +** Change the page size used by the Pager object. The new page size +** is passed in *pPageSize. +** +** If the pager is in the error state when this function is called, it +** is a no-op. The value returned is the error state error code (i.e. +** one of SQLITE_IOERR, an SQLITE_IOERR_xxx sub-code or SQLITE_FULL). +** +** Otherwise, if all of the following are true: +** +** * the new page size (value of *pPageSize) is valid (a power +** of two between 512 and SQLITE_MAX_PAGE_SIZE, inclusive), and +** +** * there are no outstanding page references, and +** +** * the database is either not an in-memory database or it is +** an in-memory database that currently consists of zero pages. +** +** then the pager object page size is set to *pPageSize. +** +** If the page size is changed, then this function uses sqlite3PagerMalloc() +** to obtain a new Pager.pTmpSpace buffer. If this allocation attempt +** fails, SQLITE_NOMEM is returned and the page size remains unchanged. +** In all other cases, SQLITE_OK is returned. +** +** If the page size is not changed, either because one of the enumerated +** conditions above is not true, the pager was in error state when this +** function was called, or because the memory allocation attempt failed, +** then *pPageSize is set to the old, retained page size before returning. +*/ +SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){ + int rc = SQLITE_OK; + + /* It is not possible to do a full assert_pager_state() here, as this + ** function may be called from within PagerOpen(), before the state + ** of the Pager object is internally consistent. + ** + ** At one point this function returned an error if the pager was in + ** PAGER_ERROR state. But since PAGER_ERROR state guarantees that + ** there is at least one outstanding page reference, this function + ** is a no-op for that case anyhow. + */ + + u32 pageSize = *pPageSize; + assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) ); + if( (pPager->memDb==0 || pPager->dbSize==0) + && sqlite3PcacheRefCount(pPager->pPCache)==0 + && pageSize && pageSize!=(u32)pPager->pageSize + ){ + char *pNew = NULL; /* New temp space */ + i64 nByte = 0; + + if( pPager->eState>PAGER_OPEN && isOpen(pPager->fd) ){ + rc = sqlite3OsFileSize(pPager->fd, &nByte); + } + if( rc==SQLITE_OK ){ + pNew = (char *)sqlite3PageMalloc(pageSize); + if( !pNew ) rc = SQLITE_NOMEM; + } + + if( rc==SQLITE_OK ){ + pager_reset(pPager); + rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize); + } + if( rc==SQLITE_OK ){ + sqlite3PageFree(pPager->pTmpSpace); + pPager->pTmpSpace = pNew; + pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize); + pPager->pageSize = pageSize; + }else{ + sqlite3PageFree(pNew); + } + } + + *pPageSize = pPager->pageSize; + if( rc==SQLITE_OK ){ + if( nReserve<0 ) nReserve = pPager->nReserve; + assert( nReserve>=0 && nReserve<1000 ); + pPager->nReserve = (i16)nReserve; + pagerReportSize(pPager); + pagerFixMaplimit(pPager); + } + return rc; +} + +/* +** Return a pointer to the "temporary page" buffer held internally +** by the pager. This is a buffer that is big enough to hold the +** entire content of a database page. This buffer is used internally +** during rollback and will be overwritten whenever a rollback +** occurs. But other modules are free to use it too, as long as +** no rollbacks are happening. +*/ +SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager *pPager){ + return pPager->pTmpSpace; +} + +/* +** Attempt to set the maximum database page count if mxPage is positive. +** Make no changes if mxPage is zero or negative. And never reduce the +** maximum page count below the current size of the database. +** +** Regardless of mxPage, return the current maximum page count. +*/ +SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager *pPager, int mxPage){ + if( mxPage>0 ){ + pPager->mxPgno = mxPage; + } + assert( pPager->eState!=PAGER_OPEN ); /* Called only by OP_MaxPgcnt */ + assert( pPager->mxPgno>=pPager->dbSize ); /* OP_MaxPgcnt enforces this */ + return pPager->mxPgno; +} + +/* +** 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 +SQLITE_API extern int sqlite3_io_error_pending; +SQLITE_API extern int sqlite3_io_error_hit; +static int saved_cnt; +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 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. +** +** If the pager was opened on a transient file (zFilename==""), or +** opened on a file less than N bytes in size, the output buffer is +** zeroed and SQLITE_OK returned. The rationale for this is that this +** function is used to read database headers, and a new transient or +** zero sized database has a header than consists entirely of zeroes. +** +** If any IO error apart from SQLITE_IOERR_SHORT_READ is encountered, +** the error code is returned to the caller and the contents of the +** output buffer undefined. +*/ +SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){ + int rc = SQLITE_OK; + memset(pDest, 0, N); + assert( isOpen(pPager->fd) || pPager->tempFile ); + + /* This routine is only called by btree immediately after creating + ** the Pager object. There has not been an opportunity to transition + ** to WAL mode yet. + */ + assert( !pagerUseWal(pPager) ); + + if( isOpen(pPager->fd) ){ + IOTRACE(("DBHDR %p 0 %d\n", pPager, N)) + rc = sqlite3OsRead(pPager->fd, pDest, N, 0); + if( rc==SQLITE_IOERR_SHORT_READ ){ + rc = SQLITE_OK; + } + } + return rc; +} + +/* +** This function may only be called when a read-transaction is open on +** the pager. It returns the total number of pages in the database. +** +** However, if the file is between 1 and bytes in size, then +** this is considered a 1 page file. +*/ +SQLITE_PRIVATE void sqlite3PagerPagecount(Pager *pPager, int *pnPage){ + assert( pPager->eState>=PAGER_READER ); + assert( pPager->eState!=PAGER_WRITER_FINISHED ); + *pnPage = (int)pPager->dbSize; +} + + +/* +** Try to obtain a lock of type locktype on the database file. If +** a similar or greater lock is already held, this function is a no-op +** (returning SQLITE_OK immediately). +** +** Otherwise, attempt to obtain the lock using sqlite3OsLock(). Invoke +** the busy callback if the lock is currently not available. Repeat +** until the busy callback returns false or until the attempt to +** obtain the lock succeeds. +** +** Return SQLITE_OK on success and an error code if we cannot obtain +** the lock. If the lock is obtained successfully, set the Pager.state +** variable to locktype before returning. +*/ +static int pager_wait_on_lock(Pager *pPager, int locktype){ + int rc; /* Return code */ + + /* Check that this is either a no-op (because the requested lock is + ** already held), or one of the transitions that the busy-handler + ** may be invoked during, according to the comment above + ** sqlite3PagerSetBusyhandler(). + */ + assert( (pPager->eLock>=locktype) + || (pPager->eLock==NO_LOCK && locktype==SHARED_LOCK) + || (pPager->eLock==RESERVED_LOCK && locktype==EXCLUSIVE_LOCK) + ); + + do { + rc = pagerLockDb(pPager, locktype); + }while( rc==SQLITE_BUSY && pPager->xBusyHandler(pPager->pBusyHandlerArg) ); + return rc; +} + +/* +** Function assertTruncateConstraint(pPager) checks that one of the +** following is true for all dirty pages currently in the page-cache: +** +** a) The page number is less than or equal to the size of the +** current database image, in pages, OR +** +** b) if the page content were written at this time, it would not +** be necessary to write the current content out to the sub-journal +** (as determined by function subjRequiresPage()). +** +** If the condition asserted by this function were not true, and the +** dirty page were to be discarded from the cache via the pagerStress() +** routine, pagerStress() would not write the current page content to +** the database file. If a savepoint transaction were rolled back after +** this happened, the correct behavior would be to restore the current +** content of the page. However, since this content is not present in either +** the database file or the portion of the rollback journal and +** sub-journal rolled back the content could not be restored and the +** database image would become corrupt. It is therefore fortunate that +** this circumstance cannot arise. +*/ +#if defined(SQLITE_DEBUG) +static void assertTruncateConstraintCb(PgHdr *pPg){ + assert( pPg->flags&PGHDR_DIRTY ); + assert( !subjRequiresPage(pPg) || pPg->pgno<=pPg->pPager->dbSize ); +} +static void assertTruncateConstraint(Pager *pPager){ + sqlite3PcacheIterateDirty(pPager->pPCache, assertTruncateConstraintCb); +} +#else +# define assertTruncateConstraint(pPager) +#endif + +/* +** Truncate the in-memory database file image to nPage pages. This +** function does not actually modify the database file on disk. It +** just sets the internal state of the pager object so that the +** truncation will be done when the current transaction is committed. +** +** This function is only called right before committing a transaction. +** Once this function has been called, the transaction must either be +** rolled back or committed. It is not safe to call this function and +** then continue writing to the database. +*/ +SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){ + assert( pPager->dbSize>=nPage ); + assert( pPager->eState>=PAGER_WRITER_CACHEMOD ); + pPager->dbSize = nPage; + + /* At one point the code here called assertTruncateConstraint() to + ** ensure that all pages being truncated away by this operation are, + ** if one or more savepoints are open, present in the savepoint + ** journal so that they can be restored if the savepoint is rolled + ** back. This is no longer necessary as this function is now only + ** called right before committing a transaction. So although the + ** Pager object may still have open savepoints (Pager.nSavepoint!=0), + ** they cannot be rolled back. So the assertTruncateConstraint() call + ** is no longer correct. */ +} + + +/* +** This function is called before attempting a hot-journal rollback. It +** syncs the journal file to disk, then sets pPager->journalHdr to the +** size of the journal file so that the pager_playback() routine knows +** that the entire journal file has been synced. +** +** Syncing a hot-journal to disk before attempting to roll it back ensures +** that if a power-failure occurs during the rollback, the process that +** attempts rollback following system recovery sees the same journal +** content as this process. +** +** If everything goes as planned, SQLITE_OK is returned. Otherwise, +** an SQLite error code. +*/ +static int pagerSyncHotJournal(Pager *pPager){ + int rc = SQLITE_OK; + if( !pPager->noSync ){ + rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_NORMAL); + } + if( rc==SQLITE_OK ){ + rc = sqlite3OsFileSize(pPager->jfd, &pPager->journalHdr); + } + return rc; +} + +/* +** Obtain a reference to a memory mapped page object for page number pgno. +** The new object will use the pointer pData, obtained from xFetch(). +** If successful, set *ppPage to point to the new page reference +** and return SQLITE_OK. Otherwise, return an SQLite error code and set +** *ppPage to zero. +** +** Page references obtained by calling this function should be released +** by calling pagerReleaseMapPage(). +*/ +static int pagerAcquireMapPage( + Pager *pPager, /* Pager object */ + Pgno pgno, /* Page number */ + void *pData, /* xFetch()'d data for this page */ + PgHdr **ppPage /* OUT: Acquired page object */ +){ + PgHdr *p; /* Memory mapped page to return */ + + if( pPager->pMmapFreelist ){ + *ppPage = p = pPager->pMmapFreelist; + pPager->pMmapFreelist = p->pDirty; + p->pDirty = 0; + memset(p->pExtra, 0, pPager->nExtra); + }else{ + *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra); + if( p==0 ){ + sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData); + return SQLITE_NOMEM; + } + p->pExtra = (void *)&p[1]; + p->flags = PGHDR_MMAP; + p->nRef = 1; + p->pPager = pPager; + } + + assert( p->pExtra==(void *)&p[1] ); + assert( p->pPage==0 ); + assert( p->flags==PGHDR_MMAP ); + assert( p->pPager==pPager ); + assert( p->nRef==1 ); + + p->pgno = pgno; + p->pData = pData; + pPager->nMmapOut++; + + return SQLITE_OK; +} + +/* +** Release a reference to page pPg. pPg must have been returned by an +** earlier call to pagerAcquireMapPage(). +*/ +static void pagerReleaseMapPage(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + pPager->nMmapOut--; + pPg->pDirty = pPager->pMmapFreelist; + pPager->pMmapFreelist = pPg; + + assert( pPager->fd->pMethods->iVersion>=3 ); + sqlite3OsUnfetch(pPager->fd, (i64)(pPg->pgno-1)*pPager->pageSize, pPg->pData); +} + +/* +** Free all PgHdr objects stored in the Pager.pMmapFreelist list. +*/ +static void pagerFreeMapHdrs(Pager *pPager){ + PgHdr *p; + PgHdr *pNext; + for(p=pPager->pMmapFreelist; p; p=pNext){ + pNext = p->pDirty; + sqlite3_free(p); + } +} + + +/* +** 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. +*/ +SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager){ + u8 *pTmp = (u8 *)pPager->pTmpSpace; + + assert( assert_pager_state(pPager) ); + disable_simulated_io_errors(); + sqlite3BeginBenignMalloc(); + pagerFreeMapHdrs(pPager); + /* pPager->errCode = 0; */ + pPager->exclusiveMode = 0; +#ifndef SQLITE_OMIT_WAL + sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, pPager->pageSize, pTmp); + pPager->pWal = 0; +#endif + pager_reset(pPager); + if( MEMDB ){ + pager_unlock(pPager); + }else{ + /* If it is open, sync the journal file before calling UnlockAndRollback. + ** If this is not done, then an unsynced portion of the open journal + ** file may be played back into the database. If a power failure occurs + ** while this is happening, the database could become corrupt. + ** + ** If an error occurs while trying to sync the journal, shift the pager + ** into the ERROR state. This causes UnlockAndRollback to unlock the + ** database and close the journal file without attempting to roll it + ** back or finalize it. The next database user will have to do hot-journal + ** rollback before accessing the database file. + */ + if( isOpen(pPager->jfd) ){ + pager_error(pPager, pagerSyncHotJournal(pPager)); + } + pagerUnlockAndRollback(pPager); + } + sqlite3EndBenignMalloc(); + enable_simulated_io_errors(); + PAGERTRACE(("CLOSE %d\n", PAGERID(pPager))); + IOTRACE(("CLOSE %p\n", pPager)) + sqlite3OsClose(pPager->jfd); + sqlite3OsClose(pPager->fd); + sqlite3PageFree(pTmp); + sqlite3PcacheClose(pPager->pPCache); + +#ifdef SQLITE_HAS_CODEC + if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec); +#endif + + assert( !pPager->aSavepoint && !pPager->pInJournal ); + assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) ); + + sqlite3_free(pPager); + return SQLITE_OK; +} + +#if !defined(NDEBUG) || defined(SQLITE_TEST) +/* +** Return the page number for page pPg. +*/ +SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage *pPg){ + return pPg->pgno; +} +#endif + +/* +** Increment the reference count for page pPg. +*/ +SQLITE_PRIVATE void sqlite3PagerRef(DbPage *pPg){ + sqlite3PcacheRef(pPg); +} + +/* +** Sync the journal. In other words, make sure all the pages that have +** been written to the journal have actually reached the surface of the +** disk and can be restored in the event of a hot-journal rollback. +** +** If the Pager.noSync flag is set, then this function is a no-op. +** Otherwise, the actions required depend on the journal-mode and the +** device characteristics of the file-system, as follows: +** +** * If the journal file is an in-memory journal file, no action need +** be taken. +** +** * Otherwise, if the device does not support the SAFE_APPEND property, +** then the nRec field of the most recently written journal header +** is updated to contain the number of journal records that have +** been written following it. If the pager is operating in full-sync +** mode, then the journal file is synced before this field is updated. +** +** * If the device does not support the SEQUENTIAL property, then +** journal file is synced. +** +** Or, in pseudo-code: +** +** if( NOT ){ +** if( NOT SAFE_APPEND ){ +** if( ) xSync(); +** +** } +** if( NOT SEQUENTIAL ) xSync(); +** } +** +** If successful, this routine clears the PGHDR_NEED_SYNC flag of every +** page currently held in memory before returning SQLITE_OK. If an IO +** error is encountered, then the IO error code is returned to the caller. +*/ +static int syncJournal(Pager *pPager, int newHdr){ + int rc; /* Return code */ + + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + ); + assert( assert_pager_state(pPager) ); + assert( !pagerUseWal(pPager) ); + + rc = sqlite3PagerExclusiveLock(pPager); + if( rc!=SQLITE_OK ) return rc; + + if( !pPager->noSync ){ + assert( !pPager->tempFile ); + if( isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){ + const int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); + assert( isOpen(pPager->jfd) ); + + if( 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){ + /* This block deals with an obscure problem. If the last connection + ** that wrote to this database was operating in persistent-journal + ** mode, then the journal file may at this point actually be larger + ** than Pager.journalOff bytes. If the next thing in the journal + ** file happens to be a journal-header (written as part of the + ** previous connection's transaction), and a crash or power-failure + ** occurs after nRec is updated but before this connection writes + ** anything else to the journal file (or commits/rolls back its + ** transaction), then SQLite may become confused when doing the + ** hot-journal rollback following recovery. It may roll back all + ** of this connections data, then proceed to rolling back the old, + ** out-of-date data that follows it. Database corruption. + ** + ** To work around this, if the journal file does appear to contain + ** a valid header following Pager.journalOff, then write a 0x00 + ** byte to the start of it to prevent it from being recognized. + ** + ** Variable iNextHdrOffset is set to the offset at which this + ** problematic header will occur, if it exists. aMagic is used + ** as a temporary buffer to inspect the first couple of bytes of + ** the potential journal header. + */ + i64 iNextHdrOffset; + u8 aMagic[8]; + u8 zHeader[sizeof(aJournalMagic)+4]; + + memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); + put32bits(&zHeader[sizeof(aJournalMagic)], pPager->nRec); + + iNextHdrOffset = journalHdrOffset(pPager); + rc = sqlite3OsRead(pPager->jfd, aMagic, 8, iNextHdrOffset); + if( rc==SQLITE_OK && 0==memcmp(aMagic, aJournalMagic, 8) ){ + static const u8 zerobyte = 0; + rc = sqlite3OsWrite(pPager->jfd, &zerobyte, 1, iNextHdrOffset); + } + if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){ + return rc; + } + + /* 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. + ** + ** This is not required if the persistent media supports the + ** SAFE_APPEND property. Because in this case it is not possible + ** for garbage data to be appended to the file, the nRec field + ** is populated with 0xFFFFFFFF when the journal header is written + ** and never needs to be updated. + */ + if( pPager->fullSync && 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){ + PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager))); + IOTRACE(("JSYNC %p\n", pPager)) + rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags); + if( rc!=SQLITE_OK ) return rc; + } + IOTRACE(("JHDR %p %lld\n", pPager, pPager->journalHdr)); + rc = sqlite3OsWrite( + pPager->jfd, zHeader, sizeof(zHeader), pPager->journalHdr + ); + if( rc!=SQLITE_OK ) return rc; + } + if( 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){ + PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager))); + IOTRACE(("JSYNC %p\n", pPager)) + rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags| + (pPager->syncFlags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0) + ); + if( rc!=SQLITE_OK ) return rc; + } + + pPager->journalHdr = pPager->journalOff; + if( newHdr && 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){ + pPager->nRec = 0; + rc = writeJournalHdr(pPager); + if( rc!=SQLITE_OK ) return rc; + } + }else{ + pPager->journalHdr = pPager->journalOff; + } + } + + /* Unless the pager is in noSync mode, the journal file was just + ** successfully synced. Either way, clear the PGHDR_NEED_SYNC flag on + ** all pages. + */ + sqlite3PcacheClearSyncFlags(pPager->pPCache); + pPager->eState = PAGER_WRITER_DBMOD; + assert( assert_pager_state(pPager) ); + return SQLITE_OK; +} + +/* +** The argument is the first in a linked list of dirty pages connected +** by the PgHdr.pDirty pointer. This function writes each one of the +** in-memory pages in the list to the database file. The argument may +** be NULL, representing an empty list. In this case this function is +** a no-op. +** +** The pager must hold at least a RESERVED lock when this function +** is called. Before writing anything to the database file, this lock +** is upgraded to an EXCLUSIVE lock. If the lock cannot be obtained, +** SQLITE_BUSY is returned and no data is written to the database file. +** +** If the pager is a temp-file pager and the actual file-system file +** is not yet open, it is created and opened before any data is +** written out. +** +** Once the lock has been upgraded and, if necessary, the file opened, +** the pages are written out to the database file in list order. Writing +** a page is skipped if it meets either of the following criteria: +** +** * The page number is greater than Pager.dbSize, or +** * The PGHDR_DONT_WRITE flag is set on the page. +** +** If writing out a page causes the database file to grow, Pager.dbFileSize +** is updated accordingly. If page 1 is written out, then the value cached +** in Pager.dbFileVers[] is updated to match the new value stored in +** the database file. +** +** If everything is successful, SQLITE_OK is returned. If an IO error +** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot +** be obtained, SQLITE_BUSY is returned. +*/ +static int pager_write_pagelist(Pager *pPager, PgHdr *pList){ + int rc = SQLITE_OK; /* Return code */ + + /* This function is only called for rollback pagers in WRITER_DBMOD state. */ + assert( !pagerUseWal(pPager) ); + assert( pPager->eState==PAGER_WRITER_DBMOD ); + assert( pPager->eLock==EXCLUSIVE_LOCK ); + + /* If the file is a temp-file has not yet been opened, open it now. It + ** is not possible for rc to be other than SQLITE_OK if this branch + ** is taken, as pager_wait_on_lock() is a no-op for temp-files. + */ + if( !isOpen(pPager->fd) ){ + assert( pPager->tempFile && rc==SQLITE_OK ); + rc = pagerOpentemp(pPager, pPager->fd, pPager->vfsFlags); + } + + /* Before the first write, give the VFS a hint of what the final + ** file size will be. + */ + assert( rc!=SQLITE_OK || isOpen(pPager->fd) ); + if( rc==SQLITE_OK + && pPager->dbHintSizedbSize + && (pList->pDirty || pList->pgno>pPager->dbHintSize) + ){ + sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize; + sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile); + pPager->dbHintSize = pPager->dbSize; + } + + while( rc==SQLITE_OK && pList ){ + Pgno pgno = pList->pgno; + + /* If there are dirty pages in the page cache with page numbers greater + ** than Pager.dbSize, this means sqlite3PagerTruncateImage() was called to + ** make the file smaller (presumably by auto-vacuum code). Do not write + ** any such pages to the file. + ** + ** Also, do not write out any page that has the PGHDR_DONT_WRITE flag + ** set (set by sqlite3PagerDontWrite()). + */ + if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){ + i64 offset = (pgno-1)*(i64)pPager->pageSize; /* Offset to write */ + char *pData; /* Data to write */ + + assert( (pList->flags&PGHDR_NEED_SYNC)==0 ); + if( pList->pgno==1 ) pager_write_changecounter(pList); + + /* Encode the database */ + CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData); + + /* Write out the page data. */ + rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset); + + /* If page 1 was just written, update Pager.dbFileVers to match + ** the value now stored in the database file. If writing this + ** page caused the database file to grow, update dbFileSize. + */ + if( pgno==1 ){ + memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers)); + } + if( pgno>pPager->dbFileSize ){ + pPager->dbFileSize = pgno; + } + pPager->aStat[PAGER_STAT_WRITE]++; + + /* Update any backup objects copying the contents of this pager. */ + sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)pList->pData); + + PAGERTRACE(("STORE %d page %d hash(%08x)\n", + PAGERID(pPager), pgno, pager_pagehash(pList))); + IOTRACE(("PGOUT %p %d\n", pPager, pgno)); + PAGER_INCR(sqlite3_pager_writedb_count); + }else{ + PAGERTRACE(("NOSTORE %d page %d\n", PAGERID(pPager), pgno)); + } + pager_set_pagehash(pList); + pList = pList->pDirty; + } + + return rc; +} + +/* +** Ensure that the sub-journal file is open. If it is already open, this +** function is a no-op. +** +** SQLITE_OK is returned if everything goes according to plan. An +** SQLITE_IOERR_XXX error code is returned if a call to sqlite3OsOpen() +** fails. +*/ +static int openSubJournal(Pager *pPager){ + int rc = SQLITE_OK; + if( !isOpen(pPager->sjfd) ){ + if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){ + sqlite3MemJournalOpen(pPager->sjfd); + }else{ + rc = pagerOpentemp(pPager, pPager->sjfd, SQLITE_OPEN_SUBJOURNAL); + } + } + return rc; +} + +/* +** Append a record of the current state of page pPg to the sub-journal. +** It is the callers responsibility to use subjRequiresPage() to check +** that it is really required before calling this function. +** +** If successful, set the bit corresponding to pPg->pgno in the bitvecs +** for all open savepoints before returning. +** +** This function returns SQLITE_OK if everything is successful, an IO +** error code if the attempt to write to the sub-journal fails, or +** SQLITE_NOMEM if a malloc fails while setting a bit in a savepoint +** bitvec. +*/ +static int subjournalPage(PgHdr *pPg){ + int rc = SQLITE_OK; + Pager *pPager = pPg->pPager; + if( pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ + + /* Open the sub-journal, if it has not already been opened */ + assert( pPager->useJournal ); + assert( isOpen(pPager->jfd) || pagerUseWal(pPager) ); + assert( isOpen(pPager->sjfd) || pPager->nSubRec==0 ); + assert( pagerUseWal(pPager) + || pageInJournal(pPager, pPg) + || pPg->pgno>pPager->dbOrigSize + ); + rc = openSubJournal(pPager); + + /* If the sub-journal was opened successfully (or was already open), + ** write the journal record into the file. */ + if( rc==SQLITE_OK ){ + void *pData = pPg->pData; + i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize); + char *pData2; + + CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2); + PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno)); + rc = write32bits(pPager->sjfd, offset, pPg->pgno); + if( rc==SQLITE_OK ){ + rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4); + } + } + } + if( rc==SQLITE_OK ){ + pPager->nSubRec++; + assert( pPager->nSavepoint>0 ); + rc = addToSavepointBitvecs(pPager, pPg->pgno); + } + return rc; +} + +/* +** This function is called by the pcache layer when it has reached some +** soft memory limit. The first argument is a pointer to a Pager object +** (cast as a void*). The pager is always 'purgeable' (not an in-memory +** database). The second argument is a reference to a page that is +** currently dirty but has no outstanding references. The page +** is always associated with the Pager object passed as the first +** argument. +** +** The job of this function is to make pPg clean by writing its contents +** out to the database file, if possible. This may involve syncing the +** journal file. +** +** If successful, sqlite3PcacheMakeClean() is called on the page and +** SQLITE_OK returned. If an IO error occurs while trying to make the +** page clean, the IO error code is returned. If the page cannot be +** made clean for some other reason, but no error occurs, then SQLITE_OK +** is returned by sqlite3PcacheMakeClean() is not called. +*/ +static int pagerStress(void *p, PgHdr *pPg){ + Pager *pPager = (Pager *)p; + int rc = SQLITE_OK; + + assert( pPg->pPager==pPager ); + assert( pPg->flags&PGHDR_DIRTY ); + + /* The doNotSpill NOSYNC bit is set during times when doing a sync of + ** journal (and adding a new header) is not allowed. This occurs + ** during calls to sqlite3PagerWrite() while trying to journal multiple + ** pages belonging to the same sector. + ** + ** The doNotSpill ROLLBACK and OFF bits inhibits all cache spilling + ** regardless of whether or not a sync is required. This is set during + ** a rollback or by user request, respectively. + ** + ** Spilling is also prohibited when in an error state since that could + ** lead to database corruption. In the current implementation it + ** is impossible for sqlite3PcacheFetch() to be called with createFlag==3 + ** while in the error state, hence it is impossible for this routine to + ** be called in the error state. Nevertheless, we include a NEVER() + ** test for the error state as a safeguard against future changes. + */ + if( NEVER(pPager->errCode) ) return SQLITE_OK; + testcase( pPager->doNotSpill & SPILLFLAG_ROLLBACK ); + testcase( pPager->doNotSpill & SPILLFLAG_OFF ); + testcase( pPager->doNotSpill & SPILLFLAG_NOSYNC ); + if( pPager->doNotSpill + && ((pPager->doNotSpill & (SPILLFLAG_ROLLBACK|SPILLFLAG_OFF))!=0 + || (pPg->flags & PGHDR_NEED_SYNC)!=0) + ){ + return SQLITE_OK; + } + + pPg->pDirty = 0; + if( pagerUseWal(pPager) ){ + /* Write a single frame for this page to the log. */ + if( subjRequiresPage(pPg) ){ + rc = subjournalPage(pPg); + } + if( rc==SQLITE_OK ){ + rc = pagerWalFrames(pPager, pPg, 0, 0); + } + }else{ + + /* Sync the journal file if required. */ + if( pPg->flags&PGHDR_NEED_SYNC + || pPager->eState==PAGER_WRITER_CACHEMOD + ){ + rc = syncJournal(pPager, 1); + } + + /* If the page number of this page is larger than the current size of + ** the database image, it may need to be written to the sub-journal. + ** This is because the call to pager_write_pagelist() below will not + ** actually write data to the file in this case. + ** + ** Consider the following sequence of events: + ** + ** BEGIN; + ** + ** + ** SAVEPOINT sp; + ** + ** pagerStress(page X) + ** ROLLBACK TO sp; + ** + ** If (X>Y), then when pagerStress is called page X will not be written + ** out to the database file, but will be dropped from the cache. Then, + ** following the "ROLLBACK TO sp" statement, reading page X will read + ** data from the database file. This will be the copy of page X as it + ** was when the transaction started, not as it was when "SAVEPOINT sp" + ** was executed. + ** + ** The solution is to write the current data for page X into the + ** sub-journal file now (if it is not already there), so that it will + ** be restored to its current value when the "ROLLBACK TO sp" is + ** executed. + */ + if( NEVER( + rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg) + ) ){ + rc = subjournalPage(pPg); + } + + /* Write the contents of the page out to the database file. */ + if( rc==SQLITE_OK ){ + assert( (pPg->flags&PGHDR_NEED_SYNC)==0 ); + rc = pager_write_pagelist(pPager, pPg); + } + } + + /* Mark the page as clean. */ + if( rc==SQLITE_OK ){ + PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno)); + sqlite3PcacheMakeClean(pPg); + } + + return pager_error(pPager, rc); +} + + +/* +** Allocate and initialize a new Pager object and put a pointer to it +** in *ppPager. The pager should eventually be freed by passing it +** to sqlite3PagerClose(). +** +** The zFilename argument is the path to the database file to open. +** If zFilename is NULL then a randomly-named temporary file is created +** and used as the file to be cached. Temporary files are be deleted +** automatically when they are closed. If zFilename is ":memory:" then +** all information is held in cache. It is never written to disk. +** This can be used to implement an in-memory database. +** +** The nExtra parameter specifies the number of bytes of space allocated +** along with each page reference. This space is available to the user +** via the sqlite3PagerGetExtra() API. +** +** The flags argument is used to specify properties that affect the +** operation of the pager. It should be passed some bitwise combination +** of the PAGER_* flags. +** +** The vfsFlags parameter is a bitmask to pass to the flags parameter +** of the xOpen() method of the supplied VFS when opening files. +** +** If the pager object is allocated and the specified file opened +** successfully, SQLITE_OK is returned and *ppPager set to point to +** the new pager object. If an error occurs, *ppPager is set to NULL +** and error code returned. This function may return SQLITE_NOMEM +** (sqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or +** various SQLITE_IO_XXX errors. +*/ +SQLITE_PRIVATE int sqlite3PagerOpen( + sqlite3_vfs *pVfs, /* The virtual file system to use */ + Pager **ppPager, /* OUT: 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 */ + int vfsFlags, /* flags passed through to sqlite3_vfs.xOpen() */ + void (*xReinit)(DbPage*) /* Function to reinitialize pages */ +){ + u8 *pPtr; + Pager *pPager = 0; /* Pager object to allocate and return */ + int rc = SQLITE_OK; /* Return code */ + int tempFile = 0; /* True for temp files (incl. in-memory files) */ + int memDb = 0; /* True if this is an in-memory file */ + int readOnly = 0; /* True if this is a read-only file */ + int journalFileSize; /* Bytes to allocate for each journal fd */ + char *zPathname = 0; /* Full path to database file */ + int nPathname = 0; /* Number of bytes in zPathname */ + int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */ + int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */ + u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */ + const char *zUri = 0; /* URI args to copy */ + int nUri = 0; /* Number of bytes of URI args at *zUri */ + + /* Figure out how much space is required for each journal file-handle + ** (there are two of them, the main journal and the sub-journal). This + ** is the maximum space required for an in-memory journal file handle + ** and a regular journal file-handle. Note that a "regular journal-handle" + ** may be a wrapper capable of caching the first portion of the journal + ** file in memory to implement the atomic-write optimization (see + ** source file journal.c). + */ + if( sqlite3JournalSize(pVfs)>sqlite3MemJournalSize() ){ + journalFileSize = ROUND8(sqlite3JournalSize(pVfs)); + }else{ + journalFileSize = ROUND8(sqlite3MemJournalSize()); + } + + /* Set the output variable to NULL in case an error occurs. */ + *ppPager = 0; + +#ifndef SQLITE_OMIT_MEMORYDB + if( flags & PAGER_MEMORY ){ + memDb = 1; + if( zFilename && zFilename[0] ){ + zPathname = sqlite3DbStrDup(0, zFilename); + if( zPathname==0 ) return SQLITE_NOMEM; + nPathname = sqlite3Strlen30(zPathname); + zFilename = 0; + } + } +#endif + + /* Compute and store the full pathname in an allocated buffer pointed + ** to by zPathname, length nPathname. Or, if this is a temporary file, + ** leave both nPathname and zPathname set to 0. + */ + if( zFilename && zFilename[0] ){ + const char *z; + nPathname = pVfs->mxPathname+1; + zPathname = sqlite3DbMallocRaw(0, nPathname*2); + if( zPathname==0 ){ + return SQLITE_NOMEM; + } + zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */ + rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname); + nPathname = sqlite3Strlen30(zPathname); + z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1]; + while( *z ){ + z += sqlite3Strlen30(z)+1; + z += sqlite3Strlen30(z)+1; + } + nUri = (int)(&z[1] - zUri); + assert( nUri>=0 ); + if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){ + /* This branch is taken when the journal path required by + ** the database being opened will be more than pVfs->mxPathname + ** bytes in length. This means the database cannot be opened, + ** as it will not be possible to open the journal file or even + ** check for a hot-journal before reading. + */ + rc = SQLITE_CANTOPEN_BKPT; + } + if( rc!=SQLITE_OK ){ + sqlite3DbFree(0, zPathname); + return rc; + } + } + + /* Allocate memory for the Pager structure, PCache object, the + ** three file descriptors, the database file name and the journal + ** file name. The layout in memory is as follows: + ** + ** Pager object (sizeof(Pager) bytes) + ** PCache object (sqlite3PcacheSize() bytes) + ** Database file handle (pVfs->szOsFile bytes) + ** Sub-journal file handle (journalFileSize bytes) + ** Main journal file handle (journalFileSize bytes) + ** Database file name (nPathname+1 bytes) + ** Journal file name (nPathname+8+1 bytes) + */ + pPtr = (u8 *)sqlite3MallocZero( + ROUND8(sizeof(*pPager)) + /* Pager structure */ + ROUND8(pcacheSize) + /* PCache object */ + ROUND8(pVfs->szOsFile) + /* The main db file */ + journalFileSize * 2 + /* The two journal files */ + nPathname + 1 + nUri + /* zFilename */ + nPathname + 8 + 2 /* zJournal */ +#ifndef SQLITE_OMIT_WAL + + nPathname + 4 + 2 /* zWal */ +#endif + ); + assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) ); + if( !pPtr ){ + sqlite3DbFree(0, zPathname); + return SQLITE_NOMEM; + } + pPager = (Pager*)(pPtr); + pPager->pPCache = (PCache*)(pPtr += ROUND8(sizeof(*pPager))); + pPager->fd = (sqlite3_file*)(pPtr += ROUND8(pcacheSize)); + pPager->sjfd = (sqlite3_file*)(pPtr += ROUND8(pVfs->szOsFile)); + pPager->jfd = (sqlite3_file*)(pPtr += journalFileSize); + pPager->zFilename = (char*)(pPtr += journalFileSize); + assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) ); + + /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */ + if( zPathname ){ + assert( nPathname>0 ); + pPager->zJournal = (char*)(pPtr += nPathname + 1 + nUri); + memcpy(pPager->zFilename, zPathname, nPathname); + if( nUri ) memcpy(&pPager->zFilename[nPathname+1], zUri, nUri); + memcpy(pPager->zJournal, zPathname, nPathname); + memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+2); + sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal); +#ifndef SQLITE_OMIT_WAL + pPager->zWal = &pPager->zJournal[nPathname+8+1]; + memcpy(pPager->zWal, zPathname, nPathname); + memcpy(&pPager->zWal[nPathname], "-wal\000", 4+1); + sqlite3FileSuffix3(pPager->zFilename, pPager->zWal); +#endif + sqlite3DbFree(0, zPathname); + } + pPager->pVfs = pVfs; + pPager->vfsFlags = vfsFlags; + + /* Open the pager file. + */ + if( zFilename && zFilename[0] ){ + int fout = 0; /* VFS flags returned by xOpen() */ + rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); + assert( !memDb ); + readOnly = (fout&SQLITE_OPEN_READONLY); + + /* If the file was successfully opened for read/write access, + ** choose a default page size in case we have to create the + ** database file. The default page size is the maximum of: + ** + ** + SQLITE_DEFAULT_PAGE_SIZE, + ** + The value returned by sqlite3OsSectorSize() + ** + The largest page size that can be written atomically. + */ + if( rc==SQLITE_OK ){ + int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); + if( !readOnly ){ + setSectorSize(pPager); + assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE); + if( szPageDfltsectorSize ){ + if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){ + szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE; + }else{ + szPageDflt = (u32)pPager->sectorSize; + } + } +#ifdef SQLITE_ENABLE_ATOMIC_WRITE + { + int ii; + assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); + assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); + assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536); + for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){ + if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ){ + szPageDflt = ii; + } + } + } +#endif + } + pPager->noLock = sqlite3_uri_boolean(zFilename, "nolock", 0); + if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0 + || sqlite3_uri_boolean(zFilename, "immutable", 0) ){ + vfsFlags |= SQLITE_OPEN_READONLY; + goto act_like_temp_file; + } + } + }else{ + /* If a temporary file is requested, it is not opened immediately. + ** In this case we accept the default page size and delay actually + ** opening the file until the first call to OsWrite(). + ** + ** This branch is also run for an in-memory database. An in-memory + ** database is the same as a temp-file that is never written out to + ** disk and uses an in-memory rollback journal. + ** + ** This branch also runs for files marked as immutable. + */ +act_like_temp_file: + tempFile = 1; + pPager->eState = PAGER_READER; /* Pretend we already have a lock */ + pPager->eLock = EXCLUSIVE_LOCK; /* Pretend we are in EXCLUSIVE locking mode */ + pPager->noLock = 1; /* Do no locking */ + readOnly = (vfsFlags&SQLITE_OPEN_READONLY); + } + + /* The following call to PagerSetPagesize() serves to set the value of + ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer. + */ + if( rc==SQLITE_OK ){ + assert( pPager->memDb==0 ); + rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1); + testcase( rc!=SQLITE_OK ); + } + + /* Initialize the PCache object. */ + if( rc==SQLITE_OK ){ + assert( nExtra<1000 ); + nExtra = ROUND8(nExtra); + rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb, + !memDb?pagerStress:0, (void *)pPager, pPager->pPCache); + } + + /* If an error occurred above, free the Pager structure and close the file. + */ + if( rc!=SQLITE_OK ){ + sqlite3OsClose(pPager->fd); + sqlite3PageFree(pPager->pTmpSpace); + sqlite3_free(pPager); + return rc; + } + + PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename)); + IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename)) + + pPager->useJournal = (u8)useJournal; + /* pPager->stmtOpen = 0; */ + /* pPager->stmtInUse = 0; */ + /* pPager->nRef = 0; */ + /* pPager->stmtSize = 0; */ + /* pPager->stmtJSize = 0; */ + /* pPager->nPage = 0; */ + pPager->mxPgno = SQLITE_MAX_PAGE_COUNT; + /* pPager->state = PAGER_UNLOCK; */ + /* pPager->errMask = 0; */ + pPager->tempFile = (u8)tempFile; + assert( tempFile==PAGER_LOCKINGMODE_NORMAL + || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE ); + assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 ); + pPager->exclusiveMode = (u8)tempFile; + pPager->changeCountDone = pPager->tempFile; + pPager->memDb = (u8)memDb; + pPager->readOnly = (u8)readOnly; + assert( useJournal || pPager->tempFile ); + pPager->noSync = pPager->tempFile; + if( pPager->noSync ){ + assert( pPager->fullSync==0 ); + assert( pPager->syncFlags==0 ); + assert( pPager->walSyncFlags==0 ); + assert( pPager->ckptSyncFlags==0 ); + }else{ + pPager->fullSync = 1; + pPager->syncFlags = SQLITE_SYNC_NORMAL; + pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS; + pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; + } + /* pPager->pFirst = 0; */ + /* pPager->pFirstSynced = 0; */ + /* pPager->pLast = 0; */ + pPager->nExtra = (u16)nExtra; + pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT; + assert( isOpen(pPager->fd) || tempFile ); + setSectorSize(pPager); + if( !useJournal ){ + pPager->journalMode = PAGER_JOURNALMODE_OFF; + }else if( memDb ){ + pPager->journalMode = PAGER_JOURNALMODE_MEMORY; + } + /* pPager->xBusyHandler = 0; */ + /* pPager->pBusyHandlerArg = 0; */ + pPager->xReiniter = xReinit; + /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ + /* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */ + + *ppPager = pPager; + return SQLITE_OK; +} + + +/* Verify that the database file has not be deleted or renamed out from +** under the pager. Return SQLITE_OK if the database is still were it ought +** to be on disk. Return non-zero (SQLITE_READONLY_DBMOVED or some other error +** code from sqlite3OsAccess()) if the database has gone missing. +*/ +static int databaseIsUnmoved(Pager *pPager){ + int bHasMoved = 0; + int rc; + + if( pPager->tempFile ) return SQLITE_OK; + if( pPager->dbSize==0 ) return SQLITE_OK; + assert( pPager->zFilename && pPager->zFilename[0] ); + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved); + if( rc==SQLITE_NOTFOUND ){ + /* If the HAS_MOVED file-control is unimplemented, assume that the file + ** has not been moved. That is the historical behavior of SQLite: prior to + ** version 3.8.3, it never checked */ + rc = SQLITE_OK; + }else if( rc==SQLITE_OK && bHasMoved ){ + rc = SQLITE_READONLY_DBMOVED; + } + return rc; +} + + +/* +** This function is called after transitioning from PAGER_UNLOCK to +** PAGER_SHARED state. It tests if there is a hot journal present in +** the file-system for the given pager. A hot journal is one that +** needs to be played back. According to this function, a hot-journal +** file exists if the following criteria are met: +** +** * The journal file exists in the file system, and +** * No process holds a RESERVED or greater lock on the database file, and +** * The database file itself is greater than 0 bytes in size, and +** * The first byte of the journal file exists and is not 0x00. +** +** 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. In this case the journal file is +** just deleted using OsDelete, *pExists is set to 0 and SQLITE_OK +** is returned. +** +** This routine does not check if there is a master journal filename +** at the end of the file. If there is, and that master journal file +** does not exist, then the journal file is not really hot. In this +** case this routine will return a false-positive. The pager_playback() +** routine will discover that the journal file is not really hot and +** will not roll it back. +** +** If a hot-journal file is found to exist, *pExists is set to 1 and +** SQLITE_OK returned. If no hot-journal file is present, *pExists is +** set to 0 and SQLITE_OK returned. If an IO error occurs while trying +** to determine whether or not a hot-journal file exists, the IO error +** code is returned and the value of *pExists is undefined. +*/ +static int hasHotJournal(Pager *pPager, int *pExists){ + sqlite3_vfs * const pVfs = pPager->pVfs; + int rc = SQLITE_OK; /* Return code */ + int exists = 1; /* True if a journal file is present */ + int jrnlOpen = !!isOpen(pPager->jfd); + + assert( pPager->useJournal ); + assert( isOpen(pPager->fd) ); + assert( pPager->eState==PAGER_OPEN ); + + assert( jrnlOpen==0 || ( sqlite3OsDeviceCharacteristics(pPager->jfd) & + SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN + )); + + *pExists = 0; + if( !jrnlOpen ){ + rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists); + } + if( rc==SQLITE_OK && exists ){ + int locked = 0; /* True if some process holds a RESERVED lock */ + + /* Race condition here: Another process might have been holding the + ** the RESERVED lock and have a journal open at the sqlite3OsAccess() + ** call above, but then delete the journal and drop the lock before + ** we get to the following sqlite3OsCheckReservedLock() call. If that + ** is the case, this routine might think there is a hot journal when + ** in fact there is none. This results in a false-positive which will + ** be dealt with by the playback routine. Ticket #3883. + */ + rc = sqlite3OsCheckReservedLock(pPager->fd, &locked); + if( rc==SQLITE_OK && !locked ){ + Pgno nPage; /* Number of pages in database file */ + + rc = pagerPagecount(pPager, &nPage); + if( rc==SQLITE_OK ){ + /* If the database is zero pages in size, that means that either (1) the + ** journal is a remnant from a prior database with the same name where + ** the database file but not the journal was deleted, or (2) the initial + ** transaction that populates a new database is being rolled back. + ** In either case, the journal file can be deleted. However, take care + ** not to delete the journal file if it is already open due to + ** journal_mode=PERSIST. + */ + if( nPage==0 && !jrnlOpen ){ + sqlite3BeginBenignMalloc(); + if( pagerLockDb(pPager, RESERVED_LOCK)==SQLITE_OK ){ + sqlite3OsDelete(pVfs, pPager->zJournal, 0); + if( !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK); + } + sqlite3EndBenignMalloc(); + }else{ + /* The journal file exists and no other connection has a reserved + ** or greater lock on the database file. Now check that there is + ** at least one non-zero bytes at the start of the journal file. + ** If there is, then we consider this journal to be hot. If not, + ** it can be ignored. + */ + if( !jrnlOpen ){ + int f = SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL; + rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &f); + } + if( rc==SQLITE_OK ){ + u8 first = 0; + rc = sqlite3OsRead(pPager->jfd, (void *)&first, 1, 0); + if( rc==SQLITE_IOERR_SHORT_READ ){ + rc = SQLITE_OK; + } + if( !jrnlOpen ){ + sqlite3OsClose(pPager->jfd); + } + *pExists = (first!=0); + }else if( rc==SQLITE_CANTOPEN ){ + /* If we cannot open the rollback journal file in order to see if + ** it has a zero header, that might be due to an I/O error, or + ** it might be due to the race condition described above and in + ** ticket #3883. Either way, assume that the journal is hot. + ** This might be a false positive. But if it is, then the + ** automatic journal playback and recovery mechanism will deal + ** with it under an EXCLUSIVE lock where we do not need to + ** worry so much with race conditions. + */ + *pExists = 1; + rc = SQLITE_OK; + } + } + } + } + } + + return rc; +} + +/* +** This function is called to obtain a shared lock on the database file. +** It is illegal to call sqlite3PagerAcquire() until after this function +** has been successfully called. If a shared-lock is already held when +** this function is called, it is a no-op. +** +** The following operations are also performed by this function. +** +** 1) If the pager is currently in PAGER_OPEN state (no lock held +** on the database file), then an attempt is made to obtain a +** SHARED lock on the database file. Immediately after obtaining +** the SHARED lock, the file-system is checked for a hot-journal, +** which is played back if present. Following any hot-journal +** rollback, the contents of the cache are validated by checking +** the 'change-counter' field of the database file header and +** discarded if they are found to be invalid. +** +** 2) If the pager is running in exclusive-mode, and there are currently +** no outstanding references to any pages, and is in the error state, +** then an attempt is made to clear the error state by discarding +** the contents of the page cache and rolling back any open journal +** file. +** +** If everything is successful, SQLITE_OK is returned. If an IO error +** occurs while locking the database, checking for a hot-journal file or +** rolling back a journal file, the IO error code is returned. +*/ +SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){ + int rc = SQLITE_OK; /* Return code */ + + /* This routine is only called from b-tree and only when there are no + ** outstanding pages. This implies that the pager state should either + ** be OPEN or READER. READER is only possible if the pager is or was in + ** exclusive access mode. + */ + assert( sqlite3PcacheRefCount(pPager->pPCache)==0 ); + assert( assert_pager_state(pPager) ); + assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER ); + if( NEVER(MEMDB && pPager->errCode) ){ return pPager->errCode; } + + if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){ + int bHotJournal = 1; /* True if there exists a hot journal-file */ + + assert( !MEMDB ); + + rc = pager_wait_on_lock(pPager, SHARED_LOCK); + if( rc!=SQLITE_OK ){ + assert( pPager->eLock==NO_LOCK || pPager->eLock==UNKNOWN_LOCK ); + goto failed; + } + + /* 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->eLock<=SHARED_LOCK ){ + rc = hasHotJournal(pPager, &bHotJournal); + } + if( rc!=SQLITE_OK ){ + goto failed; + } + if( bHotJournal ){ + if( pPager->readOnly ){ + rc = SQLITE_READONLY_ROLLBACK; + goto failed; + } + + /* 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 the + ** hot-journal back. + ** + ** Because the intermediate RESERVED lock is not requested, any + ** other process attempting to access the database file will get to + ** this point in the code and fail to obtain its own EXCLUSIVE lock + ** on the database file. + ** + ** Unless the pager is in locking_mode=exclusive mode, the lock is + ** downgraded to SHARED_LOCK before this function returns. + */ + rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); + if( rc!=SQLITE_OK ){ + goto failed; + } + + /* If it is not already open and the file exists on disk, open the + ** journal for read/write access. Write access is required because + ** in exclusive-access mode the file descriptor will be kept open + ** and possibly used for a transaction later on. Also, write-access + ** is usually required to finalize the journal in journal_mode=persist + ** mode (and also for journal_mode=truncate on some systems). + ** + ** If the journal does not exist, it usually means that some + ** other connection managed to get in and roll it back before + ** this connection obtained the exclusive lock above. Or, it + ** may mean that the pager was in the error-state when this + ** function was called and the journal file does not exist. + */ + if( !isOpen(pPager->jfd) ){ + sqlite3_vfs * const pVfs = pPager->pVfs; + int bExists; /* True if journal file exists */ + rc = sqlite3OsAccess( + pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &bExists); + if( rc==SQLITE_OK && bExists ){ + int fout = 0; + int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL; + assert( !pPager->tempFile ); + rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout); + assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); + if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){ + rc = SQLITE_CANTOPEN_BKPT; + sqlite3OsClose(pPager->jfd); + } + } + } + + /* Playback and delete the journal. Drop the database write + ** lock and reacquire the read lock. Purge the cache before + ** playing back the hot-journal so that we don't end up with + ** an inconsistent cache. Sync the hot journal before playing + ** it back since the process that crashed and left the hot journal + ** probably did not sync it and we are required to always sync + ** the journal before playing it back. + */ + if( isOpen(pPager->jfd) ){ + assert( rc==SQLITE_OK ); + rc = pagerSyncHotJournal(pPager); + if( rc==SQLITE_OK ){ + rc = pager_playback(pPager, 1); + pPager->eState = PAGER_OPEN; + } + }else if( !pPager->exclusiveMode ){ + pagerUnlockDb(pPager, SHARED_LOCK); + } + + if( rc!=SQLITE_OK ){ + /* This branch is taken if an error occurs while trying to open + ** or roll back a hot-journal while holding an EXCLUSIVE lock. The + ** pager_unlock() routine will be called before returning to unlock + ** the file. If the unlock attempt fails, then Pager.eLock must be + ** set to UNKNOWN_LOCK (see the comment above the #define for + ** UNKNOWN_LOCK above for an explanation). + ** + ** In order to get pager_unlock() to do this, set Pager.eState to + ** PAGER_ERROR now. This is not actually counted as a transition + ** to ERROR state in the state diagram at the top of this file, + ** since we know that the same call to pager_unlock() will very + ** shortly transition the pager object to the OPEN state. Calling + ** assert_pager_state() would fail now, as it should not be possible + ** to be in ERROR state when there are zero outstanding page + ** references. + */ + pager_error(pPager, rc); + goto failed; + } + + assert( pPager->eState==PAGER_OPEN ); + assert( (pPager->eLock==SHARED_LOCK) + || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK) + ); + } + + if( !pPager->tempFile && pPager->hasBeenUsed ){ + /* The shared-lock has just been acquired then check to + ** see if the database has been modified. If the database has changed, + ** flush the cache. The pPager->hasBeenUsed flag prevents this from + ** occurring on the very first access to a file, in order to save a + ** single unnecessary sqlite3OsRead() call at the start-up. + ** + ** Database changes is detected by looking at 15 bytes beginning + ** at offset 24 into the file. The first 4 of these 16 bytes are + ** a 32-bit counter that is incremented with each change. The + ** other bytes change randomly with each file change when + ** a codec is in use. + ** + ** There is a vanishingly small chance that a change will not be + ** detected. The chance of an undetected change is so small that + ** it can be neglected. + */ + Pgno nPage = 0; + char dbFileVers[sizeof(pPager->dbFileVers)]; + + rc = pagerPagecount(pPager, &nPage); + if( rc ) goto failed; + + if( nPage>0 ){ + IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers))); + rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24); + if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){ + goto failed; + } + }else{ + memset(dbFileVers, 0, sizeof(dbFileVers)); + } + + if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){ + pager_reset(pPager); + + /* Unmap the database file. It is possible that external processes + ** may have truncated the database file and then extended it back + ** to its original size while this process was not holding a lock. + ** In this case there may exist a Pager.pMap mapping that appears + ** to be the right size but is not actually valid. Avoid this + ** possibility by unmapping the db here. */ + if( USEFETCH(pPager) ){ + sqlite3OsUnfetch(pPager->fd, 0, 0); + } + } + } + + /* If there is a WAL file in the file-system, open this database in WAL + ** mode. Otherwise, the following function call is a no-op. + */ + rc = pagerOpenWalIfPresent(pPager); +#ifndef SQLITE_OMIT_WAL + assert( pPager->pWal==0 || rc==SQLITE_OK ); +#endif + } + + if( pagerUseWal(pPager) ){ + assert( rc==SQLITE_OK ); + rc = pagerBeginReadTransaction(pPager); + } + + if( pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){ + rc = pagerPagecount(pPager, &pPager->dbSize); + } + + failed: + if( rc!=SQLITE_OK ){ + assert( !MEMDB ); + pager_unlock(pPager); + assert( pPager->eState==PAGER_OPEN ); + }else{ + pPager->eState = PAGER_READER; + } + return rc; +} + +/* +** If the reference count has reached zero, rollback any active +** transaction and unlock the pager. +** +** Except, in locking_mode=EXCLUSIVE when there is nothing to in +** the rollback journal, the unlock is not performed and there is +** nothing to rollback, so this routine is a no-op. +*/ +static void pagerUnlockIfUnused(Pager *pPager){ + if( pPager->nMmapOut==0 && (sqlite3PcacheRefCount(pPager->pPCache)==0) ){ + pagerUnlockAndRollback(pPager); + } +} + +/* +** Acquire a reference to page number pgno in pager pPager (a page +** reference has type DbPage*). If the requested reference is +** successfully obtained, it is copied to *ppPage and SQLITE_OK returned. +** +** If the requested page is already in the cache, it is returned. +** Otherwise, a new page object is allocated and populated with data +** read from the database file. In some cases, the pcache module may +** choose not to allocate a new page object and may reuse an existing +** object with no outstanding references. +** +** The extra data appended to a page is always initialized to zeros the +** first time a page is loaded into memory. If the page requested is +** already in the cache when this function is called, then the extra +** data is left as it was when the page object was last used. +** +** If the database image is smaller than the requested page or if a +** non-zero value is passed as the noContent parameter and the +** requested page is not already stored in the cache, then no +** actual disk read occurs. In this case the memory image of the +** page is initialized to all zeros. +** +** If noContent is true, it means that we do not care about the contents +** of the page. This occurs in two scenarios: +** +** a) When reading a free-list leaf page from the database, and +** +** b) When a savepoint is being rolled back and we need to load +** a new page into the cache to be filled with the data read +** from the savepoint journal. +** +** If noContent is true, then the data returned is zeroed instead of +** being read from the database. Additionally, the bits corresponding +** to pgno in Pager.pInJournal (bitvec of pages already written to the +** journal file) and the PagerSavepoint.pInSavepoint bitvecs of any open +** savepoints are set. This means if the page is made writable at any +** point in the future, using a call to sqlite3PagerWrite(), its contents +** will not be journaled. This saves IO. +** +** The acquisition might fail for several reasons. In all cases, +** an appropriate error code is returned and *ppPage is set to NULL. +** +** See also sqlite3PagerLookup(). Both this routine and Lookup() attempt +** to find a page in the in-memory cache first. If the page is not already +** in memory, this routine goes to disk to read it in whereas Lookup() +** 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. +*/ +SQLITE_PRIVATE int sqlite3PagerAcquire( + Pager *pPager, /* The pager open on the database file */ + Pgno pgno, /* Page number to fetch */ + DbPage **ppPage, /* Write a pointer to the page here */ + int flags /* PAGER_GET_XXX flags */ +){ + int rc = SQLITE_OK; + PgHdr *pPg = 0; + u32 iFrame = 0; /* Frame to read from WAL file */ + const int noContent = (flags & PAGER_GET_NOCONTENT); + + /* It is acceptable to use a read-only (mmap) page for any page except + ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY + ** flag was specified by the caller. And so long as the db is not a + ** temporary or in-memory database. */ + const int bMmapOk = (pgno!=1 && USEFETCH(pPager) + && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY)) +#ifdef SQLITE_HAS_CODEC + && pPager->xCodec==0 +#endif + ); + + assert( pPager->eState>=PAGER_READER ); + assert( assert_pager_state(pPager) ); + assert( noContent==0 || bMmapOk==0 ); + + if( pgno==0 ){ + return SQLITE_CORRUPT_BKPT; + } + pPager->hasBeenUsed = 1; + + /* If the pager is in the error state, return an error immediately. + ** Otherwise, request the page from the PCache layer. */ + if( pPager->errCode!=SQLITE_OK ){ + rc = pPager->errCode; + }else{ + if( bMmapOk && pagerUseWal(pPager) ){ + rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); + if( rc!=SQLITE_OK ) goto pager_acquire_err; + } + + if( bMmapOk && iFrame==0 ){ + void *pData = 0; + + rc = sqlite3OsFetch(pPager->fd, + (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData + ); + + if( rc==SQLITE_OK && pData ){ + if( pPager->eState>PAGER_READER ){ + pPg = sqlite3PagerLookup(pPager, pgno); + } + if( pPg==0 ){ + rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg); + }else{ + sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData); + } + if( pPg ){ + assert( rc==SQLITE_OK ); + *ppPage = pPg; + return SQLITE_OK; + } + } + if( rc!=SQLITE_OK ){ + goto pager_acquire_err; + } + } + + { + sqlite3_pcache_page *pBase; + pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3); + if( pBase==0 ){ + rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase); + if( rc!=SQLITE_OK ) goto pager_acquire_err; + } + pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase); + if( pPg==0 ) rc = SQLITE_NOMEM; + } + } + + if( rc!=SQLITE_OK ){ + /* Either the call to sqlite3PcacheFetch() returned an error or the + ** pager was already in the error-state when this function was called. + ** Set pPg to 0 and jump to the exception handler. */ + pPg = 0; + goto pager_acquire_err; + } + assert( (*ppPage)->pgno==pgno ); + assert( (*ppPage)->pPager==pPager || (*ppPage)->pPager==0 ); + + if( (*ppPage)->pPager && !noContent ){ + /* In this case the pcache already contains an initialized copy of + ** the page. Return without further ado. */ + assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) ); + pPager->aStat[PAGER_STAT_HIT]++; + return SQLITE_OK; + + }else{ + /* The pager cache has created a new page. Its content needs to + ** be initialized. */ + + pPg = *ppPage; + pPg->pPager = pPager; + + /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page + ** number greater than this, or the unused locking-page, is requested. */ + if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){ + rc = SQLITE_CORRUPT_BKPT; + goto pager_acquire_err; + } + + if( MEMDB || pPager->dbSizefd) ){ + if( pgno>pPager->mxPgno ){ + rc = SQLITE_FULL; + goto pager_acquire_err; + } + if( noContent ){ + /* Failure to set the bits in the InJournal bit-vectors is benign. + ** It merely means that we might do some extra work to journal a + ** page that does not need to be journaled. Nevertheless, be sure + ** to test the case where a malloc error occurs while trying to set + ** a bit in a bit vector. + */ + sqlite3BeginBenignMalloc(); + if( pgno<=pPager->dbOrigSize ){ + TESTONLY( rc = ) sqlite3BitvecSet(pPager->pInJournal, pgno); + testcase( rc==SQLITE_NOMEM ); + } + TESTONLY( rc = ) addToSavepointBitvecs(pPager, pgno); + testcase( rc==SQLITE_NOMEM ); + sqlite3EndBenignMalloc(); + } + memset(pPg->pData, 0, pPager->pageSize); + IOTRACE(("ZERO %p %d\n", pPager, pgno)); + }else{ + if( pagerUseWal(pPager) && bMmapOk==0 ){ + rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); + if( rc!=SQLITE_OK ) goto pager_acquire_err; + } + assert( pPg->pPager==pPager ); + pPager->aStat[PAGER_STAT_MISS]++; + rc = readDbPage(pPg, iFrame); + if( rc!=SQLITE_OK ){ + goto pager_acquire_err; + } + } + pager_set_pagehash(pPg); + } + + return SQLITE_OK; + +pager_acquire_err: + assert( rc!=SQLITE_OK ); + if( pPg ){ + sqlite3PcacheDrop(pPg); + } + pagerUnlockIfUnused(pPager); + + *ppPage = 0; + return rc; +} + +/* +** Acquire a page if it is already in the in-memory cache. Do +** not read the page from disk. Return a pointer to the page, +** or 0 if the page is not in cache. +** +** See also sqlite3PagerGet(). The difference between this routine +** and sqlite3PagerGet() is that _get() will go to the disk and read +** in the page if the page is not already in cache. This routine +** returns NULL if the page is not in cache or if a disk I/O error +** has ever happened. +*/ +SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){ + sqlite3_pcache_page *pPage; + assert( pPager!=0 ); + assert( pgno!=0 ); + assert( pPager->pPCache!=0 ); + pPage = sqlite3PcacheFetch(pPager->pPCache, pgno, 0); + assert( pPage==0 || pPager->hasBeenUsed ); + return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage); +} + +/* +** Release a page reference. +** +** If the number of references to the page drop to zero, then the +** page is added to the LRU list. When all references to all pages +** are released, a rollback occurs and the lock on the database is +** removed. +*/ +SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage *pPg){ + Pager *pPager; + assert( pPg!=0 ); + pPager = pPg->pPager; + if( pPg->flags & PGHDR_MMAP ){ + pagerReleaseMapPage(pPg); + }else{ + sqlite3PcacheRelease(pPg); + } + pagerUnlockIfUnused(pPager); +} +SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){ + if( pPg ) sqlite3PagerUnrefNotNull(pPg); +} + +/* +** This function is called at the start of every write transaction. +** There must already be a RESERVED or EXCLUSIVE lock on the database +** file when this routine is called. +** +** Open the journal file for pager pPager and write a journal header +** to the start of it. If there are active savepoints, open the sub-journal +** as well. This function is only used when the journal file is being +** opened to write a rollback log for a transaction. It is not used +** when opening a hot journal file to roll it back. +** +** If the journal file is already open (as it may be in exclusive mode), +** then this function just writes a journal header to the start of the +** already open file. +** +** Whether or not the journal file is opened by this function, the +** Pager.pInJournal bitvec structure is allocated. +** +** Return SQLITE_OK if everything is successful. Otherwise, return +** SQLITE_NOMEM if the attempt to allocate Pager.pInJournal fails, or +** an IO error code if opening or writing the journal file fails. +*/ +static int pager_open_journal(Pager *pPager){ + int rc = SQLITE_OK; /* Return code */ + sqlite3_vfs * const pVfs = pPager->pVfs; /* Local cache of vfs pointer */ + + assert( pPager->eState==PAGER_WRITER_LOCKED ); + assert( assert_pager_state(pPager) ); + assert( pPager->pInJournal==0 ); + + /* If already in the error state, this function is a no-op. But on + ** the other hand, this routine is never called if we are already in + ** an error state. */ + if( NEVER(pPager->errCode) ) return pPager->errCode; + + if( !pagerUseWal(pPager) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ + pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize); + if( pPager->pInJournal==0 ){ + return SQLITE_NOMEM; + } + + /* Open the journal file if it is not already open. */ + if( !isOpen(pPager->jfd) ){ + if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){ + sqlite3MemJournalOpen(pPager->jfd); + }else{ + const int flags = /* VFS flags to open journal file */ + SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE| + (pPager->tempFile ? + (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL): + (SQLITE_OPEN_MAIN_JOURNAL) + ); + + /* Verify that the database still has the same name as it did when + ** it was originally opened. */ + rc = databaseIsUnmoved(pPager); + if( rc==SQLITE_OK ){ +#ifdef SQLITE_ENABLE_ATOMIC_WRITE + rc = sqlite3JournalOpen( + pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager) + ); +#else + rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0); +#endif + } + } + assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); + } + + + /* Write the first journal header to the journal file and open + ** the sub-journal if necessary. + */ + if( rc==SQLITE_OK ){ + /* TODO: Check if all of these are really required. */ + pPager->nRec = 0; + pPager->journalOff = 0; + pPager->setMaster = 0; + pPager->journalHdr = 0; + rc = writeJournalHdr(pPager); + } + } + + if( rc!=SQLITE_OK ){ + sqlite3BitvecDestroy(pPager->pInJournal); + pPager->pInJournal = 0; + }else{ + assert( pPager->eState==PAGER_WRITER_LOCKED ); + pPager->eState = PAGER_WRITER_CACHEMOD; + } + + return rc; +} + +/* +** Begin a write-transaction on the specified pager object. If a +** write-transaction has already been opened, this function is a no-op. +** +** If the exFlag argument is false, then acquire at least a RESERVED +** lock on the database file. If exFlag is true, then acquire at least +** an EXCLUSIVE lock. If such a lock is already held, no locking +** functions need be called. +** +** If the subjInMemory argument is non-zero, then any sub-journal opened +** within this transaction will be opened as an in-memory file. This +** has no effect if the sub-journal is already opened (as it may be when +** running in exclusive mode) or if the transaction does not require a +** sub-journal. If the subjInMemory argument is zero, then any required +** sub-journal is implemented in-memory if pPager is an in-memory database, +** or using a temporary file otherwise. +*/ +SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){ + int rc = SQLITE_OK; + + if( pPager->errCode ) return pPager->errCode; + assert( pPager->eState>=PAGER_READER && pPager->eStatesubjInMemory = (u8)subjInMemory; + + if( ALWAYS(pPager->eState==PAGER_READER) ){ + assert( pPager->pInJournal==0 ); + + if( pagerUseWal(pPager) ){ + /* If the pager is configured to use locking_mode=exclusive, and an + ** exclusive lock on the database is not already held, obtain it now. + */ + if( pPager->exclusiveMode && sqlite3WalExclusiveMode(pPager->pWal, -1) ){ + rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); + if( rc!=SQLITE_OK ){ + return rc; + } + sqlite3WalExclusiveMode(pPager->pWal, 1); + } + + /* Grab the write lock on the log file. If successful, upgrade to + ** PAGER_RESERVED state. Otherwise, return an error code to the caller. + ** The busy-handler is not invoked if another connection already + ** holds the write-lock. If possible, the upper layer will call it. + */ + rc = sqlite3WalBeginWriteTransaction(pPager->pWal); + }else{ + /* Obtain a RESERVED lock on the database file. If the exFlag parameter + ** is true, then immediately upgrade this to an EXCLUSIVE lock. The + ** busy-handler callback can be used when upgrading to the EXCLUSIVE + ** lock, but not when obtaining the RESERVED lock. + */ + rc = pagerLockDb(pPager, RESERVED_LOCK); + if( rc==SQLITE_OK && exFlag ){ + rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); + } + } + + if( rc==SQLITE_OK ){ + /* Change to WRITER_LOCKED state. + ** + ** WAL mode sets Pager.eState to PAGER_WRITER_LOCKED or CACHEMOD + ** when it has an open transaction, but never to DBMOD or FINISHED. + ** This is because in those states the code to roll back savepoint + ** transactions may copy data from the sub-journal into the database + ** file as well as into the page cache. Which would be incorrect in + ** WAL mode. + */ + pPager->eState = PAGER_WRITER_LOCKED; + pPager->dbHintSize = pPager->dbSize; + pPager->dbFileSize = pPager->dbSize; + pPager->dbOrigSize = pPager->dbSize; + pPager->journalOff = 0; + } + + assert( rc==SQLITE_OK || pPager->eState==PAGER_READER ); + assert( rc!=SQLITE_OK || pPager->eState==PAGER_WRITER_LOCKED ); + assert( assert_pager_state(pPager) ); + } + + PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager))); + return rc; +} + +/* +** Mark a single data page as writeable. The page is written into the +** main journal or sub-journal as required. If the page is written into +** one of the journals, the corresponding bit is set in the +** Pager.pInJournal bitvec and the PagerSavepoint.pInSavepoint bitvecs +** of any open savepoints as appropriate. +*/ +static int pager_write(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + int rc = SQLITE_OK; + int inJournal; + + /* This routine is not called unless a write-transaction has already + ** been started. The journal file may or may not be open at this point. + ** It is never called in the ERROR state. + */ + assert( pPager->eState==PAGER_WRITER_LOCKED + || pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + ); + assert( assert_pager_state(pPager) ); + assert( pPager->errCode==0 ); + assert( pPager->readOnly==0 ); + + CHECK_PAGE(pPg); + + /* The journal file needs to be opened. Higher level routines have already + ** obtained the necessary locks to begin the write-transaction, but the + ** rollback journal might not yet be open. Open it now if this is the case. + ** + ** This is done before calling sqlite3PcacheMakeDirty() on the page. + ** Otherwise, if it were done after calling sqlite3PcacheMakeDirty(), then + ** an error might occur and the pager would end up in WRITER_LOCKED state + ** with pages marked as dirty in the cache. + */ + if( pPager->eState==PAGER_WRITER_LOCKED ){ + rc = pager_open_journal(pPager); + if( rc!=SQLITE_OK ) return rc; + } + assert( pPager->eState>=PAGER_WRITER_CACHEMOD ); + assert( assert_pager_state(pPager) ); + + /* Mark the page as dirty. If the page has already been written + ** to the journal then we can return right away. + */ + sqlite3PcacheMakeDirty(pPg); + inJournal = pageInJournal(pPager, pPg); + if( inJournal && (pPager->nSavepoint==0 || !subjRequiresPage(pPg)) ){ + assert( !pagerUseWal(pPager) ); + }else{ + + /* The transaction journal now exists and we have a RESERVED or an + ** EXCLUSIVE lock on the main database file. Write the current page to + ** the transaction journal if it is not there already. + */ + if( !inJournal && !pagerUseWal(pPager) ){ + assert( pagerUseWal(pPager)==0 ); + if( pPg->pgno<=pPager->dbOrigSize && isOpen(pPager->jfd) ){ + u32 cksum; + char *pData2; + i64 iOff = pPager->journalOff; + + /* 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) ); + + assert( pPager->journalHdr<=pPager->journalOff ); + CODEC2(pPager, pPg->pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2); + cksum = pager_cksum(pPager, (u8*)pData2); + + /* Even if an IO or diskfull error occurs while journalling the + ** page in the block above, set the need-sync flag for the page. + ** Otherwise, when the transaction is rolled back, the logic in + ** playback_one_page() will think that the page needs to be restored + ** in the database file. And if an IO error occurs while doing so, + ** then corruption may follow. + */ + pPg->flags |= PGHDR_NEED_SYNC; + + rc = write32bits(pPager->jfd, iOff, pPg->pgno); + if( rc!=SQLITE_OK ) return rc; + rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize, iOff+4); + if( rc!=SQLITE_OK ) return rc; + rc = write32bits(pPager->jfd, iOff+pPager->pageSize+4, cksum); + if( rc!=SQLITE_OK ) return rc; + + IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, + pPager->journalOff, pPager->pageSize)); + PAGER_INCR(sqlite3_pager_writej_count); + PAGERTRACE(("JOURNAL %d page %d needSync=%d hash(%08x)\n", + PAGERID(pPager), pPg->pgno, + ((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg))); + + pPager->journalOff += 8 + pPager->pageSize; + pPager->nRec++; + assert( pPager->pInJournal!=0 ); + rc = sqlite3BitvecSet(pPager->pInJournal, pPg->pgno); + testcase( rc==SQLITE_NOMEM ); + assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); + rc |= addToSavepointBitvecs(pPager, pPg->pgno); + if( rc!=SQLITE_OK ){ + assert( rc==SQLITE_NOMEM ); + return rc; + } + }else{ + if( pPager->eState!=PAGER_WRITER_DBMOD ){ + pPg->flags |= PGHDR_NEED_SYNC; + } + PAGERTRACE(("APPEND %d page %d needSync=%d\n", + PAGERID(pPager), pPg->pgno, + ((pPg->flags&PGHDR_NEED_SYNC)?1:0))); + } + } + + /* If the statement journal is open and the page is not in it, + ** then write the current page to the statement journal. Note that + ** the statement journal format differs from the standard journal format + ** in that it omits the checksums and the header. + */ + if( pPager->nSavepoint>0 && subjRequiresPage(pPg) ){ + rc = subjournalPage(pPg); + } + } + + /* Update the database size and return. + */ + if( pPager->dbSizepgno ){ + pPager->dbSize = pPg->pgno; + } + return rc; +} + +/* +** This is a variant of sqlite3PagerWrite() that runs when the sector size +** is larger than the page size. SQLite makes the (reasonable) assumption that +** all bytes of a sector are written together by hardware. Hence, all bytes of +** a sector need to be journalled in case of a power loss in the middle of +** a write. +** +** Usually, the sector size is less than or equal to the page size, in which +** case pages can be individually written. This routine only runs in the exceptional +** case where the page size is smaller than the sector size. +*/ +static SQLITE_NOINLINE int pagerWriteLargeSector(PgHdr *pPg){ + int rc = SQLITE_OK; /* Return code */ + Pgno nPageCount; /* Total number of pages in database file */ + Pgno pg1; /* First page of the sector pPg is located on. */ + int nPage = 0; /* Number of pages starting at pg1 to journal */ + int ii; /* Loop counter */ + int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */ + Pager *pPager = pPg->pPager; /* The pager that owns pPg */ + Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize); + + /* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow + ** a journal header to be written between the pages journaled by + ** this function. + */ + assert( !MEMDB ); + assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)==0 ); + pPager->doNotSpill |= SPILLFLAG_NOSYNC; + + /* This trick assumes that both the page-size and sector-size are + ** an integer power of 2. It sets variable pg1 to the identifier + ** of the first page of the sector pPg is located on. + */ + pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1; + + nPageCount = pPager->dbSize; + if( pPg->pgno>nPageCount ){ + nPage = (pPg->pgno - pg1)+1; + }else if( (pg1+nPagePerSector-1)>nPageCount ){ + nPage = nPageCount+1-pg1; + }else{ + nPage = nPagePerSector; + } + assert(nPage>0); + assert(pg1<=pPg->pgno); + assert((pg1+nPage)>pPg->pgno); + + for(ii=0; iipgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){ + if( pg!=PAGER_MJ_PGNO(pPager) ){ + rc = sqlite3PagerGet(pPager, pg, &pPage); + if( rc==SQLITE_OK ){ + rc = pager_write(pPage); + if( pPage->flags&PGHDR_NEED_SYNC ){ + needSync = 1; + } + sqlite3PagerUnrefNotNull(pPage); + } + } + }else if( (pPage = sqlite3PagerLookup(pPager, pg))!=0 ){ + if( pPage->flags&PGHDR_NEED_SYNC ){ + needSync = 1; + } + sqlite3PagerUnrefNotNull(pPage); + } + } + + /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages + ** starting at pg1, then it needs to be set for all of them. Because + ** writing to any of these nPage pages may damage the others, the + ** journal file must contain sync()ed copies of all of them + ** before any of them can be written out to the database file. + */ + if( rc==SQLITE_OK && needSync ){ + assert( !MEMDB ); + for(ii=0; iiflags |= PGHDR_NEED_SYNC; + sqlite3PagerUnrefNotNull(pPage); + } + } + } + + assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)!=0 ); + pPager->doNotSpill &= ~SPILLFLAG_NOSYNC; + return rc; +} + +/* +** Mark a data page as writeable. This routine must be called before +** making changes to a page. The caller must check the return value +** of this function and be careful not to change any page data unless +** this routine returns SQLITE_OK. +** +** The difference between this function and pager_write() is that this +** function also deals with the special case where 2 or more pages +** fit on a single disk sector. In this case all co-resident pages +** must have been written to the journal file before returning. +** +** If an error occurs, SQLITE_NOMEM or an IO error code is returned +** as appropriate. Otherwise, SQLITE_OK. +*/ +SQLITE_PRIVATE int sqlite3PagerWrite(PgHdr *pPg){ + assert( (pPg->flags & PGHDR_MMAP)==0 ); + assert( pPg->pPager->eState>=PAGER_WRITER_LOCKED ); + assert( pPg->pPager->eState!=PAGER_ERROR ); + assert( assert_pager_state(pPg->pPager) ); + if( pPg->pPager->sectorSize > (u32)pPg->pPager->pageSize ){ + return pagerWriteLargeSector(pPg); + }else{ + return pager_write(pPg); + } +} + +/* +** Return TRUE if the page given in the argument was previously passed +** to sqlite3PagerWrite(). In other words, return TRUE if it is ok +** to change the content of the page. +*/ +#ifndef NDEBUG +SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage *pPg){ + return pPg->flags&PGHDR_DIRTY; +} +#endif + +/* +** A call to this routine tells the pager that it is not necessary to +** write the information on page pPg back to the disk, even though +** that page might be marked as dirty. This happens, for example, when +** the page has been added as a leaf of the freelist and so its +** content no longer matters. +** +** The overlying software layer calls this routine when all of the data +** on the given page is unused. The pager marks the page as clean so +** that it does not get written to disk. +** +** Tests show that this optimization can quadruple the speed of large +** DELETE operations. +*/ +SQLITE_PRIVATE void sqlite3PagerDontWrite(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + if( (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){ + PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager))); + IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno)) + pPg->flags |= PGHDR_DONT_WRITE; + pager_set_pagehash(pPg); + } +} + +/* +** This routine is called to increment the value of the database file +** change-counter, stored as a 4-byte big-endian integer starting at +** byte offset 24 of the pager file. The secondary change counter at +** 92 is also updated, as is the SQLite version number at offset 96. +** +** But this only happens if the pPager->changeCountDone flag is false. +** To avoid excess churning of page 1, the update only happens once. +** See also the pager_write_changecounter() routine that does an +** unconditional update of the change counters. +** +** If the isDirectMode flag is zero, then this is done by calling +** sqlite3PagerWrite() on page 1, then modifying the contents of the +** page data. In this case the file will be updated when the current +** transaction is committed. +** +** The isDirectMode flag may only be non-zero if the library was compiled +** with the SQLITE_ENABLE_ATOMIC_WRITE macro defined. In this case, +** if isDirect is non-zero, then the database file is updated directly +** by writing an updated version of page 1 using a call to the +** sqlite3OsWrite() function. +*/ +static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ + int rc = SQLITE_OK; + + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + ); + assert( assert_pager_state(pPager) ); + + /* Declare and initialize constant integer 'isDirect'. If the + ** atomic-write optimization is enabled in this build, then isDirect + ** is initialized to the value passed as the isDirectMode parameter + ** to this function. Otherwise, it is always set to zero. + ** + ** The idea is that if the atomic-write optimization is not + ** enabled at compile time, the compiler can omit the tests of + ** 'isDirect' below, as well as the block enclosed in the + ** "if( isDirect )" condition. + */ +#ifndef SQLITE_ENABLE_ATOMIC_WRITE +# define DIRECT_MODE 0 + assert( isDirectMode==0 ); + UNUSED_PARAMETER(isDirectMode); +#else +# define DIRECT_MODE isDirectMode +#endif + + if( !pPager->changeCountDone && ALWAYS(pPager->dbSize>0) ){ + PgHdr *pPgHdr; /* Reference to page 1 */ + + assert( !pPager->tempFile && isOpen(pPager->fd) ); + + /* Open page 1 of the file for writing. */ + rc = sqlite3PagerGet(pPager, 1, &pPgHdr); + assert( pPgHdr==0 || rc==SQLITE_OK ); + + /* If page one was fetched successfully, and this function is not + ** operating in direct-mode, make page 1 writable. When not in + ** direct mode, page 1 is always held in cache and hence the PagerGet() + ** above is always successful - hence the ALWAYS on rc==SQLITE_OK. + */ + if( !DIRECT_MODE && ALWAYS(rc==SQLITE_OK) ){ + rc = sqlite3PagerWrite(pPgHdr); + } + + if( rc==SQLITE_OK ){ + /* Actually do the update of the change counter */ + pager_write_changecounter(pPgHdr); + + /* If running in direct mode, write the contents of page 1 to the file. */ + if( DIRECT_MODE ){ + const void *zBuf; + assert( pPager->dbFileSize>0 ); + CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM, zBuf); + if( rc==SQLITE_OK ){ + rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0); + pPager->aStat[PAGER_STAT_WRITE]++; + } + if( rc==SQLITE_OK ){ + /* Update the pager's copy of the change-counter. Otherwise, the + ** next time a read transaction is opened the cache will be + ** flushed (as the change-counter values will not match). */ + const void *pCopy = (const void *)&((const char *)zBuf)[24]; + memcpy(&pPager->dbFileVers, pCopy, sizeof(pPager->dbFileVers)); + pPager->changeCountDone = 1; + } + }else{ + pPager->changeCountDone = 1; + } + } + + /* Release the page reference. */ + sqlite3PagerUnref(pPgHdr); + } + return rc; +} + +/* +** Sync the database file to disk. This is a no-op for in-memory databases +** or pages with the Pager.noSync flag set. +** +** If successful, or if called on a pager for which it is a no-op, this +** function returns SQLITE_OK. Otherwise, an IO error code is returned. +*/ +SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager, const char *zMaster){ + int rc = SQLITE_OK; + + if( isOpen(pPager->fd) ){ + void *pArg = (void*)zMaster; + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg); + if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; + } + if( rc==SQLITE_OK && !pPager->noSync ){ + assert( !MEMDB ); + rc = sqlite3OsSync(pPager->fd, pPager->syncFlags); + } + return rc; +} + +/* +** This function may only be called while a write-transaction is active in +** rollback. If the connection is in WAL mode, this call is a no-op. +** Otherwise, if the connection does not already have an EXCLUSIVE lock on +** the database file, an attempt is made to obtain one. +** +** If the EXCLUSIVE lock is already held or the attempt to obtain it is +** successful, or the connection is in WAL mode, SQLITE_OK is returned. +** Otherwise, either SQLITE_BUSY or an SQLITE_IOERR_XXX error code is +** returned. +*/ +SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager *pPager){ + int rc = SQLITE_OK; + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + || pPager->eState==PAGER_WRITER_LOCKED + ); + assert( assert_pager_state(pPager) ); + if( 0==pagerUseWal(pPager) ){ + rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); + } + return rc; +} + +/* +** Sync the database file for the pager pPager. zMaster points to the name +** of a master journal file that should be written into the individual +** journal file. zMaster may be NULL, which is interpreted as no master +** journal (a single database transaction). +** +** This routine ensures that: +** +** * The database file change-counter is updated, +** * the journal is synced (unless the atomic-write optimization is used), +** * all dirty pages are written to the database file, +** * the database file is truncated (if required), and +** * the database file synced. +** +** The only thing that remains to commit the transaction is to finalize +** (delete, truncate or zero the first part of) the journal file (or +** delete the master journal file if specified). +** +** Note that if zMaster==NULL, this does not overwrite a previous value +** passed to an sqlite3PagerCommitPhaseOne() call. +** +** If the final parameter - noSync - is true, then the database file itself +** is not synced. The caller must call sqlite3PagerSync() directly to +** sync the database file before calling CommitPhaseTwo() to delete the +** journal file in this case. +*/ +SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne( + Pager *pPager, /* Pager object */ + const char *zMaster, /* If not NULL, the master journal name */ + int noSync /* True to omit the xSync on the db file */ +){ + int rc = SQLITE_OK; /* Return code */ + + assert( pPager->eState==PAGER_WRITER_LOCKED + || pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + || pPager->eState==PAGER_ERROR + ); + assert( assert_pager_state(pPager) ); + + /* If a prior error occurred, report that error again. */ + if( NEVER(pPager->errCode) ) return pPager->errCode; + + PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", + pPager->zFilename, zMaster, pPager->dbSize)); + + /* If no database changes have been made, return early. */ + if( pPager->eStatepBackup); + }else{ + if( pagerUseWal(pPager) ){ + PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); + PgHdr *pPageOne = 0; + if( pList==0 ){ + /* Must have at least one page for the WAL commit flag. + ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */ + rc = sqlite3PagerGet(pPager, 1, &pPageOne); + pList = pPageOne; + pList->pDirty = 0; + } + assert( rc==SQLITE_OK ); + if( ALWAYS(pList) ){ + rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1); + } + sqlite3PagerUnref(pPageOne); + if( rc==SQLITE_OK ){ + sqlite3PcacheCleanAll(pPager->pPCache); + } + }else{ + /* The following block updates the change-counter. Exactly how it + ** does this depends on whether or not the atomic-update optimization + ** was enabled at compile time, and if this transaction meets the + ** runtime criteria to use the operation: + ** + ** * The file-system supports the atomic-write property for + ** blocks of size page-size, and + ** * This commit is not part of a multi-file transaction, and + ** * Exactly one page has been modified and store in the journal file. + ** + ** If the optimization was not enabled at compile time, then the + ** pager_incr_changecounter() function is called to update the change + ** counter in 'indirect-mode'. If the optimization is compiled in but + ** is not applicable to this transaction, call sqlite3JournalCreate() + ** to make sure the journal file has actually been created, then call + ** pager_incr_changecounter() to update the change-counter in indirect + ** mode. + ** + ** Otherwise, if the optimization is both enabled and applicable, + ** then call pager_incr_changecounter() to update the change-counter + ** in 'direct' mode. In this case the journal file will never be + ** created for this transaction. + */ + #ifdef SQLITE_ENABLE_ATOMIC_WRITE + PgHdr *pPg; + assert( isOpen(pPager->jfd) + || pPager->journalMode==PAGER_JOURNALMODE_OFF + || pPager->journalMode==PAGER_JOURNALMODE_WAL + ); + if( !zMaster && isOpen(pPager->jfd) + && pPager->journalOff==jrnlBufferSize(pPager) + && pPager->dbSize>=pPager->dbOrigSize + && (0==(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty) + ){ + /* Update the db file change counter via the direct-write method. The + ** following call will modify the in-memory representation of page 1 + ** to include the updated change counter and then write page 1 + ** directly to the database file. Because of the atomic-write + ** property of the host file-system, this is safe. + */ + rc = pager_incr_changecounter(pPager, 1); + }else{ + rc = sqlite3JournalCreate(pPager->jfd); + if( rc==SQLITE_OK ){ + rc = pager_incr_changecounter(pPager, 0); + } + } + #else + rc = pager_incr_changecounter(pPager, 0); + #endif + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + + /* Write the master journal name into the journal file. If a master + ** journal file name has already been written to the journal file, + ** or if zMaster is NULL (no master journal), then this call is a no-op. + */ + rc = writeMasterJournal(pPager, zMaster); + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + + /* Sync the journal file and write all dirty pages to the database. + ** If the atomic-update optimization is being used, this sync will not + ** create the journal file or perform any real IO. + ** + ** Because the change-counter page was just modified, unless the + ** atomic-update optimization is used it is almost certain that the + ** journal requires a sync here. However, in locking_mode=exclusive + ** on a system under memory pressure it is just possible that this is + ** not the case. In this case it is likely enough that the redundant + ** xSync() call will be changed to a no-op by the OS anyhow. + */ + rc = syncJournal(pPager, 0); + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + + rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache)); + if( rc!=SQLITE_OK ){ + assert( rc!=SQLITE_IOERR_BLOCKED ); + goto commit_phase_one_exit; + } + sqlite3PcacheCleanAll(pPager->pPCache); + + /* If the file on disk is smaller than the database image, use + ** pager_truncate to grow the file here. This can happen if the database + ** image was extended as part of the current transaction and then the + ** last page in the db image moved to the free-list. In this case the + ** last page is never written out to disk, leaving the database file + ** undersized. Fix this now if it is the case. */ + if( pPager->dbSize>pPager->dbFileSize ){ + Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager)); + assert( pPager->eState==PAGER_WRITER_DBMOD ); + rc = pager_truncate(pPager, nNew); + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + } + + /* Finally, sync the database file. */ + if( !noSync ){ + rc = sqlite3PagerSync(pPager, zMaster); + } + IOTRACE(("DBSYNC %p\n", pPager)) + } + } + +commit_phase_one_exit: + if( rc==SQLITE_OK && !pagerUseWal(pPager) ){ + pPager->eState = PAGER_WRITER_FINISHED; + } + return rc; +} + + +/* +** When this function is called, the database file has been completely +** updated to reflect the changes made by the current transaction and +** synced to disk. The journal file still exists in the file-system +** though, and if a failure occurs at this point it will eventually +** be used as a hot-journal and the current transaction rolled back. +** +** This function finalizes the journal file, either by deleting, +** truncating or partially zeroing it, so that it cannot be used +** for hot-journal rollback. Once this is done the transaction is +** irrevocably committed. +** +** If an error occurs, an IO error code is returned and the pager +** moves into the error state. Otherwise, SQLITE_OK is returned. +*/ +SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager *pPager){ + int rc = SQLITE_OK; /* Return code */ + + /* This routine should not be called if a prior error has occurred. + ** But if (due to a coding error elsewhere in the system) it does get + ** called, just return the same error code without doing anything. */ + if( NEVER(pPager->errCode) ) return pPager->errCode; + + assert( pPager->eState==PAGER_WRITER_LOCKED + || pPager->eState==PAGER_WRITER_FINISHED + || (pagerUseWal(pPager) && pPager->eState==PAGER_WRITER_CACHEMOD) + ); + assert( assert_pager_state(pPager) ); + + /* An optimization. If the database was not actually modified during + ** this transaction, the pager is running in exclusive-mode and is + ** using persistent journals, then this function is a no-op. + ** + ** The start of the journal file currently contains a single journal + ** header with the nRec field set to 0. If such a journal is used as + ** a hot-journal during hot-journal rollback, 0 changes will be made + ** to the database file. So there is no need to zero the journal + ** header. Since the pager is in exclusive mode, there is no need + ** to drop any locks either. + */ + if( pPager->eState==PAGER_WRITER_LOCKED + && pPager->exclusiveMode + && pPager->journalMode==PAGER_JOURNALMODE_PERSIST + ){ + assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) || !pPager->journalOff ); + pPager->eState = PAGER_READER; + return SQLITE_OK; + } + + PAGERTRACE(("COMMIT %d\n", PAGERID(pPager))); + pPager->iDataVersion++; + rc = pager_end_transaction(pPager, pPager->setMaster, 1); + return pager_error(pPager, rc); +} + +/* +** If a write transaction is open, then all changes made within the +** transaction are reverted and the current write-transaction is closed. +** The pager falls back to PAGER_READER state if successful, or PAGER_ERROR +** state if an error occurs. +** +** If the pager is already in PAGER_ERROR state when this function is called, +** it returns Pager.errCode immediately. No work is performed in this case. +** +** Otherwise, in rollback mode, this function performs two functions: +** +** 1) It rolls back the journal file, restoring all database file and +** in-memory cache pages to the state they were in when the transaction +** was opened, and +** +** 2) It finalizes the journal file, so that it is not used for hot +** rollback at any point in the future. +** +** Finalization of the journal file (task 2) is only performed if the +** rollback is successful. +** +** In WAL mode, all cache-entries containing data modified within the +** current transaction are either expelled from the cache or reverted to +** their pre-transaction state by re-reading data from the database or +** WAL files. The WAL transaction is then closed. +*/ +SQLITE_PRIVATE int sqlite3PagerRollback(Pager *pPager){ + int rc = SQLITE_OK; /* Return code */ + PAGERTRACE(("ROLLBACK %d\n", PAGERID(pPager))); + + /* PagerRollback() is a no-op if called in READER or OPEN state. If + ** the pager is already in the ERROR state, the rollback is not + ** attempted here. Instead, the error code is returned to the caller. + */ + assert( assert_pager_state(pPager) ); + if( pPager->eState==PAGER_ERROR ) return pPager->errCode; + if( pPager->eState<=PAGER_READER ) return SQLITE_OK; + + if( pagerUseWal(pPager) ){ + int rc2; + rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1); + rc2 = pager_end_transaction(pPager, pPager->setMaster, 0); + if( rc==SQLITE_OK ) rc = rc2; + }else if( !isOpen(pPager->jfd) || pPager->eState==PAGER_WRITER_LOCKED ){ + int eState = pPager->eState; + rc = pager_end_transaction(pPager, 0, 0); + if( !MEMDB && eState>PAGER_WRITER_LOCKED ){ + /* This can happen using journal_mode=off. Move the pager to the error + ** state to indicate that the contents of the cache may not be trusted. + ** Any active readers will get SQLITE_ABORT. + */ + pPager->errCode = SQLITE_ABORT; + pPager->eState = PAGER_ERROR; + return rc; + } + }else{ + rc = pager_playback(pPager, 0); + } + + assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK ); + assert( rc==SQLITE_OK || rc==SQLITE_FULL || rc==SQLITE_CORRUPT + || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR + || rc==SQLITE_CANTOPEN + ); + + /* If an error occurs during a ROLLBACK, we can no longer trust the pager + ** cache. So call pager_error() on the way out to make any error persistent. + */ + return pager_error(pPager, rc); +} + +/* +** Return TRUE if the database file is opened read-only. Return FALSE +** if the database is (in theory) writable. +*/ +SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager *pPager){ + return pPager->readOnly; +} + +/* +** Return the number of references to the pager. +*/ +SQLITE_PRIVATE int sqlite3PagerRefcount(Pager *pPager){ + return sqlite3PcacheRefCount(pPager->pPCache); +} + +/* +** Return the approximate number of bytes of memory currently +** used by the pager and its associated cache. +*/ +SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager *pPager){ + int perPageSize = pPager->pageSize + pPager->nExtra + sizeof(PgHdr) + + 5*sizeof(void*); + return perPageSize*sqlite3PcachePagecount(pPager->pPCache) + + sqlite3MallocSize(pPager) + + pPager->pageSize; +} + +/* +** Return the number of references to the specified page. +*/ +SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage *pPage){ + return sqlite3PcachePageRefcount(pPage); +} + +#ifdef SQLITE_TEST +/* +** This routine is used for testing and analysis only. +*/ +SQLITE_PRIVATE int *sqlite3PagerStats(Pager *pPager){ + static int a[11]; + a[0] = sqlite3PcacheRefCount(pPager->pPCache); + a[1] = sqlite3PcachePagecount(pPager->pPCache); + a[2] = sqlite3PcacheGetCachesize(pPager->pPCache); + a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize; + a[4] = pPager->eState; + a[5] = pPager->errCode; + a[6] = pPager->aStat[PAGER_STAT_HIT]; + a[7] = pPager->aStat[PAGER_STAT_MISS]; + a[8] = 0; /* Used to be pPager->nOvfl */ + a[9] = pPager->nRead; + a[10] = pPager->aStat[PAGER_STAT_WRITE]; + return a; +} +#endif + +/* +** Parameter eStat must be either SQLITE_DBSTATUS_CACHE_HIT or +** SQLITE_DBSTATUS_CACHE_MISS. Before returning, *pnVal is incremented by the +** current cache hit or miss count, according to the value of eStat. If the +** reset parameter is non-zero, the cache hit or miss count is zeroed before +** returning. +*/ +SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){ + + assert( eStat==SQLITE_DBSTATUS_CACHE_HIT + || eStat==SQLITE_DBSTATUS_CACHE_MISS + || eStat==SQLITE_DBSTATUS_CACHE_WRITE + ); + + assert( SQLITE_DBSTATUS_CACHE_HIT+1==SQLITE_DBSTATUS_CACHE_MISS ); + assert( SQLITE_DBSTATUS_CACHE_HIT+2==SQLITE_DBSTATUS_CACHE_WRITE ); + assert( PAGER_STAT_HIT==0 && PAGER_STAT_MISS==1 && PAGER_STAT_WRITE==2 ); + + *pnVal += pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT]; + if( reset ){ + pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT] = 0; + } +} + +/* +** Return true if this is an in-memory pager. +*/ +SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){ + return MEMDB; +} + +/* +** Check that there are at least nSavepoint savepoints open. If there are +** currently less than nSavepoints open, then open one or more savepoints +** to make up the difference. If the number of savepoints is already +** equal to nSavepoint, then this function is a no-op. +** +** If a memory allocation fails, SQLITE_NOMEM is returned. If an error +** occurs while opening the sub-journal file, then an IO error code is +** returned. Otherwise, SQLITE_OK. +*/ +SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){ + int rc = SQLITE_OK; /* Return code */ + int nCurrent = pPager->nSavepoint; /* Current number of savepoints */ + + assert( pPager->eState>=PAGER_WRITER_LOCKED ); + assert( assert_pager_state(pPager) ); + + if( nSavepoint>nCurrent && pPager->useJournal ){ + int ii; /* Iterator variable */ + PagerSavepoint *aNew; /* New Pager.aSavepoint array */ + + /* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM + ** if the allocation fails. Otherwise, zero the new portion in case a + ** malloc failure occurs while populating it in the for(...) loop below. + */ + aNew = (PagerSavepoint *)sqlite3Realloc( + pPager->aSavepoint, sizeof(PagerSavepoint)*nSavepoint + ); + if( !aNew ){ + return SQLITE_NOMEM; + } + memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint)); + pPager->aSavepoint = aNew; + + /* Populate the PagerSavepoint structures just allocated. */ + for(ii=nCurrent; iidbSize; + if( isOpen(pPager->jfd) && pPager->journalOff>0 ){ + aNew[ii].iOffset = pPager->journalOff; + }else{ + aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager); + } + aNew[ii].iSubRec = pPager->nSubRec; + aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize); + if( !aNew[ii].pInSavepoint ){ + return SQLITE_NOMEM; + } + if( pagerUseWal(pPager) ){ + sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData); + } + pPager->nSavepoint = ii+1; + } + assert( pPager->nSavepoint==nSavepoint ); + assertTruncateConstraint(pPager); + } + + return rc; +} + +/* +** This function is called to rollback or release (commit) a savepoint. +** The savepoint to release or rollback need not be the most recently +** created savepoint. +** +** Parameter op is always either SAVEPOINT_ROLLBACK or SAVEPOINT_RELEASE. +** If it is SAVEPOINT_RELEASE, then release and destroy the savepoint with +** index iSavepoint. If it is SAVEPOINT_ROLLBACK, then rollback all changes +** that have occurred since the specified savepoint was created. +** +** The savepoint to rollback or release is identified by parameter +** iSavepoint. A value of 0 means to operate on the outermost savepoint +** (the first created). A value of (Pager.nSavepoint-1) means operate +** on the most recently created savepoint. If iSavepoint is greater than +** (Pager.nSavepoint-1), then this function is a no-op. +** +** If a negative value is passed to this function, then the current +** transaction is rolled back. This is different to calling +** sqlite3PagerRollback() because this function does not terminate +** the transaction or unlock the database, it just restores the +** contents of the database to its original state. +** +** In any case, all savepoints with an index greater than iSavepoint +** are destroyed. If this is a release operation (op==SAVEPOINT_RELEASE), +** then savepoint iSavepoint is also destroyed. +** +** This function may return SQLITE_NOMEM if a memory allocation fails, +** or an IO error code if an IO error occurs while rolling back a +** savepoint. If no errors occur, SQLITE_OK is returned. +*/ +SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ + int rc = pPager->errCode; /* Return code */ + + assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK ); + assert( iSavepoint>=0 || op==SAVEPOINT_ROLLBACK ); + + if( rc==SQLITE_OK && iSavepointnSavepoint ){ + int ii; /* Iterator variable */ + int nNew; /* Number of remaining savepoints after this op. */ + + /* Figure out how many savepoints will still be active after this + ** operation. Store this value in nNew. Then free resources associated + ** with any savepoints that are destroyed by this operation. + */ + nNew = iSavepoint + (( op==SAVEPOINT_RELEASE ) ? 0 : 1); + for(ii=nNew; iinSavepoint; ii++){ + sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint); + } + pPager->nSavepoint = nNew; + + /* If this is a release of the outermost savepoint, truncate + ** the sub-journal to zero bytes in size. */ + if( op==SAVEPOINT_RELEASE ){ + if( nNew==0 && isOpen(pPager->sjfd) ){ + /* Only truncate if it is an in-memory sub-journal. */ + if( sqlite3IsMemJournal(pPager->sjfd) ){ + rc = sqlite3OsTruncate(pPager->sjfd, 0); + assert( rc==SQLITE_OK ); + } + pPager->nSubRec = 0; + } + } + /* Else this is a rollback operation, playback the specified savepoint. + ** If this is a temp-file, it is possible that the journal file has + ** not yet been opened. In this case there have been no changes to + ** the database file, so the playback operation can be skipped. + */ + else if( pagerUseWal(pPager) || isOpen(pPager->jfd) ){ + PagerSavepoint *pSavepoint = (nNew==0)?0:&pPager->aSavepoint[nNew-1]; + rc = pagerPlaybackSavepoint(pPager, pSavepoint); + assert(rc!=SQLITE_DONE); + } + } + + return rc; +} + +/* +** Return the full pathname of the database file. +** +** Except, if the pager is in-memory only, then return an empty string if +** nullIfMemDb is true. This routine is called with nullIfMemDb==1 when +** used to report the filename to the user, for compatibility with legacy +** behavior. But when the Btree needs to know the filename for matching to +** shared cache, it uses nullIfMemDb==0 so that in-memory databases can +** participate in shared-cache. +*/ +SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){ + return (nullIfMemDb && pPager->memDb) ? "" : pPager->zFilename; +} + +/* +** Return the VFS structure for the pager. +*/ +SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){ + return pPager->pVfs; +} + +/* +** Return the file handle for the database file associated +** with the pager. This might return NULL if the file has +** not yet been opened. +*/ +SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){ + return pPager->fd; +} + +/* +** Return the full pathname of the journal file. +*/ +SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager *pPager){ + return pPager->zJournal; +} + +/* +** Return true if fsync() calls are disabled for this pager. Return FALSE +** if fsync()s are executed normally. +*/ +SQLITE_PRIVATE int sqlite3PagerNosync(Pager *pPager){ + return pPager->noSync; +} + +#ifdef SQLITE_HAS_CODEC +/* +** Set or retrieve the codec for this pager +*/ +SQLITE_PRIVATE void sqlite3PagerSetCodec( + Pager *pPager, + void *(*xCodec)(void*,void*,Pgno,int), + void (*xCodecSizeChng)(void*,int,int), + void (*xCodecFree)(void*), + void *pCodec +){ + if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec); + pPager->xCodec = pPager->memDb ? 0 : xCodec; + pPager->xCodecSizeChng = xCodecSizeChng; + pPager->xCodecFree = xCodecFree; + pPager->pCodec = pCodec; + pagerReportSize(pPager); +} +SQLITE_PRIVATE void *sqlite3PagerGetCodec(Pager *pPager){ + return pPager->pCodec; +} + +/* +** This function is called by the wal module when writing page content +** into the log file. +** +** This function returns a pointer to a buffer containing the encrypted +** page content. If a malloc fails, this function may return NULL. +*/ +SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){ + void *aData = 0; + CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData); + return aData; +} + +/* +** Return the current pager state +*/ +SQLITE_PRIVATE int sqlite3PagerState(Pager *pPager){ + return pPager->eState; +} +#endif /* SQLITE_HAS_CODEC */ + +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** Move the page pPg to location pgno in the file. +** +** There must be no references to the page previously located at +** pgno (which we call pPgOld) though that page is allowed to be +** in cache. If the page previously located at pgno is not already +** in the rollback journal, it is not put there by by this routine. +** +** References to the page pPg remain valid. Updating any +** meta-data associated with pPg (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). +** +** If the fourth argument, isCommit, is non-zero, then this page is being +** moved as part of a database reorganization just before the transaction +** is being committed. In this case, it is guaranteed that the database page +** pPg refers to will not be written to again within this transaction. +** +** This function may return SQLITE_NOMEM or an IO error code if an error +** occurs. Otherwise, it returns SQLITE_OK. +*/ +SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ + PgHdr *pPgOld; /* The page being overwritten. */ + Pgno needSyncPgno = 0; /* Old value of pPg->pgno, if sync is required */ + int rc; /* Return code */ + Pgno origPgno; /* The original page number */ + + assert( pPg->nRef>0 ); + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + ); + assert( assert_pager_state(pPager) ); + + /* In order to be able to rollback, an in-memory database must journal + ** the page we are moving from. + */ + if( MEMDB ){ + rc = sqlite3PagerWrite(pPg); + if( rc ) return rc; + } + + /* If the page being moved is dirty and has not been saved by the latest + ** savepoint, then save the current contents of the page into the + ** sub-journal now. This is required to handle the following scenario: + ** + ** BEGIN; + ** + ** SAVEPOINT one; + ** + ** ROLLBACK TO one; + ** + ** If page X were not written to the sub-journal here, it would not + ** be possible to restore its contents when the "ROLLBACK TO one" + ** statement were is processed. + ** + ** subjournalPage() may need to allocate space to store pPg->pgno into + ** one or more savepoint bitvecs. This is the reason this function + ** may return SQLITE_NOMEM. + */ + if( pPg->flags&PGHDR_DIRTY + && subjRequiresPage(pPg) + && SQLITE_OK!=(rc = subjournalPage(pPg)) + ){ + return rc; + } + + PAGERTRACE(("MOVE %d page %d (needSync=%d) moves to %d\n", + PAGERID(pPager), pPg->pgno, (pPg->flags&PGHDR_NEED_SYNC)?1:0, pgno)); + IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno)) + + /* If the journal needs to be sync()ed before page pPg->pgno can + ** be written to, store pPg->pgno in local variable needSyncPgno. + ** + ** If the isCommit flag is set, there is no need to remember that + ** the journal needs to be sync()ed before database page pPg->pgno + ** can be written to. The caller has already promised not to write to it. + */ + if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){ + needSyncPgno = pPg->pgno; + assert( pPager->journalMode==PAGER_JOURNALMODE_OFF || + pageInJournal(pPager, pPg) || pPg->pgno>pPager->dbOrigSize ); + assert( pPg->flags&PGHDR_DIRTY ); + } + + /* If the cache contains a page with page-number pgno, remove it + ** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for + ** page pgno before the 'move' operation, it needs to be retained + ** for the page moved there. + */ + pPg->flags &= ~PGHDR_NEED_SYNC; + pPgOld = sqlite3PagerLookup(pPager, pgno); + assert( !pPgOld || pPgOld->nRef==1 ); + if( pPgOld ){ + pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC); + if( MEMDB ){ + /* Do not discard pages from an in-memory database since we might + ** need to rollback later. Just move the page out of the way. */ + sqlite3PcacheMove(pPgOld, pPager->dbSize+1); + }else{ + sqlite3PcacheDrop(pPgOld); + } + } + + origPgno = pPg->pgno; + sqlite3PcacheMove(pPg, pgno); + sqlite3PcacheMakeDirty(pPg); + + /* For an in-memory database, make sure the original page continues + ** to exist, in case the transaction needs to roll back. Use pPgOld + ** as the original page since it has already been allocated. + */ + if( MEMDB ){ + assert( pPgOld ); + sqlite3PcacheMove(pPgOld, origPgno); + sqlite3PagerUnrefNotNull(pPgOld); + } + + if( needSyncPgno ){ + /* If needSyncPgno is non-zero, then the journal file needs to be + ** sync()ed before any data is written to database file page needSyncPgno. + ** Currently, no such page exists in the page-cache and the + ** "is journaled" bitvec flag has been set. This needs to be remedied by + ** loading the page into the pager-cache and setting the PGHDR_NEED_SYNC + ** flag. + ** + ** If the attempt to load the page into the page-cache fails, (due + ** to a malloc() or IO failure), clear the bit in the pInJournal[] + ** array. Otherwise, if the page is loaded and written again in + ** this transaction, it may be written to the database file before + ** it is synced into the journal file. This way, it may end up in + ** the journal file twice, but that is not a problem. + */ + PgHdr *pPgHdr; + rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr); + if( rc!=SQLITE_OK ){ + if( needSyncPgno<=pPager->dbOrigSize ){ + assert( pPager->pTmpSpace!=0 ); + sqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace); + } + return rc; + } + pPgHdr->flags |= PGHDR_NEED_SYNC; + sqlite3PcacheMakeDirty(pPgHdr); + sqlite3PagerUnrefNotNull(pPgHdr); + } + + return SQLITE_OK; +} +#endif + +/* +** The page handle passed as the first argument refers to a dirty page +** with a page number other than iNew. This function changes the page's +** page number to iNew and sets the value of the PgHdr.flags field to +** the value passed as the third parameter. +*/ +SQLITE_PRIVATE void sqlite3PagerRekey(DbPage *pPg, Pgno iNew, u16 flags){ + assert( pPg->pgno!=iNew ); + pPg->flags = flags; + sqlite3PcacheMove(pPg, iNew); +} + +/* +** Return a pointer to the data for the specified page. +*/ +SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *pPg){ + assert( pPg->nRef>0 || pPg->pPager->memDb ); + return pPg->pData; +} + +/* +** Return a pointer to the Pager.nExtra bytes of "extra" space +** allocated along with the specified page. +*/ +SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *pPg){ + return pPg->pExtra; +} + +/* +** Get/set the locking-mode for this pager. Parameter eMode must be one +** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or +** PAGER_LOCKINGMODE_EXCLUSIVE. If the parameter is not _QUERY, then +** the locking-mode is set to the value specified. +** +** The returned value is either PAGER_LOCKINGMODE_NORMAL or +** PAGER_LOCKINGMODE_EXCLUSIVE, indicating the current (possibly updated) +** locking-mode. +*/ +SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *pPager, int eMode){ + assert( eMode==PAGER_LOCKINGMODE_QUERY + || eMode==PAGER_LOCKINGMODE_NORMAL + || eMode==PAGER_LOCKINGMODE_EXCLUSIVE ); + assert( PAGER_LOCKINGMODE_QUERY<0 ); + assert( PAGER_LOCKINGMODE_NORMAL>=0 && PAGER_LOCKINGMODE_EXCLUSIVE>=0 ); + assert( pPager->exclusiveMode || 0==sqlite3WalHeapMemory(pPager->pWal) ); + if( eMode>=0 && !pPager->tempFile && !sqlite3WalHeapMemory(pPager->pWal) ){ + pPager->exclusiveMode = (u8)eMode; + } + return (int)pPager->exclusiveMode; +} + +/* +** Set the journal-mode for this pager. Parameter eMode must be one of: +** +** PAGER_JOURNALMODE_DELETE +** PAGER_JOURNALMODE_TRUNCATE +** PAGER_JOURNALMODE_PERSIST +** PAGER_JOURNALMODE_OFF +** PAGER_JOURNALMODE_MEMORY +** PAGER_JOURNALMODE_WAL +** +** The journalmode is set to the value specified if the change is allowed. +** The change may be disallowed for the following reasons: +** +** * An in-memory database can only have its journal_mode set to _OFF +** or _MEMORY. +** +** * Temporary databases cannot have _WAL journalmode. +** +** The returned indicate the current (possibly updated) journal-mode. +*/ +SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){ + u8 eOld = pPager->journalMode; /* Prior journalmode */ + +#ifdef SQLITE_DEBUG + /* The print_pager_state() routine is intended to be used by the debugger + ** only. We invoke it once here to suppress a compiler warning. */ + print_pager_state(pPager); +#endif + + + /* The eMode parameter is always valid */ + assert( eMode==PAGER_JOURNALMODE_DELETE + || eMode==PAGER_JOURNALMODE_TRUNCATE + || eMode==PAGER_JOURNALMODE_PERSIST + || eMode==PAGER_JOURNALMODE_OFF + || eMode==PAGER_JOURNALMODE_WAL + || eMode==PAGER_JOURNALMODE_MEMORY ); + + /* This routine is only called from the OP_JournalMode opcode, and + ** the logic there will never allow a temporary file to be changed + ** to WAL mode. + */ + assert( pPager->tempFile==0 || eMode!=PAGER_JOURNALMODE_WAL ); + + /* Do allow the journalmode of an in-memory database to be set to + ** anything other than MEMORY or OFF + */ + if( MEMDB ){ + assert( eOld==PAGER_JOURNALMODE_MEMORY || eOld==PAGER_JOURNALMODE_OFF ); + if( eMode!=PAGER_JOURNALMODE_MEMORY && eMode!=PAGER_JOURNALMODE_OFF ){ + eMode = eOld; + } + } + + if( eMode!=eOld ){ + + /* Change the journal mode. */ + assert( pPager->eState!=PAGER_ERROR ); + pPager->journalMode = (u8)eMode; + + /* When transistioning from TRUNCATE or PERSIST to any other journal + ** mode except WAL, unless the pager is in locking_mode=exclusive mode, + ** delete the journal file. + */ + assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 ); + assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 ); + assert( (PAGER_JOURNALMODE_DELETE & 5)==0 ); + assert( (PAGER_JOURNALMODE_MEMORY & 5)==4 ); + assert( (PAGER_JOURNALMODE_OFF & 5)==0 ); + assert( (PAGER_JOURNALMODE_WAL & 5)==5 ); + + assert( isOpen(pPager->fd) || pPager->exclusiveMode ); + if( !pPager->exclusiveMode && (eOld & 5)==1 && (eMode & 1)==0 ){ + + /* In this case we would like to delete the journal file. If it is + ** not possible, then that is not a problem. Deleting the journal file + ** here is an optimization only. + ** + ** Before deleting the journal file, obtain a RESERVED lock on the + ** database file. This ensures that the journal file is not deleted + ** while it is in use by some other client. + */ + sqlite3OsClose(pPager->jfd); + if( pPager->eLock>=RESERVED_LOCK ){ + sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); + }else{ + int rc = SQLITE_OK; + int state = pPager->eState; + assert( state==PAGER_OPEN || state==PAGER_READER ); + if( state==PAGER_OPEN ){ + rc = sqlite3PagerSharedLock(pPager); + } + if( pPager->eState==PAGER_READER ){ + assert( rc==SQLITE_OK ); + rc = pagerLockDb(pPager, RESERVED_LOCK); + } + if( rc==SQLITE_OK ){ + sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); + } + if( rc==SQLITE_OK && state==PAGER_READER ){ + pagerUnlockDb(pPager, SHARED_LOCK); + }else if( state==PAGER_OPEN ){ + pager_unlock(pPager); + } + assert( state==pPager->eState ); + } + }else if( eMode==PAGER_JOURNALMODE_OFF ){ + sqlite3OsClose(pPager->jfd); + } + } + + /* Return the new journal mode */ + return (int)pPager->journalMode; +} + +/* +** Return the current journal mode. +*/ +SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager *pPager){ + return (int)pPager->journalMode; +} + +/* +** Return TRUE if the pager is in a state where it is OK to change the +** journalmode. Journalmode changes can only happen when the database +** is unmodified. +*/ +SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager *pPager){ + assert( assert_pager_state(pPager) ); + if( pPager->eState>=PAGER_WRITER_CACHEMOD ) return 0; + if( NEVER(isOpen(pPager->jfd) && pPager->journalOff>0) ) return 0; + return 1; +} + +/* +** Get/set the size-limit used for persistent journal files. +** +** Setting the size limit to -1 means no limit is enforced. +** An attempt to set a limit smaller than -1 is a no-op. +*/ +SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){ + if( iLimit>=-1 ){ + pPager->journalSizeLimit = iLimit; + sqlite3WalLimit(pPager->pWal, iLimit); + } + return pPager->journalSizeLimit; +} + +/* +** Return a pointer to the pPager->pBackup variable. The backup module +** in backup.c maintains the content of this variable. This module +** uses it opaquely as an argument to sqlite3BackupRestart() and +** sqlite3BackupUpdate() only. +*/ +SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){ + return &pPager->pBackup; +} + +#ifndef SQLITE_OMIT_VACUUM +/* +** Unless this is an in-memory or temporary database, clear the pager cache. +*/ +SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *pPager){ + if( !MEMDB && pPager->tempFile==0 ) pager_reset(pPager); +} +#endif + +#ifndef SQLITE_OMIT_WAL +/* +** This function is called when the user invokes "PRAGMA wal_checkpoint", +** "PRAGMA wal_blocking_checkpoint" or calls the sqlite3_wal_checkpoint() +** or wal_blocking_checkpoint() API functions. +** +** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. +*/ +SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){ + int rc = SQLITE_OK; + if( pPager->pWal ){ + rc = sqlite3WalCheckpoint(pPager->pWal, eMode, + (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler), + pPager->pBusyHandlerArg, + pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, + pnLog, pnCkpt + ); + } + return rc; +} + +SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){ + return sqlite3WalCallback(pPager->pWal); +} + +/* +** Return true if the underlying VFS for the given pager supports the +** primitives necessary for write-ahead logging. +*/ +SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager){ + const sqlite3_io_methods *pMethods = pPager->fd->pMethods; + return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap); +} + +/* +** Attempt to take an exclusive lock on the database file. If a PENDING lock +** is obtained instead, immediately release it. +*/ +static int pagerExclusiveLock(Pager *pPager){ + int rc; /* Return code */ + + assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK ); + rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); + if( rc!=SQLITE_OK ){ + /* If the attempt to grab the exclusive lock failed, release the + ** pending lock that may have been obtained instead. */ + pagerUnlockDb(pPager, SHARED_LOCK); + } + + return rc; +} + +/* +** Call sqlite3WalOpen() to open the WAL handle. If the pager is in +** exclusive-locking mode when this function is called, take an EXCLUSIVE +** lock on the database file and use heap-memory to store the wal-index +** in. Otherwise, use the normal shared-memory. +*/ +static int pagerOpenWal(Pager *pPager){ + int rc = SQLITE_OK; + + assert( pPager->pWal==0 && pPager->tempFile==0 ); + assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK ); + + /* If the pager is already in exclusive-mode, the WAL module will use + ** heap-memory for the wal-index instead of the VFS shared-memory + ** implementation. Take the exclusive lock now, before opening the WAL + ** file, to make sure this is safe. + */ + if( pPager->exclusiveMode ){ + rc = pagerExclusiveLock(pPager); + } + + /* Open the connection to the log file. If this operation fails, + ** (e.g. due to malloc() failure), return an error code. + */ + if( rc==SQLITE_OK ){ + rc = sqlite3WalOpen(pPager->pVfs, + pPager->fd, pPager->zWal, pPager->exclusiveMode, + pPager->journalSizeLimit, &pPager->pWal + ); + } + pagerFixMaplimit(pPager); + + return rc; +} + + +/* +** The caller must be holding a SHARED lock on the database file to call +** this function. +** +** If the pager passed as the first argument is open on a real database +** file (not a temp file or an in-memory database), and the WAL file +** is not already open, make an attempt to open it now. If successful, +** return SQLITE_OK. If an error occurs or the VFS used by the pager does +** not support the xShmXXX() methods, return an error code. *pbOpen is +** not modified in either case. +** +** If the pager is open on a temp-file (or in-memory database), or if +** the WAL file is already open, set *pbOpen to 1 and return SQLITE_OK +** without doing anything. +*/ +SQLITE_PRIVATE int sqlite3PagerOpenWal( + Pager *pPager, /* Pager object */ + int *pbOpen /* OUT: Set to true if call is a no-op */ +){ + int rc = SQLITE_OK; /* Return code */ + + assert( assert_pager_state(pPager) ); + assert( pPager->eState==PAGER_OPEN || pbOpen ); + assert( pPager->eState==PAGER_READER || !pbOpen ); + assert( pbOpen==0 || *pbOpen==0 ); + assert( pbOpen!=0 || (!pPager->tempFile && !pPager->pWal) ); + + if( !pPager->tempFile && !pPager->pWal ){ + if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN; + + /* Close any rollback journal previously open */ + sqlite3OsClose(pPager->jfd); + + rc = pagerOpenWal(pPager); + if( rc==SQLITE_OK ){ + pPager->journalMode = PAGER_JOURNALMODE_WAL; + pPager->eState = PAGER_OPEN; + } + }else{ + *pbOpen = 1; + } + + return rc; +} + +/* +** This function is called to close the connection to the log file prior +** to switching from WAL to rollback mode. +** +** Before closing the log file, this function attempts to take an +** EXCLUSIVE lock on the database file. If this cannot be obtained, an +** error (SQLITE_BUSY) is returned and the log connection is not closed. +** If successful, the EXCLUSIVE lock is not released before returning. +*/ +SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager){ + int rc = SQLITE_OK; + + assert( pPager->journalMode==PAGER_JOURNALMODE_WAL ); + + /* If the log file is not already open, but does exist in the file-system, + ** it may need to be checkpointed before the connection can switch to + ** rollback mode. Open it now so this can happen. + */ + if( !pPager->pWal ){ + int logexists = 0; + rc = pagerLockDb(pPager, SHARED_LOCK); + if( rc==SQLITE_OK ){ + rc = sqlite3OsAccess( + pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &logexists + ); + } + if( rc==SQLITE_OK && logexists ){ + rc = pagerOpenWal(pPager); + } + } + + /* Checkpoint and close the log. Because an EXCLUSIVE lock is held on + ** the database file, the log and log-summary files will be deleted. + */ + if( rc==SQLITE_OK && pPager->pWal ){ + rc = pagerExclusiveLock(pPager); + if( rc==SQLITE_OK ){ + rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, + pPager->pageSize, (u8*)pPager->pTmpSpace); + pPager->pWal = 0; + pagerFixMaplimit(pPager); + } + } + return rc; +} + +#endif /* !SQLITE_OMIT_WAL */ + +#ifdef SQLITE_ENABLE_ZIPVFS +/* +** A read-lock must be held on the pager when this function is called. If +** the pager is in WAL mode and the WAL file currently contains one or more +** frames, return the size in bytes of the page images stored within the +** WAL frames. Otherwise, if this is not a WAL database or the WAL file +** is empty, return 0. +*/ +SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){ + assert( pPager->eState>=PAGER_READER ); + return sqlite3WalFramesize(pPager->pWal); +} +#endif + + +#endif /* SQLITE_OMIT_DISKIO */ + +/************** End of pager.c ***********************************************/ +/************** Begin file wal.c *********************************************/ +/* +** 2010 February 1 +** +** 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 a write-ahead log (WAL) used in +** "journal_mode=WAL" mode. +** +** WRITE-AHEAD LOG (WAL) FILE FORMAT +** +** A WAL file consists of a header followed by zero or more "frames". +** Each frame records the revised content of a single page from the +** database file. All changes to the database are recorded by writing +** frames into the WAL. Transactions commit when a frame is written that +** contains a commit marker. A single WAL can and usually does record +** multiple transactions. Periodically, the content of the WAL is +** transferred back into the database file in an operation called a +** "checkpoint". +** +** A single WAL file can be used multiple times. In other words, the +** WAL can fill up with frames and then be checkpointed and then new +** frames can overwrite the old ones. A WAL always grows from beginning +** toward the end. Checksums and counters attached to each frame are +** used to determine which frames within the WAL are valid and which +** are leftovers from prior checkpoints. +** +** The WAL header is 32 bytes in size and consists of the following eight +** big-endian 32-bit unsigned integer values: +** +** 0: Magic number. 0x377f0682 or 0x377f0683 +** 4: File format version. Currently 3007000 +** 8: Database page size. Example: 1024 +** 12: Checkpoint sequence number +** 16: Salt-1, random integer incremented with each checkpoint +** 20: Salt-2, a different random integer changing with each ckpt +** 24: Checksum-1 (first part of checksum for first 24 bytes of header). +** 28: Checksum-2 (second part of checksum for first 24 bytes of header). +** +** Immediately following the wal-header are zero or more frames. Each +** frame consists of a 24-byte frame-header followed by a bytes +** of page data. The frame-header is six big-endian 32-bit unsigned +** integer values, as follows: +** +** 0: Page number. +** 4: For commit records, the size of the database image in pages +** after the commit. For all other records, zero. +** 8: Salt-1 (copied from the header) +** 12: Salt-2 (copied from the header) +** 16: Checksum-1. +** 20: Checksum-2. +** +** A frame is considered valid if and only if the following conditions are +** true: +** +** (1) The salt-1 and salt-2 values in the frame-header match +** salt values in the wal-header +** +** (2) The checksum values in the final 8 bytes of the frame-header +** exactly match the checksum computed consecutively on the +** WAL header and the first 8 bytes and the content of all frames +** up to and including the current frame. +** +** The checksum is computed using 32-bit big-endian integers if the +** magic number in the first 4 bytes of the WAL is 0x377f0683 and it +** is computed using little-endian if the magic number is 0x377f0682. +** The checksum values are always stored in the frame header in a +** big-endian format regardless of which byte order is used to compute +** the checksum. The checksum is computed by interpreting the input as +** an even number of unsigned 32-bit integers: x[0] through x[N]. The +** algorithm used for the checksum is as follows: +** +** for i from 0 to n-1 step 2: +** s0 += x[i] + s1; +** s1 += x[i+1] + s0; +** endfor +** +** Note that s0 and s1 are both weighted checksums using fibonacci weights +** in reverse order (the largest fibonacci weight occurs on the first element +** of the sequence being summed.) The s1 value spans all 32-bit +** terms of the sequence whereas s0 omits the final term. +** +** On a checkpoint, the WAL is first VFS.xSync-ed, then valid content of the +** WAL is transferred into the database, then the database is VFS.xSync-ed. +** The VFS.xSync operations serve as write barriers - all writes launched +** before the xSync must complete before any write that launches after the +** xSync begins. +** +** After each checkpoint, the salt-1 value is incremented and the salt-2 +** value is randomized. This prevents old and new frames in the WAL from +** being considered valid at the same time and being checkpointing together +** following a crash. +** +** READER ALGORITHM +** +** To read a page from the database (call it page number P), a reader +** first checks the WAL to see if it contains page P. If so, then the +** last valid instance of page P that is a followed by a commit frame +** or is a commit frame itself becomes the value read. If the WAL +** contains no copies of page P that are valid and which are a commit +** frame or are followed by a commit frame, then page P is read from +** the database file. +** +** To start a read transaction, the reader records the index of the last +** valid frame in the WAL. The reader uses this recorded "mxFrame" value +** for all subsequent read operations. New transactions can be appended +** to the WAL, but as long as the reader uses its original mxFrame value +** and ignores the newly appended content, it will see a consistent snapshot +** of the database from a single point in time. This technique allows +** multiple concurrent readers to view different versions of the database +** content simultaneously. +** +** The reader algorithm in the previous paragraphs works correctly, but +** because frames for page P can appear anywhere within the WAL, the +** reader has to scan the entire WAL looking for page P frames. If the +** WAL is large (multiple megabytes is typical) that scan can be slow, +** and read performance suffers. To overcome this problem, a separate +** data structure called the wal-index is maintained to expedite the +** search for frames of a particular page. +** +** WAL-INDEX FORMAT +** +** Conceptually, the wal-index is shared memory, though VFS implementations +** might choose to implement the wal-index using a mmapped file. Because +** the wal-index is shared memory, SQLite does not support journal_mode=WAL +** on a network filesystem. All users of the database must be able to +** share memory. +** +** The wal-index is transient. After a crash, the wal-index can (and should +** be) reconstructed from the original WAL file. In fact, the VFS is required +** to either truncate or zero the header of the wal-index when the last +** connection to it closes. Because the wal-index is transient, it can +** use an architecture-specific format; it does not have to be cross-platform. +** Hence, unlike the database and WAL file formats which store all values +** as big endian, the wal-index can store multi-byte values in the native +** byte order of the host computer. +** +** The purpose of the wal-index is to answer this question quickly: Given +** a page number P and a maximum frame index M, return the index of the +** last frame in the wal before frame M for page P in the WAL, or return +** NULL if there are no frames for page P in the WAL prior to M. +** +** The wal-index consists of a header region, followed by an one or +** more index blocks. +** +** The wal-index header contains the total number of frames within the WAL +** in the mxFrame field. +** +** Each index block except for the first contains information on +** HASHTABLE_NPAGE frames. The first index block contains information on +** HASHTABLE_NPAGE_ONE frames. The values of HASHTABLE_NPAGE_ONE and +** HASHTABLE_NPAGE are selected so that together the wal-index header and +** first index block are the same size as all other index blocks in the +** wal-index. +** +** Each index block contains two sections, a page-mapping that contains the +** database page number associated with each wal frame, and a hash-table +** that allows readers to query an index block for a specific page number. +** The page-mapping is an array of HASHTABLE_NPAGE (or HASHTABLE_NPAGE_ONE +** for the first index block) 32-bit page numbers. The first entry in the +** first index-block contains the database page number corresponding to the +** first frame in the WAL file. The first entry in the second index block +** in the WAL file corresponds to the (HASHTABLE_NPAGE_ONE+1)th frame in +** the log, and so on. +** +** The last index block in a wal-index usually contains less than the full +** complement of HASHTABLE_NPAGE (or HASHTABLE_NPAGE_ONE) page-numbers, +** depending on the contents of the WAL file. This does not change the +** allocated size of the page-mapping array - the page-mapping array merely +** contains unused entries. +** +** Even without using the hash table, the last frame for page P +** can be found by scanning the page-mapping sections of each index block +** starting with the last index block and moving toward the first, and +** within each index block, starting at the end and moving toward the +** beginning. The first entry that equals P corresponds to the frame +** holding the content for that page. +** +** The hash table consists of HASHTABLE_NSLOT 16-bit unsigned integers. +** HASHTABLE_NSLOT = 2*HASHTABLE_NPAGE, and there is one entry in the +** hash table for each page number in the mapping section, so the hash +** table is never more than half full. The expected number of collisions +** prior to finding a match is 1. Each entry of the hash table is an +** 1-based index of an entry in the mapping section of the same +** index block. Let K be the 1-based index of the largest entry in +** the mapping section. (For index blocks other than the last, K will +** always be exactly HASHTABLE_NPAGE (4096) and for the last index block +** K will be (mxFrame%HASHTABLE_NPAGE).) Unused slots of the hash table +** contain a value of 0. +** +** To look for page P in the hash table, first compute a hash iKey on +** P as follows: +** +** iKey = (P * 383) % HASHTABLE_NSLOT +** +** Then start scanning entries of the hash table, starting with iKey +** (wrapping around to the beginning when the end of the hash table is +** reached) until an unused hash slot is found. Let the first unused slot +** be at index iUnused. (iUnused might be less than iKey if there was +** wrap-around.) Because the hash table is never more than half full, +** the search is guaranteed to eventually hit an unused entry. Let +** iMax be the value between iKey and iUnused, closest to iUnused, +** where aHash[iMax]==P. If there is no iMax entry (if there exists +** no hash slot such that aHash[i]==p) then page P is not in the +** current index block. Otherwise the iMax-th mapping entry of the +** current index block corresponds to the last entry that references +** page P. +** +** A hash search begins with the last index block and moves toward the +** first index block, looking for entries corresponding to page P. On +** average, only two or three slots in each index block need to be +** examined in order to either find the last entry for page P, or to +** establish that no such entry exists in the block. Each index block +** holds over 4000 entries. So two or three index blocks are sufficient +** to cover a typical 10 megabyte WAL file, assuming 1K pages. 8 or 10 +** comparisons (on average) suffice to either locate a frame in the +** WAL or to establish that the frame does not exist in the WAL. This +** is much faster than scanning the entire 10MB WAL. +** +** Note that entries are added in order of increasing K. Hence, one +** reader might be using some value K0 and a second reader that started +** at a later time (after additional transactions were added to the WAL +** and to the wal-index) might be using a different value K1, where K1>K0. +** Both readers can use the same hash table and mapping section to get +** the correct result. There may be entries in the hash table with +** K>K0 but to the first reader, those entries will appear to be unused +** slots in the hash table and so the first reader will get an answer as +** if no values greater than K0 had ever been inserted into the hash table +** in the first place - which is what reader one wants. Meanwhile, the +** second reader using K1 will see additional values that were inserted +** later, which is exactly what reader two wants. +** +** When a rollback occurs, the value of K is decreased. Hash table entries +** that correspond to frames greater than the new K value are removed +** from the hash table at this point. +*/ +#ifndef SQLITE_OMIT_WAL + + +/* +** Trace output macros +*/ +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) +SQLITE_PRIVATE int sqlite3WalTrace = 0; +# define WALTRACE(X) if(sqlite3WalTrace) sqlite3DebugPrintf X +#else +# define WALTRACE(X) +#endif + +/* +** The maximum (and only) versions of the wal and wal-index formats +** that may be interpreted by this version of SQLite. +** +** If a client begins recovering a WAL file and finds that (a) the checksum +** values in the wal-header are correct and (b) the version field is not +** WAL_MAX_VERSION, recovery fails and SQLite returns SQLITE_CANTOPEN. +** +** Similarly, if a client successfully reads a wal-index header (i.e. the +** checksum test is successful) and finds that the version field is not +** WALINDEX_MAX_VERSION, then no read-transaction is opened and SQLite +** returns SQLITE_CANTOPEN. +*/ +#define WAL_MAX_VERSION 3007000 +#define WALINDEX_MAX_VERSION 3007000 + +/* +** Indices of various locking bytes. WAL_NREADER is the number +** of available reader locks and should be at least 3. +*/ +#define WAL_WRITE_LOCK 0 +#define WAL_ALL_BUT_WRITE 1 +#define WAL_CKPT_LOCK 1 +#define WAL_RECOVER_LOCK 2 +#define WAL_READ_LOCK(I) (3+(I)) +#define WAL_NREADER (SQLITE_SHM_NLOCK-3) + + +/* Object declarations */ +typedef struct WalIndexHdr WalIndexHdr; +typedef struct WalIterator WalIterator; +typedef struct WalCkptInfo WalCkptInfo; + + +/* +** The following object holds a copy of the wal-index header content. +** +** The actual header in the wal-index consists of two copies of this +** object. +** +** The szPage value can be any power of 2 between 512 and 32768, inclusive. +** Or it can be 1 to represent a 65536-byte page. The latter case was +** added in 3.7.1 when support for 64K pages was added. +*/ +struct WalIndexHdr { + u32 iVersion; /* Wal-index version */ + u32 unused; /* Unused (padding) field */ + u32 iChange; /* Counter incremented each transaction */ + u8 isInit; /* 1 when initialized */ + u8 bigEndCksum; /* True if checksums in WAL are big-endian */ + u16 szPage; /* Database page size in bytes. 1==64K */ + u32 mxFrame; /* Index of last valid frame in the WAL */ + u32 nPage; /* Size of database in pages */ + u32 aFrameCksum[2]; /* Checksum of last frame in log */ + u32 aSalt[2]; /* Two salt values copied from WAL header */ + u32 aCksum[2]; /* Checksum over all prior fields */ +}; + +/* +** A copy of the following object occurs in the wal-index immediately +** following the second copy of the WalIndexHdr. This object stores +** information used by checkpoint. +** +** nBackfill is the number of frames in the WAL that have been written +** back into the database. (We call the act of moving content from WAL to +** database "backfilling".) The nBackfill number is never greater than +** WalIndexHdr.mxFrame. nBackfill can only be increased by threads +** holding the WAL_CKPT_LOCK lock (which includes a recovery thread). +** However, a WAL_WRITE_LOCK thread can move the value of nBackfill from +** mxFrame back to zero when the WAL is reset. +** +** There is one entry in aReadMark[] for each reader lock. If a reader +** holds read-lock K, then the value in aReadMark[K] is no greater than +** the mxFrame for that reader. The value READMARK_NOT_USED (0xffffffff) +** for any aReadMark[] means that entry is unused. aReadMark[0] is +** a special case; its value is never used and it exists as a place-holder +** to avoid having to offset aReadMark[] indexs by one. Readers holding +** WAL_READ_LOCK(0) always ignore the entire WAL and read all content +** directly from the database. +** +** The value of aReadMark[K] may only be changed by a thread that +** is holding an exclusive lock on WAL_READ_LOCK(K). Thus, the value of +** aReadMark[K] cannot changed while there is a reader is using that mark +** since the reader will be holding a shared lock on WAL_READ_LOCK(K). +** +** The checkpointer may only transfer frames from WAL to database where +** the frame numbers are less than or equal to every aReadMark[] that is +** in use (that is, every aReadMark[j] for which there is a corresponding +** WAL_READ_LOCK(j)). New readers (usually) pick the aReadMark[] with the +** largest value and will increase an unused aReadMark[] to mxFrame if there +** is not already an aReadMark[] equal to mxFrame. The exception to the +** previous sentence is when nBackfill equals mxFrame (meaning that everything +** in the WAL has been backfilled into the database) then new readers +** will choose aReadMark[0] which has value 0 and hence such reader will +** get all their all content directly from the database file and ignore +** the WAL. +** +** Writers normally append new frames to the end of the WAL. However, +** if nBackfill equals mxFrame (meaning that all WAL content has been +** written back into the database) and if no readers are using the WAL +** (in other words, if there are no WAL_READ_LOCK(i) where i>0) then +** the writer will first "reset" the WAL back to the beginning and start +** writing new content beginning at frame 1. +** +** We assume that 32-bit loads are atomic and so no locks are needed in +** order to read from any aReadMark[] entries. +*/ +struct WalCkptInfo { + u32 nBackfill; /* Number of WAL frames backfilled into DB */ + u32 aReadMark[WAL_NREADER]; /* Reader marks */ +}; +#define READMARK_NOT_USED 0xffffffff + + +/* A block of WALINDEX_LOCK_RESERVED bytes beginning at +** WALINDEX_LOCK_OFFSET is reserved for locks. Since some systems +** only support mandatory file-locks, we do not read or write data +** from the region of the file on which locks are applied. +*/ +#define WALINDEX_LOCK_OFFSET (sizeof(WalIndexHdr)*2 + sizeof(WalCkptInfo)) +#define WALINDEX_LOCK_RESERVED 16 +#define WALINDEX_HDR_SIZE (WALINDEX_LOCK_OFFSET+WALINDEX_LOCK_RESERVED) + +/* Size of header before each frame in wal */ +#define WAL_FRAME_HDRSIZE 24 + +/* Size of write ahead log header, including checksum. */ +/* #define WAL_HDRSIZE 24 */ +#define WAL_HDRSIZE 32 + +/* WAL magic value. Either this value, or the same value with the least +** significant bit also set (WAL_MAGIC | 0x00000001) is stored in 32-bit +** big-endian format in the first 4 bytes of a WAL file. +** +** If the LSB is set, then the checksums for each frame within the WAL +** file are calculated by treating all data as an array of 32-bit +** big-endian words. Otherwise, they are calculated by interpreting +** all data as 32-bit little-endian words. +*/ +#define WAL_MAGIC 0x377f0682 + +/* +** Return the offset of frame iFrame in the write-ahead log file, +** assuming a database page size of szPage bytes. The offset returned +** is to the start of the write-ahead log frame-header. +*/ +#define walFrameOffset(iFrame, szPage) ( \ + WAL_HDRSIZE + ((iFrame)-1)*(i64)((szPage)+WAL_FRAME_HDRSIZE) \ +) + +/* +** An open write-ahead log file is represented by an instance of the +** following object. +*/ +struct Wal { + sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */ + sqlite3_file *pDbFd; /* File handle for the database file */ + sqlite3_file *pWalFd; /* File handle for WAL file */ + u32 iCallback; /* Value to pass to log callback (or 0) */ + i64 mxWalSize; /* Truncate WAL to this size upon reset */ + int nWiData; /* Size of array apWiData */ + int szFirstBlock; /* Size of first block written to WAL file */ + volatile u32 **apWiData; /* Pointer to wal-index content in memory */ + u32 szPage; /* Database page size */ + i16 readLock; /* Which read lock is being held. -1 for none */ + u8 syncFlags; /* Flags to use to sync header writes */ + u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */ + u8 writeLock; /* True if in a write transaction */ + u8 ckptLock; /* True if holding a checkpoint lock */ + u8 readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */ + u8 truncateOnCommit; /* True to truncate WAL file on commit */ + u8 syncHeader; /* Fsync the WAL header if true */ + u8 padToSectorBoundary; /* Pad transactions out to the next sector */ + WalIndexHdr hdr; /* Wal-index header for current transaction */ + const char *zWalName; /* Name of WAL file */ + u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ +#ifdef SQLITE_DEBUG + u8 lockError; /* True if a locking error has occurred */ +#endif +}; + +/* +** Candidate values for Wal.exclusiveMode. +*/ +#define WAL_NORMAL_MODE 0 +#define WAL_EXCLUSIVE_MODE 1 +#define WAL_HEAPMEMORY_MODE 2 + +/* +** Possible values for WAL.readOnly +*/ +#define WAL_RDWR 0 /* Normal read/write connection */ +#define WAL_RDONLY 1 /* The WAL file is readonly */ +#define WAL_SHM_RDONLY 2 /* The SHM file is readonly */ + +/* +** Each page of the wal-index mapping contains a hash-table made up of +** an array of HASHTABLE_NSLOT elements of the following type. +*/ +typedef u16 ht_slot; + +/* +** This structure is used to implement an iterator that loops through +** all frames in the WAL in database page order. Where two or more frames +** correspond to the same database page, the iterator visits only the +** frame most recently written to the WAL (in other words, the frame with +** the largest index). +** +** The internals of this structure are only accessed by: +** +** walIteratorInit() - Create a new iterator, +** walIteratorNext() - Step an iterator, +** walIteratorFree() - Free an iterator. +** +** This functionality is used by the checkpoint code (see walCheckpoint()). +*/ +struct WalIterator { + int iPrior; /* Last result returned from the iterator */ + int nSegment; /* Number of entries in aSegment[] */ + struct WalSegment { + int iNext; /* Next slot in aIndex[] not yet returned */ + ht_slot *aIndex; /* i0, i1, i2... such that aPgno[iN] ascend */ + u32 *aPgno; /* Array of page numbers. */ + int nEntry; /* Nr. of entries in aPgno[] and aIndex[] */ + int iZero; /* Frame number associated with aPgno[0] */ + } aSegment[1]; /* One for every 32KB page in the wal-index */ +}; + +/* +** Define the parameters of the hash tables in the wal-index file. There +** is a hash-table following every HASHTABLE_NPAGE page numbers in the +** wal-index. +** +** Changing any of these constants will alter the wal-index format and +** create incompatibilities. +*/ +#define HASHTABLE_NPAGE 4096 /* Must be power of 2 */ +#define HASHTABLE_HASH_1 383 /* Should be prime */ +#define HASHTABLE_NSLOT (HASHTABLE_NPAGE*2) /* Must be a power of 2 */ + +/* +** The block of page numbers associated with the first hash-table in a +** wal-index is smaller than usual. This is so that there is a complete +** hash-table on each aligned 32KB page of the wal-index. +*/ +#define HASHTABLE_NPAGE_ONE (HASHTABLE_NPAGE - (WALINDEX_HDR_SIZE/sizeof(u32))) + +/* The wal-index is divided into pages of WALINDEX_PGSZ bytes each. */ +#define WALINDEX_PGSZ ( \ + sizeof(ht_slot)*HASHTABLE_NSLOT + HASHTABLE_NPAGE*sizeof(u32) \ +) + +/* +** Obtain a pointer to the iPage'th page of the wal-index. The wal-index +** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are +** numbered from zero. +** +** If this call is successful, *ppPage is set to point to the wal-index +** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs, +** then an SQLite error code is returned and *ppPage is set to 0. +*/ +static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){ + int rc = SQLITE_OK; + + /* Enlarge the pWal->apWiData[] array if required */ + if( pWal->nWiData<=iPage ){ + int nByte = sizeof(u32*)*(iPage+1); + volatile u32 **apNew; + apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte); + if( !apNew ){ + *ppPage = 0; + return SQLITE_NOMEM; + } + memset((void*)&apNew[pWal->nWiData], 0, + sizeof(u32*)*(iPage+1-pWal->nWiData)); + pWal->apWiData = apNew; + pWal->nWiData = iPage+1; + } + + /* Request a pointer to the required page from the VFS */ + if( pWal->apWiData[iPage]==0 ){ + if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){ + pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ); + if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM; + }else{ + rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, + pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] + ); + if( rc==SQLITE_READONLY ){ + pWal->readOnly |= WAL_SHM_RDONLY; + rc = SQLITE_OK; + } + } + } + + *ppPage = pWal->apWiData[iPage]; + assert( iPage==0 || *ppPage || rc!=SQLITE_OK ); + return rc; +} + +/* +** Return a pointer to the WalCkptInfo structure in the wal-index. +*/ +static volatile WalCkptInfo *walCkptInfo(Wal *pWal){ + assert( pWal->nWiData>0 && pWal->apWiData[0] ); + return (volatile WalCkptInfo*)&(pWal->apWiData[0][sizeof(WalIndexHdr)/2]); +} + +/* +** Return a pointer to the WalIndexHdr structure in the wal-index. +*/ +static volatile WalIndexHdr *walIndexHdr(Wal *pWal){ + assert( pWal->nWiData>0 && pWal->apWiData[0] ); + return (volatile WalIndexHdr*)pWal->apWiData[0]; +} + +/* +** The argument to this macro must be of type u32. On a little-endian +** architecture, it returns the u32 value that results from interpreting +** the 4 bytes as a big-endian value. On a big-endian architecture, it +** returns the value that would be produced by interpreting the 4 bytes +** of the input value as a little-endian integer. +*/ +#define BYTESWAP32(x) ( \ + (((x)&0x000000FF)<<24) + (((x)&0x0000FF00)<<8) \ + + (((x)&0x00FF0000)>>8) + (((x)&0xFF000000)>>24) \ +) + +/* +** Generate or extend an 8 byte checksum based on the data in +** array aByte[] and the initial values of aIn[0] and aIn[1] (or +** initial values of 0 and 0 if aIn==NULL). +** +** The checksum is written back into aOut[] before returning. +** +** nByte must be a positive multiple of 8. +*/ +static void walChecksumBytes( + int nativeCksum, /* True for native byte-order, false for non-native */ + u8 *a, /* Content to be checksummed */ + int nByte, /* Bytes of content in a[]. Must be a multiple of 8. */ + const u32 *aIn, /* Initial checksum value input */ + u32 *aOut /* OUT: Final checksum value output */ +){ + u32 s1, s2; + u32 *aData = (u32 *)a; + u32 *aEnd = (u32 *)&a[nByte]; + + if( aIn ){ + s1 = aIn[0]; + s2 = aIn[1]; + }else{ + s1 = s2 = 0; + } + + assert( nByte>=8 ); + assert( (nByte&0x00000007)==0 ); + + if( nativeCksum ){ + do { + s1 += *aData++ + s2; + s2 += *aData++ + s1; + }while( aDataexclusiveMode!=WAL_HEAPMEMORY_MODE ){ + sqlite3OsShmBarrier(pWal->pDbFd); + } +} + +/* +** Write the header information in pWal->hdr into the wal-index. +** +** The checksum on pWal->hdr is updated before it is written. +*/ +static void walIndexWriteHdr(Wal *pWal){ + volatile WalIndexHdr *aHdr = walIndexHdr(pWal); + const int nCksum = offsetof(WalIndexHdr, aCksum); + + assert( pWal->writeLock ); + pWal->hdr.isInit = 1; + pWal->hdr.iVersion = WALINDEX_MAX_VERSION; + walChecksumBytes(1, (u8*)&pWal->hdr, nCksum, 0, pWal->hdr.aCksum); + memcpy((void *)&aHdr[1], (void *)&pWal->hdr, sizeof(WalIndexHdr)); + walShmBarrier(pWal); + memcpy((void *)&aHdr[0], (void *)&pWal->hdr, sizeof(WalIndexHdr)); +} + +/* +** This function encodes a single frame header and writes it to a buffer +** supplied by the caller. A frame-header is made up of a series of +** 4-byte big-endian integers, as follows: +** +** 0: Page number. +** 4: For commit records, the size of the database image in pages +** after the commit. For all other records, zero. +** 8: Salt-1 (copied from the wal-header) +** 12: Salt-2 (copied from the wal-header) +** 16: Checksum-1. +** 20: Checksum-2. +*/ +static void walEncodeFrame( + Wal *pWal, /* The write-ahead log */ + u32 iPage, /* Database page number for frame */ + u32 nTruncate, /* New db size (or 0 for non-commit frames) */ + u8 *aData, /* Pointer to page data */ + u8 *aFrame /* OUT: Write encoded frame here */ +){ + int nativeCksum; /* True for native byte-order checksums */ + u32 *aCksum = pWal->hdr.aFrameCksum; + assert( WAL_FRAME_HDRSIZE==24 ); + sqlite3Put4byte(&aFrame[0], iPage); + sqlite3Put4byte(&aFrame[4], nTruncate); + memcpy(&aFrame[8], pWal->hdr.aSalt, 8); + + nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN); + walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum); + walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum); + + sqlite3Put4byte(&aFrame[16], aCksum[0]); + sqlite3Put4byte(&aFrame[20], aCksum[1]); +} + +/* +** Check to see if the frame with header in aFrame[] and content +** in aData[] is valid. If it is a valid frame, fill *piPage and +** *pnTruncate and return true. Return if the frame is not valid. +*/ +static int walDecodeFrame( + Wal *pWal, /* The write-ahead log */ + u32 *piPage, /* OUT: Database page number for frame */ + u32 *pnTruncate, /* OUT: New db size (or 0 if not commit) */ + u8 *aData, /* Pointer to page data (for checksum) */ + u8 *aFrame /* Frame data */ +){ + int nativeCksum; /* True for native byte-order checksums */ + u32 *aCksum = pWal->hdr.aFrameCksum; + u32 pgno; /* Page number of the frame */ + assert( WAL_FRAME_HDRSIZE==24 ); + + /* A frame is only valid if the salt values in the frame-header + ** match the salt values in the wal-header. + */ + if( memcmp(&pWal->hdr.aSalt, &aFrame[8], 8)!=0 ){ + return 0; + } + + /* A frame is only valid if the page number is creater than zero. + */ + pgno = sqlite3Get4byte(&aFrame[0]); + if( pgno==0 ){ + return 0; + } + + /* A frame is only valid if a checksum of the WAL header, + ** all prior frams, the first 16 bytes of this frame-header, + ** and the frame-data matches the checksum in the last 8 + ** bytes of this frame-header. + */ + nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN); + walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum); + walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum); + if( aCksum[0]!=sqlite3Get4byte(&aFrame[16]) + || aCksum[1]!=sqlite3Get4byte(&aFrame[20]) + ){ + /* Checksum failed. */ + return 0; + } + + /* If we reach this point, the frame is valid. Return the page number + ** and the new database size. + */ + *piPage = pgno; + *pnTruncate = sqlite3Get4byte(&aFrame[4]); + return 1; +} + + +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) +/* +** Names of locks. This routine is used to provide debugging output and is not +** a part of an ordinary build. +*/ +static const char *walLockName(int lockIdx){ + if( lockIdx==WAL_WRITE_LOCK ){ + return "WRITE-LOCK"; + }else if( lockIdx==WAL_CKPT_LOCK ){ + return "CKPT-LOCK"; + }else if( lockIdx==WAL_RECOVER_LOCK ){ + return "RECOVER-LOCK"; + }else{ + static char zName[15]; + sqlite3_snprintf(sizeof(zName), zName, "READ-LOCK[%d]", + lockIdx-WAL_READ_LOCK(0)); + return zName; + } +} +#endif /*defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */ + + +/* +** Set or release locks on the WAL. Locks are either shared or exclusive. +** A lock cannot be moved directly between shared and exclusive - it must go +** through the unlocked state first. +** +** In locking_mode=EXCLUSIVE, all of these routines become no-ops. +*/ +static int walLockShared(Wal *pWal, int lockIdx){ + int rc; + if( pWal->exclusiveMode ) return SQLITE_OK; + rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, + SQLITE_SHM_LOCK | SQLITE_SHM_SHARED); + WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal, + walLockName(lockIdx), rc ? "failed" : "ok")); + VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); ) + return rc; +} +static void walUnlockShared(Wal *pWal, int lockIdx){ + if( pWal->exclusiveMode ) return; + (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, + SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED); + WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx))); +} +static int walLockExclusive(Wal *pWal, int lockIdx, int n, int fBlock){ + int rc; + if( pWal->exclusiveMode ) return SQLITE_OK; + if( fBlock ) sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_WAL_BLOCK, 0); + rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, + SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE); + WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal, + walLockName(lockIdx), n, rc ? "failed" : "ok")); + VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); ) + return rc; +} +static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){ + if( pWal->exclusiveMode ) return; + (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, + SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE); + WALTRACE(("WAL%p: release EXCLUSIVE-%s cnt=%d\n", pWal, + walLockName(lockIdx), n)); +} + +/* +** Compute a hash on a page number. The resulting hash value must land +** between 0 and (HASHTABLE_NSLOT-1). The walHashNext() function advances +** the hash to the next value in the event of a collision. +*/ +static int walHash(u32 iPage){ + assert( iPage>0 ); + assert( (HASHTABLE_NSLOT & (HASHTABLE_NSLOT-1))==0 ); + return (iPage*HASHTABLE_HASH_1) & (HASHTABLE_NSLOT-1); +} +static int walNextHash(int iPriorHash){ + return (iPriorHash+1)&(HASHTABLE_NSLOT-1); +} + +/* +** Return pointers to the hash table and page number array stored on +** page iHash of the wal-index. The wal-index is broken into 32KB pages +** numbered starting from 0. +** +** Set output variable *paHash to point to the start of the hash table +** in the wal-index file. Set *piZero to one less than the frame +** number of the first frame indexed by this hash table. If a +** slot in the hash table is set to N, it refers to frame number +** (*piZero+N) in the log. +** +** Finally, set *paPgno so that *paPgno[1] is the page number of the +** first frame indexed by the hash table, frame (*piZero+1). +*/ +static int walHashGet( + Wal *pWal, /* WAL handle */ + int iHash, /* Find the iHash'th table */ + volatile ht_slot **paHash, /* OUT: Pointer to hash index */ + volatile u32 **paPgno, /* OUT: Pointer to page number array */ + u32 *piZero /* OUT: Frame associated with *paPgno[0] */ +){ + int rc; /* Return code */ + volatile u32 *aPgno; + + rc = walIndexPage(pWal, iHash, &aPgno); + assert( rc==SQLITE_OK || iHash>0 ); + + if( rc==SQLITE_OK ){ + u32 iZero; + volatile ht_slot *aHash; + + aHash = (volatile ht_slot *)&aPgno[HASHTABLE_NPAGE]; + if( iHash==0 ){ + aPgno = &aPgno[WALINDEX_HDR_SIZE/sizeof(u32)]; + iZero = 0; + }else{ + iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE; + } + + *paPgno = &aPgno[-1]; + *paHash = aHash; + *piZero = iZero; + } + return rc; +} + +/* +** Return the number of the wal-index page that contains the hash-table +** and page-number array that contain entries corresponding to WAL frame +** iFrame. The wal-index is broken up into 32KB pages. Wal-index pages +** are numbered starting from 0. +*/ +static int walFramePage(u32 iFrame){ + int iHash = (iFrame+HASHTABLE_NPAGE-HASHTABLE_NPAGE_ONE-1) / HASHTABLE_NPAGE; + assert( (iHash==0 || iFrame>HASHTABLE_NPAGE_ONE) + && (iHash>=1 || iFrame<=HASHTABLE_NPAGE_ONE) + && (iHash<=1 || iFrame>(HASHTABLE_NPAGE_ONE+HASHTABLE_NPAGE)) + && (iHash>=2 || iFrame<=HASHTABLE_NPAGE_ONE+HASHTABLE_NPAGE) + && (iHash<=2 || iFrame>(HASHTABLE_NPAGE_ONE+2*HASHTABLE_NPAGE)) + ); + return iHash; +} + +/* +** Return the page number associated with frame iFrame in this WAL. +*/ +static u32 walFramePgno(Wal *pWal, u32 iFrame){ + int iHash = walFramePage(iFrame); + if( iHash==0 ){ + return pWal->apWiData[0][WALINDEX_HDR_SIZE/sizeof(u32) + iFrame - 1]; + } + return pWal->apWiData[iHash][(iFrame-1-HASHTABLE_NPAGE_ONE)%HASHTABLE_NPAGE]; +} + +/* +** Remove entries from the hash table that point to WAL slots greater +** than pWal->hdr.mxFrame. +** +** This function is called whenever pWal->hdr.mxFrame is decreased due +** to a rollback or savepoint. +** +** At most only the hash table containing pWal->hdr.mxFrame needs to be +** updated. Any later hash tables will be automatically cleared when +** pWal->hdr.mxFrame advances to the point where those hash tables are +** actually needed. +*/ +static void walCleanupHash(Wal *pWal){ + volatile ht_slot *aHash = 0; /* Pointer to hash table to clear */ + volatile u32 *aPgno = 0; /* Page number array for hash table */ + u32 iZero = 0; /* frame == (aHash[x]+iZero) */ + int iLimit = 0; /* Zero values greater than this */ + int nByte; /* Number of bytes to zero in aPgno[] */ + int i; /* Used to iterate through aHash[] */ + + assert( pWal->writeLock ); + testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE-1 ); + testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE ); + testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE+1 ); + + if( pWal->hdr.mxFrame==0 ) return; + + /* Obtain pointers to the hash-table and page-number array containing + ** the entry that corresponds to frame pWal->hdr.mxFrame. It is guaranteed + ** that the page said hash-table and array reside on is already mapped. + */ + assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) ); + assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] ); + walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &aHash, &aPgno, &iZero); + + /* Zero all hash-table entries that correspond to frame numbers greater + ** than pWal->hdr.mxFrame. + */ + iLimit = pWal->hdr.mxFrame - iZero; + assert( iLimit>0 ); + for(i=0; iiLimit ){ + aHash[i] = 0; + } + } + + /* Zero the entries in the aPgno array that correspond to frames with + ** frame numbers greater than pWal->hdr.mxFrame. + */ + nByte = (int)((char *)aHash - (char *)&aPgno[iLimit+1]); + memset((void *)&aPgno[iLimit+1], 0, nByte); + +#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT + /* Verify that the every entry in the mapping region is still reachable + ** via the hash table even after the cleanup. + */ + if( iLimit ){ + int i; /* Loop counter */ + int iKey; /* Hash key */ + for(i=1; i<=iLimit; i++){ + for(iKey=walHash(aPgno[i]); aHash[iKey]; iKey=walNextHash(iKey)){ + if( aHash[iKey]==i ) break; + } + assert( aHash[iKey]==i ); + } + } +#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */ +} + + +/* +** Set an entry in the wal-index that will map database page number +** pPage into WAL frame iFrame. +*/ +static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){ + int rc; /* Return code */ + u32 iZero = 0; /* One less than frame number of aPgno[1] */ + volatile u32 *aPgno = 0; /* Page number array */ + volatile ht_slot *aHash = 0; /* Hash table */ + + rc = walHashGet(pWal, walFramePage(iFrame), &aHash, &aPgno, &iZero); + + /* Assuming the wal-index file was successfully mapped, populate the + ** page number array and hash table entry. + */ + if( rc==SQLITE_OK ){ + int iKey; /* Hash table key */ + int idx; /* Value to write to hash-table slot */ + int nCollide; /* Number of hash collisions */ + + idx = iFrame - iZero; + assert( idx <= HASHTABLE_NSLOT/2 + 1 ); + + /* If this is the first entry to be added to this hash-table, zero the + ** entire hash table and aPgno[] array before proceeding. + */ + if( idx==1 ){ + int nByte = (int)((u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]); + memset((void*)&aPgno[1], 0, nByte); + } + + /* If the entry in aPgno[] is already set, then the previous writer + ** must have exited unexpectedly in the middle of a transaction (after + ** writing one or more dirty pages to the WAL to free up memory). + ** Remove the remnants of that writers uncommitted transaction from + ** the hash-table before writing any new entries. + */ + if( aPgno[idx] ){ + walCleanupHash(pWal); + assert( !aPgno[idx] ); + } + + /* Write the aPgno[] array entry and the hash-table slot. */ + nCollide = idx; + for(iKey=walHash(iPage); aHash[iKey]; iKey=walNextHash(iKey)){ + if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT; + } + aPgno[idx] = iPage; + aHash[iKey] = (ht_slot)idx; + +#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT + /* Verify that the number of entries in the hash table exactly equals + ** the number of entries in the mapping region. + */ + { + int i; /* Loop counter */ + int nEntry = 0; /* Number of entries in the hash table */ + for(i=0; ickptLock==1 || pWal->ckptLock==0 ); + assert( WAL_ALL_BUT_WRITE==WAL_WRITE_LOCK+1 ); + assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE ); + assert( pWal->writeLock ); + iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock; + nLock = SQLITE_SHM_NLOCK - iLock; + rc = walLockExclusive(pWal, iLock, nLock, 0); + if( rc ){ + return rc; + } + WALTRACE(("WAL%p: recovery begin...\n", pWal)); + + memset(&pWal->hdr, 0, sizeof(WalIndexHdr)); + + rc = sqlite3OsFileSize(pWal->pWalFd, &nSize); + if( rc!=SQLITE_OK ){ + goto recovery_error; + } + + if( nSize>WAL_HDRSIZE ){ + u8 aBuf[WAL_HDRSIZE]; /* Buffer to load WAL header into */ + u8 *aFrame = 0; /* Malloc'd buffer to load entire frame */ + int szFrame; /* Number of bytes in buffer aFrame[] */ + u8 *aData; /* Pointer to data part of aFrame buffer */ + int iFrame; /* Index of last frame read */ + i64 iOffset; /* Next offset to read from log file */ + int szPage; /* Page size according to the log */ + u32 magic; /* Magic value read from WAL header */ + u32 version; /* Magic value read from WAL header */ + int isValid; /* True if this frame is valid */ + + /* Read in the WAL header. */ + rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0); + if( rc!=SQLITE_OK ){ + goto recovery_error; + } + + /* If the database page size is not a power of two, or is greater than + ** SQLITE_MAX_PAGE_SIZE, conclude that the WAL file contains no valid + ** data. Similarly, if the 'magic' value is invalid, ignore the whole + ** WAL file. + */ + magic = sqlite3Get4byte(&aBuf[0]); + szPage = sqlite3Get4byte(&aBuf[8]); + if( (magic&0xFFFFFFFE)!=WAL_MAGIC + || szPage&(szPage-1) + || szPage>SQLITE_MAX_PAGE_SIZE + || szPage<512 + ){ + goto finished; + } + pWal->hdr.bigEndCksum = (u8)(magic&0x00000001); + pWal->szPage = szPage; + pWal->nCkpt = sqlite3Get4byte(&aBuf[12]); + memcpy(&pWal->hdr.aSalt, &aBuf[16], 8); + + /* Verify that the WAL header checksum is correct */ + walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, + aBuf, WAL_HDRSIZE-2*4, 0, pWal->hdr.aFrameCksum + ); + if( pWal->hdr.aFrameCksum[0]!=sqlite3Get4byte(&aBuf[24]) + || pWal->hdr.aFrameCksum[1]!=sqlite3Get4byte(&aBuf[28]) + ){ + goto finished; + } + + /* Verify that the version number on the WAL format is one that + ** are able to understand */ + version = sqlite3Get4byte(&aBuf[4]); + if( version!=WAL_MAX_VERSION ){ + rc = SQLITE_CANTOPEN_BKPT; + goto finished; + } + + /* Malloc a buffer to read frames into. */ + szFrame = szPage + WAL_FRAME_HDRSIZE; + aFrame = (u8 *)sqlite3_malloc64(szFrame); + if( !aFrame ){ + rc = SQLITE_NOMEM; + goto recovery_error; + } + aData = &aFrame[WAL_FRAME_HDRSIZE]; + + /* Read all frames from the log file. */ + iFrame = 0; + for(iOffset=WAL_HDRSIZE; (iOffset+szFrame)<=nSize; iOffset+=szFrame){ + u32 pgno; /* Database page number for frame */ + u32 nTruncate; /* dbsize field from frame header */ + + /* Read and decode the next log frame. */ + iFrame++; + rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset); + if( rc!=SQLITE_OK ) break; + isValid = walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame); + if( !isValid ) break; + rc = walIndexAppend(pWal, iFrame, pgno); + if( rc!=SQLITE_OK ) break; + + /* If nTruncate is non-zero, this is a commit record. */ + if( nTruncate ){ + pWal->hdr.mxFrame = iFrame; + pWal->hdr.nPage = nTruncate; + pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16)); + testcase( szPage<=32768 ); + testcase( szPage>=65536 ); + aFrameCksum[0] = pWal->hdr.aFrameCksum[0]; + aFrameCksum[1] = pWal->hdr.aFrameCksum[1]; + } + } + + sqlite3_free(aFrame); + } + +finished: + if( rc==SQLITE_OK ){ + volatile WalCkptInfo *pInfo; + int i; + pWal->hdr.aFrameCksum[0] = aFrameCksum[0]; + pWal->hdr.aFrameCksum[1] = aFrameCksum[1]; + walIndexWriteHdr(pWal); + + /* Reset the checkpoint-header. This is safe because this thread is + ** currently holding locks that exclude all other readers, writers and + ** checkpointers. + */ + pInfo = walCkptInfo(pWal); + pInfo->nBackfill = 0; + pInfo->aReadMark[0] = 0; + for(i=1; iaReadMark[i] = READMARK_NOT_USED; + if( pWal->hdr.mxFrame ) pInfo->aReadMark[1] = pWal->hdr.mxFrame; + + /* If more than one frame was recovered from the log file, report an + ** event via sqlite3_log(). This is to help with identifying performance + ** problems caused by applications routinely shutting down without + ** checkpointing the log file. + */ + if( pWal->hdr.nPage ){ + sqlite3_log(SQLITE_NOTICE_RECOVER_WAL, + "recovered %d frames from WAL file %s", + pWal->hdr.mxFrame, pWal->zWalName + ); + } + } + +recovery_error: + WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok")); + walUnlockExclusive(pWal, iLock, nLock); + return rc; +} + +/* +** Close an open wal-index. +*/ +static void walIndexClose(Wal *pWal, int isDelete){ + if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){ + int i; + for(i=0; inWiData; i++){ + sqlite3_free((void *)pWal->apWiData[i]); + pWal->apWiData[i] = 0; + } + }else{ + sqlite3OsShmUnmap(pWal->pDbFd, isDelete); + } +} + +/* +** Open a connection to the WAL file zWalName. The database file must +** already be opened on connection pDbFd. The buffer that zWalName points +** to must remain valid for the lifetime of the returned Wal* handle. +** +** A SHARED lock should be held on the database file when this function +** is called. The purpose of this SHARED lock is to prevent any other +** client from unlinking the WAL or wal-index file. If another process +** were to do this just after this client opened one of these files, the +** system would be badly broken. +** +** If the log file is successfully opened, SQLITE_OK is returned and +** *ppWal is set to point to a new WAL handle. If an error occurs, +** an SQLite error code is returned and *ppWal is left unmodified. +*/ +SQLITE_PRIVATE int sqlite3WalOpen( + sqlite3_vfs *pVfs, /* vfs module to open wal and wal-index */ + sqlite3_file *pDbFd, /* The open database file */ + const char *zWalName, /* Name of the WAL file */ + int bNoShm, /* True to run in heap-memory mode */ + i64 mxWalSize, /* Truncate WAL to this size on reset */ + Wal **ppWal /* OUT: Allocated Wal handle */ +){ + int rc; /* Return Code */ + Wal *pRet; /* Object to allocate and return */ + int flags; /* Flags passed to OsOpen() */ + + assert( zWalName && zWalName[0] ); + assert( pDbFd ); + + /* In the amalgamation, the os_unix.c and os_win.c source files come before + ** this source file. Verify that the #defines of the locking byte offsets + ** in os_unix.c and os_win.c agree with the WALINDEX_LOCK_OFFSET value. + */ +#ifdef WIN_SHM_BASE + assert( WIN_SHM_BASE==WALINDEX_LOCK_OFFSET ); +#endif +#ifdef UNIX_SHM_BASE + assert( UNIX_SHM_BASE==WALINDEX_LOCK_OFFSET ); +#endif + + + /* Allocate an instance of struct Wal to return. */ + *ppWal = 0; + pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile); + if( !pRet ){ + return SQLITE_NOMEM; + } + + pRet->pVfs = pVfs; + pRet->pWalFd = (sqlite3_file *)&pRet[1]; + pRet->pDbFd = pDbFd; + pRet->readLock = -1; + pRet->mxWalSize = mxWalSize; + pRet->zWalName = zWalName; + pRet->syncHeader = 1; + pRet->padToSectorBoundary = 1; + pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE); + + /* Open file handle on the write-ahead log file. */ + flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL); + rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags); + if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){ + pRet->readOnly = WAL_RDONLY; + } + + if( rc!=SQLITE_OK ){ + walIndexClose(pRet, 0); + sqlite3OsClose(pRet->pWalFd); + sqlite3_free(pRet); + }else{ + int iDC = sqlite3OsDeviceCharacteristics(pDbFd); + if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->syncHeader = 0; } + if( iDC & SQLITE_IOCAP_POWERSAFE_OVERWRITE ){ + pRet->padToSectorBoundary = 0; + } + *ppWal = pRet; + WALTRACE(("WAL%d: opened\n", pRet)); + } + return rc; +} + +/* +** Change the size to which the WAL file is trucated on each reset. +*/ +SQLITE_PRIVATE void sqlite3WalLimit(Wal *pWal, i64 iLimit){ + if( pWal ) pWal->mxWalSize = iLimit; +} + +/* +** Find the smallest page number out of all pages held in the WAL that +** has not been returned by any prior invocation of this method on the +** same WalIterator object. Write into *piFrame the frame index where +** that page was last written into the WAL. Write into *piPage the page +** number. +** +** Return 0 on success. If there are no pages in the WAL with a page +** number larger than *piPage, then return 1. +*/ +static int walIteratorNext( + WalIterator *p, /* Iterator */ + u32 *piPage, /* OUT: The page number of the next page */ + u32 *piFrame /* OUT: Wal frame index of next page */ +){ + u32 iMin; /* Result pgno must be greater than iMin */ + u32 iRet = 0xFFFFFFFF; /* 0xffffffff is never a valid page number */ + int i; /* For looping through segments */ + + iMin = p->iPrior; + assert( iMin<0xffffffff ); + for(i=p->nSegment-1; i>=0; i--){ + struct WalSegment *pSegment = &p->aSegment[i]; + while( pSegment->iNextnEntry ){ + u32 iPg = pSegment->aPgno[pSegment->aIndex[pSegment->iNext]]; + if( iPg>iMin ){ + if( iPgiZero + pSegment->aIndex[pSegment->iNext]; + } + break; + } + pSegment->iNext++; + } + } + + *piPage = p->iPrior = iRet; + return (iRet==0xFFFFFFFF); +} + +/* +** This function merges two sorted lists into a single sorted list. +** +** aLeft[] and aRight[] are arrays of indices. The sort key is +** aContent[aLeft[]] and aContent[aRight[]]. Upon entry, the following +** is guaranteed for all J0 && nRight>0 ); + while( iRight=nRight || aContent[aLeft[iLeft]]=nLeft || aContent[aLeft[iLeft]]>dbpage ); + assert( iRight>=nRight || aContent[aRight[iRight]]>dbpage ); + } + + *paRight = aLeft; + *pnRight = iOut; + memcpy(aLeft, aTmp, sizeof(aTmp[0])*iOut); +} + +/* +** Sort the elements in list aList using aContent[] as the sort key. +** Remove elements with duplicate keys, preferring to keep the +** larger aList[] values. +** +** The aList[] entries are indices into aContent[]. The values in +** aList[] are to be sorted so that for all J0 ); + assert( HASHTABLE_NPAGE==(1<<(ArraySize(aSub)-1)) ); + + for(iList=0; iListaList && p->nList<=(1<aList==&aList[iList&~((2<aList, p->nList, &aMerge, &nMerge, aBuffer); + } + aSub[iSub].aList = aMerge; + aSub[iSub].nList = nMerge; + } + + for(iSub++; iSubnList<=(1<aList==&aList[nList&~((2<aList, p->nList, &aMerge, &nMerge, aBuffer); + } + } + assert( aMerge==aList ); + *pnList = nMerge; + +#ifdef SQLITE_DEBUG + { + int i; + for(i=1; i<*pnList; i++){ + assert( aContent[aList[i]] > aContent[aList[i-1]] ); + } + } +#endif +} + +/* +** Free an iterator allocated by walIteratorInit(). +*/ +static void walIteratorFree(WalIterator *p){ + sqlite3_free(p); +} + +/* +** Construct a WalInterator object that can be used to loop over all +** pages in the WAL in ascending order. The caller must hold the checkpoint +** lock. +** +** On success, make *pp point to the newly allocated WalInterator object +** return SQLITE_OK. Otherwise, return an error code. If this routine +** returns an error, the value of *pp is undefined. +** +** The calling routine should invoke walIteratorFree() to destroy the +** WalIterator object when it has finished with it. +*/ +static int walIteratorInit(Wal *pWal, WalIterator **pp){ + WalIterator *p; /* Return value */ + int nSegment; /* Number of segments to merge */ + u32 iLast; /* Last frame in log */ + int nByte; /* Number of bytes to allocate */ + int i; /* Iterator variable */ + ht_slot *aTmp; /* Temp space used by merge-sort */ + int rc = SQLITE_OK; /* Return Code */ + + /* This routine only runs while holding the checkpoint lock. And + ** it only runs if there is actually content in the log (mxFrame>0). + */ + assert( pWal->ckptLock && pWal->hdr.mxFrame>0 ); + iLast = pWal->hdr.mxFrame; + + /* Allocate space for the WalIterator object. */ + nSegment = walFramePage(iLast) + 1; + nByte = sizeof(WalIterator) + + (nSegment-1)*sizeof(struct WalSegment) + + iLast*sizeof(ht_slot); + p = (WalIterator *)sqlite3_malloc64(nByte); + if( !p ){ + return SQLITE_NOMEM; + } + memset(p, 0, nByte); + p->nSegment = nSegment; + + /* Allocate temporary space used by the merge-sort routine. This block + ** of memory will be freed before this function returns. + */ + aTmp = (ht_slot *)sqlite3_malloc64( + sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast) + ); + if( !aTmp ){ + rc = SQLITE_NOMEM; + } + + for(i=0; rc==SQLITE_OK && iaSegment[p->nSegment])[iZero]; + iZero++; + + for(j=0; jaSegment[i].iZero = iZero; + p->aSegment[i].nEntry = nEntry; + p->aSegment[i].aIndex = aIndex; + p->aSegment[i].aPgno = (u32 *)aPgno; + } + } + sqlite3_free(aTmp); + + if( rc!=SQLITE_OK ){ + walIteratorFree(p); + } + *pp = p; + return rc; +} + +/* +** Attempt to obtain the exclusive WAL lock defined by parameters lockIdx and +** n. If the attempt fails and parameter xBusy is not NULL, then it is a +** busy-handler function. Invoke it and retry the lock until either the +** lock is successfully obtained or the busy-handler returns 0. +*/ +static int walBusyLock( + Wal *pWal, /* WAL connection */ + int (*xBusy)(void*), /* Function to call when busy */ + void *pBusyArg, /* Context argument for xBusyHandler */ + int lockIdx, /* Offset of first byte to lock */ + int n /* Number of bytes to lock */ +){ + int rc; + do { + rc = walLockExclusive(pWal, lockIdx, n, 0); + }while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) ); + return rc; +} + +/* +** The cache of the wal-index header must be valid to call this function. +** Return the page-size in bytes used by the database. +*/ +static int walPagesize(Wal *pWal){ + return (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16); +} + +/* +** The following is guaranteed when this function is called: +** +** a) the WRITER lock is held, +** b) the entire log file has been checkpointed, and +** c) any existing readers are reading exclusively from the database +** file - there are no readers that may attempt to read a frame from +** the log file. +** +** This function updates the shared-memory structures so that the next +** client to write to the database (which may be this one) does so by +** writing frames into the start of the log file. +** +** The value of parameter salt1 is used as the aSalt[1] value in the +** new wal-index header. It should be passed a pseudo-random value (i.e. +** one obtained from sqlite3_randomness()). +*/ +static void walRestartHdr(Wal *pWal, u32 salt1){ + volatile WalCkptInfo *pInfo = walCkptInfo(pWal); + int i; /* Loop counter */ + u32 *aSalt = pWal->hdr.aSalt; /* Big-endian salt values */ + pWal->nCkpt++; + pWal->hdr.mxFrame = 0; + sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0])); + memcpy(&pWal->hdr.aSalt[1], &salt1, 4); + walIndexWriteHdr(pWal); + pInfo->nBackfill = 0; + pInfo->aReadMark[1] = 0; + for(i=2; iaReadMark[i] = READMARK_NOT_USED; + assert( pInfo->aReadMark[0]==0 ); +} + +/* +** Copy as much content as we can from the WAL back into the database file +** in response to an sqlite3_wal_checkpoint() request or the equivalent. +** +** The amount of information copies from WAL to database might be limited +** by active readers. This routine will never overwrite a database page +** that a concurrent reader might be using. +** +** All I/O barrier operations (a.k.a fsyncs) occur in this routine when +** SQLite is in WAL-mode in synchronous=NORMAL. That means that if +** checkpoints are always run by a background thread or background +** process, foreground threads will never block on a lengthy fsync call. +** +** Fsync is called on the WAL before writing content out of the WAL and +** into the database. This ensures that if the new content is persistent +** in the WAL and can be recovered following a power-loss or hard reset. +** +** Fsync is also called on the database file if (and only if) the entire +** WAL content is copied into the database file. This second fsync makes +** it safe to delete the WAL since the new content will persist in the +** database file. +** +** This routine uses and updates the nBackfill field of the wal-index header. +** This is the only routine that will increase the value of nBackfill. +** (A WAL reset or recovery will revert nBackfill to zero, but not increase +** its value.) +** +** The caller must be holding sufficient locks to ensure that no other +** checkpoint is running (in any other thread or process) at the same +** time. +*/ +static int walCheckpoint( + Wal *pWal, /* Wal connection */ + int eMode, /* One of PASSIVE, FULL or RESTART */ + int (*xBusy)(void*), /* Function to call when busy */ + void *pBusyArg, /* Context argument for xBusyHandler */ + int sync_flags, /* Flags for OsSync() (or 0) */ + u8 *zBuf /* Temporary buffer to use */ +){ + int rc = SQLITE_OK; /* Return code */ + int szPage; /* Database page-size */ + WalIterator *pIter = 0; /* Wal iterator context */ + u32 iDbpage = 0; /* Next database page to write */ + u32 iFrame = 0; /* Wal frame containing data for iDbpage */ + u32 mxSafeFrame; /* Max frame that can be backfilled */ + u32 mxPage; /* Max database page to write */ + int i; /* Loop counter */ + volatile WalCkptInfo *pInfo; /* The checkpoint status information */ + + szPage = walPagesize(pWal); + testcase( szPage<=32768 ); + testcase( szPage>=65536 ); + pInfo = walCkptInfo(pWal); + if( pInfo->nBackfillhdr.mxFrame ){ + + /* Allocate the iterator */ + rc = walIteratorInit(pWal, &pIter); + if( rc!=SQLITE_OK ){ + return rc; + } + assert( pIter ); + + /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked + ** in the SQLITE_CHECKPOINT_PASSIVE mode. */ + assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 ); + + /* Compute in mxSafeFrame the index of the last frame of the WAL that is + ** safe to write into the database. Frames beyond mxSafeFrame might + ** overwrite database pages that are in use by active readers and thus + ** cannot be backfilled from the WAL. + */ + mxSafeFrame = pWal->hdr.mxFrame; + mxPage = pWal->hdr.nPage; + for(i=1; iaReadMark[i]; + if( mxSafeFrame>y ){ + assert( y<=pWal->hdr.mxFrame ); + rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1); + if( rc==SQLITE_OK ){ + pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED); + walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); + }else if( rc==SQLITE_BUSY ){ + mxSafeFrame = y; + xBusy = 0; + }else{ + goto walcheckpoint_out; + } + } + } + + if( pInfo->nBackfillnBackfill; + + /* Sync the WAL to disk */ + if( sync_flags ){ + rc = sqlite3OsSync(pWal->pWalFd, sync_flags); + } + + /* If the database may grow as a result of this checkpoint, hint + ** about the eventual size of the db file to the VFS layer. + */ + if( rc==SQLITE_OK ){ + i64 nReq = ((i64)mxPage * szPage); + rc = sqlite3OsFileSize(pWal->pDbFd, &nSize); + if( rc==SQLITE_OK && nSizepDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq); + } + } + + + /* Iterate through the contents of the WAL, copying data to the db file */ + while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){ + i64 iOffset; + assert( walFramePgno(pWal, iFrame)==iDbpage ); + if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){ + continue; + } + iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE; + /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */ + rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset); + if( rc!=SQLITE_OK ) break; + iOffset = (iDbpage-1)*(i64)szPage; + testcase( IS_BIG_INT(iOffset) ); + rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset); + if( rc!=SQLITE_OK ) break; + } + + /* If work was actually accomplished... */ + if( rc==SQLITE_OK ){ + if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){ + i64 szDb = pWal->hdr.nPage*(i64)szPage; + testcase( IS_BIG_INT(szDb) ); + rc = sqlite3OsTruncate(pWal->pDbFd, szDb); + if( rc==SQLITE_OK && sync_flags ){ + rc = sqlite3OsSync(pWal->pDbFd, sync_flags); + } + } + if( rc==SQLITE_OK ){ + pInfo->nBackfill = mxSafeFrame; + } + } + + /* Release the reader lock held while backfilling */ + walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1); + } + + if( rc==SQLITE_BUSY ){ + /* Reset the return code so as not to report a checkpoint failure + ** just because there are active readers. */ + rc = SQLITE_OK; + } + } + + /* If this is an SQLITE_CHECKPOINT_RESTART or TRUNCATE operation, and the + ** entire wal file has been copied into the database file, then block + ** until all readers have finished using the wal file. This ensures that + ** the next process to write to the database restarts the wal file. + */ + if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){ + assert( pWal->writeLock ); + if( pInfo->nBackfillhdr.mxFrame ){ + rc = SQLITE_BUSY; + }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){ + u32 salt1; + sqlite3_randomness(4, &salt1); + assert( pInfo->nBackfill==pWal->hdr.mxFrame ); + rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1); + if( rc==SQLITE_OK ){ + if( eMode==SQLITE_CHECKPOINT_TRUNCATE ){ + /* IMPLEMENTATION-OF: R-44699-57140 This mode works the same way as + ** SQLITE_CHECKPOINT_RESTART with the addition that it also + ** truncates the log file to zero bytes just prior to a + ** successful return. + ** + ** In theory, it might be safe to do this without updating the + ** wal-index header in shared memory, as all subsequent reader or + ** writer clients should see that the entire log file has been + ** checkpointed and behave accordingly. This seems unsafe though, + ** as it would leave the system in a state where the contents of + ** the wal-index header do not match the contents of the + ** file-system. To avoid this, update the wal-index header to + ** indicate that the log file contains zero valid frames. */ + walRestartHdr(pWal, salt1); + rc = sqlite3OsTruncate(pWal->pWalFd, 0); + } + walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); + } + } + } + + walcheckpoint_out: + walIteratorFree(pIter); + return rc; +} + +/* +** If the WAL file is currently larger than nMax bytes in size, truncate +** it to exactly nMax bytes. If an error occurs while doing so, ignore it. +*/ +static void walLimitSize(Wal *pWal, i64 nMax){ + i64 sz; + int rx; + sqlite3BeginBenignMalloc(); + rx = sqlite3OsFileSize(pWal->pWalFd, &sz); + if( rx==SQLITE_OK && (sz > nMax ) ){ + rx = sqlite3OsTruncate(pWal->pWalFd, nMax); + } + sqlite3EndBenignMalloc(); + if( rx ){ + sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName); + } +} + +/* +** Close a connection to a log file. +*/ +SQLITE_PRIVATE int sqlite3WalClose( + Wal *pWal, /* Wal to close */ + int sync_flags, /* Flags to pass to OsSync() (or 0) */ + int nBuf, + u8 *zBuf /* Buffer of at least nBuf bytes */ +){ + int rc = SQLITE_OK; + if( pWal ){ + int isDelete = 0; /* True to unlink wal and wal-index files */ + + /* If an EXCLUSIVE lock can be obtained on the database file (using the + ** ordinary, rollback-mode locking methods, this guarantees that the + ** connection associated with this log file is the only connection to + ** the database. In this case checkpoint the database and unlink both + ** the wal and wal-index files. + ** + ** The EXCLUSIVE lock is not released before returning. + */ + rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE); + if( rc==SQLITE_OK ){ + if( pWal->exclusiveMode==WAL_NORMAL_MODE ){ + pWal->exclusiveMode = WAL_EXCLUSIVE_MODE; + } + rc = sqlite3WalCheckpoint( + pWal, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0 + ); + if( rc==SQLITE_OK ){ + int bPersist = -1; + sqlite3OsFileControlHint( + pWal->pDbFd, SQLITE_FCNTL_PERSIST_WAL, &bPersist + ); + if( bPersist!=1 ){ + /* Try to delete the WAL file if the checkpoint completed and + ** fsyned (rc==SQLITE_OK) and if we are not in persistent-wal + ** mode (!bPersist) */ + isDelete = 1; + }else if( pWal->mxWalSize>=0 ){ + /* Try to truncate the WAL file to zero bytes if the checkpoint + ** completed and fsynced (rc==SQLITE_OK) and we are in persistent + ** WAL mode (bPersist) and if the PRAGMA journal_size_limit is a + ** non-negative value (pWal->mxWalSize>=0). Note that we truncate + ** to zero bytes as truncating to the journal_size_limit might + ** leave a corrupt WAL file on disk. */ + walLimitSize(pWal, 0); + } + } + } + + walIndexClose(pWal, isDelete); + sqlite3OsClose(pWal->pWalFd); + if( isDelete ){ + sqlite3BeginBenignMalloc(); + sqlite3OsDelete(pWal->pVfs, pWal->zWalName, 0); + sqlite3EndBenignMalloc(); + } + WALTRACE(("WAL%p: closed\n", pWal)); + sqlite3_free((void *)pWal->apWiData); + sqlite3_free(pWal); + } + return rc; +} + +/* +** Try to read the wal-index header. Return 0 on success and 1 if +** there is a problem. +** +** The wal-index is in shared memory. Another thread or process might +** be writing the header at the same time this procedure is trying to +** read it, which might result in inconsistency. A dirty read is detected +** by verifying that both copies of the header are the same and also by +** a checksum on the header. +** +** If and only if the read is consistent and the header is different from +** pWal->hdr, then pWal->hdr is updated to the content of the new header +** and *pChanged is set to 1. +** +** If the checksum cannot be verified return non-zero. If the header +** is read successfully and the checksum verified, return zero. +*/ +static int walIndexTryHdr(Wal *pWal, int *pChanged){ + u32 aCksum[2]; /* Checksum on the header content */ + WalIndexHdr h1, h2; /* Two copies of the header content */ + WalIndexHdr volatile *aHdr; /* Header in shared memory */ + + /* The first page of the wal-index must be mapped at this point. */ + assert( pWal->nWiData>0 && pWal->apWiData[0] ); + + /* Read the header. This might happen concurrently with a write to the + ** same area of shared memory on a different CPU in a SMP, + ** meaning it is possible that an inconsistent snapshot is read + ** from the file. If this happens, return non-zero. + ** + ** There are two copies of the header at the beginning of the wal-index. + ** When reading, read [0] first then [1]. Writes are in the reverse order. + ** Memory barriers are used to prevent the compiler or the hardware from + ** reordering the reads and writes. + */ + aHdr = walIndexHdr(pWal); + memcpy(&h1, (void *)&aHdr[0], sizeof(h1)); + walShmBarrier(pWal); + memcpy(&h2, (void *)&aHdr[1], sizeof(h2)); + + if( memcmp(&h1, &h2, sizeof(h1))!=0 ){ + return 1; /* Dirty read */ + } + if( h1.isInit==0 ){ + return 1; /* Malformed header - probably all zeros */ + } + walChecksumBytes(1, (u8*)&h1, sizeof(h1)-sizeof(h1.aCksum), 0, aCksum); + if( aCksum[0]!=h1.aCksum[0] || aCksum[1]!=h1.aCksum[1] ){ + return 1; /* Checksum does not match */ + } + + if( memcmp(&pWal->hdr, &h1, sizeof(WalIndexHdr)) ){ + *pChanged = 1; + memcpy(&pWal->hdr, &h1, sizeof(WalIndexHdr)); + pWal->szPage = (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16); + testcase( pWal->szPage<=32768 ); + testcase( pWal->szPage>=65536 ); + } + + /* The header was successfully read. Return zero. */ + return 0; +} + +/* +** Read the wal-index header from the wal-index and into pWal->hdr. +** If the wal-header appears to be corrupt, try to reconstruct the +** wal-index from the WAL before returning. +** +** Set *pChanged to 1 if the wal-index header value in pWal->hdr is +** changed by this operation. If pWal->hdr is unchanged, set *pChanged +** to 0. +** +** If the wal-index header is successfully read, return SQLITE_OK. +** Otherwise an SQLite error code. +*/ +static int walIndexReadHdr(Wal *pWal, int *pChanged){ + int rc; /* Return code */ + int badHdr; /* True if a header read failed */ + volatile u32 *page0; /* Chunk of wal-index containing header */ + + /* Ensure that page 0 of the wal-index (the page that contains the + ** wal-index header) is mapped. Return early if an error occurs here. + */ + assert( pChanged ); + rc = walIndexPage(pWal, 0, &page0); + if( rc!=SQLITE_OK ){ + return rc; + }; + assert( page0 || pWal->writeLock==0 ); + + /* If the first page of the wal-index has been mapped, try to read the + ** wal-index header immediately, without holding any lock. This usually + ** works, but may fail if the wal-index header is corrupt or currently + ** being modified by another thread or process. + */ + badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1); + + /* If the first attempt failed, it might have been due to a race + ** with a writer. So get a WRITE lock and try again. + */ + assert( badHdr==0 || pWal->writeLock==0 ); + if( badHdr ){ + if( pWal->readOnly & WAL_SHM_RDONLY ){ + if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){ + walUnlockShared(pWal, WAL_WRITE_LOCK); + rc = SQLITE_READONLY_RECOVERY; + } + }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 1)) ){ + pWal->writeLock = 1; + if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ + badHdr = walIndexTryHdr(pWal, pChanged); + if( badHdr ){ + /* If the wal-index header is still malformed even while holding + ** a WRITE lock, it can only mean that the header is corrupted and + ** needs to be reconstructed. So run recovery to do exactly that. + */ + rc = walIndexRecover(pWal); + *pChanged = 1; + } + } + pWal->writeLock = 0; + walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); + } + } + + /* If the header is read successfully, check the version number to make + ** sure the wal-index was not constructed with some future format that + ** this version of SQLite cannot understand. + */ + if( badHdr==0 && pWal->hdr.iVersion!=WALINDEX_MAX_VERSION ){ + rc = SQLITE_CANTOPEN_BKPT; + } + + return rc; +} + +/* +** This is the value that walTryBeginRead returns when it needs to +** be retried. +*/ +#define WAL_RETRY (-1) + +/* +** Attempt to start a read transaction. This might fail due to a race or +** other transient condition. When that happens, it returns WAL_RETRY to +** indicate to the caller that it is safe to retry immediately. +** +** On success return SQLITE_OK. On a permanent failure (such an +** I/O error or an SQLITE_BUSY because another process is running +** recovery) return a positive error code. +** +** The useWal parameter is true to force the use of the WAL and disable +** the case where the WAL is bypassed because it has been completely +** checkpointed. If useWal==0 then this routine calls walIndexReadHdr() +** to make a copy of the wal-index header into pWal->hdr. If the +** wal-index header has changed, *pChanged is set to 1 (as an indication +** to the caller that the local paget cache is obsolete and needs to be +** flushed.) When useWal==1, the wal-index header is assumed to already +** be loaded and the pChanged parameter is unused. +** +** The caller must set the cnt parameter to the number of prior calls to +** this routine during the current read attempt that returned WAL_RETRY. +** This routine will start taking more aggressive measures to clear the +** race conditions after multiple WAL_RETRY returns, and after an excessive +** number of errors will ultimately return SQLITE_PROTOCOL. The +** SQLITE_PROTOCOL return indicates that some other process has gone rogue +** and is not honoring the locking protocol. There is a vanishingly small +** chance that SQLITE_PROTOCOL could be returned because of a run of really +** bad luck when there is lots of contention for the wal-index, but that +** possibility is so small that it can be safely neglected, we believe. +** +** On success, this routine obtains a read lock on +** WAL_READ_LOCK(pWal->readLock). The pWal->readLock integer is +** in the range 0 <= pWal->readLock < WAL_NREADER. If pWal->readLock==(-1) +** that means the Wal does not hold any read lock. The reader must not +** access any database page that is modified by a WAL frame up to and +** including frame number aReadMark[pWal->readLock]. The reader will +** use WAL frames up to and including pWal->hdr.mxFrame if pWal->readLock>0 +** Or if pWal->readLock==0, then the reader will ignore the WAL +** completely and get all content directly from the database file. +** If the useWal parameter is 1 then the WAL will never be ignored and +** this routine will always set pWal->readLock>0 on success. +** When the read transaction is completed, the caller must release the +** lock on WAL_READ_LOCK(pWal->readLock) and set pWal->readLock to -1. +** +** This routine uses the nBackfill and aReadMark[] fields of the header +** to select a particular WAL_READ_LOCK() that strives to let the +** checkpoint process do as much work as possible. This routine might +** update values of the aReadMark[] array in the header, but if it does +** so it takes care to hold an exclusive lock on the corresponding +** WAL_READ_LOCK() while changing values. +*/ +static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ + volatile WalCkptInfo *pInfo; /* Checkpoint information in wal-index */ + u32 mxReadMark; /* Largest aReadMark[] value */ + int mxI; /* Index of largest aReadMark[] value */ + int i; /* Loop counter */ + int rc = SQLITE_OK; /* Return code */ + + assert( pWal->readLock<0 ); /* Not currently locked */ + + /* Take steps to avoid spinning forever if there is a protocol error. + ** + ** Circumstances that cause a RETRY should only last for the briefest + ** instances of time. No I/O or other system calls are done while the + ** locks are held, so the locks should not be held for very long. But + ** if we are unlucky, another process that is holding a lock might get + ** paged out or take a page-fault that is time-consuming to resolve, + ** during the few nanoseconds that it is holding the lock. In that case, + ** it might take longer than normal for the lock to free. + ** + ** After 5 RETRYs, we begin calling sqlite3OsSleep(). The first few + ** calls to sqlite3OsSleep() have a delay of 1 microsecond. Really this + ** is more of a scheduler yield than an actual delay. But on the 10th + ** an subsequent retries, the delays start becoming longer and longer, + ** so that on the 100th (and last) RETRY we delay for 323 milliseconds. + ** The total delay time before giving up is less than 10 seconds. + */ + if( cnt>5 ){ + int nDelay = 1; /* Pause time in microseconds */ + if( cnt>100 ){ + VVA_ONLY( pWal->lockError = 1; ) + return SQLITE_PROTOCOL; + } + if( cnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39; + sqlite3OsSleep(pWal->pVfs, nDelay); + } + + if( !useWal ){ + rc = walIndexReadHdr(pWal, pChanged); + if( rc==SQLITE_BUSY ){ + /* If there is not a recovery running in another thread or process + ** then convert BUSY errors to WAL_RETRY. If recovery is known to + ** be running, convert BUSY to BUSY_RECOVERY. There is a race here + ** which might cause WAL_RETRY to be returned even if BUSY_RECOVERY + ** would be technically correct. But the race is benign since with + ** WAL_RETRY this routine will be called again and will probably be + ** right on the second iteration. + */ + if( pWal->apWiData[0]==0 ){ + /* This branch is taken when the xShmMap() method returns SQLITE_BUSY. + ** We assume this is a transient condition, so return WAL_RETRY. The + ** xShmMap() implementation used by the default unix and win32 VFS + ** modules may return SQLITE_BUSY due to a race condition in the + ** code that determines whether or not the shared-memory region + ** must be zeroed before the requested page is returned. + */ + rc = WAL_RETRY; + }else if( SQLITE_OK==(rc = walLockShared(pWal, WAL_RECOVER_LOCK)) ){ + walUnlockShared(pWal, WAL_RECOVER_LOCK); + rc = WAL_RETRY; + }else if( rc==SQLITE_BUSY ){ + rc = SQLITE_BUSY_RECOVERY; + } + } + if( rc!=SQLITE_OK ){ + return rc; + } + } + + pInfo = walCkptInfo(pWal); + if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame ){ + /* The WAL has been completely backfilled (or it is empty). + ** and can be safely ignored. + */ + rc = walLockShared(pWal, WAL_READ_LOCK(0)); + walShmBarrier(pWal); + if( rc==SQLITE_OK ){ + if( memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) ){ + /* It is not safe to allow the reader to continue here if frames + ** may have been appended to the log before READ_LOCK(0) was obtained. + ** When holding READ_LOCK(0), the reader ignores the entire log file, + ** which implies that the database file contains a trustworthy + ** snapshot. Since holding READ_LOCK(0) prevents a checkpoint from + ** happening, this is usually correct. + ** + ** However, if frames have been appended to the log (or if the log + ** is wrapped and written for that matter) before the READ_LOCK(0) + ** is obtained, that is not necessarily true. A checkpointer may + ** have started to backfill the appended frames but crashed before + ** it finished. Leaving a corrupt image in the database file. + */ + walUnlockShared(pWal, WAL_READ_LOCK(0)); + return WAL_RETRY; + } + pWal->readLock = 0; + return SQLITE_OK; + }else if( rc!=SQLITE_BUSY ){ + return rc; + } + } + + /* If we get this far, it means that the reader will want to use + ** the WAL to get at content from recent commits. The job now is + ** to select one of the aReadMark[] entries that is closest to + ** but not exceeding pWal->hdr.mxFrame and lock that entry. + */ + mxReadMark = 0; + mxI = 0; + for(i=1; iaReadMark[i]; + if( mxReadMark<=thisMark && thisMark<=pWal->hdr.mxFrame ){ + assert( thisMark!=READMARK_NOT_USED ); + mxReadMark = thisMark; + mxI = i; + } + } + /* There was once an "if" here. The extra "{" is to preserve indentation. */ + { + if( (pWal->readOnly & WAL_SHM_RDONLY)==0 + && (mxReadMarkhdr.mxFrame || mxI==0) + ){ + for(i=1; iaReadMark[i] = pWal->hdr.mxFrame; + mxI = i; + walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); + break; + }else if( rc!=SQLITE_BUSY ){ + return rc; + } + } + } + if( mxI==0 ){ + assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 ); + return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK; + } + + rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); + if( rc ){ + return rc==SQLITE_BUSY ? WAL_RETRY : rc; + } + /* Now that the read-lock has been obtained, check that neither the + ** value in the aReadMark[] array or the contents of the wal-index + ** header have changed. + ** + ** It is necessary to check that the wal-index header did not change + ** between the time it was read and when the shared-lock was obtained + ** on WAL_READ_LOCK(mxI) was obtained to account for the possibility + ** that the log file may have been wrapped by a writer, or that frames + ** that occur later in the log than pWal->hdr.mxFrame may have been + ** copied into the database by a checkpointer. If either of these things + ** happened, then reading the database with the current value of + ** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry + ** instead. + ** + ** This does not guarantee that the copy of the wal-index header is up to + ** date before proceeding. That would not be possible without somehow + ** blocking writers. It only guarantees that a dangerous checkpoint or + ** log-wrap (either of which would require an exclusive lock on + ** WAL_READ_LOCK(mxI)) has not occurred since the snapshot was valid. + */ + walShmBarrier(pWal); + if( pInfo->aReadMark[mxI]!=mxReadMark + || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) + ){ + walUnlockShared(pWal, WAL_READ_LOCK(mxI)); + return WAL_RETRY; + }else{ + assert( mxReadMark<=pWal->hdr.mxFrame ); + pWal->readLock = (i16)mxI; + } + } + return rc; +} + +/* +** Begin a read transaction on the database. +** +** This routine used to be called sqlite3OpenSnapshot() and with good reason: +** it takes a snapshot of the state of the WAL and wal-index for the current +** instant in time. The current thread will continue to use this snapshot. +** Other threads might append new content to the WAL and wal-index but +** that extra content is ignored by the current thread. +** +** If the database contents have changes since the previous read +** transaction, then *pChanged is set to 1 before returning. The +** Pager layer will use this to know that is cache is stale and +** needs to be flushed. +*/ +SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ + int rc; /* Return code */ + int cnt = 0; /* Number of TryBeginRead attempts */ + + do{ + rc = walTryBeginRead(pWal, pChanged, 0, ++cnt); + }while( rc==WAL_RETRY ); + testcase( (rc&0xff)==SQLITE_BUSY ); + testcase( (rc&0xff)==SQLITE_IOERR ); + testcase( rc==SQLITE_PROTOCOL ); + testcase( rc==SQLITE_OK ); + return rc; +} + +/* +** Finish with a read transaction. All this does is release the +** read-lock. +*/ +SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){ + sqlite3WalEndWriteTransaction(pWal); + if( pWal->readLock>=0 ){ + walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock)); + pWal->readLock = -1; + } +} + +/* +** Search the wal file for page pgno. If found, set *piRead to the frame that +** contains the page. Otherwise, if pgno is not in the wal file, set *piRead +** to zero. +** +** Return SQLITE_OK if successful, or an error code if an error occurs. If an +** error does occur, the final value of *piRead is undefined. +*/ +SQLITE_PRIVATE int sqlite3WalFindFrame( + Wal *pWal, /* WAL handle */ + Pgno pgno, /* Database page number to read data for */ + u32 *piRead /* OUT: Frame number (or zero) */ +){ + u32 iRead = 0; /* If !=0, WAL frame to return data from */ + u32 iLast = pWal->hdr.mxFrame; /* Last page in WAL for this reader */ + int iHash; /* Used to loop through N hash tables */ + + /* This routine is only be called from within a read transaction. */ + assert( pWal->readLock>=0 || pWal->lockError ); + + /* If the "last page" field of the wal-index header snapshot is 0, then + ** no data will be read from the wal under any circumstances. Return early + ** in this case as an optimization. Likewise, if pWal->readLock==0, + ** then the WAL is ignored by the reader so return early, as if the + ** WAL were empty. + */ + if( iLast==0 || pWal->readLock==0 ){ + *piRead = 0; + return SQLITE_OK; + } + + /* Search the hash table or tables for an entry matching page number + ** pgno. Each iteration of the following for() loop searches one + ** hash table (each hash table indexes up to HASHTABLE_NPAGE frames). + ** + ** This code might run concurrently to the code in walIndexAppend() + ** that adds entries to the wal-index (and possibly to this hash + ** table). This means the value just read from the hash + ** slot (aHash[iKey]) may have been added before or after the + ** current read transaction was opened. Values added after the + ** read transaction was opened may have been written incorrectly - + ** i.e. these slots may contain garbage data. However, we assume + ** that any slots written before the current read transaction was + ** opened remain unmodified. + ** + ** For the reasons above, the if(...) condition featured in the inner + ** loop of the following block is more stringent that would be required + ** if we had exclusive access to the hash-table: + ** + ** (aPgno[iFrame]==pgno): + ** This condition filters out normal hash-table collisions. + ** + ** (iFrame<=iLast): + ** This condition filters out entries that were added to the hash + ** table after the current read-transaction had started. + */ + for(iHash=walFramePage(iLast); iHash>=0 && iRead==0; iHash--){ + volatile ht_slot *aHash; /* Pointer to hash table */ + volatile u32 *aPgno; /* Pointer to array of page numbers */ + u32 iZero; /* Frame number corresponding to aPgno[0] */ + int iKey; /* Hash slot index */ + int nCollide; /* Number of hash collisions remaining */ + int rc; /* Error code */ + + rc = walHashGet(pWal, iHash, &aHash, &aPgno, &iZero); + if( rc!=SQLITE_OK ){ + return rc; + } + nCollide = HASHTABLE_NSLOT; + for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){ + u32 iFrame = aHash[iKey] + iZero; + if( iFrame<=iLast && aPgno[aHash[iKey]]==pgno ){ + assert( iFrame>iRead || CORRUPT_DB ); + iRead = iFrame; + } + if( (nCollide--)==0 ){ + return SQLITE_CORRUPT_BKPT; + } + } + } + +#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT + /* If expensive assert() statements are available, do a linear search + ** of the wal-index file content. Make sure the results agree with the + ** result obtained using the hash indexes above. */ + { + u32 iRead2 = 0; + u32 iTest; + for(iTest=iLast; iTest>0; iTest--){ + if( walFramePgno(pWal, iTest)==pgno ){ + iRead2 = iTest; + break; + } + } + assert( iRead==iRead2 ); + } +#endif + + *piRead = iRead; + return SQLITE_OK; +} + +/* +** Read the contents of frame iRead from the wal file into buffer pOut +** (which is nOut bytes in size). Return SQLITE_OK if successful, or an +** error code otherwise. +*/ +SQLITE_PRIVATE int sqlite3WalReadFrame( + Wal *pWal, /* WAL handle */ + u32 iRead, /* Frame to read */ + int nOut, /* Size of buffer pOut in bytes */ + u8 *pOut /* Buffer to write page data to */ +){ + int sz; + i64 iOffset; + sz = pWal->hdr.szPage; + sz = (sz&0xfe00) + ((sz&0x0001)<<16); + testcase( sz<=32768 ); + testcase( sz>=65536 ); + iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE; + /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ + return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset); +} + +/* +** Return the size of the database in pages (or zero, if unknown). +*/ +SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal){ + if( pWal && ALWAYS(pWal->readLock>=0) ){ + return pWal->hdr.nPage; + } + return 0; +} + + +/* +** This function starts a write transaction on the WAL. +** +** A read transaction must have already been started by a prior call +** to sqlite3WalBeginReadTransaction(). +** +** If another thread or process has written into the database since +** the read transaction was started, then it is not possible for this +** thread to write as doing so would cause a fork. So this routine +** returns SQLITE_BUSY in that case and no write transaction is started. +** +** There can only be a single writer active at a time. +*/ +SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){ + int rc; + + /* Cannot start a write transaction without first holding a read + ** transaction. */ + assert( pWal->readLock>=0 ); + + if( pWal->readOnly ){ + return SQLITE_READONLY; + } + + /* Only one writer allowed at a time. Get the write lock. Return + ** SQLITE_BUSY if unable. + */ + rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 0); + if( rc ){ + return rc; + } + pWal->writeLock = 1; + + /* If another connection has written to the database file since the + ** time the read transaction on this connection was started, then + ** the write is disallowed. + */ + if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){ + walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); + pWal->writeLock = 0; + rc = SQLITE_BUSY_SNAPSHOT; + } + + return rc; +} + +/* +** End a write transaction. The commit has already been done. This +** routine merely releases the lock. +*/ +SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal){ + if( pWal->writeLock ){ + walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); + pWal->writeLock = 0; + pWal->truncateOnCommit = 0; + } + return SQLITE_OK; +} + +/* +** If any data has been written (but not committed) to the log file, this +** function moves the write-pointer back to the start of the transaction. +** +** Additionally, the callback function is invoked for each frame written +** to the WAL since the start of the transaction. If the callback returns +** other than SQLITE_OK, it is not invoked again and the error code is +** returned to the caller. +** +** Otherwise, if the callback function does not return an error, this +** function returns SQLITE_OK. +*/ +SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){ + int rc = SQLITE_OK; + if( ALWAYS(pWal->writeLock) ){ + Pgno iMax = pWal->hdr.mxFrame; + Pgno iFrame; + + /* Restore the clients cache of the wal-index header to the state it + ** was in before the client began writing to the database. + */ + memcpy(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr)); + + for(iFrame=pWal->hdr.mxFrame+1; + ALWAYS(rc==SQLITE_OK) && iFrame<=iMax; + iFrame++ + ){ + /* This call cannot fail. Unless the page for which the page number + ** is passed as the second argument is (a) in the cache and + ** (b) has an outstanding reference, then xUndo is either a no-op + ** (if (a) is false) or simply expels the page from the cache (if (b) + ** is false). + ** + ** If the upper layer is doing a rollback, it is guaranteed that there + ** are no outstanding references to any page other than page 1. And + ** page 1 is never written to the log until the transaction is + ** committed. As a result, the call to xUndo may not fail. + */ + assert( walFramePgno(pWal, iFrame)!=1 ); + rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame)); + } + if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal); + } + return rc; +} + +/* +** Argument aWalData must point to an array of WAL_SAVEPOINT_NDATA u32 +** values. This function populates the array with values required to +** "rollback" the write position of the WAL handle back to the current +** point in the event of a savepoint rollback (via WalSavepointUndo()). +*/ +SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData){ + assert( pWal->writeLock ); + aWalData[0] = pWal->hdr.mxFrame; + aWalData[1] = pWal->hdr.aFrameCksum[0]; + aWalData[2] = pWal->hdr.aFrameCksum[1]; + aWalData[3] = pWal->nCkpt; +} + +/* +** Move the write position of the WAL back to the point identified by +** the values in the aWalData[] array. aWalData must point to an array +** of WAL_SAVEPOINT_NDATA u32 values that has been previously populated +** by a call to WalSavepoint(). +*/ +SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){ + int rc = SQLITE_OK; + + assert( pWal->writeLock ); + assert( aWalData[3]!=pWal->nCkpt || aWalData[0]<=pWal->hdr.mxFrame ); + + if( aWalData[3]!=pWal->nCkpt ){ + /* This savepoint was opened immediately after the write-transaction + ** was started. Right after that, the writer decided to wrap around + ** to the start of the log. Update the savepoint values to match. + */ + aWalData[0] = 0; + aWalData[3] = pWal->nCkpt; + } + + if( aWalData[0]hdr.mxFrame ){ + pWal->hdr.mxFrame = aWalData[0]; + pWal->hdr.aFrameCksum[0] = aWalData[1]; + pWal->hdr.aFrameCksum[1] = aWalData[2]; + walCleanupHash(pWal); + } + + return rc; +} + +/* +** This function is called just before writing a set of frames to the log +** file (see sqlite3WalFrames()). It checks to see if, instead of appending +** to the current log file, it is possible to overwrite the start of the +** existing log file with the new frames (i.e. "reset" the log). If so, +** it sets pWal->hdr.mxFrame to 0. Otherwise, pWal->hdr.mxFrame is left +** unchanged. +** +** SQLITE_OK is returned if no error is encountered (regardless of whether +** or not pWal->hdr.mxFrame is modified). An SQLite error code is returned +** if an error occurs. +*/ +static int walRestartLog(Wal *pWal){ + int rc = SQLITE_OK; + int cnt; + + if( pWal->readLock==0 ){ + volatile WalCkptInfo *pInfo = walCkptInfo(pWal); + assert( pInfo->nBackfill==pWal->hdr.mxFrame ); + if( pInfo->nBackfill>0 ){ + u32 salt1; + sqlite3_randomness(4, &salt1); + rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1, 0); + if( rc==SQLITE_OK ){ + /* If all readers are using WAL_READ_LOCK(0) (in other words if no + ** readers are currently using the WAL), then the transactions + ** frames will overwrite the start of the existing log. Update the + ** wal-index header to reflect this. + ** + ** In theory it would be Ok to update the cache of the header only + ** at this point. But updating the actual wal-index header is also + ** safe and means there is no special case for sqlite3WalUndo() + ** to handle if this transaction is rolled back. */ + walRestartHdr(pWal, salt1); + walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); + }else if( rc!=SQLITE_BUSY ){ + return rc; + } + } + walUnlockShared(pWal, WAL_READ_LOCK(0)); + pWal->readLock = -1; + cnt = 0; + do{ + int notUsed; + rc = walTryBeginRead(pWal, ¬Used, 1, ++cnt); + }while( rc==WAL_RETRY ); + assert( (rc&0xff)!=SQLITE_BUSY ); /* BUSY not possible when useWal==1 */ + testcase( (rc&0xff)==SQLITE_IOERR ); + testcase( rc==SQLITE_PROTOCOL ); + testcase( rc==SQLITE_OK ); + } + return rc; +} + +/* +** Information about the current state of the WAL file and where +** the next fsync should occur - passed from sqlite3WalFrames() into +** walWriteToLog(). +*/ +typedef struct WalWriter { + Wal *pWal; /* The complete WAL information */ + sqlite3_file *pFd; /* The WAL file to which we write */ + sqlite3_int64 iSyncPoint; /* Fsync at this offset */ + int syncFlags; /* Flags for the fsync */ + int szPage; /* Size of one page */ +} WalWriter; + +/* +** Write iAmt bytes of content into the WAL file beginning at iOffset. +** Do a sync when crossing the p->iSyncPoint boundary. +** +** In other words, if iSyncPoint is in between iOffset and iOffset+iAmt, +** first write the part before iSyncPoint, then sync, then write the +** rest. +*/ +static int walWriteToLog( + WalWriter *p, /* WAL to write to */ + void *pContent, /* Content to be written */ + int iAmt, /* Number of bytes to write */ + sqlite3_int64 iOffset /* Start writing at this offset */ +){ + int rc; + if( iOffsetiSyncPoint && iOffset+iAmt>=p->iSyncPoint ){ + int iFirstAmt = (int)(p->iSyncPoint - iOffset); + rc = sqlite3OsWrite(p->pFd, pContent, iFirstAmt, iOffset); + if( rc ) return rc; + iOffset += iFirstAmt; + iAmt -= iFirstAmt; + pContent = (void*)(iFirstAmt + (char*)pContent); + assert( p->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) ); + rc = sqlite3OsSync(p->pFd, p->syncFlags & SQLITE_SYNC_MASK); + if( iAmt==0 || rc ) return rc; + } + rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset); + return rc; +} + +/* +** Write out a single frame of the WAL +*/ +static int walWriteOneFrame( + WalWriter *p, /* Where to write the frame */ + PgHdr *pPage, /* The page of the frame to be written */ + int nTruncate, /* The commit flag. Usually 0. >0 for commit */ + sqlite3_int64 iOffset /* Byte offset at which to write */ +){ + int rc; /* Result code from subfunctions */ + void *pData; /* Data actually written */ + u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-header in */ +#if defined(SQLITE_HAS_CODEC) + if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM; +#else + pData = pPage->pData; +#endif + walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame); + rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset); + if( rc ) return rc; + /* Write the page data */ + rc = walWriteToLog(p, pData, p->szPage, iOffset+sizeof(aFrame)); + return rc; +} + +/* +** Write a set of frames to the log. The caller must hold the write-lock +** on the log file (obtained using sqlite3WalBeginWriteTransaction()). +*/ +SQLITE_PRIVATE int sqlite3WalFrames( + Wal *pWal, /* Wal handle to write to */ + int szPage, /* Database page-size in bytes */ + PgHdr *pList, /* List of dirty pages to write */ + Pgno nTruncate, /* Database size after this commit */ + int isCommit, /* True if this is a commit */ + int sync_flags /* Flags to pass to OsSync() (or 0) */ +){ + int rc; /* Used to catch return codes */ + u32 iFrame; /* Next frame address */ + PgHdr *p; /* Iterator to run through pList with. */ + PgHdr *pLast = 0; /* Last frame in list */ + int nExtra = 0; /* Number of extra copies of last page */ + int szFrame; /* The size of a single frame */ + i64 iOffset; /* Next byte to write in WAL file */ + WalWriter w; /* The writer */ + + assert( pList ); + assert( pWal->writeLock ); + + /* If this frame set completes a transaction, then nTruncate>0. If + ** nTruncate==0 then this frame set does not complete the transaction. */ + assert( (isCommit!=0)==(nTruncate!=0) ); + +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) + { int cnt; for(cnt=0, p=pList; p; p=p->pDirty, cnt++){} + WALTRACE(("WAL%p: frame write begin. %d frames. mxFrame=%d. %s\n", + pWal, cnt, pWal->hdr.mxFrame, isCommit ? "Commit" : "Spill")); + } +#endif + + /* See if it is possible to write these frames into the start of the + ** log file, instead of appending to it at pWal->hdr.mxFrame. + */ + if( SQLITE_OK!=(rc = walRestartLog(pWal)) ){ + return rc; + } + + /* If this is the first frame written into the log, write the WAL + ** header to the start of the WAL file. See comments at the top of + ** this source file for a description of the WAL header format. + */ + iFrame = pWal->hdr.mxFrame; + if( iFrame==0 ){ + u8 aWalHdr[WAL_HDRSIZE]; /* Buffer to assemble wal-header in */ + u32 aCksum[2]; /* Checksum for wal-header */ + + sqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN)); + sqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION); + sqlite3Put4byte(&aWalHdr[8], szPage); + sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt); + if( pWal->nCkpt==0 ) sqlite3_randomness(8, pWal->hdr.aSalt); + memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8); + walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum); + sqlite3Put4byte(&aWalHdr[24], aCksum[0]); + sqlite3Put4byte(&aWalHdr[28], aCksum[1]); + + pWal->szPage = szPage; + pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN; + pWal->hdr.aFrameCksum[0] = aCksum[0]; + pWal->hdr.aFrameCksum[1] = aCksum[1]; + pWal->truncateOnCommit = 1; + + rc = sqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0); + WALTRACE(("WAL%p: wal-header write %s\n", pWal, rc ? "failed" : "ok")); + if( rc!=SQLITE_OK ){ + return rc; + } + + /* Sync the header (unless SQLITE_IOCAP_SEQUENTIAL is true or unless + ** all syncing is turned off by PRAGMA synchronous=OFF). Otherwise + ** an out-of-order write following a WAL restart could result in + ** database corruption. See the ticket: + ** + ** http://localhost:591/sqlite/info/ff5be73dee + */ + if( pWal->syncHeader && sync_flags ){ + rc = sqlite3OsSync(pWal->pWalFd, sync_flags & SQLITE_SYNC_MASK); + if( rc ) return rc; + } + } + assert( (int)pWal->szPage==szPage ); + + /* Setup information needed to write frames into the WAL */ + w.pWal = pWal; + w.pFd = pWal->pWalFd; + w.iSyncPoint = 0; + w.syncFlags = sync_flags; + w.szPage = szPage; + iOffset = walFrameOffset(iFrame+1, szPage); + szFrame = szPage + WAL_FRAME_HDRSIZE; + + /* Write all frames into the log file exactly once */ + for(p=pList; p; p=p->pDirty){ + int nDbSize; /* 0 normally. Positive == commit flag */ + iFrame++; + assert( iOffset==walFrameOffset(iFrame, szPage) ); + nDbSize = (isCommit && p->pDirty==0) ? nTruncate : 0; + rc = walWriteOneFrame(&w, p, nDbSize, iOffset); + if( rc ) return rc; + pLast = p; + iOffset += szFrame; + } + + /* If this is the end of a transaction, then we might need to pad + ** the transaction and/or sync the WAL file. + ** + ** Padding and syncing only occur if this set of frames complete a + ** transaction and if PRAGMA synchronous=FULL. If synchronous==NORMAL + ** or synchronous==OFF, then no padding or syncing are needed. + ** + ** If SQLITE_IOCAP_POWERSAFE_OVERWRITE is defined, then padding is not + ** needed and only the sync is done. If padding is needed, then the + ** final frame is repeated (with its commit mark) until the next sector + ** boundary is crossed. Only the part of the WAL prior to the last + ** sector boundary is synced; the part of the last frame that extends + ** past the sector boundary is written after the sync. + */ + if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){ + if( pWal->padToSectorBoundary ){ + int sectorSize = sqlite3SectorSize(pWal->pWalFd); + w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize; + while( iOffsettruncateOnCommit && pWal->mxWalSize>=0 ){ + i64 sz = pWal->mxWalSize; + if( walFrameOffset(iFrame+nExtra+1, szPage)>pWal->mxWalSize ){ + sz = walFrameOffset(iFrame+nExtra+1, szPage); + } + walLimitSize(pWal, sz); + pWal->truncateOnCommit = 0; + } + + /* Append data to the wal-index. It is not necessary to lock the + ** wal-index to do this as the SQLITE_SHM_WRITE lock held on the wal-index + ** guarantees that there are no other writers, and no data that may + ** be in use by existing readers is being overwritten. + */ + iFrame = pWal->hdr.mxFrame; + for(p=pList; p && rc==SQLITE_OK; p=p->pDirty){ + iFrame++; + rc = walIndexAppend(pWal, iFrame, p->pgno); + } + while( rc==SQLITE_OK && nExtra>0 ){ + iFrame++; + nExtra--; + rc = walIndexAppend(pWal, iFrame, pLast->pgno); + } + + if( rc==SQLITE_OK ){ + /* Update the private copy of the header. */ + pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16)); + testcase( szPage<=32768 ); + testcase( szPage>=65536 ); + pWal->hdr.mxFrame = iFrame; + if( isCommit ){ + pWal->hdr.iChange++; + pWal->hdr.nPage = nTruncate; + } + /* If this is a commit, update the wal-index header too. */ + if( isCommit ){ + walIndexWriteHdr(pWal); + pWal->iCallback = iFrame; + } + } + + WALTRACE(("WAL%p: frame write %s\n", pWal, rc ? "failed" : "ok")); + return rc; +} + +/* +** This routine is called to implement sqlite3_wal_checkpoint() and +** related interfaces. +** +** Obtain a CHECKPOINT lock and then backfill as much information as +** we can from WAL into the database. +** +** If parameter xBusy is not NULL, it is a pointer to a busy-handler +** callback. In this case this function runs a blocking checkpoint. +*/ +SQLITE_PRIVATE int sqlite3WalCheckpoint( + Wal *pWal, /* Wal connection */ + int eMode, /* PASSIVE, FULL, RESTART, or TRUNCATE */ + int (*xBusy)(void*), /* Function to call when busy */ + void *pBusyArg, /* Context argument for xBusyHandler */ + int sync_flags, /* Flags to sync db file with (or 0) */ + int nBuf, /* Size of temporary buffer */ + u8 *zBuf, /* Temporary buffer to use */ + int *pnLog, /* OUT: Number of frames in WAL */ + int *pnCkpt /* OUT: Number of backfilled frames in WAL */ +){ + int rc; /* Return code */ + int isChanged = 0; /* True if a new wal-index header is loaded */ + int eMode2 = eMode; /* Mode to pass to walCheckpoint() */ + int (*xBusy2)(void*) = xBusy; /* Busy handler for eMode2 */ + + assert( pWal->ckptLock==0 ); + assert( pWal->writeLock==0 ); + + /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked + ** in the SQLITE_CHECKPOINT_PASSIVE mode. */ + assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 ); + + if( pWal->readOnly ) return SQLITE_READONLY; + WALTRACE(("WAL%p: checkpoint begins\n", pWal)); + + /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive + ** "checkpoint" lock on the database file. */ + rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1, 0); + if( rc ){ + /* EVIDENCE-OF: R-10421-19736 If any other process is running a + ** checkpoint operation at the same time, the lock cannot be obtained and + ** SQLITE_BUSY is returned. + ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured, + ** it will not be invoked in this case. + */ + testcase( rc==SQLITE_BUSY ); + testcase( xBusy!=0 ); + return rc; + } + pWal->ckptLock = 1; + + /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and + ** TRUNCATE modes also obtain the exclusive "writer" lock on the database + ** file. + ** + ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained + ** immediately, and a busy-handler is configured, it is invoked and the + ** writer lock retried until either the busy-handler returns 0 or the + ** lock is successfully obtained. + */ + if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){ + rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1); + if( rc==SQLITE_OK ){ + pWal->writeLock = 1; + }else if( rc==SQLITE_BUSY ){ + eMode2 = SQLITE_CHECKPOINT_PASSIVE; + xBusy2 = 0; + rc = SQLITE_OK; + } + } + + /* Read the wal-index header. */ + if( rc==SQLITE_OK ){ + rc = walIndexReadHdr(pWal, &isChanged); + if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){ + sqlite3OsUnfetch(pWal->pDbFd, 0, 0); + } + } + + /* Copy data from the log to the database file. */ + if( rc==SQLITE_OK ){ + if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){ + rc = SQLITE_CORRUPT_BKPT; + }else{ + rc = walCheckpoint(pWal, eMode2, xBusy2, pBusyArg, sync_flags, zBuf); + } + + /* If no error occurred, set the output variables. */ + if( rc==SQLITE_OK || rc==SQLITE_BUSY ){ + if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame; + if( pnCkpt ) *pnCkpt = (int)(walCkptInfo(pWal)->nBackfill); + } + } + + if( isChanged ){ + /* If a new wal-index header was loaded before the checkpoint was + ** performed, then the pager-cache associated with pWal is now + ** out of date. So zero the cached wal-index header to ensure that + ** next time the pager opens a snapshot on this database it knows that + ** the cache needs to be reset. + */ + memset(&pWal->hdr, 0, sizeof(WalIndexHdr)); + } + + /* Release the locks. */ + sqlite3WalEndWriteTransaction(pWal); + walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1); + pWal->ckptLock = 0; + WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok")); + return (rc==SQLITE_OK && eMode!=eMode2 ? SQLITE_BUSY : rc); +} + +/* Return the value to pass to a sqlite3_wal_hook callback, the +** number of frames in the WAL at the point of the last commit since +** sqlite3WalCallback() was called. If no commits have occurred since +** the last call, then return 0. +*/ +SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal){ + u32 ret = 0; + if( pWal ){ + ret = pWal->iCallback; + pWal->iCallback = 0; + } + return (int)ret; +} + +/* +** This function is called to change the WAL subsystem into or out +** of locking_mode=EXCLUSIVE. +** +** If op is zero, then attempt to change from locking_mode=EXCLUSIVE +** into locking_mode=NORMAL. This means that we must acquire a lock +** on the pWal->readLock byte. If the WAL is already in locking_mode=NORMAL +** or if the acquisition of the lock fails, then return 0. If the +** transition out of exclusive-mode is successful, return 1. This +** operation must occur while the pager is still holding the exclusive +** lock on the main database file. +** +** If op is one, then change from locking_mode=NORMAL into +** locking_mode=EXCLUSIVE. This means that the pWal->readLock must +** be released. Return 1 if the transition is made and 0 if the +** WAL is already in exclusive-locking mode - meaning that this +** routine is a no-op. The pager must already hold the exclusive lock +** on the main database file before invoking this operation. +** +** If op is negative, then do a dry-run of the op==1 case but do +** not actually change anything. The pager uses this to see if it +** should acquire the database exclusive lock prior to invoking +** the op==1 case. +*/ +SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op){ + int rc; + assert( pWal->writeLock==0 ); + assert( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE || op==-1 ); + + /* pWal->readLock is usually set, but might be -1 if there was a + ** prior error while attempting to acquire are read-lock. This cannot + ** happen if the connection is actually in exclusive mode (as no xShmLock + ** locks are taken in this case). Nor should the pager attempt to + ** upgrade to exclusive-mode following such an error. + */ + assert( pWal->readLock>=0 || pWal->lockError ); + assert( pWal->readLock>=0 || (op<=0 && pWal->exclusiveMode==0) ); + + if( op==0 ){ + if( pWal->exclusiveMode ){ + pWal->exclusiveMode = 0; + if( walLockShared(pWal, WAL_READ_LOCK(pWal->readLock))!=SQLITE_OK ){ + pWal->exclusiveMode = 1; + } + rc = pWal->exclusiveMode==0; + }else{ + /* Already in locking_mode=NORMAL */ + rc = 0; + } + }else if( op>0 ){ + assert( pWal->exclusiveMode==0 ); + assert( pWal->readLock>=0 ); + walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock)); + pWal->exclusiveMode = 1; + rc = 1; + }else{ + rc = pWal->exclusiveMode==0; + } + return rc; +} + +/* +** Return true if the argument is non-NULL and the WAL module is using +** heap-memory for the wal-index. Otherwise, if the argument is NULL or the +** WAL module is using shared-memory, return false. +*/ +SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal){ + return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ); +} + +#ifdef SQLITE_ENABLE_ZIPVFS +/* +** If the argument is not NULL, it points to a Wal object that holds a +** read-lock. This function returns the database page-size if it is known, +** or zero if it is not (or if pWal is NULL). +*/ +SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){ + assert( pWal==0 || pWal->readLock>=0 ); + return (pWal ? pWal->szPage : 0); +} +#endif + +#endif /* #ifndef SQLITE_OMIT_WAL */ + +/************** End of wal.c *************************************************/ +/************** Begin file btmutex.c *****************************************/ +/* +** 2007 August 27 +** +** 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 mutexes on Btree objects. +** This code really belongs in btree.c. But btree.c is getting too +** big and we want to break it down some. This packaged seemed like +** a good breakout. +*/ +/************** Include btreeInt.h in the middle of btmutex.c ****************/ +/************** Begin file btreeInt.h ****************************************/ +/* +** 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. +** +************************************************************************* +** This file implements an 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. +** +** The basic idea is that each page of the file contains N database +** entries and N+1 pointers to subpages. +** +** ---------------------------------------------------------------- +** | Ptr(0) | Key(0) | Ptr(1) | Key(1) | ... | Key(N-1) | Ptr(N) | +** ---------------------------------------------------------------- +** +** All of the keys on the page that Ptr(0) points to have values less +** than Key(0). All of the keys on page Ptr(1) and its subpages have +** values greater than Key(0) and less than Key(1). All of the keys +** on Ptr(N) and its subpages have values greater than Key(N-1). And +** so forth. +** +** Finding a particular key requires reading O(log(M)) pages from the +** disk where M is the number of entries in the tree. +** +** In this implementation, a single file can hold one or more separate +** BTrees. Each BTree is identified by the index of its root page. The +** key and data for any entry are combined to form the "payload". A +** fixed amount of payload can be carried directly on the database +** page. If the payload is larger than the preset amount then surplus +** bytes are stored on overflow pages. The payload for an entry +** and the preceding pointer are combined to form a "Cell". Each +** page has a small header which contains the Ptr(N) pointer and other +** information such as the size of key and data. +** +** FORMAT DETAILS +** +** The file is divided into pages. The first page is called page 1, +** the second is page 2, and so forth. A page number of zero indicates +** "no such page". The page size can be any power of 2 between 512 and 65536. +** Each page can be either a btree page, a freelist page, an overflow +** page, or a pointer-map page. +** +** The first page is always a btree page. The first 100 bytes of the first +** page contain a special header (the "file header") that describes the file. +** The format of the file header is as follows: +** +** OFFSET SIZE DESCRIPTION +** 0 16 Header string: "SQLite format 3\000" +** 16 2 Page size in bytes. (1 means 65536) +** 18 1 File format write version +** 19 1 File format read version +** 20 1 Bytes of unused space at the end of each page +** 21 1 Max embedded payload fraction (must be 64) +** 22 1 Min embedded payload fraction (must be 32) +** 23 1 Min leaf payload fraction (must be 32) +** 24 4 File change counter +** 28 4 Reserved for future use +** 32 4 First freelist page +** 36 4 Number of freelist pages in the file +** 40 60 15 4-byte meta values passed to higher layers +** +** 40 4 Schema cookie +** 44 4 File format of schema layer +** 48 4 Size of page cache +** 52 4 Largest root-page (auto/incr_vacuum) +** 56 4 1=UTF-8 2=UTF16le 3=UTF16be +** 60 4 User version +** 64 4 Incremental vacuum mode +** 68 4 Application-ID +** 72 20 unused +** 92 4 The version-valid-for number +** 96 4 SQLITE_VERSION_NUMBER +** +** All of the integer values are big-endian (most significant byte first). +** +** The file change counter is incremented when the database is changed +** This counter allows other processes to know when the file has changed +** and thus when they need to flush their cache. +** +** The max embedded payload fraction is the amount of the total usable +** space in a page that can be consumed by a single cell for standard +** B-tree (non-LEAFDATA) tables. A value of 255 means 100%. The default +** is to limit the maximum cell size so that at least 4 cells will fit +** on one page. Thus the default max embedded payload fraction is 64. +** +** If the payload for a cell is larger than the max payload, then extra +** payload is spilled to overflow pages. Once an overflow page is allocated, +** as many bytes as possible are moved into the overflow pages without letting +** the cell size drop below the min embedded payload fraction. +** +** The min leaf payload fraction is like the min embedded payload fraction +** except that it applies to leaf nodes in a LEAFDATA tree. The maximum +** payload fraction for a LEAFDATA tree is always 100% (or 255) and it +** not specified in the header. +** +** Each btree pages is divided into three sections: The header, the +** cell pointer array, and the cell content area. Page 1 also has a 100-byte +** file header that occurs before the page header. +** +** |----------------| +** | file header | 100 bytes. Page 1 only. +** |----------------| +** | page header | 8 bytes for leaves. 12 bytes for interior nodes +** |----------------| +** | cell pointer | | 2 bytes per cell. Sorted order. +** | array | | Grows downward +** | | v +** |----------------| +** | unallocated | +** | space | +** |----------------| ^ Grows upwards +** | cell content | | Arbitrary order interspersed with freeblocks. +** | area | | and free space fragments. +** |----------------| +** +** The page headers looks like this: +** +** OFFSET SIZE DESCRIPTION +** 0 1 Flags. 1: intkey, 2: zerodata, 4: leafdata, 8: leaf +** 1 2 byte offset to the first freeblock +** 3 2 number of cells on this page +** 5 2 first byte of the cell content area +** 7 1 number of fragmented free bytes +** 8 4 Right child (the Ptr(N) value). Omitted on leaves. +** +** The flags define the format of this btree page. The leaf flag means that +** this page has no children. The zerodata flag means that this page carries +** only keys and no data. The intkey flag means that the key is an integer +** which is stored in the key size entry of the cell header rather than in +** the payload area. +** +** The cell pointer array begins on the first byte after the page header. +** The cell pointer array contains zero or more 2-byte numbers which are +** offsets from the beginning of the page to the cell content in the cell +** content area. The cell pointers occur in sorted order. The system strives +** to keep free space after the last cell pointer so that new cells can +** be easily added without having to defragment the page. +** +** Cell content is stored at the very end of the page and grows toward the +** beginning of the page. +** +** Unused space within the cell content area is collected into a linked list of +** freeblocks. Each freeblock is at least 4 bytes in size. The byte offset +** to the first freeblock is given in the header. Freeblocks occur in +** increasing order. Because a freeblock must be at least 4 bytes in size, +** any group of 3 or fewer unused bytes in the cell content area cannot +** exist on the freeblock chain. A group of 3 or fewer free bytes is called +** a fragment. The total number of bytes in all fragments is recorded. +** in the page header at offset 7. +** +** SIZE DESCRIPTION +** 2 Byte offset of the next freeblock +** 2 Bytes in this freeblock +** +** Cells are of variable length. Cells are stored in the cell content area at +** the end of the page. Pointers to the cells are in the cell pointer array +** that immediately follows the page header. Cells is not necessarily +** contiguous or in order, but cell pointers are contiguous and in order. +** +** Cell content makes use of variable length integers. A variable +** length integer is 1 to 9 bytes where the lower 7 bits of each +** byte are used. The integer consists of all bytes that have bit 8 set and +** the first byte with bit 8 clear. The most significant byte of the integer +** appears first. A variable-length integer may not be more than 9 bytes long. +** As a special case, all 8 bytes of the 9th byte are used as data. This +** allows a 64-bit integer to be encoded in 9 bytes. +** +** 0x00 becomes 0x00000000 +** 0x7f becomes 0x0000007f +** 0x81 0x00 becomes 0x00000080 +** 0x82 0x00 becomes 0x00000100 +** 0x80 0x7f becomes 0x0000007f +** 0x8a 0x91 0xd1 0xac 0x78 becomes 0x12345678 +** 0x81 0x81 0x81 0x81 0x01 becomes 0x10204081 +** +** Variable length integers are used for rowids and to hold the number of +** bytes of key and data in a btree cell. +** +** The content of a cell looks like this: +** +** SIZE DESCRIPTION +** 4 Page number of the left child. Omitted if leaf flag is set. +** var Number of bytes of data. Omitted if the zerodata flag is set. +** var Number of bytes of key. Or the key itself if intkey flag is set. +** * Payload +** 4 First page of the overflow chain. Omitted if no overflow +** +** Overflow pages form a linked list. Each page except the last is completely +** filled with data (pagesize - 4 bytes). The last page can have as little +** as 1 byte of data. +** +** SIZE DESCRIPTION +** 4 Page number of next overflow page +** * Data +** +** Freelist pages come in two subtypes: trunk pages and leaf pages. The +** file header points to the first in a linked list of trunk page. Each trunk +** page points to multiple leaf pages. The content of a leaf page is +** unspecified. A trunk page looks like this: +** +** SIZE DESCRIPTION +** 4 Page number of next trunk page +** 4 Number of leaf pointers on this page +** * zero or more pages numbers of leaves +*/ + + +/* The following value is the maximum cell size assuming a maximum page +** size give above. +*/ +#define MX_CELL_SIZE(pBt) ((int)(pBt->pageSize-8)) + +/* The maximum number of cells on a single page of the database. This +** assumes a minimum cell size of 6 bytes (4 bytes for the cell itself +** plus 2 bytes for the index to the cell in the page header). Such +** small cells will be rare, but they are possible. +*/ +#define MX_CELL(pBt) ((pBt->pageSize-8)/6) + +/* 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 + +/* +** Page type flags. An ORed combination of these flags appear as the +** first byte of on-disk image of every BTree page. +*/ +#define PTF_INTKEY 0x01 +#define PTF_ZERODATA 0x02 +#define PTF_LEAFDATA 0x04 +#define PTF_LEAF 0x08 + +/* +** As each page of the file is loaded into memory, an instance of the following +** structure is appended and initialized to zero. This structure stores +** information about the page that is decoded from the raw file page. +** +** The pParent field points back to the parent page. This allows us to +** walk up the BTree from any leaf to the root. Care must be taken to +** unref() the parent page pointer when this page is no longer referenced. +** The pageDestructor() routine handles that chore. +** +** Access to all fields of this structure is controlled by the mutex +** stored in MemPage.pBt->mutex. +*/ +struct MemPage { + u8 isInit; /* True if previously initialized. MUST BE FIRST! */ + u8 nOverflow; /* Number of overflow cell bodies in aCell[] */ + u8 intKey; /* True if table b-trees. False for index b-trees */ + u8 intKeyLeaf; /* True if the leaf of an intKey table */ + u8 noPayload; /* True if internal intKey page (thus w/o data) */ + u8 leaf; /* True if a leaf page */ + u8 hdrOffset; /* 100 for page 1. 0 otherwise */ + u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */ + u8 max1bytePayload; /* min(maxLocal,127) */ + u8 bBusy; /* Prevent endless loops on corrupt database files */ + u16 maxLocal; /* Copy of BtShared.maxLocal or BtShared.maxLeaf */ + u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */ + u16 cellOffset; /* Index in aData of first cell pointer */ + u16 nFree; /* Number of free bytes on the page */ + u16 nCell; /* Number of cells on this page, local and ovfl */ + u16 maskPage; /* Mask for page offset */ + u16 aiOvfl[5]; /* Insert the i-th overflow cell before the aiOvfl-th + ** non-overflow cell */ + u8 *apOvfl[5]; /* Pointers to the body of overflow cells */ + BtShared *pBt; /* Pointer to BtShared that this page is part of */ + u8 *aData; /* Pointer to disk image of the page data */ + u8 *aDataEnd; /* One byte past the end of usable data */ + u8 *aCellIdx; /* The cell index area */ + DbPage *pDbPage; /* Pager page handle */ + Pgno pgno; /* Page number for this page */ +}; + +/* +** 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) + +/* +** 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 + +/* A Btree handle +** +** A database connection contains a pointer to an instance of +** this object for every database file that it has open. This structure +** is opaque to the database connection. The database connection cannot +** see the internals of this structure and only deals with pointers to +** this structure. +** +** For some database files, the same underlying database cache might be +** shared between multiple connections. In that case, each connection +** has it own instance of this object. But each instance of this object +** points to the same BtShared object. The database cache and the +** schema associated with the database file are all contained within +** the BtShared object. +** +** All fields in this structure are accessed under sqlite3.mutex. +** The pBt pointer itself may not be changed while there exists cursors +** in the referenced BtShared that point back to this Btree since those +** cursors have to go through this Btree to find their BtShared and +** they often do so without holding sqlite3.mutex. +*/ +struct Btree { + sqlite3 *db; /* The database connection holding this btree */ + BtShared *pBt; /* Sharable content of this btree */ + u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */ + u8 sharable; /* True if we can share pBt with another db */ + u8 locked; /* True if db currently has pBt locked */ + int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */ + int nBackup; /* Number of backup operations reading this btree */ + u32 iDataVersion; /* Combines with pBt->pPager->iDataVersion */ + Btree *pNext; /* List of other sharable Btrees from the same db */ + Btree *pPrev; /* Back pointer of the same list */ +#ifndef SQLITE_OMIT_SHARED_CACHE + BtLock lock; /* Object used to lock page 1 */ +#endif +}; + +/* +** 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. +*/ +#define TRANS_NONE 0 +#define TRANS_READ 1 +#define TRANS_WRITE 2 + +/* +** An instance of this object represents a single database file. +** +** A single database file can be in use at the same time by two +** or more database connections. When two or more connections are +** sharing the same database file, each connection has it own +** private Btree object for the file and each of those Btrees points +** to this one BtShared object. BtShared.nRef is the number of +** connections currently sharing this database file. +** +** Fields in this structure are accessed under the BtShared.mutex +** mutex, except for nRef and pNext which are accessed under the +** global SQLITE_MUTEX_STATIC_MASTER mutex. The pPager field +** may not be modified once it is initially set as long as nRef>0. +** The pSchema field may be set once under BtShared.mutex and +** thereafter is unchanged as long as nRef>0. +** +** isPending: +** +** If a BtShared client fails to obtain a write-lock on a database +** table (because there exists one or more read-locks on the table), +** the shared-cache enters 'pending-lock' state and isPending is +** set to true. +** +** The shared-cache leaves the 'pending lock' state when either of +** the following occur: +** +** 1) The current writer (BtShared.pWriter) concludes its transaction, OR +** 2) The number of locks held by other connections drops to zero. +** +** while in the 'pending-lock' state, no connection may start a new +** transaction. +** +** This feature is included to help prevent writer-starvation. +*/ +struct BtShared { + Pager *pPager; /* The page cache */ + sqlite3 *db; /* Database connection currently using this Btree */ + BtCursor *pCursor; /* A list of all open cursors */ + MemPage *pPage1; /* First page of the database */ + u8 openFlags; /* Flags to sqlite3BtreeOpen() */ +#ifndef SQLITE_OMIT_AUTOVACUUM + u8 autoVacuum; /* True if auto-vacuum is enabled */ + u8 incrVacuum; /* True if incr-vacuum is enabled */ + u8 bDoTruncate; /* True to truncate db on commit */ +#endif + u8 inTransaction; /* Transaction state */ + u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */ +#ifdef SQLITE_HAS_CODEC + u8 optimalReserve; /* Desired amount of reserved space per page */ +#endif + u16 btsFlags; /* Boolean parameters. See BTS_* macros below */ + u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */ + u16 minLocal; /* Minimum local payload in non-LEAFDATA tables */ + u16 maxLeaf; /* Maximum local payload in a LEAFDATA table */ + u16 minLeaf; /* Minimum local payload in a LEAFDATA table */ + u32 pageSize; /* Total number of bytes on a page */ + u32 usableSize; /* Number of usable bytes on each page */ + int nTransaction; /* Number of open transactions (read + write) */ + u32 nPage; /* Number of pages in the database */ + void *pSchema; /* Pointer to space allocated by sqlite3BtreeSchema() */ + void (*xFreeSchema)(void*); /* Destructor for BtShared.pSchema */ + sqlite3_mutex *mutex; /* Non-recursive mutex required to access this object */ + Bitvec *pHasContent; /* Set of pages moved to free-list this transaction */ +#ifndef SQLITE_OMIT_SHARED_CACHE + int nRef; /* Number of references to this structure */ + BtShared *pNext; /* Next on a list of sharable BtShared structs */ + BtLock *pLock; /* List of locks held on this shared-btree struct */ + Btree *pWriter; /* Btree with currently open write transaction */ +#endif + u8 *pTmpSpace; /* Temp space sufficient to hold a single cell */ +}; + +/* +** Allowed values for BtShared.btsFlags +*/ +#define BTS_READ_ONLY 0x0001 /* Underlying file is readonly */ +#define BTS_PAGESIZE_FIXED 0x0002 /* Page size can no longer be changed */ +#define BTS_SECURE_DELETE 0x0004 /* PRAGMA secure_delete is enabled */ +#define BTS_INITIALLY_EMPTY 0x0008 /* Database was empty at trans start */ +#define BTS_NO_WAL 0x0010 /* Do not open write-ahead-log files */ +#define BTS_EXCLUSIVE 0x0020 /* pWriter has an exclusive lock */ +#define BTS_PENDING 0x0040 /* Waiting for read-locks to clear */ + +/* +** 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; +struct CellInfo { + i64 nKey; /* The key for INTKEY tables, or nPayload otherwise */ + u8 *pPayload; /* Pointer to the start of payload */ + u32 nPayload; /* Bytes of payload */ + u16 nLocal; /* Amount of payload held locally, not on overflow */ + u16 iOverflow; /* Offset to overflow page number. Zero if no overflow */ + u16 nSize; /* Size of the cell content on the main b-tree page */ +}; + +/* +** Maximum depth of an SQLite B-Tree structure. Any B-Tree deeper than +** this will be declared corrupt. This value is calculated based on a +** maximum database size of 2^31 pages a minimum fanout of 2 for a +** root-node and 3 for all other internal nodes. +** +** If a tree that appears to be taller than this is encountered, it is +** assumed that the database is corrupt. +*/ +#define BTCURSOR_MAX_DEPTH 20 + +/* +** A cursor is a pointer to a particular entry within a particular +** b-tree within a database file. +** +** The entry is identified by its MemPage and the index in +** MemPage.aCell[] of the entry. +** +** A single database file can be shared by two more database connections, +** but cursors cannot be shared. Each cursor is associated with a +** particular database connection identified BtCursor.pBtree.db. +** +** Fields in this structure are accessed under the BtShared.mutex +** found at self->pBt->mutex. +** +** skipNext meaning: +** eState==SKIPNEXT && skipNext>0: Next sqlite3BtreeNext() is no-op. +** eState==SKIPNEXT && skipNext<0: Next sqlite3BtreePrevious() is no-op. +** eState==FAULT: Cursor fault with skipNext as error code. +*/ +struct BtCursor { + Btree *pBtree; /* The Btree to which this cursor belongs */ + BtShared *pBt; /* The BtShared this cursor points to */ + BtCursor *pNext, *pPrev; /* Forms a linked list of all cursors */ + struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */ + Pgno *aOverflow; /* Cache of overflow page locations */ + CellInfo info; /* A parse of the cell we are pointing at */ + i64 nKey; /* Size of pKey, or last integer key */ + void *pKey; /* Saved key that was cursor last known position */ + Pgno pgnoRoot; /* The root page of this tree */ + int nOvflAlloc; /* Allocated size of aOverflow[] array */ + int skipNext; /* Prev() is noop if negative. Next() is noop if positive. + ** Error code if eState==CURSOR_FAULT */ + u8 curFlags; /* zero or more BTCF_* flags defined below */ + u8 eState; /* One of the CURSOR_XXX constants (see below) */ + u8 hints; /* As configured by CursorSetHints() */ + i16 iPage; /* Index of current page in apPage */ + u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */ + MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */ +}; + +/* +** Legal values for BtCursor.curFlags +*/ +#define BTCF_WriteFlag 0x01 /* True if a write cursor */ +#define BTCF_ValidNKey 0x02 /* True if info.nKey is valid */ +#define BTCF_ValidOvfl 0x04 /* True if aOverflow is valid */ +#define BTCF_AtLast 0x08 /* Cursor is pointing ot the last entry */ +#define BTCF_Incrblob 0x10 /* True if an incremental I/O handle */ + +/* +** Potential values for BtCursor.eState. +** +** 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_VALID: +** Cursor points to a valid entry. getPayload() etc. may be called. +** +** CURSOR_SKIPNEXT: +** Cursor is valid except that the Cursor.skipNext field is non-zero +** indicating that the next sqlite3BtreeNext() or sqlite3BtreePrevious() +** operation should be a no-op. +** +** 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, restoreCursorPosition() can be called to attempt to +** seek the cursor to the saved position. +** +** CURSOR_FAULT: +** An unrecoverable error (an I/O error or a malloc failure) has occurred +** on a different connection that shares the BtShared cache with this +** cursor. The error has left the cache in an inconsistent state. +** Do nothing else with this cursor. Any attempt to use the cursor +** should return the error code stored in BtCursor.skipNext +*/ +#define CURSOR_INVALID 0 +#define CURSOR_VALID 1 +#define CURSOR_SKIPNEXT 2 +#define CURSOR_REQUIRESEEK 3 +#define CURSOR_FAULT 4 + +/* +** The database page the PENDING_BYTE occupies. This page is never used. +*/ +# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt) + +/* +** 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. +** +** PTRMAP_PAGENO returns the database page number of the pointer-map +** page that stores the required pointer. PTRMAP_PTROFFSET returns +** the offset of the requested map entry. +** +** If the pgno argument passed to PTRMAP_PAGENO is a pointer-map page, +** then pgno is returned. So (pgno==PTRMAP_PAGENO(pgsz, pgno)) can be +** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements +** this test. +*/ +#define PTRMAP_PAGENO(pBt, pgno) ptrmapPageno(pBt, pgno) +#define PTRMAP_PTROFFSET(pgptrmap, pgno) (5*(pgno-pgptrmap-1)) +#define PTRMAP_ISPAGE(pBt, pgno) (PTRMAP_PAGENO((pBt),(pgno))==(pgno)) + +/* +** The pointer map is a lookup table that identifies the parent page for +** each child page in the database file. The parent page is the page that +** contains a pointer to the child. Every page in the database contains +** 0 or 1 parent pages. (In this context 'database page' refers +** to any page that is not part of the pointer map itself.) Each pointer map +** entry consists of a single byte 'type' and a 4 byte parent page number. +** The PTRMAP_XXX identifiers below are the valid types. +** +** The purpose of the pointer map is to facility moving pages from one +** position in the file to another as part of autovacuum. When a page +** is moved, the pointer in its parent must be updated to point to the +** new location. The pointer map is used to locate the parent page quickly. +** +** PTRMAP_ROOTPAGE: The database page is a root-page. The page-number is not +** used in this case. +** +** PTRMAP_FREEPAGE: The database page is an unused (free) page. The page-number +** is not used in this case. +** +** PTRMAP_OVERFLOW1: The database page is the first page in a list of +** overflow pages. The page number identifies the page that +** contains the cell with a pointer to this overflow page. +** +** PTRMAP_OVERFLOW2: The database page is the second or later page in a list of +** overflow pages. The page-number identifies the previous +** page in the overflow page list. +** +** PTRMAP_BTREE: The database page is a non-root btree page. The page number +** identifies the parent page in the btree. +*/ +#define PTRMAP_ROOTPAGE 1 +#define PTRMAP_FREEPAGE 2 +#define PTRMAP_OVERFLOW1 3 +#define PTRMAP_OVERFLOW2 4 +#define PTRMAP_BTREE 5 + +/* A bunch of assert() statements to check the transaction state variables +** of handle p (type Btree*) are internally consistent. +*/ +#define btreeIntegrity(p) \ + assert( p->pBt->inTransaction!=TRANS_NONE || p->pBt->nTransaction==0 ); \ + assert( p->pBt->inTransaction>=p->inTrans ); + + +/* +** The ISAUTOVACUUM macro is used within balance_nonroot() to determine +** if the database supports auto-vacuum or not. Because it is used +** within an expression that is an argument to another macro +** (sqliteMallocRaw), it is not possible to use conditional compilation. +** So, this macro is defined instead. +*/ +#ifndef SQLITE_OMIT_AUTOVACUUM +#define ISAUTOVACUUM (pBt->autoVacuum) +#else +#define ISAUTOVACUUM 0 +#endif + + +/* +** This structure is passed around through all the sanity checking routines +** in order to keep track of some global state information. +** +** The aRef[] array is allocated so that there is 1 bit for each page in +** the database. As the integrity-check proceeds, for each page used in +** the database the corresponding bit is set. This allows integrity-check to +** detect pages that are used twice and orphaned pages (both of which +** indicate corruption). +*/ +typedef struct IntegrityCk IntegrityCk; +struct IntegrityCk { + BtShared *pBt; /* The tree being checked out */ + Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */ + u8 *aPgRef; /* 1 bit per page in the db (see above) */ + Pgno nPage; /* Number of pages in the database */ + int mxErr; /* Stop accumulating errors when this reaches zero */ + int nErr; /* Number of messages written to zErrMsg so far */ + int mallocFailed; /* A memory allocation error has occurred */ + const char *zPfx; /* Error message prefix */ + int v1, v2; /* Values for up to two %d fields in zPfx */ + StrAccum errMsg; /* Accumulate the error message text here */ +}; + +/* +** Routines to read or write a two- and four-byte big-endian integer values. +*/ +#define get2byte(x) ((x)[0]<<8 | (x)[1]) +#define put2byte(p,v) ((p)[0] = (u8)((v)>>8), (p)[1] = (u8)(v)) +#define get4byte sqlite3Get4byte +#define put4byte sqlite3Put4byte + +/************** End of btreeInt.h ********************************************/ +/************** Continuing where we left off in btmutex.c ********************/ +#ifndef SQLITE_OMIT_SHARED_CACHE +#if SQLITE_THREADSAFE + +/* +** Obtain the BtShared mutex associated with B-Tree handle p. Also, +** set BtShared.db to the database handle associated with p and the +** p->locked boolean to true. +*/ +static void lockBtreeMutex(Btree *p){ + assert( p->locked==0 ); + assert( sqlite3_mutex_notheld(p->pBt->mutex) ); + assert( sqlite3_mutex_held(p->db->mutex) ); + + sqlite3_mutex_enter(p->pBt->mutex); + p->pBt->db = p->db; + p->locked = 1; +} + +/* +** Release the BtShared mutex associated with B-Tree handle p and +** clear the p->locked boolean. +*/ +static void SQLITE_NOINLINE unlockBtreeMutex(Btree *p){ + BtShared *pBt = p->pBt; + assert( p->locked==1 ); + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3_mutex_held(p->db->mutex) ); + assert( p->db==pBt->db ); + + sqlite3_mutex_leave(pBt->mutex); + p->locked = 0; +} + +/* Forward reference */ +static void SQLITE_NOINLINE btreeLockCarefully(Btree *p); + +/* +** Enter a mutex on the given BTree object. +** +** If the object is not sharable, then no mutex is ever required +** and this routine is a no-op. The underlying mutex is non-recursive. +** But we keep a reference count in Btree.wantToLock so the behavior +** of this interface is recursive. +** +** To avoid deadlocks, multiple Btrees are locked in the same order +** by all database connections. The p->pNext is a list of other +** Btrees belonging to the same database connection as the p Btree +** which need to be locked after p. If we cannot get a lock on +** p, then first unlock all of the others on p->pNext, then wait +** for the lock to become available on p, then relock all of the +** subsequent Btrees that desire a lock. +*/ +SQLITE_PRIVATE void sqlite3BtreeEnter(Btree *p){ + /* Some basic sanity checking on the Btree. The list of Btrees + ** connected by pNext and pPrev should be in sorted order by + ** Btree.pBt value. All elements of the list should belong to + ** the same connection. Only shared Btrees are on the list. */ + assert( p->pNext==0 || p->pNext->pBt>p->pBt ); + assert( p->pPrev==0 || p->pPrev->pBtpBt ); + assert( p->pNext==0 || p->pNext->db==p->db ); + assert( p->pPrev==0 || p->pPrev->db==p->db ); + assert( p->sharable || (p->pNext==0 && p->pPrev==0) ); + + /* Check for locking consistency */ + assert( !p->locked || p->wantToLock>0 ); + assert( p->sharable || p->wantToLock==0 ); + + /* We should already hold a lock on the database connection */ + assert( sqlite3_mutex_held(p->db->mutex) ); + + /* Unless the database is sharable and unlocked, then BtShared.db + ** should already be set correctly. */ + assert( (p->locked==0 && p->sharable) || p->pBt->db==p->db ); + + if( !p->sharable ) return; + p->wantToLock++; + if( p->locked ) return; + btreeLockCarefully(p); +} + +/* This is a helper function for sqlite3BtreeLock(). By moving +** complex, but seldom used logic, out of sqlite3BtreeLock() and +** into this routine, we avoid unnecessary stack pointer changes +** and thus help the sqlite3BtreeLock() routine to run much faster +** in the common case. +*/ +static void SQLITE_NOINLINE btreeLockCarefully(Btree *p){ + Btree *pLater; + + /* In most cases, we should be able to acquire the lock we + ** want without having to go through the ascending lock + ** procedure that follows. Just be sure not to block. + */ + if( sqlite3_mutex_try(p->pBt->mutex)==SQLITE_OK ){ + p->pBt->db = p->db; + p->locked = 1; + return; + } + + /* To avoid deadlock, first release all locks with a larger + ** BtShared address. Then acquire our lock. Then reacquire + ** the other BtShared locks that we used to hold in ascending + ** order. + */ + for(pLater=p->pNext; pLater; pLater=pLater->pNext){ + assert( pLater->sharable ); + assert( pLater->pNext==0 || pLater->pNext->pBt>pLater->pBt ); + assert( !pLater->locked || pLater->wantToLock>0 ); + if( pLater->locked ){ + unlockBtreeMutex(pLater); + } + } + lockBtreeMutex(p); + for(pLater=p->pNext; pLater; pLater=pLater->pNext){ + if( pLater->wantToLock ){ + lockBtreeMutex(pLater); + } + } +} + + +/* +** Exit the recursive mutex on a Btree. +*/ +SQLITE_PRIVATE void sqlite3BtreeLeave(Btree *p){ + assert( sqlite3_mutex_held(p->db->mutex) ); + if( p->sharable ){ + assert( p->wantToLock>0 ); + p->wantToLock--; + if( p->wantToLock==0 ){ + unlockBtreeMutex(p); + } + } +} + +#ifndef NDEBUG +/* +** Return true if the BtShared mutex is held on the btree, or if the +** B-Tree is not marked as sharable. +** +** This routine is used only from within assert() statements. +*/ +SQLITE_PRIVATE int sqlite3BtreeHoldsMutex(Btree *p){ + assert( p->sharable==0 || p->locked==0 || p->wantToLock>0 ); + assert( p->sharable==0 || p->locked==0 || p->db==p->pBt->db ); + assert( p->sharable==0 || p->locked==0 || sqlite3_mutex_held(p->pBt->mutex) ); + assert( p->sharable==0 || p->locked==0 || sqlite3_mutex_held(p->db->mutex) ); + + return (p->sharable==0 || p->locked); +} +#endif + + +#ifndef SQLITE_OMIT_INCRBLOB +/* +** Enter and leave a mutex on a Btree given a cursor owned by that +** Btree. These entry points are used by incremental I/O and can be +** omitted if that module is not used. +*/ +SQLITE_PRIVATE void sqlite3BtreeEnterCursor(BtCursor *pCur){ + sqlite3BtreeEnter(pCur->pBtree); +} +SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor *pCur){ + sqlite3BtreeLeave(pCur->pBtree); +} +#endif /* SQLITE_OMIT_INCRBLOB */ + + +/* +** Enter the mutex on every Btree associated with a database +** connection. This is needed (for example) prior to parsing +** a statement since we will be comparing table and column names +** against all schemas and we do not want those schemas being +** reset out from under us. +** +** There is a corresponding leave-all procedures. +** +** Enter the mutexes in accending order by BtShared pointer address +** to avoid the possibility of deadlock when two threads with +** two or more btrees in common both try to lock all their btrees +** at the same instant. +*/ +SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){ + int i; + Btree *p; + assert( sqlite3_mutex_held(db->mutex) ); + for(i=0; inDb; i++){ + p = db->aDb[i].pBt; + if( p ) sqlite3BtreeEnter(p); + } +} +SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3 *db){ + int i; + Btree *p; + assert( sqlite3_mutex_held(db->mutex) ); + for(i=0; inDb; i++){ + p = db->aDb[i].pBt; + if( p ) sqlite3BtreeLeave(p); + } +} + +/* +** Return true if a particular Btree requires a lock. Return FALSE if +** no lock is ever required since it is not sharable. +*/ +SQLITE_PRIVATE int sqlite3BtreeSharable(Btree *p){ + return p->sharable; +} + +#ifndef NDEBUG +/* +** Return true if the current thread holds the database connection +** mutex and all required BtShared mutexes. +** +** This routine is used inside assert() statements only. +*/ +SQLITE_PRIVATE int sqlite3BtreeHoldsAllMutexes(sqlite3 *db){ + int i; + if( !sqlite3_mutex_held(db->mutex) ){ + return 0; + } + for(i=0; inDb; i++){ + Btree *p; + p = db->aDb[i].pBt; + if( p && p->sharable && + (p->wantToLock==0 || !sqlite3_mutex_held(p->pBt->mutex)) ){ + return 0; + } + } + return 1; +} +#endif /* NDEBUG */ + +#ifndef NDEBUG +/* +** Return true if the correct mutexes are held for accessing the +** db->aDb[iDb].pSchema structure. The mutexes required for schema +** access are: +** +** (1) The mutex on db +** (2) if iDb!=1, then the mutex on db->aDb[iDb].pBt. +** +** If pSchema is not NULL, then iDb is computed from pSchema and +** db using sqlite3SchemaToIndex(). +*/ +SQLITE_PRIVATE int sqlite3SchemaMutexHeld(sqlite3 *db, int iDb, Schema *pSchema){ + Btree *p; + assert( db!=0 ); + if( pSchema ) iDb = sqlite3SchemaToIndex(db, pSchema); + assert( iDb>=0 && iDbnDb ); + if( !sqlite3_mutex_held(db->mutex) ) return 0; + if( iDb==1 ) return 1; + p = db->aDb[iDb].pBt; + assert( p!=0 ); + return p->sharable==0 || p->locked==1; +} +#endif /* NDEBUG */ + +#else /* SQLITE_THREADSAFE>0 above. SQLITE_THREADSAFE==0 below */ +/* +** The following are special cases for mutex enter routines for use +** in single threaded applications that use shared cache. Except for +** these two routines, all mutex operations are no-ops in that case and +** are null #defines in btree.h. +** +** If shared cache is disabled, then all btree mutex routines, including +** the ones below, are no-ops and are null #defines in btree.h. +*/ + +SQLITE_PRIVATE void sqlite3BtreeEnter(Btree *p){ + p->pBt->db = p->db; +} +SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){ + int i; + for(i=0; inDb; i++){ + Btree *p = db->aDb[i].pBt; + if( p ){ + p->pBt->db = p->db; + } + } +} +#endif /* if SQLITE_THREADSAFE */ +#endif /* ifndef SQLITE_OMIT_SHARED_CACHE */ + +/************** End of btmutex.c *********************************************/ +/************** Begin file btree.c *******************************************/ +/* +** 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. +** +************************************************************************* +** This file implements an external (disk-based) database using BTrees. +** See the header comment on "btreeInt.h" for additional information. +** Including a description of file format and an overview of operation. +*/ + +/* +** The header string that appears at the beginning of every +** SQLite database. +*/ +static const char zMagicHeader[] = SQLITE_FILE_HEADER; + +/* +** Set this global variable to 1 to enable tracing using the TRACE +** macro. +*/ +#if 0 +int sqlite3BtreeTrace=1; /* True to enable tracing */ +# define TRACE(X) if(sqlite3BtreeTrace){printf X;fflush(stdout);} +#else +# define TRACE(X) +#endif + +/* +** Extract a 2-byte big-endian integer from an array of unsigned bytes. +** But if the value is zero, make it 65536. +** +** This routine is used to extract the "offset to cell content area" value +** from the header of a btree page. If the page size is 65536 and the page +** is empty, the offset should be 65536, but the 2-byte value stores zero. +** This routine makes the necessary adjustment to 65536. +*/ +#define get2byteNotZero(X) (((((int)get2byte(X))-1)&0xffff)+1) + +/* +** Values passed as the 5th argument to allocateBtreePage() +*/ +#define BTALLOC_ANY 0 /* Allocate any page */ +#define BTALLOC_EXACT 1 /* Allocate exact page if possible */ +#define BTALLOC_LE 2 /* Allocate any page <= the parameter */ + +/* +** Macro IfNotOmitAV(x) returns (x) if SQLITE_OMIT_AUTOVACUUM is not +** defined, or 0 if it is. For example: +** +** bIncrVacuum = IfNotOmitAV(pBtShared->incrVacuum); +*/ +#ifndef SQLITE_OMIT_AUTOVACUUM +#define IfNotOmitAV(expr) (expr) +#else +#define IfNotOmitAV(expr) 0 +#endif + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** A list of BtShared objects that are eligible for participation +** in shared cache. This variable has file scope during normal builds, +** but the test harness needs to access it so we make it global for +** test builds. +** +** Access to this variable is protected by SQLITE_MUTEX_STATIC_MASTER. +*/ +#ifdef SQLITE_TEST +SQLITE_PRIVATE BtShared *SQLITE_WSD sqlite3SharedCacheList = 0; +#else +static BtShared *SQLITE_WSD sqlite3SharedCacheList = 0; +#endif +#endif /* SQLITE_OMIT_SHARED_CACHE */ + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** Enable or disable the shared pager and schema features. +** +** This routine has no effect on existing database connections. +** The shared cache setting effects only future calls to +** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2(). +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int enable){ + sqlite3GlobalConfig.sharedCacheEnabled = enable; + return SQLITE_OK; +} +#endif + + + +#ifdef SQLITE_OMIT_SHARED_CACHE + /* + ** The functions querySharedCacheTableLock(), setSharedCacheTableLock(), + ** and clearAllSharedCacheTableLocks() + ** 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 querySharedCacheTableLock(a,b,c) SQLITE_OK + #define setSharedCacheTableLock(a,b,c) SQLITE_OK + #define clearAllSharedCacheTableLocks(a) + #define downgradeAllSharedCacheTableLocks(a) + #define hasSharedCacheTableLock(a,b,c,d) 1 + #define hasReadConflicts(a, b) 0 +#endif + +#ifndef SQLITE_OMIT_SHARED_CACHE + +#ifdef SQLITE_DEBUG +/* +**** This function is only used as part of an assert() statement. *** +** +** Check to see if pBtree holds the required locks to read or write to the +** table with root page iRoot. Return 1 if it does and 0 if not. +** +** For example, when writing to a table with root-page iRoot via +** Btree connection pBtree: +** +** assert( hasSharedCacheTableLock(pBtree, iRoot, 0, WRITE_LOCK) ); +** +** When writing to an index that resides in a sharable database, the +** caller should have first obtained a lock specifying the root page of +** the corresponding table. This makes things a bit more complicated, +** as this module treats each table as a separate structure. To determine +** the table corresponding to the index being written, this +** function has to search through the database schema. +** +** Instead of a lock on the table/index rooted at page iRoot, the caller may +** hold a write-lock on the schema table (root page 1). This is also +** acceptable. +*/ +static int hasSharedCacheTableLock( + Btree *pBtree, /* Handle that must hold lock */ + Pgno iRoot, /* Root page of b-tree */ + int isIndex, /* True if iRoot is the root of an index b-tree */ + int eLockType /* Required lock type (READ_LOCK or WRITE_LOCK) */ +){ + Schema *pSchema = (Schema *)pBtree->pBt->pSchema; + Pgno iTab = 0; + BtLock *pLock; + + /* If this database is not shareable, or if the client is reading + ** and has the read-uncommitted flag set, then no lock is required. + ** Return true immediately. + */ + if( (pBtree->sharable==0) + || (eLockType==READ_LOCK && (pBtree->db->flags & SQLITE_ReadUncommitted)) + ){ + return 1; + } + + /* If the client is reading or writing an index and the schema is + ** not loaded, then it is too difficult to actually check to see if + ** the correct locks are held. So do not bother - just return true. + ** This case does not come up very often anyhow. + */ + if( isIndex && (!pSchema || (pSchema->schemaFlags&DB_SchemaLoaded)==0) ){ + return 1; + } + + /* Figure out the root-page that the lock should be held on. For table + ** b-trees, this is just the root page of the b-tree being read or + ** written. For index b-trees, it is the root page of the associated + ** table. */ + if( isIndex ){ + HashElem *p; + for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){ + Index *pIdx = (Index *)sqliteHashData(p); + if( pIdx->tnum==(int)iRoot ){ + if( iTab ){ + /* Two or more indexes share the same root page. There must + ** be imposter tables. So just return true. The assert is not + ** useful in that case. */ + return 1; + } + iTab = pIdx->pTable->tnum; + } + } + }else{ + iTab = iRoot; + } + + /* Search for the required lock. Either a write-lock on root-page iTab, a + ** write-lock on the schema table, or (if the client is reading) a + ** read-lock on iTab will suffice. Return 1 if any of these are found. */ + for(pLock=pBtree->pBt->pLock; pLock; pLock=pLock->pNext){ + if( pLock->pBtree==pBtree + && (pLock->iTable==iTab || (pLock->eLock==WRITE_LOCK && pLock->iTable==1)) + && pLock->eLock>=eLockType + ){ + return 1; + } + } + + /* Failed to find the required lock. */ + return 0; +} +#endif /* SQLITE_DEBUG */ + +#ifdef SQLITE_DEBUG +/* +**** This function may be used as part of assert() statements only. **** +** +** Return true if it would be illegal for pBtree to write into the +** table or index rooted at iRoot because other shared connections are +** simultaneously reading that same table or index. +** +** It is illegal for pBtree to write if some other Btree object that +** shares the same BtShared object is currently reading or writing +** the iRoot table. Except, if the other Btree object has the +** read-uncommitted flag set, then it is OK for the other object to +** have a read cursor. +** +** For example, before writing to any part of the table or index +** rooted at page iRoot, one should call: +** +** assert( !hasReadConflicts(pBtree, iRoot) ); +*/ +static int hasReadConflicts(Btree *pBtree, Pgno iRoot){ + BtCursor *p; + for(p=pBtree->pBt->pCursor; p; p=p->pNext){ + if( p->pgnoRoot==iRoot + && p->pBtree!=pBtree + && 0==(p->pBtree->db->flags & SQLITE_ReadUncommitted) + ){ + return 1; + } + } + return 0; +} +#endif /* #ifdef SQLITE_DEBUG */ + +/* +** 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 +** setSharedCacheTableLock()), or SQLITE_LOCKED if not. +*/ +static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){ + BtShared *pBt = p->pBt; + BtLock *pIter; + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( eLock==READ_LOCK || eLock==WRITE_LOCK ); + assert( p->db!=0 ); + assert( !(p->db->flags&SQLITE_ReadUncommitted)||eLock==WRITE_LOCK||iTab==1 ); + + /* If requesting a write-lock, then the Btree must have an open write + ** transaction on this file. And, obviously, for this to be so there + ** must be an open write transaction on the file itself. + */ + assert( eLock==READ_LOCK || (p==pBt->pWriter && p->inTrans==TRANS_WRITE) ); + assert( eLock==READ_LOCK || pBt->inTransaction==TRANS_WRITE ); + + /* This routine is a no-op if the shared-cache is not enabled */ + if( !p->sharable ){ + return SQLITE_OK; + } + + /* If some other connection is holding an exclusive lock, the + ** requested lock may not be obtained. + */ + if( pBt->pWriter!=p && (pBt->btsFlags & BTS_EXCLUSIVE)!=0 ){ + sqlite3ConnectionBlocked(p->db, pBt->pWriter->db); + return SQLITE_LOCKED_SHAREDCACHE; + } + + for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ + /* The condition (pIter->eLock!=eLock) in the following if(...) + ** statement is a simplification of: + ** + ** (eLock==WRITE_LOCK || pIter->eLock==WRITE_LOCK) + ** + ** since we know that if eLock==WRITE_LOCK, then no other connection + ** may hold a WRITE_LOCK on any table in this file (since there can + ** only be a single writer). + */ + assert( pIter->eLock==READ_LOCK || pIter->eLock==WRITE_LOCK ); + assert( eLock==READ_LOCK || pIter->pBtree==p || pIter->eLock==READ_LOCK); + if( pIter->pBtree!=p && pIter->iTable==iTab && pIter->eLock!=eLock ){ + sqlite3ConnectionBlocked(p->db, pIter->pBtree->db); + if( eLock==WRITE_LOCK ){ + assert( p==pBt->pWriter ); + pBt->btsFlags |= BTS_PENDING; + } + return SQLITE_LOCKED_SHAREDCACHE; + } + } + return SQLITE_OK; +} +#endif /* !SQLITE_OMIT_SHARED_CACHE */ + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** 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. +** +** This function assumes the following: +** +** (a) The specified Btree object p is connected to a sharable +** database (one with the BtShared.sharable flag set), and +** +** (b) No other Btree objects hold a lock that conflicts +** with the requested lock (i.e. querySharedCacheTableLock() has +** already been called and returned SQLITE_OK). +** +** SQLITE_OK is returned if the lock is added successfully. SQLITE_NOMEM +** is returned if a malloc attempt fails. +*/ +static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){ + BtShared *pBt = p->pBt; + BtLock *pLock = 0; + BtLock *pIter; + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( eLock==READ_LOCK || eLock==WRITE_LOCK ); + assert( p->db!=0 ); + + /* A connection with the read-uncommitted flag set will never try to + ** obtain a read-lock using this function. The only read-lock obtained + ** by a connection in read-uncommitted mode is on the sqlite_master + ** table, and that lock is obtained in BtreeBeginTrans(). */ + assert( 0==(p->db->flags&SQLITE_ReadUncommitted) || eLock==WRITE_LOCK ); + + /* This function should only be called on a sharable b-tree after it + ** has been determined that no other b-tree holds a conflicting lock. */ + assert( p->sharable ); + assert( SQLITE_OK==querySharedCacheTableLock(p, iTable, eLock) ); + + /* 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 *)sqlite3MallocZero(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; +} +#endif /* !SQLITE_OMIT_SHARED_CACHE */ + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** Release all the table locks (locks obtained via calls to +** the setSharedCacheTableLock() procedure) held by Btree object p. +** +** This function assumes that Btree p has an open read or write +** transaction. If it does not, then the BTS_PENDING flag +** may be incorrectly cleared. +*/ +static void clearAllSharedCacheTableLocks(Btree *p){ + BtShared *pBt = p->pBt; + BtLock **ppIter = &pBt->pLock; + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( p->sharable || 0==*ppIter ); + assert( p->inTrans>0 ); + + while( *ppIter ){ + BtLock *pLock = *ppIter; + assert( (pBt->btsFlags & BTS_EXCLUSIVE)==0 || pBt->pWriter==pLock->pBtree ); + assert( pLock->pBtree->inTrans>=pLock->eLock ); + if( pLock->pBtree==p ){ + *ppIter = pLock->pNext; + assert( pLock->iTable!=1 || pLock==&p->lock ); + if( pLock->iTable!=1 ){ + sqlite3_free(pLock); + } + }else{ + ppIter = &pLock->pNext; + } + } + + assert( (pBt->btsFlags & BTS_PENDING)==0 || pBt->pWriter ); + if( pBt->pWriter==p ){ + pBt->pWriter = 0; + pBt->btsFlags &= ~(BTS_EXCLUSIVE|BTS_PENDING); + }else if( pBt->nTransaction==2 ){ + /* This function is called when Btree p is concluding its + ** transaction. If there currently exists a writer, and p is not + ** that writer, then the number of locks held by connections other + ** than the writer must be about to drop to zero. In this case + ** set the BTS_PENDING flag to 0. + ** + ** If there is not currently a writer, then BTS_PENDING must + ** be zero already. So this next line is harmless in that case. + */ + pBt->btsFlags &= ~BTS_PENDING; + } +} + +/* +** This function changes all write-locks held by Btree p into read-locks. +*/ +static void downgradeAllSharedCacheTableLocks(Btree *p){ + BtShared *pBt = p->pBt; + if( pBt->pWriter==p ){ + BtLock *pLock; + pBt->pWriter = 0; + pBt->btsFlags &= ~(BTS_EXCLUSIVE|BTS_PENDING); + for(pLock=pBt->pLock; pLock; pLock=pLock->pNext){ + assert( pLock->eLock==READ_LOCK || pLock->pBtree==p ); + pLock->eLock = READ_LOCK; + } + } +} + +#endif /* SQLITE_OMIT_SHARED_CACHE */ + +static void releasePage(MemPage *pPage); /* Forward reference */ + +/* +***** This routine is used inside of assert() only **** +** +** Verify that the cursor holds the mutex on its BtShared +*/ +#ifdef SQLITE_DEBUG +static int cursorHoldsMutex(BtCursor *p){ + return sqlite3_mutex_held(p->pBt->mutex); +} +#endif + +/* +** Invalidate the overflow cache of the cursor passed as the first argument. +** on the shared btree structure pBt. +*/ +#define invalidateOverflowCache(pCur) (pCur->curFlags &= ~BTCF_ValidOvfl) + +/* +** Invalidate the overflow page-list cache for all cursors opened +** on the shared btree structure pBt. +*/ +static void invalidateAllOverflowCache(BtShared *pBt){ + BtCursor *p; + assert( sqlite3_mutex_held(pBt->mutex) ); + for(p=pBt->pCursor; p; p=p->pNext){ + invalidateOverflowCache(p); + } +} + +#ifndef SQLITE_OMIT_INCRBLOB +/* +** This function is called before modifying the contents of a table +** to invalidate any incrblob cursors that are open on the +** row or one of the rows being modified. +** +** If argument isClearTable is true, then the entire contents of the +** table is about to be deleted. In this case invalidate all incrblob +** cursors open on any row within the table with root-page pgnoRoot. +** +** Otherwise, if argument isClearTable is false, then the row with +** rowid iRow is being replaced or deleted. In this case invalidate +** only those incrblob cursors open on that specific row. +*/ +static void invalidateIncrblobCursors( + Btree *pBtree, /* The database file to check */ + i64 iRow, /* The rowid that might be changing */ + int isClearTable /* True if all rows are being deleted */ +){ + BtCursor *p; + BtShared *pBt = pBtree->pBt; + assert( sqlite3BtreeHoldsMutex(pBtree) ); + for(p=pBt->pCursor; p; p=p->pNext){ + if( (p->curFlags & BTCF_Incrblob)!=0 + && (isClearTable || p->info.nKey==iRow) + ){ + p->eState = CURSOR_INVALID; + } + } +} + +#else + /* Stub function when INCRBLOB is omitted */ + #define invalidateIncrblobCursors(x,y,z) +#endif /* SQLITE_OMIT_INCRBLOB */ + +/* +** Set bit pgno of the BtShared.pHasContent bitvec. This is called +** when a page that previously contained data becomes a free-list leaf +** page. +** +** The BtShared.pHasContent bitvec exists to work around an obscure +** bug caused by the interaction of two useful IO optimizations surrounding +** free-list leaf pages: +** +** 1) When all data is deleted from a page and the page becomes +** a free-list leaf page, the page is not written to the database +** (as free-list leaf pages contain no meaningful data). Sometimes +** such a page is not even journalled (as it will not be modified, +** why bother journalling it?). +** +** 2) When a free-list leaf page is reused, its content is not read +** from the database or written to the journal file (why should it +** be, if it is not at all meaningful?). +** +** By themselves, these optimizations work fine and provide a handy +** performance boost to bulk delete or insert operations. However, if +** a page is moved to the free-list and then reused within the same +** transaction, a problem comes up. If the page is not journalled when +** it is moved to the free-list and it is also not journalled when it +** is extracted from the free-list and reused, then the original data +** may be lost. In the event of a rollback, it may not be possible +** to restore the database to its original configuration. +** +** The solution is the BtShared.pHasContent bitvec. Whenever a page is +** moved to become a free-list leaf page, the corresponding bit is +** set in the bitvec. Whenever a leaf page is extracted from the free-list, +** optimization 2 above is omitted if the corresponding bit is already +** set in BtShared.pHasContent. The contents of the bitvec are cleared +** at the end of every transaction. +*/ +static int btreeSetHasContent(BtShared *pBt, Pgno pgno){ + int rc = SQLITE_OK; + if( !pBt->pHasContent ){ + assert( pgno<=pBt->nPage ); + pBt->pHasContent = sqlite3BitvecCreate(pBt->nPage); + if( !pBt->pHasContent ){ + rc = SQLITE_NOMEM; + } + } + if( rc==SQLITE_OK && pgno<=sqlite3BitvecSize(pBt->pHasContent) ){ + rc = sqlite3BitvecSet(pBt->pHasContent, pgno); + } + return rc; +} + +/* +** Query the BtShared.pHasContent vector. +** +** This function is called when a free-list leaf page is removed from the +** free-list for reuse. It returns false if it is safe to retrieve the +** page from the pager layer with the 'no-content' flag set. True otherwise. +*/ +static int btreeGetHasContent(BtShared *pBt, Pgno pgno){ + Bitvec *p = pBt->pHasContent; + return (p && (pgno>sqlite3BitvecSize(p) || sqlite3BitvecTest(p, pgno))); +} + +/* +** Clear (destroy) the BtShared.pHasContent bitvec. This should be +** invoked at the conclusion of each write-transaction. +*/ +static void btreeClearHasContent(BtShared *pBt){ + sqlite3BitvecDestroy(pBt->pHasContent); + pBt->pHasContent = 0; +} + +/* +** Release all of the apPage[] pages for a cursor. +*/ +static void btreeReleaseAllCursorPages(BtCursor *pCur){ + int i; + for(i=0; i<=pCur->iPage; i++){ + releasePage(pCur->apPage[i]); + pCur->apPage[i] = 0; + } + pCur->iPage = -1; +} + + +/* +** Save the current cursor position in the variables BtCursor.nKey +** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK. +** +** The caller must ensure that the cursor is valid (has eState==CURSOR_VALID) +** prior to calling this routine. +*/ +static int saveCursorPosition(BtCursor *pCur){ + int rc; + + assert( CURSOR_VALID==pCur->eState || CURSOR_SKIPNEXT==pCur->eState ); + assert( 0==pCur->pKey ); + assert( cursorHoldsMutex(pCur) ); + + if( pCur->eState==CURSOR_SKIPNEXT ){ + pCur->eState = CURSOR_VALID; + }else{ + pCur->skipNext = 0; + } + rc = sqlite3BtreeKeySize(pCur, &pCur->nKey); + assert( rc==SQLITE_OK ); /* KeySize() cannot fail */ + + /* 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( 0==pCur->apPage[0]->intKey ){ + void *pKey = sqlite3Malloc( pCur->nKey ); + if( pKey ){ + rc = sqlite3BtreeKey(pCur, 0, (int)pCur->nKey, pKey); + if( rc==SQLITE_OK ){ + pCur->pKey = pKey; + }else{ + sqlite3_free(pKey); + } + }else{ + rc = SQLITE_NOMEM; + } + } + assert( !pCur->apPage[0]->intKey || !pCur->pKey ); + + if( rc==SQLITE_OK ){ + btreeReleaseAllCursorPages(pCur); + pCur->eState = CURSOR_REQUIRESEEK; + } + + invalidateOverflowCache(pCur); + return rc; +} + +/* Forward reference */ +static int SQLITE_NOINLINE saveCursorsOnList(BtCursor*,Pgno,BtCursor*); + +/* +** Save the positions of all cursors (except pExcept) that are open on +** the table with root-page iRoot. "Saving the cursor position" means that +** the location in the btree is remembered in such a way that it can be +** moved back to the same spot after the btree has been modified. This +** routine is called just before cursor pExcept is used to modify the +** table, for example in BtreeDelete() or BtreeInsert(). +** +** Implementation note: This routine merely checks to see if any cursors +** need to be saved. It calls out to saveCursorsOnList() in the (unusual) +** event that cursors are in need to being saved. +*/ +static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){ + BtCursor *p; + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( pExcept==0 || pExcept->pBt==pBt ); + for(p=pBt->pCursor; p; p=p->pNext){ + if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ) break; + } + return p ? saveCursorsOnList(p, iRoot, pExcept) : SQLITE_OK; +} + +/* This helper routine to saveAllCursors does the actual work of saving +** the cursors if and when a cursor is found that actually requires saving. +** The common case is that no cursors need to be saved, so this routine is +** broken out from its caller to avoid unnecessary stack pointer movement. +*/ +static int SQLITE_NOINLINE saveCursorsOnList( + BtCursor *p, /* The first cursor that needs saving */ + Pgno iRoot, /* Only save cursor with this iRoot. Save all if zero */ + BtCursor *pExcept /* Do not save this cursor */ +){ + do{ + if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){ + if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){ + int rc = saveCursorPosition(p); + if( SQLITE_OK!=rc ){ + return rc; + } + }else{ + testcase( p->iPage>0 ); + btreeReleaseAllCursorPages(p); + } + } + p = p->pNext; + }while( p ); + return SQLITE_OK; +} + +/* +** Clear the current cursor position. +*/ +SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *pCur){ + assert( cursorHoldsMutex(pCur) ); + sqlite3_free(pCur->pKey); + pCur->pKey = 0; + pCur->eState = CURSOR_INVALID; +} + +/* +** In this version of BtreeMoveto, pKey is a packed index record +** such as is generated by the OP_MakeRecord opcode. Unpack the +** record and then call BtreeMovetoUnpacked() to do the work. +*/ +static int btreeMoveto( + BtCursor *pCur, /* Cursor open on the btree to be searched */ + const void *pKey, /* Packed key if the btree is an index */ + i64 nKey, /* Integer key for tables. Size of pKey for indices */ + int bias, /* Bias search to the high end */ + int *pRes /* Write search results here */ +){ + int rc; /* Status code */ + UnpackedRecord *pIdxKey; /* Unpacked index key */ + char aSpace[200]; /* Temp space for pIdxKey - to avoid a malloc */ + char *pFree = 0; + + if( pKey ){ + assert( nKey==(i64)(int)nKey ); + pIdxKey = sqlite3VdbeAllocUnpackedRecord( + pCur->pKeyInfo, aSpace, sizeof(aSpace), &pFree + ); + if( pIdxKey==0 ) return SQLITE_NOMEM; + sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey); + if( pIdxKey->nField==0 ){ + sqlite3DbFree(pCur->pKeyInfo->db, pFree); + return SQLITE_CORRUPT_BKPT; + } + }else{ + pIdxKey = 0; + } + rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes); + if( pFree ){ + sqlite3DbFree(pCur->pKeyInfo->db, pFree); + } + return rc; +} + +/* +** 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 restoreCursorPosition() call after each +** saveCursorPosition(). +*/ +static int btreeRestoreCursorPosition(BtCursor *pCur){ + int rc; + int skipNext; + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState>=CURSOR_REQUIRESEEK ); + if( pCur->eState==CURSOR_FAULT ){ + return pCur->skipNext; + } + pCur->eState = CURSOR_INVALID; + rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &skipNext); + if( rc==SQLITE_OK ){ + sqlite3_free(pCur->pKey); + pCur->pKey = 0; + assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID ); + pCur->skipNext |= skipNext; + if( pCur->skipNext && pCur->eState==CURSOR_VALID ){ + pCur->eState = CURSOR_SKIPNEXT; + } + } + return rc; +} + +#define restoreCursorPosition(p) \ + (p->eState>=CURSOR_REQUIRESEEK ? \ + btreeRestoreCursorPosition(p) : \ + SQLITE_OK) + +/* +** Determine whether or not a cursor has moved from the position where +** it was last placed, or has been invalidated for any other reason. +** Cursors can move when the row they are pointing at is deleted out +** from under them, for example. Cursor might also move if a btree +** is rebalanced. +** +** Calling this routine with a NULL cursor pointer returns false. +** +** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor +** back to where it ought to be if this routine returns true. +*/ +SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){ + return pCur->eState!=CURSOR_VALID; +} + +/* +** This routine restores a cursor back to its original position after it +** has been moved by some outside activity (such as a btree rebalance or +** a row having been deleted out from under the cursor). +** +** On success, the *pDifferentRow parameter is false if the cursor is left +** pointing at exactly the same row. *pDifferntRow is the row the cursor +** was pointing to has been deleted, forcing the cursor to point to some +** nearby row. +** +** This routine should only be called for a cursor that just returned +** TRUE from sqlite3BtreeCursorHasMoved(). +*/ +SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow){ + int rc; + + assert( pCur!=0 ); + assert( pCur->eState!=CURSOR_VALID ); + rc = restoreCursorPosition(pCur); + if( rc ){ + *pDifferentRow = 1; + return rc; + } + if( pCur->eState!=CURSOR_VALID ){ + *pDifferentRow = 1; + }else{ + assert( pCur->skipNext==0 ); + *pDifferentRow = 0; + } + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** Given a page number of a regular database page, return the page +** number for the pointer-map page that contains the entry for the +** input page number. +** +** Return 0 (not a valid page) for pgno==1 since there is +** no pointer map associated with page 1. The integrity_check logic +** requires that ptrmapPageno(*,1)!=1. +*/ +static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){ + int nPagesPerMapPage; + Pgno iPtrMap, ret; + assert( sqlite3_mutex_held(pBt->mutex) ); + if( pgno<2 ) return 0; + nPagesPerMapPage = (pBt->usableSize/5)+1; + iPtrMap = (pgno-2)/nPagesPerMapPage; + ret = (iPtrMap*nPagesPerMapPage) + 2; + if( ret==PENDING_BYTE_PAGE(pBt) ){ + ret++; + } + return ret; +} + +/* +** 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'. +** +** If *pRC is initially non-zero (non-SQLITE_OK) then this routine is +** a no-op. If an error occurs, the appropriate error code is written +** into *pRC. +*/ +static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){ + DbPage *pDbPage; /* The pointer map page */ + u8 *pPtrmap; /* The pointer map data */ + Pgno iPtrmap; /* The pointer map page number */ + int offset; /* Offset in pointer map page */ + int rc; /* Return code from subfunctions */ + + if( *pRC ) return; + + assert( sqlite3_mutex_held(pBt->mutex) ); + /* The master-journal page number must never be used as a pointer map page */ + assert( 0==PTRMAP_ISPAGE(pBt, PENDING_BYTE_PAGE(pBt)) ); + + assert( pBt->autoVacuum ); + if( key==0 ){ + *pRC = SQLITE_CORRUPT_BKPT; + return; + } + iPtrmap = PTRMAP_PAGENO(pBt, key); + rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage); + if( rc!=SQLITE_OK ){ + *pRC = rc; + return; + } + offset = PTRMAP_PTROFFSET(iPtrmap, key); + if( offset<0 ){ + *pRC = SQLITE_CORRUPT_BKPT; + goto ptrmap_exit; + } + assert( offset <= (int)pBt->usableSize-5 ); + pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); + + if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){ + TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent)); + *pRC= rc = sqlite3PagerWrite(pDbPage); + if( rc==SQLITE_OK ){ + pPtrmap[offset] = eType; + put4byte(&pPtrmap[offset+1], parent); + } + } + +ptrmap_exit: + sqlite3PagerUnref(pDbPage); +} + +/* +** 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){ + DbPage *pDbPage; /* The pointer map page */ + int iPtrmap; /* Pointer map page index */ + u8 *pPtrmap; /* Pointer map page data */ + int offset; /* Offset of entry in pointer map */ + int rc; + + assert( sqlite3_mutex_held(pBt->mutex) ); + + iPtrmap = PTRMAP_PAGENO(pBt, key); + rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage); + if( rc!=0 ){ + return rc; + } + pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); + + offset = PTRMAP_PTROFFSET(iPtrmap, key); + if( offset<0 ){ + sqlite3PagerUnref(pDbPage); + return SQLITE_CORRUPT_BKPT; + } + assert( offset <= (int)pBt->usableSize-5 ); + assert( pEType!=0 ); + *pEType = pPtrmap[offset]; + if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]); + + sqlite3PagerUnref(pDbPage); + if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT_BKPT; + return SQLITE_OK; +} + +#else /* if defined SQLITE_OMIT_AUTOVACUUM */ + #define ptrmapPut(w,x,y,z,rc) + #define ptrmapGet(w,x,y,z) SQLITE_OK + #define ptrmapPutOvflPtr(x, y, rc) +#endif + +/* +** Given a btree page and a cell index (0 means the first cell on +** the page, 1 means the second cell, and so forth) return a pointer +** to the cell content. +** +** This routine works only for pages that do not contain overflow cells. +*/ +#define findCell(P,I) \ + ((P)->aData + ((P)->maskPage & get2byte(&(P)->aCellIdx[2*(I)]))) +#define findCellv2(D,M,O,I) (D+(M&get2byte(D+(O+2*(I))))) + + +/* +** This a more complex version of findCell() that works for +** pages that do contain overflow cells. +*/ +static u8 *findOverflowCell(MemPage *pPage, int iCell){ + int i; + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + for(i=pPage->nOverflow-1; i>=0; i--){ + int k; + k = pPage->aiOvfl[i]; + if( k<=iCell ){ + if( k==iCell ){ + return pPage->apOvfl[i]; + } + iCell--; + } + } + return findCell(pPage, iCell); +} + +/* +** Parse a cell content block and fill in the CellInfo structure. There +** are two versions of this function. btreeParseCell() takes a +** cell index as the second argument and btreeParseCellPtr() +** takes a pointer to the body of the cell as its second argument. +*/ +static void btreeParseCellPtr( + MemPage *pPage, /* Page containing the cell */ + u8 *pCell, /* Pointer to the cell text. */ + CellInfo *pInfo /* Fill in this structure */ +){ + u8 *pIter; /* For scanning through pCell */ + u32 nPayload; /* Number of bytes of cell payload */ + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->leaf==0 || pPage->leaf==1 ); + if( pPage->intKeyLeaf ){ + assert( pPage->childPtrSize==0 ); + pIter = pCell + getVarint32(pCell, nPayload); + pIter += getVarint(pIter, (u64*)&pInfo->nKey); + }else if( pPage->noPayload ){ + assert( pPage->childPtrSize==4 ); + pInfo->nSize = 4 + getVarint(&pCell[4], (u64*)&pInfo->nKey); + pInfo->nPayload = 0; + pInfo->nLocal = 0; + pInfo->iOverflow = 0; + pInfo->pPayload = 0; + return; + }else{ + pIter = pCell + pPage->childPtrSize; + pIter += getVarint32(pIter, nPayload); + pInfo->nKey = nPayload; + } + pInfo->nPayload = nPayload; + pInfo->pPayload = pIter; + testcase( nPayload==pPage->maxLocal ); + testcase( nPayload==pPage->maxLocal+1 ); + if( nPayload<=pPage->maxLocal ){ + /* This is the (easy) common case where the entire payload fits + ** on the local page. No overflow is required. + */ + pInfo->nSize = nPayload + (u16)(pIter - pCell); + if( pInfo->nSize<4 ) pInfo->nSize = 4; + pInfo->nLocal = (u16)nPayload; + pInfo->iOverflow = 0; + }else{ + /* If the payload will not fit completely on the local page, we have + ** to decide how much to store locally and how much to spill onto + ** overflow pages. The strategy is to minimize the amount of unused + ** space on overflow pages while keeping the amount of local storage + ** in between minLocal and maxLocal. + ** + ** Warning: changing the way overflow payload is distributed in any + ** way will result in an incompatible file format. + */ + int minLocal; /* Minimum amount of payload held locally */ + int maxLocal; /* Maximum amount of payload held locally */ + int surplus; /* Overflow payload available for local storage */ + + minLocal = pPage->minLocal; + maxLocal = pPage->maxLocal; + surplus = minLocal + (nPayload - minLocal)%(pPage->pBt->usableSize - 4); + testcase( surplus==maxLocal ); + testcase( surplus==maxLocal+1 ); + if( surplus <= maxLocal ){ + pInfo->nLocal = (u16)surplus; + }else{ + pInfo->nLocal = (u16)minLocal; + } + pInfo->iOverflow = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell); + pInfo->nSize = pInfo->iOverflow + 4; + } +} +static void btreeParseCell( + MemPage *pPage, /* Page containing the cell */ + int iCell, /* The cell index. First cell is 0 */ + CellInfo *pInfo /* Fill in this structure */ +){ + btreeParseCellPtr(pPage, findCell(pPage, iCell), pInfo); +} + +/* +** Compute the total number of bytes that a Cell needs in the cell +** data area of the btree-page. The return number includes the cell +** data header and the local payload, but not any overflow page or +** the space used by the cell pointer. +*/ +static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ + u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */ + u8 *pEnd; /* End mark for a varint */ + u32 nSize; /* Size value to return */ + +#ifdef SQLITE_DEBUG + /* The value returned by this function should always be the same as + ** the (CellInfo.nSize) value found by doing a full parse of the + ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of + ** this function verifies that this invariant is not violated. */ + CellInfo debuginfo; + btreeParseCellPtr(pPage, pCell, &debuginfo); +#endif + + if( pPage->noPayload ){ + pEnd = &pIter[9]; + while( (*pIter++)&0x80 && pIterchildPtrSize==4 ); + return (u16)(pIter - pCell); + } + nSize = *pIter; + if( nSize>=0x80 ){ + pEnd = &pIter[9]; + nSize &= 0x7f; + do{ + nSize = (nSize<<7) | (*++pIter & 0x7f); + }while( *(pIter)>=0x80 && pIterintKey ){ + /* pIter now points at the 64-bit integer key value, a variable length + ** integer. The following block moves pIter to point at the first byte + ** past the end of the key value. */ + pEnd = &pIter[9]; + while( (*pIter++)&0x80 && pItermaxLocal ); + testcase( nSize==pPage->maxLocal+1 ); + if( nSize<=pPage->maxLocal ){ + nSize += (u32)(pIter - pCell); + if( nSize<4 ) nSize = 4; + }else{ + int minLocal = pPage->minLocal; + nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4); + testcase( nSize==pPage->maxLocal ); + testcase( nSize==pPage->maxLocal+1 ); + if( nSize>pPage->maxLocal ){ + nSize = minLocal; + } + nSize += 4 + (u16)(pIter - pCell); + } + assert( nSize==debuginfo.nSize || CORRUPT_DB ); + return (u16)nSize; +} + +#ifdef SQLITE_DEBUG +/* This variation on cellSizePtr() is used inside of assert() statements +** only. */ +static u16 cellSize(MemPage *pPage, int iCell){ + return cellSizePtr(pPage, findCell(pPage, iCell)); +} +#endif + +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** If the cell pCell, part of page pPage contains a pointer +** to an overflow page, insert an entry into the pointer-map +** for the overflow page. +*/ +static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){ + CellInfo info; + if( *pRC ) return; + assert( pCell!=0 ); + btreeParseCellPtr(pPage, pCell, &info); + if( info.iOverflow ){ + Pgno ovfl = get4byte(&pCell[info.iOverflow]); + ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC); + } +} +#endif + + +/* +** 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. +** +** EVIDENCE-OF: R-44582-60138 SQLite may from time to time reorganize a +** b-tree page so that there are no freeblocks or fragment bytes, all +** unused bytes are contained in the unallocated space region, and all +** cells are packed tightly at the end of the page. +*/ +static int defragmentPage(MemPage *pPage){ + int i; /* Loop counter */ + int pc; /* Address of the i-th cell */ + int hdr; /* Offset to the page header */ + int size; /* Size of a cell */ + int usableSize; /* Number of usable bytes on a page */ + int cellOffset; /* Offset to the cell pointer array */ + int cbrk; /* Offset to the cell content area */ + int nCell; /* Number of cells on the page */ + unsigned char *data; /* The page data */ + unsigned char *temp; /* Temp area for cell content */ + unsigned char *src; /* Source of content */ + int iCellFirst; /* First allowable cell index */ + int iCellLast; /* Last possible cell index */ + + + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( pPage->pBt!=0 ); + assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE ); + assert( pPage->nOverflow==0 ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + temp = 0; + src = data = pPage->aData; + hdr = pPage->hdrOffset; + cellOffset = pPage->cellOffset; + nCell = pPage->nCell; + assert( nCell==get2byte(&data[hdr+3]) ); + usableSize = pPage->pBt->usableSize; + cbrk = usableSize; + iCellFirst = cellOffset + 2*nCell; + iCellLast = usableSize - 4; + for(i=0; iiCellLast ){ + return SQLITE_CORRUPT_BKPT; + } +#endif + assert( pc>=iCellFirst && pc<=iCellLast ); + size = cellSizePtr(pPage, &src[pc]); + cbrk -= size; +#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK) + if( cbrkusableSize ){ + return SQLITE_CORRUPT_BKPT; + } +#endif + assert( cbrk+size<=usableSize && cbrk>=iCellFirst ); + testcase( cbrk+size==usableSize ); + testcase( pc+size==usableSize ); + put2byte(pAddr, cbrk); + if( temp==0 ){ + int x; + if( cbrk==pc ) continue; + temp = sqlite3PagerTempSpace(pPage->pBt->pPager); + x = get2byte(&data[hdr+5]); + memcpy(&temp[x], &data[x], (cbrk+size) - x); + src = temp; + } + memcpy(&data[cbrk], &src[pc], size); + } + assert( cbrk>=iCellFirst ); + put2byte(&data[hdr+5], cbrk); + data[hdr+1] = 0; + data[hdr+2] = 0; + data[hdr+7] = 0; + memset(&data[iCellFirst], 0, cbrk-iCellFirst); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + if( cbrk-iCellFirst!=pPage->nFree ){ + return SQLITE_CORRUPT_BKPT; + } + return SQLITE_OK; +} + +/* +** Search the free-list on page pPg for space to store a cell nByte bytes in +** size. If one can be found, return a pointer to the space and remove it +** from the free-list. +** +** If no suitable space can be found on the free-list, return NULL. +** +** This function may detect corruption within pPg. If corruption is +** detected then *pRc is set to SQLITE_CORRUPT and NULL is returned. +** +** If a slot of at least nByte bytes is found but cannot be used because +** there are already at least 60 fragmented bytes on the page, return NULL. +** In this case, if pbDefrag parameter is not NULL, set *pbDefrag to true. +*/ +static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc, int *pbDefrag){ + const int hdr = pPg->hdrOffset; + u8 * const aData = pPg->aData; + int iAddr; + int pc; + int usableSize = pPg->pBt->usableSize; + + for(iAddr=hdr+1; (pc = get2byte(&aData[iAddr]))>0; iAddr=pc){ + int size; /* Size of the free slot */ + /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of + ** increasing offset. */ + if( pc>usableSize-4 || pc=nByte ){ + int x = size - nByte; + testcase( x==4 ); + testcase( x==3 ); + if( x<4 ){ + /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total + ** number of bytes in fragments may not exceed 60. */ + if( aData[hdr+7]>=60 ){ + if( pbDefrag ) *pbDefrag = 1; + return 0; + } + /* Remove the slot from the free-list. Update the number of + ** fragmented bytes within the page. */ + memcpy(&aData[iAddr], &aData[pc], 2); + aData[hdr+7] += (u8)x; + }else if( size+pc > usableSize ){ + *pRc = SQLITE_CORRUPT_BKPT; + return 0; + }else{ + /* The slot remains on the free-list. Reduce its size to account + ** for the portion used by the new allocation. */ + put2byte(&aData[pc+2], x); + } + return &aData[pc + x]; + } + } + + return 0; +} + +/* +** Allocate nByte bytes of space from within the B-Tree page passed +** as the first argument. Write into *pIdx the index into pPage->aData[] +** of the first byte of allocated space. Return either SQLITE_OK or +** an error code (usually SQLITE_CORRUPT). +** +** The caller guarantees that there is sufficient space to make the +** allocation. This routine might need to defragment in order to bring +** all the space together, however. This routine will avoid using +** the first two bytes past the cell pointer area since presumably this +** allocation is being made in order to insert a new cell, so we will +** also end up needing a new cell pointer. +*/ +static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ + const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */ + u8 * const data = pPage->aData; /* Local cache of pPage->aData */ + int top; /* First byte of cell content area */ + int rc = SQLITE_OK; /* Integer return code */ + int gap; /* First byte of gap between cell pointers and cell content */ + + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( pPage->pBt ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( nByte>=0 ); /* Minimum cell size is 4 */ + assert( pPage->nFree>=nByte ); + assert( pPage->nOverflow==0 ); + assert( nByte < (int)(pPage->pBt->usableSize-8) ); + + assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf ); + gap = pPage->cellOffset + 2*pPage->nCell; + assert( gap<=65536 ); + /* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size + ** and the reserved space is zero (the usual value for reserved space) + ** then the cell content offset of an empty page wants to be 65536. + ** However, that integer is too large to be stored in a 2-byte unsigned + ** integer, so a value of 0 is used in its place. */ + top = get2byteNotZero(&data[hdr+5]); + if( gap>top ) return SQLITE_CORRUPT_BKPT; + + /* If there is enough space between gap and top for one more cell pointer + ** array entry offset, and if the freelist is not empty, then search the + ** freelist looking for a free slot big enough to satisfy the request. + */ + testcase( gap+2==top ); + testcase( gap+1==top ); + testcase( gap==top ); + if( gap+2<=top && (data[hdr+1] || data[hdr+2]) ){ + int bDefrag = 0; + u8 *pSpace = pageFindSlot(pPage, nByte, &rc, &bDefrag); + if( rc ) return rc; + if( bDefrag ) goto defragment_page; + if( pSpace ){ + assert( pSpace>=data && (pSpace - data)<65536 ); + *pIdx = (int)(pSpace - data); + return SQLITE_OK; + } + } + + /* The request could not be fulfilled using a freelist slot. Check + ** to see if defragmentation is necessary. + */ + testcase( gap+2+nByte==top ); + if( gap+2+nByte>top ){ + defragment_page: + assert( pPage->nCell>0 || CORRUPT_DB ); + rc = defragmentPage(pPage); + if( rc ) return rc; + top = get2byteNotZero(&data[hdr+5]); + assert( gap+nByte<=top ); + } + + + /* Allocate memory from the gap in between the cell pointer array + ** and the cell content area. The btreeInitPage() call has already + ** validated the freelist. Given that the freelist is valid, there + ** is no way that the allocation can extend off the end of the page. + ** The assert() below verifies the previous sentence. + */ + top -= nByte; + put2byte(&data[hdr+5], top); + assert( top+nByte <= (int)pPage->pBt->usableSize ); + *pIdx = top; + return SQLITE_OK; +} + +/* +** Return a section of the pPage->aData to the freelist. +** The first byte of the new free block is pPage->aData[iStart] +** and the size of the block is iSize bytes. +** +** Adjacent freeblocks are coalesced. +** +** Note that even though the freeblock list was checked by btreeInitPage(), +** that routine will not detect overlap between cells or freeblocks. Nor +** does it detect cells or freeblocks that encrouch into the reserved bytes +** at the end of the page. So do additional corruption checks inside this +** routine and return SQLITE_CORRUPT if any problems are found. +*/ +static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ + u16 iPtr; /* Address of ptr to next freeblock */ + u16 iFreeBlk; /* Address of the next freeblock */ + u8 hdr; /* Page header size. 0 or 100 */ + u8 nFrag = 0; /* Reduction in fragmentation */ + u16 iOrigSize = iSize; /* Original value of iSize */ + u32 iLast = pPage->pBt->usableSize-4; /* Largest possible freeblock offset */ + u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */ + unsigned char *data = pPage->aData; /* Page content */ + + assert( pPage->pBt!=0 ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( iStart>=pPage->hdrOffset+6+pPage->childPtrSize ); + assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( iSize>=4 ); /* Minimum cell size is 4 */ + assert( iStart<=iLast ); + + /* Overwrite deleted information with zeros when the secure_delete + ** option is enabled */ + if( pPage->pBt->btsFlags & BTS_SECURE_DELETE ){ + memset(&data[iStart], 0, iSize); + } + + /* The list of freeblocks must be in ascending order. Find the + ** spot on the list where iStart should be inserted. + */ + hdr = pPage->hdrOffset; + iPtr = hdr + 1; + if( data[iPtr+1]==0 && data[iPtr]==0 ){ + iFreeBlk = 0; /* Shortcut for the case when the freelist is empty */ + }else{ + while( (iFreeBlk = get2byte(&data[iPtr]))>0 && iFreeBlkiLast ) return SQLITE_CORRUPT_BKPT; + assert( iFreeBlk>iPtr || iFreeBlk==0 ); + + /* At this point: + ** iFreeBlk: First freeblock after iStart, or zero if none + ** iPtr: The address of a pointer iFreeBlk + ** + ** Check to see if iFreeBlk should be coalesced onto the end of iStart. + */ + if( iFreeBlk && iEnd+3>=iFreeBlk ){ + nFrag = iFreeBlk - iEnd; + if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_BKPT; + iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]); + iSize = iEnd - iStart; + iFreeBlk = get2byte(&data[iFreeBlk]); + } + + /* If iPtr is another freeblock (that is, if iPtr is not the freelist + ** pointer in the page header) then check to see if iStart should be + ** coalesced onto the end of iPtr. + */ + if( iPtr>hdr+1 ){ + int iPtrEnd = iPtr + get2byte(&data[iPtr+2]); + if( iPtrEnd+3>=iStart ){ + if( iPtrEnd>iStart ) return SQLITE_CORRUPT_BKPT; + nFrag += iStart - iPtrEnd; + iSize = iEnd - iPtr; + iStart = iPtr; + } + } + if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_BKPT; + data[hdr+7] -= nFrag; + } + if( iStart==get2byte(&data[hdr+5]) ){ + /* The new freeblock is at the beginning of the cell content area, + ** so just extend the cell content area rather than create another + ** freelist entry */ + if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_BKPT; + put2byte(&data[hdr+1], iFreeBlk); + put2byte(&data[hdr+5], iEnd); + }else{ + /* Insert the new freeblock into the freelist */ + put2byte(&data[iPtr], iStart); + put2byte(&data[iStart], iFreeBlk); + put2byte(&data[iStart+2], iSize); + } + pPage->nFree += iOrigSize; + return SQLITE_OK; +} + +/* +** Decode the flags byte (the first byte of the header) for a page +** and initialize fields of the MemPage structure accordingly. +** +** Only the following combinations are supported. Anything different +** indicates a corrupt database files: +** +** PTF_ZERODATA +** PTF_ZERODATA | PTF_LEAF +** PTF_LEAFDATA | PTF_INTKEY +** PTF_LEAFDATA | PTF_INTKEY | PTF_LEAF +*/ +static int decodeFlags(MemPage *pPage, int flagByte){ + BtShared *pBt; /* A copy of pPage->pBt */ + + assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + pPage->leaf = (u8)(flagByte>>3); assert( PTF_LEAF == 1<<3 ); + flagByte &= ~PTF_LEAF; + pPage->childPtrSize = 4-4*pPage->leaf; + pBt = pPage->pBt; + if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){ + /* EVIDENCE-OF: R-03640-13415 A value of 5 means the page is an interior + ** table b-tree page. */ + assert( (PTF_LEAFDATA|PTF_INTKEY)==5 ); + /* EVIDENCE-OF: R-20501-61796 A value of 13 means the page is a leaf + ** table b-tree page. */ + assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 ); + pPage->intKey = 1; + pPage->intKeyLeaf = pPage->leaf; + pPage->noPayload = !pPage->leaf; + pPage->maxLocal = pBt->maxLeaf; + pPage->minLocal = pBt->minLeaf; + }else if( flagByte==PTF_ZERODATA ){ + /* EVIDENCE-OF: R-27225-53936 A value of 2 means the page is an interior + ** index b-tree page. */ + assert( (PTF_ZERODATA)==2 ); + /* EVIDENCE-OF: R-16571-11615 A value of 10 means the page is a leaf + ** index b-tree page. */ + assert( (PTF_ZERODATA|PTF_LEAF)==10 ); + pPage->intKey = 0; + pPage->intKeyLeaf = 0; + pPage->noPayload = 0; + pPage->maxLocal = pBt->maxLocal; + pPage->minLocal = pBt->minLocal; + }else{ + /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is + ** an error. */ + return SQLITE_CORRUPT_BKPT; + } + pPage->max1bytePayload = pBt->max1bytePayload; + return SQLITE_OK; +} + +/* +** Initialize the auxiliary information for a disk block. +** +** Return SQLITE_OK on success. If we see that the page does +** not contain a well-formed database page, then return +** SQLITE_CORRUPT. Note that a return of SQLITE_OK does not +** guarantee that the page is well-formed. It only shows that +** we failed to detect any corruption. +*/ +static int btreeInitPage(MemPage *pPage){ + + assert( pPage->pBt!=0 ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) ); + assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) ); + assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) ); + + if( !pPage->isInit ){ + u16 pc; /* Address of a freeblock within pPage->aData[] */ + u8 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 */ + u16 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 */ + int iCellFirst; /* First allowable cell or freeblock offset */ + int iCellLast; /* Last possible cell or freeblock offset */ + + pBt = pPage->pBt; + + hdr = pPage->hdrOffset; + data = pPage->aData; + /* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating + ** the b-tree page type. */ + if( decodeFlags(pPage, data[hdr]) ) return SQLITE_CORRUPT_BKPT; + assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); + pPage->maskPage = (u16)(pBt->pageSize - 1); + pPage->nOverflow = 0; + usableSize = pBt->usableSize; + pPage->cellOffset = cellOffset = hdr + 8 + pPage->childPtrSize; + pPage->aDataEnd = &data[usableSize]; + pPage->aCellIdx = &data[cellOffset]; + /* EVIDENCE-OF: R-58015-48175 The two-byte integer at offset 5 designates + ** the start of the cell content area. A zero value for this integer is + ** interpreted as 65536. */ + top = get2byteNotZero(&data[hdr+5]); + /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the + ** number of cells on the page. */ + 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; + } + testcase( pPage->nCell==MX_CELL(pBt) ); + /* EVIDENCE-OF: R-24089-57979 If a page contains no cells (which is only + ** possible for a root page of a table that contains no rows) then the + ** offset to the cell content area will equal the page size minus the + ** bytes of reserved space. */ + assert( pPage->nCell>0 || top==usableSize || CORRUPT_DB ); + + /* A malformed database page might cause us to read past the end + ** of page when parsing a cell. + ** + ** The following block of code checks early to see if a cell extends + ** past the end of a page boundary and causes SQLITE_CORRUPT to be + ** returned if it does. + */ + iCellFirst = cellOffset + 2*pPage->nCell; + iCellLast = usableSize - 4; +#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK) + { + int i; /* Index into the cell pointer array */ + int sz; /* Size of a cell */ + + if( !pPage->leaf ) iCellLast--; + for(i=0; inCell; i++){ + pc = get2byte(&data[cellOffset+i*2]); + testcase( pc==iCellFirst ); + testcase( pc==iCellLast ); + if( pciCellLast ){ + return SQLITE_CORRUPT_BKPT; + } + sz = cellSizePtr(pPage, &data[pc]); + testcase( pc+sz==usableSize ); + if( pc+sz>usableSize ){ + return SQLITE_CORRUPT_BKPT; + } + } + if( !pPage->leaf ) iCellLast++; + } +#endif + + /* Compute the total free space on the page + ** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the + ** start of the first freeblock on the page, or is zero if there are no + ** freeblocks. */ + pc = get2byte(&data[hdr+1]); + nFree = data[hdr+7] + top; /* Init nFree to non-freeblock free space */ + while( pc>0 ){ + u16 next, size; + if( pciCellLast ){ + /* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will + ** always be at least one cell before the first freeblock. + ** + ** Or, the freeblock is off the end of the page + */ + return SQLITE_CORRUPT_BKPT; + } + next = get2byte(&data[pc]); + size = get2byte(&data[pc+2]); + if( (next>0 && next<=pc+size+3) || pc+size>usableSize ){ + /* Free blocks must be in ascending order. And the last byte of + ** the free-block must lie on the database page. */ + return SQLITE_CORRUPT_BKPT; + } + nFree = nFree + size; + pc = next; + } + + /* At this point, nFree contains the sum of the offset to the start + ** of the cell-content area plus the number of free bytes within + ** the cell-content area. If this is greater than the usable-size + ** of the page, then the page must be corrupted. This check also + ** serves to verify that the offset to the start of the cell-content + ** area, according to the page header, lies within the page. + */ + if( nFree>usableSize ){ + return SQLITE_CORRUPT_BKPT; + } + pPage->nFree = (u16)(nFree - iCellFirst); + pPage->isInit = 1; + } + 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; + u8 hdr = pPage->hdrOffset; + u16 first; + + assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno ); + assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); + assert( sqlite3PagerGetData(pPage->pDbPage) == data ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( sqlite3_mutex_held(pBt->mutex) ); + if( pBt->btsFlags & BTS_SECURE_DELETE ){ + memset(&data[hdr], 0, pBt->usableSize - hdr); + } + data[hdr] = (char)flags; + first = hdr + ((flags&PTF_LEAF)==0 ? 12 : 8); + memset(&data[hdr+1], 0, 4); + data[hdr+7] = 0; + put2byte(&data[hdr+5], pBt->usableSize); + pPage->nFree = (u16)(pBt->usableSize - first); + decodeFlags(pPage, flags); + pPage->cellOffset = first; + pPage->aDataEnd = &data[pBt->usableSize]; + pPage->aCellIdx = &data[first]; + pPage->nOverflow = 0; + assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); + pPage->maskPage = (u16)(pBt->pageSize - 1); + pPage->nCell = 0; + pPage->isInit = 1; +} + + +/* +** Convert a DbPage obtained from the pager into a MemPage used by +** the btree layer. +*/ +static MemPage *btreePageFromDbPage(DbPage *pDbPage, Pgno pgno, BtShared *pBt){ + MemPage *pPage = (MemPage*)sqlite3PagerGetExtra(pDbPage); + pPage->aData = sqlite3PagerGetData(pDbPage); + pPage->pDbPage = pDbPage; + pPage->pBt = pBt; + pPage->pgno = pgno; + pPage->hdrOffset = pPage->pgno==1 ? 100 : 0; + return pPage; +} + +/* +** Get a page from the pager. Initialize the MemPage.pBt and +** MemPage.aData elements if needed. +** +** If the noContent flag is set, it means that we do not care about +** the content of the page at this time. So do not go to the disk +** to fetch the content. Just fill in the content with zeros for now. +** If in the future we call sqlite3PagerWrite() on this page, that +** means we have started to be concerned about content and the disk +** read should occur at that point. +*/ +static int btreeGetPage( + BtShared *pBt, /* The btree */ + Pgno pgno, /* Number of the page to fetch */ + MemPage **ppPage, /* Return the page in this parameter */ + int flags /* PAGER_GET_NOCONTENT or PAGER_GET_READONLY */ +){ + int rc; + DbPage *pDbPage; + + assert( flags==0 || flags==PAGER_GET_NOCONTENT || flags==PAGER_GET_READONLY ); + assert( sqlite3_mutex_held(pBt->mutex) ); + rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, flags); + if( rc ) return rc; + *ppPage = btreePageFromDbPage(pDbPage, pgno, pBt); + return SQLITE_OK; +} + +/* +** Retrieve a page from the pager cache. If the requested page is not +** already in the pager cache return NULL. Initialize the MemPage.pBt and +** MemPage.aData elements if needed. +*/ +static MemPage *btreePageLookup(BtShared *pBt, Pgno pgno){ + DbPage *pDbPage; + assert( sqlite3_mutex_held(pBt->mutex) ); + pDbPage = sqlite3PagerLookup(pBt->pPager, pgno); + if( pDbPage ){ + return btreePageFromDbPage(pDbPage, pgno, pBt); + } + return 0; +} + +/* +** Return the size of the database file in pages. If there is any kind of +** error, return ((unsigned int)-1). +*/ +static Pgno btreePagecount(BtShared *pBt){ + return pBt->nPage; +} +SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree *p){ + assert( sqlite3BtreeHoldsMutex(p) ); + assert( ((p->pBt->nPage)&0x8000000)==0 ); + return btreePagecount(p->pBt); +} + +/* +** Get a page from the pager and initialize it. This routine is just a +** convenience wrapper around separate calls to btreeGetPage() and +** btreeInitPage(). +** +** If an error occurs, then the value *ppPage is set to is undefined. It +** may remain unchanged, or it may be set to an invalid value. +*/ +static int getAndInitPage( + BtShared *pBt, /* The database file */ + Pgno pgno, /* Number of the page to get */ + MemPage **ppPage, /* Write the page pointer here */ + int bReadonly /* PAGER_GET_READONLY or 0 */ +){ + int rc; + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( bReadonly==PAGER_GET_READONLY || bReadonly==0 ); + + if( pgno>btreePagecount(pBt) ){ + rc = SQLITE_CORRUPT_BKPT; + }else{ + rc = btreeGetPage(pBt, pgno, ppPage, bReadonly); + if( rc==SQLITE_OK && (*ppPage)->isInit==0 ){ + rc = btreeInitPage(*ppPage); + if( rc!=SQLITE_OK ){ + releasePage(*ppPage); + } + } + } + + testcase( pgno==0 ); + assert( pgno!=0 || rc==SQLITE_CORRUPT ); + return rc; +} + +/* +** Release a MemPage. This should be called once for each prior +** call to btreeGetPage. +*/ +static void releasePage(MemPage *pPage){ + if( pPage ){ + assert( pPage->aData ); + assert( pPage->pBt ); + assert( pPage->pDbPage!=0 ); + assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); + assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + sqlite3PagerUnrefNotNull(pPage->pDbPage); + } +} + +/* +** 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(DbPage *pData){ + MemPage *pPage; + pPage = (MemPage *)sqlite3PagerGetExtra(pData); + assert( sqlite3PagerPageRefcount(pData)>0 ); + if( pPage->isInit ){ + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + pPage->isInit = 0; + if( sqlite3PagerPageRefcount(pData)>1 ){ + /* pPage might not be a btree page; it might be an overflow page + ** or ptrmap page or a free page. In those cases, the following + ** call to btreeInitPage() will likely return SQLITE_CORRUPT. + ** But no harm is done by this. And it is very important that + ** btreeInitPage() be called on every btree page so we make + ** the call for every page that comes in for re-initing. */ + btreeInitPage(pPage); + } + } +} + +/* +** Invoke the busy handler for a btree. +*/ +static int btreeInvokeBusyHandler(void *pArg){ + BtShared *pBt = (BtShared*)pArg; + assert( pBt->db ); + assert( sqlite3_mutex_held(pBt->db->mutex) ); + return sqlite3InvokeBusyHandler(&pBt->db->busyHandler); +} + +/* +** Open a database file. +** +** zFilename is the name of the database file. If zFilename is NULL +** then an ephemeral database is created. The ephemeral database might +** be exclusively in memory, or it might use a disk-based memory cache. +** Either way, the ephemeral database will be automatically deleted +** when sqlite3BtreeClose() is called. +** +** If zFilename is ":memory:" then an in-memory database is created +** that is automatically destroyed when it is closed. +** +** The "flags" parameter is a bitmask that might contain bits like +** BTREE_OMIT_JOURNAL and/or BTREE_MEMORY. +** +** If the database is already opened in the same database connection +** and we are in shared cache mode, then the open will fail with an +** SQLITE_CONSTRAINT error. We cannot allow two or more BtShared +** objects in the same database connection since doing so will lead +** to problems with locking. +*/ +SQLITE_PRIVATE int sqlite3BtreeOpen( + sqlite3_vfs *pVfs, /* VFS to use for this b-tree */ + const char *zFilename, /* Name of the file containing the BTree database */ + sqlite3 *db, /* Associated database handle */ + Btree **ppBtree, /* Pointer to new Btree object written here */ + int flags, /* Options */ + int vfsFlags /* Flags passed through to sqlite3_vfs.xOpen() */ +){ + BtShared *pBt = 0; /* Shared part of btree structure */ + Btree *p; /* Handle to return */ + sqlite3_mutex *mutexOpen = 0; /* Prevents a race condition. Ticket #3537 */ + int rc = SQLITE_OK; /* Result code from this function */ + u8 nReserve; /* Byte of unused space on each page */ + unsigned char zDbHeader[100]; /* Database header content */ + + /* True if opening an ephemeral, temporary database */ + const int isTempDb = zFilename==0 || zFilename[0]==0; + + /* Set the variable isMemdb to true for an in-memory database, or + ** false for a file-based database. + */ +#ifdef SQLITE_OMIT_MEMORYDB + const int isMemdb = 0; +#else + const int isMemdb = (zFilename && strcmp(zFilename, ":memory:")==0) + || (isTempDb && sqlite3TempInMemory(db)) + || (vfsFlags & SQLITE_OPEN_MEMORY)!=0; +#endif + + assert( db!=0 ); + assert( pVfs!=0 ); + assert( sqlite3_mutex_held(db->mutex) ); + assert( (flags&0xff)==flags ); /* flags fit in 8 bits */ + + /* Only a BTREE_SINGLE database can be BTREE_UNORDERED */ + assert( (flags & BTREE_UNORDERED)==0 || (flags & BTREE_SINGLE)!=0 ); + + /* A BTREE_SINGLE database is always a temporary and/or ephemeral */ + assert( (flags & BTREE_SINGLE)==0 || isTempDb ); + + if( isMemdb ){ + flags |= BTREE_MEMORY; + } + if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (isMemdb || isTempDb) ){ + vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB; + } + p = sqlite3MallocZero(sizeof(Btree)); + if( !p ){ + return SQLITE_NOMEM; + } + p->inTrans = TRANS_NONE; + p->db = db; +#ifndef SQLITE_OMIT_SHARED_CACHE + p->lock.pBtree = p; + p->lock.iTable = 1; +#endif + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) + /* + ** If this Btree is a candidate for shared cache, try to find an + ** existing BtShared object that we can share with + */ + if( isTempDb==0 && (isMemdb==0 || (vfsFlags&SQLITE_OPEN_URI)!=0) ){ + if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){ + int nFilename = sqlite3Strlen30(zFilename)+1; + int nFullPathname = pVfs->mxPathname+1; + char *zFullPathname = sqlite3Malloc(MAX(nFullPathname,nFilename)); + MUTEX_LOGIC( sqlite3_mutex *mutexShared; ) + + p->sharable = 1; + if( !zFullPathname ){ + sqlite3_free(p); + return SQLITE_NOMEM; + } + if( isMemdb ){ + memcpy(zFullPathname, zFilename, nFilename); + }else{ + rc = sqlite3OsFullPathname(pVfs, zFilename, + nFullPathname, zFullPathname); + if( rc ){ + sqlite3_free(zFullPathname); + sqlite3_free(p); + return rc; + } + } +#if SQLITE_THREADSAFE + mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN); + sqlite3_mutex_enter(mutexOpen); + mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); + sqlite3_mutex_enter(mutexShared); +#endif + for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){ + assert( pBt->nRef>0 ); + if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager, 0)) + && sqlite3PagerVfs(pBt->pPager)==pVfs ){ + int iDb; + for(iDb=db->nDb-1; iDb>=0; iDb--){ + Btree *pExisting = db->aDb[iDb].pBt; + if( pExisting && pExisting->pBt==pBt ){ + sqlite3_mutex_leave(mutexShared); + sqlite3_mutex_leave(mutexOpen); + sqlite3_free(zFullPathname); + sqlite3_free(p); + return SQLITE_CONSTRAINT; + } + } + p->pBt = pBt; + pBt->nRef++; + break; + } + } + sqlite3_mutex_leave(mutexShared); + sqlite3_free(zFullPathname); + } +#ifdef SQLITE_DEBUG + else{ + /* In debug mode, we mark all persistent databases as sharable + ** even when they are not. This exercises the locking code and + ** gives more opportunity for asserts(sqlite3_mutex_held()) + ** statements to find locking problems. + */ + p->sharable = 1; + } +#endif + } +#endif + if( pBt==0 ){ + /* + ** 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 = sqlite3MallocZero( sizeof(*pBt) ); + if( pBt==0 ){ + rc = SQLITE_NOMEM; + goto btree_open_out; + } + rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename, + EXTRA_SIZE, flags, vfsFlags, pageReinit); + if( rc==SQLITE_OK ){ + sqlite3PagerSetMmapLimit(pBt->pPager, db->szMmap); + rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader); + } + if( rc!=SQLITE_OK ){ + goto btree_open_out; + } + pBt->openFlags = (u8)flags; + pBt->db = db; + sqlite3PagerSetBusyhandler(pBt->pPager, btreeInvokeBusyHandler, pBt); + p->pBt = pBt; + + pBt->pCursor = 0; + pBt->pPage1 = 0; + if( sqlite3PagerIsreadonly(pBt->pPager) ) pBt->btsFlags |= BTS_READ_ONLY; +#ifdef SQLITE_SECURE_DELETE + pBt->btsFlags |= BTS_SECURE_DELETE; +#endif + /* EVIDENCE-OF: R-51873-39618 The page size for a database file is + ** determined by the 2-byte integer located at an offset of 16 bytes from + ** the beginning of the database file. */ + pBt->pageSize = (zDbHeader[16]<<8) | (zDbHeader[17]<<16); + if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE + || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){ + pBt->pageSize = 0; +#ifndef SQLITE_OMIT_AUTOVACUUM + /* If the magic name ":memory:" will create an in-memory database, then + ** leave the autoVacuum mode at 0 (do not auto-vacuum), 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. In this case the auto-vacuum applies as per normal. + */ + if( zFilename && !isMemdb ){ + pBt->autoVacuum = (SQLITE_DEFAULT_AUTOVACUUM ? 1 : 0); + pBt->incrVacuum = (SQLITE_DEFAULT_AUTOVACUUM==2 ? 1 : 0); + } +#endif + nReserve = 0; + }else{ + /* EVIDENCE-OF: R-37497-42412 The size of the reserved region is + ** determined by the one-byte unsigned integer found at an offset of 20 + ** into the database file header. */ + nReserve = zDbHeader[20]; + pBt->btsFlags |= BTS_PAGESIZE_FIXED; +#ifndef SQLITE_OMIT_AUTOVACUUM + pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0); + pBt->incrVacuum = (get4byte(&zDbHeader[36 + 7*4])?1:0); +#endif + } + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); + if( rc ) goto btree_open_out; + pBt->usableSize = pBt->pageSize - nReserve; + assert( (pBt->pageSize & 7)==0 ); /* 8-byte alignment of pageSize */ + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) + /* Add the new BtShared object to the linked list sharable BtShareds. + */ + if( p->sharable ){ + MUTEX_LOGIC( sqlite3_mutex *mutexShared; ) + pBt->nRef = 1; + MUTEX_LOGIC( mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);) + if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){ + pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST); + if( pBt->mutex==0 ){ + rc = SQLITE_NOMEM; + db->mallocFailed = 0; + goto btree_open_out; + } + } + sqlite3_mutex_enter(mutexShared); + pBt->pNext = GLOBAL(BtShared*,sqlite3SharedCacheList); + GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt; + sqlite3_mutex_leave(mutexShared); + } +#endif + } + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) + /* If the new Btree uses a sharable pBtShared, then link the new + ** Btree into the list of all sharable Btrees for the same connection. + ** The list is kept in ascending order by pBt address. + */ + if( p->sharable ){ + int i; + Btree *pSib; + for(i=0; inDb; i++){ + if( (pSib = db->aDb[i].pBt)!=0 && pSib->sharable ){ + while( pSib->pPrev ){ pSib = pSib->pPrev; } + if( p->pBtpBt ){ + p->pNext = pSib; + p->pPrev = 0; + pSib->pPrev = p; + }else{ + while( pSib->pNext && pSib->pNext->pBtpBt ){ + pSib = pSib->pNext; + } + p->pNext = pSib->pNext; + p->pPrev = pSib; + if( p->pNext ){ + p->pNext->pPrev = p; + } + pSib->pNext = p; + } + break; + } + } + } +#endif + *ppBtree = p; + +btree_open_out: + if( rc!=SQLITE_OK ){ + if( pBt && pBt->pPager ){ + sqlite3PagerClose(pBt->pPager); + } + sqlite3_free(pBt); + sqlite3_free(p); + *ppBtree = 0; + }else{ + /* If the B-Tree was successfully opened, set the pager-cache size to the + ** default value. Except, when opening on an existing shared pager-cache, + ** do not change the pager-cache size. + */ + if( sqlite3BtreeSchema(p, 0, 0)==0 ){ + sqlite3PagerSetCachesize(p->pBt->pPager, SQLITE_DEFAULT_CACHE_SIZE); + } + } + if( mutexOpen ){ + assert( sqlite3_mutex_held(mutexOpen) ); + sqlite3_mutex_leave(mutexOpen); + } + return rc; +} + +/* +** Decrement the BtShared.nRef counter. When it reaches zero, +** remove the BtShared structure from the sharing list. Return +** true if the BtShared.nRef counter reaches zero and return +** false if it is still positive. +*/ +static int removeFromSharingList(BtShared *pBt){ +#ifndef SQLITE_OMIT_SHARED_CACHE + MUTEX_LOGIC( sqlite3_mutex *pMaster; ) + BtShared *pList; + int removed = 0; + + assert( sqlite3_mutex_notheld(pBt->mutex) ); + MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) + sqlite3_mutex_enter(pMaster); + pBt->nRef--; + if( pBt->nRef<=0 ){ + if( GLOBAL(BtShared*,sqlite3SharedCacheList)==pBt ){ + GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt->pNext; + }else{ + pList = GLOBAL(BtShared*,sqlite3SharedCacheList); + while( ALWAYS(pList) && pList->pNext!=pBt ){ + pList=pList->pNext; + } + if( ALWAYS(pList) ){ + pList->pNext = pBt->pNext; + } + } + if( SQLITE_THREADSAFE ){ + sqlite3_mutex_free(pBt->mutex); + } + removed = 1; + } + sqlite3_mutex_leave(pMaster); + return removed; +#else + return 1; +#endif +} + +/* +** Make sure pBt->pTmpSpace points to an allocation of +** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child +** pointer. +*/ +static void allocateTempSpace(BtShared *pBt){ + if( !pBt->pTmpSpace ){ + pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize ); + + /* One of the uses of pBt->pTmpSpace is to format cells before + ** inserting them into a leaf page (function fillInCell()). If + ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes + ** by the various routines that manipulate binary cells. Which + ** can mean that fillInCell() only initializes the first 2 or 3 + ** bytes of pTmpSpace, but that the first 4 bytes are copied from + ** it into a database page. This is not actually a problem, but it + ** does cause a valgrind error when the 1 or 2 bytes of unitialized + ** data is passed to system call write(). So to avoid this error, + ** zero the first 4 bytes of temp space here. + ** + ** Also: Provide four bytes of initialized space before the + ** beginning of pTmpSpace as an area available to prepend the + ** left-child pointer to the beginning of a cell. + */ + if( pBt->pTmpSpace ){ + memset(pBt->pTmpSpace, 0, 8); + pBt->pTmpSpace += 4; + } + } +} + +/* +** Free the pBt->pTmpSpace allocation +*/ +static void freeTempSpace(BtShared *pBt){ + if( pBt->pTmpSpace ){ + pBt->pTmpSpace -= 4; + sqlite3PageFree(pBt->pTmpSpace); + pBt->pTmpSpace = 0; + } +} + +/* +** Close an open database and invalidate all cursors. +*/ +SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){ + BtShared *pBt = p->pBt; + BtCursor *pCur; + + /* Close all cursors opened via this handle. */ + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + 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. + ** The call to sqlite3BtreeRollback() drops any table-locks held by + ** this handle. + */ + sqlite3BtreeRollback(p, SQLITE_OK, 0); + sqlite3BtreeLeave(p); + + /* 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( p->wantToLock==0 && p->locked==0 ); + if( !p->sharable || removeFromSharingList(pBt) ){ + /* The pBt is no longer on the sharing list, so we can access + ** it without having to hold the mutex. + ** + ** Clean out and delete the BtShared object. + */ + assert( !pBt->pCursor ); + sqlite3PagerClose(pBt->pPager); + if( pBt->xFreeSchema && pBt->pSchema ){ + pBt->xFreeSchema(pBt->pSchema); + } + sqlite3DbFree(0, pBt->pSchema); + freeTempSpace(pBt); + sqlite3_free(pBt); + } + +#ifndef SQLITE_OMIT_SHARED_CACHE + assert( p->wantToLock==0 ); + assert( p->locked==0 ); + if( p->pPrev ) p->pPrev->pNext = p->pNext; + if( p->pNext ) p->pNext->pPrev = p->pPrev; +#endif + + sqlite3_free(p); + 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. +*/ +SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){ + BtShared *pBt = p->pBt; + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + sqlite3PagerSetCachesize(pBt->pPager, mxPage); + sqlite3BtreeLeave(p); + return SQLITE_OK; +} + +#if SQLITE_MAX_MMAP_SIZE>0 +/* +** Change the limit on the amount of the database file that may be +** memory mapped. +*/ +SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree *p, sqlite3_int64 szMmap){ + BtShared *pBt = p->pBt; + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + sqlite3PagerSetMmapLimit(pBt->pPager, szMmap); + sqlite3BtreeLeave(p); + return SQLITE_OK; +} +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ + +/* +** 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 +SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags( + Btree *p, /* The btree to set the safety level on */ + unsigned pgFlags /* Various PAGER_* flags */ +){ + BtShared *pBt = p->pBt; + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + sqlite3PagerSetFlags(pBt->pPager, pgFlags); + sqlite3BtreeLeave(p); + 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. +*/ +SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree *p){ + BtShared *pBt = p->pBt; + int rc; + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + assert( pBt && pBt->pPager ); + rc = sqlite3PagerNosync(pBt->pPager); + sqlite3BtreeLeave(p); + return rc; +} + +/* +** Change the default pages size and the number of reserved bytes per page. +** Or, if the page size has already been fixed, return SQLITE_READONLY +** without changing anything. +** +** 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. +** +** If the iFix!=0 then the BTS_PAGESIZE_FIXED flag is set so that the page size +** and autovacuum mode can no longer be changed. +*/ +SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){ + int rc = SQLITE_OK; + BtShared *pBt = p->pBt; + assert( nReserve>=-1 && nReserve<=255 ); + sqlite3BtreeEnter(p); +#if SQLITE_HAS_CODEC + if( nReserve>pBt->optimalReserve ) pBt->optimalReserve = (u8)nReserve; +#endif + if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){ + sqlite3BtreeLeave(p); + return SQLITE_READONLY; + } + if( nReserve<0 ){ + nReserve = pBt->pageSize - pBt->usableSize; + } + assert( nReserve>=0 && nReserve<=255 ); + if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE && + ((pageSize-1)&pageSize)==0 ){ + assert( (pageSize & 7)==0 ); + assert( !pBt->pCursor ); + pBt->pageSize = (u32)pageSize; + freeTempSpace(pBt); + } + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); + pBt->usableSize = pBt->pageSize - (u16)nReserve; + if( iFix ) pBt->btsFlags |= BTS_PAGESIZE_FIXED; + sqlite3BtreeLeave(p); + return rc; +} + +/* +** Return the currently defined page size +*/ +SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree *p){ + return p->pBt->pageSize; +} + +/* +** This function is similar to sqlite3BtreeGetReserve(), except that it +** may only be called if it is guaranteed that the b-tree mutex is already +** held. +** +** This is useful in one special case in the backup API code where it is +** known that the shared b-tree mutex is held, but the mutex on the +** database handle that owns *p is not. In this case if sqlite3BtreeEnter() +** were to be called, it might collide with some other operation on the +** database handle that owns *p, causing undefined behavior. +*/ +SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p){ + int n; + assert( sqlite3_mutex_held(p->pBt->mutex) ); + n = p->pBt->pageSize - p->pBt->usableSize; + return n; +} + +/* +** Return the number of bytes of space at the end of every page that +** are intentually left unused. This is the "reserved" space that is +** sometimes used by extensions. +** +** If SQLITE_HAS_MUTEX is defined then the number returned is the +** greater of the current reserved space and the maximum requested +** reserve space. +*/ +SQLITE_PRIVATE int sqlite3BtreeGetOptimalReserve(Btree *p){ + int n; + sqlite3BtreeEnter(p); + n = sqlite3BtreeGetReserveNoMutex(p); +#ifdef SQLITE_HAS_CODEC + if( npBt->optimalReserve ) n = p->pBt->optimalReserve; +#endif + sqlite3BtreeLeave(p); + return n; +} + + +/* +** Set the maximum page count for a database if mxPage is positive. +** No changes are made if mxPage is 0 or negative. +** Regardless of the value of mxPage, return the maximum page count. +*/ +SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree *p, int mxPage){ + int n; + sqlite3BtreeEnter(p); + n = sqlite3PagerMaxPageCount(p->pBt->pPager, mxPage); + sqlite3BtreeLeave(p); + return n; +} + +/* +** Set the BTS_SECURE_DELETE flag if newFlag is 0 or 1. If newFlag is -1, +** then make no changes. Always return the value of the BTS_SECURE_DELETE +** setting after the change. +*/ +SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree *p, int newFlag){ + int b; + if( p==0 ) return 0; + sqlite3BtreeEnter(p); + if( newFlag>=0 ){ + p->pBt->btsFlags &= ~BTS_SECURE_DELETE; + if( newFlag ) p->pBt->btsFlags |= BTS_SECURE_DELETE; + } + b = (p->pBt->btsFlags & BTS_SECURE_DELETE)!=0; + sqlite3BtreeLeave(p); + return b; +} + +/* +** 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. +*/ +SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){ +#ifdef SQLITE_OMIT_AUTOVACUUM + return SQLITE_READONLY; +#else + BtShared *pBt = p->pBt; + int rc = SQLITE_OK; + u8 av = (u8)autoVacuum; + + sqlite3BtreeEnter(p); + if( (pBt->btsFlags & BTS_PAGESIZE_FIXED)!=0 && (av ?1:0)!=pBt->autoVacuum ){ + rc = SQLITE_READONLY; + }else{ + pBt->autoVacuum = av ?1:0; + pBt->incrVacuum = av==2 ?1:0; + } + sqlite3BtreeLeave(p); + return rc; +#endif +} + +/* +** Return the value of the 'auto-vacuum' property. If auto-vacuum is +** enabled 1 is returned. Otherwise 0. +*/ +SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *p){ +#ifdef SQLITE_OMIT_AUTOVACUUM + return BTREE_AUTOVACUUM_NONE; +#else + int rc; + sqlite3BtreeEnter(p); + rc = ( + (!p->pBt->autoVacuum)?BTREE_AUTOVACUUM_NONE: + (!p->pBt->incrVacuum)?BTREE_AUTOVACUUM_FULL: + BTREE_AUTOVACUUM_INCR + ); + sqlite3BtreeLeave(p); + return rc; +#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. +*/ +static int lockBtree(BtShared *pBt){ + int rc; /* Result code from subfunctions */ + MemPage *pPage1; /* Page 1 of the database file */ + int nPage; /* Number of pages in the database */ + int nPageFile = 0; /* Number of pages in the database file */ + int nPageHeader; /* Number of pages in the database according to hdr */ + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( pBt->pPage1==0 ); + rc = sqlite3PagerSharedLock(pBt->pPager); + if( rc!=SQLITE_OK ) return rc; + rc = btreeGetPage(pBt, 1, &pPage1, 0); + if( rc!=SQLITE_OK ) return rc; + + /* Do some checking to help insure the file we opened really is + ** a valid database file. + */ + nPage = nPageHeader = get4byte(28+(u8*)pPage1->aData); + sqlite3PagerPagecount(pBt->pPager, &nPageFile); + if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){ + nPage = nPageFile; + } + if( nPage>0 ){ + u32 pageSize; + u32 usableSize; + u8 *page1 = pPage1->aData; + rc = SQLITE_NOTADB; + /* EVIDENCE-OF: R-43737-39999 Every valid SQLite database file begins + ** with the following 16 bytes (in hex): 53 51 4c 69 74 65 20 66 6f 72 6d + ** 61 74 20 33 00. */ + if( memcmp(page1, zMagicHeader, 16)!=0 ){ + goto page1_init_failed; + } + +#ifdef SQLITE_OMIT_WAL + if( page1[18]>1 ){ + pBt->btsFlags |= BTS_READ_ONLY; + } + if( page1[19]>1 ){ + goto page1_init_failed; + } +#else + if( page1[18]>2 ){ + pBt->btsFlags |= BTS_READ_ONLY; + } + if( page1[19]>2 ){ + goto page1_init_failed; + } + + /* If the write version is set to 2, this database should be accessed + ** in WAL mode. If the log is not already open, open it now. Then + ** return SQLITE_OK and return without populating BtShared.pPage1. + ** The caller detects this and calls this function again. This is + ** required as the version of page 1 currently in the page1 buffer + ** may not be the latest version - there may be a newer one in the log + ** file. + */ + if( page1[19]==2 && (pBt->btsFlags & BTS_NO_WAL)==0 ){ + int isOpen = 0; + rc = sqlite3PagerOpenWal(pBt->pPager, &isOpen); + if( rc!=SQLITE_OK ){ + goto page1_init_failed; + }else if( isOpen==0 ){ + releasePage(pPage1); + return SQLITE_OK; + } + rc = SQLITE_NOTADB; + } +#endif + + /* EVIDENCE-OF: R-15465-20813 The maximum and minimum embedded payload + ** fractions and the leaf payload fraction values must be 64, 32, and 32. + ** + ** The original design allowed these amounts to vary, but as of + ** version 3.6.0, we require them to be fixed. + */ + if( memcmp(&page1[21], "\100\040\040",3)!=0 ){ + goto page1_init_failed; + } + /* EVIDENCE-OF: R-51873-39618 The page size for a database file is + ** determined by the 2-byte integer located at an offset of 16 bytes from + ** the beginning of the database file. */ + pageSize = (page1[16]<<8) | (page1[17]<<16); + /* EVIDENCE-OF: R-25008-21688 The size of a page is a power of two + ** between 512 and 65536 inclusive. */ + if( ((pageSize-1)&pageSize)!=0 + || pageSize>SQLITE_MAX_PAGE_SIZE + || pageSize<=256 + ){ + goto page1_init_failed; + } + assert( (pageSize & 7)==0 ); + /* EVIDENCE-OF: R-59310-51205 The "reserved space" size in the 1-byte + ** integer at offset 20 is the number of bytes of space at the end of + ** each page to reserve for extensions. + ** + ** EVIDENCE-OF: R-37497-42412 The size of the reserved region is + ** determined by the one-byte unsigned integer found at an offset of 20 + ** into the database file header. */ + usableSize = pageSize - page1[20]; + if( (u32)pageSize!=pBt->pageSize ){ + /* After reading the first page of the database assuming a page size + ** of BtShared.pageSize, we have discovered that the page-size is + ** actually pageSize. Unlock the database, leave pBt->pPage1 at + ** zero and return SQLITE_OK. The caller will call this function + ** again with the correct page-size. + */ + releasePage(pPage1); + pBt->usableSize = usableSize; + pBt->pageSize = pageSize; + freeTempSpace(pBt); + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, + pageSize-usableSize); + return rc; + } + if( (pBt->db->flags & SQLITE_RecoveryMode)==0 && nPage>nPageFile ){ + rc = SQLITE_CORRUPT_BKPT; + goto page1_init_failed; + } + /* EVIDENCE-OF: R-28312-64704 However, the usable size is not allowed to + ** be less than 480. In other words, if the page size is 512, then the + ** reserved space size cannot exceed 32. */ + if( usableSize<480 ){ + goto page1_init_failed; + } + pBt->pageSize = pageSize; + pBt->usableSize = usableSize; +#ifndef SQLITE_OMIT_AUTOVACUUM + pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0); + pBt->incrVacuum = (get4byte(&page1[36 + 7*4])?1:0); +#endif + } + + /* maxLocal is the maximum amount of payload to store locally for + ** a cell. Make sure it is small enough so that at least minFanout + ** cells can will fit on one page. We assume a 10-byte page header. + ** Besides the payload, the cell must store: + ** 2-byte pointer to the cell + ** 4-byte child pointer + ** 9-byte nKey value + ** 4-byte nData value + ** 4-byte overflow page pointer + ** So a cell consists of a 2-byte pointer, a header which is as much as + ** 17 bytes long, 0 to N bytes of payload, and an optional 4 byte overflow + ** page pointer. + */ + pBt->maxLocal = (u16)((pBt->usableSize-12)*64/255 - 23); + pBt->minLocal = (u16)((pBt->usableSize-12)*32/255 - 23); + pBt->maxLeaf = (u16)(pBt->usableSize - 35); + pBt->minLeaf = (u16)((pBt->usableSize-12)*32/255 - 23); + if( pBt->maxLocal>127 ){ + pBt->max1bytePayload = 127; + }else{ + pBt->max1bytePayload = (u8)pBt->maxLocal; + } + assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) ); + pBt->pPage1 = pPage1; + pBt->nPage = nPage; + return SQLITE_OK; + +page1_init_failed: + releasePage(pPage1); + pBt->pPage1 = 0; + return rc; +} + +#ifndef NDEBUG +/* +** Return the number of cursors open on pBt. This is for use +** in assert() expressions, so it is only compiled if NDEBUG is not +** defined. +** +** Only write cursors are counted if wrOnly is true. If wrOnly is +** false then all cursors are counted. +** +** For the purposes of this routine, a cursor is any cursor that +** is capable of reading or writing to the database. Cursors that +** have been tripped into the CURSOR_FAULT state are not counted. +*/ +static int countValidCursors(BtShared *pBt, int wrOnly){ + BtCursor *pCur; + int r = 0; + for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ + if( (wrOnly==0 || (pCur->curFlags & BTCF_WriteFlag)!=0) + && pCur->eState!=CURSOR_FAULT ) r++; + } + return r; +} +#endif + +/* +** 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 is a transaction in progress, this routine is a no-op. +*/ +static void unlockBtreeIfUnused(BtShared *pBt){ + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( countValidCursors(pBt,0)==0 || pBt->inTransaction>TRANS_NONE ); + if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){ + MemPage *pPage1 = pBt->pPage1; + assert( pPage1->aData ); + assert( sqlite3PagerRefcount(pBt->pPager)==1 ); + pBt->pPage1 = 0; + releasePage(pPage1); + } +} + +/* +** If pBt points to an empty file then convert that empty file +** into a new empty database by initializing the first page of +** the database. +*/ +static int newDatabase(BtShared *pBt){ + MemPage *pP1; + unsigned char *data; + int rc; + + assert( sqlite3_mutex_held(pBt->mutex) ); + if( pBt->nPage>0 ){ + return SQLITE_OK; + } + pP1 = pBt->pPage1; + assert( pP1!=0 ); + data = pP1->aData; + rc = sqlite3PagerWrite(pP1->pDbPage); + if( rc ) return rc; + memcpy(data, zMagicHeader, sizeof(zMagicHeader)); + assert( sizeof(zMagicHeader)==16 ); + data[16] = (u8)((pBt->pageSize>>8)&0xff); + data[17] = (u8)((pBt->pageSize>>16)&0xff); + data[18] = 1; + data[19] = 1; + assert( pBt->usableSize<=pBt->pageSize && pBt->usableSize+255>=pBt->pageSize); + data[20] = (u8)(pBt->pageSize - pBt->usableSize); + data[21] = 64; + data[22] = 32; + data[23] = 32; + memset(&data[24], 0, 100-24); + zeroPage(pP1, PTF_INTKEY|PTF_LEAF|PTF_LEAFDATA ); + pBt->btsFlags |= BTS_PAGESIZE_FIXED; +#ifndef SQLITE_OMIT_AUTOVACUUM + assert( pBt->autoVacuum==1 || pBt->autoVacuum==0 ); + assert( pBt->incrVacuum==1 || pBt->incrVacuum==0 ); + put4byte(&data[36 + 4*4], pBt->autoVacuum); + put4byte(&data[36 + 7*4], pBt->incrVacuum); +#endif + pBt->nPage = 1; + data[31] = 1; + return SQLITE_OK; +} + +/* +** Initialize the first page of the database file (creating a database +** consisting of a single page and no schema objects). Return SQLITE_OK +** if successful, or an SQLite error code otherwise. +*/ +SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p){ + int rc; + sqlite3BtreeEnter(p); + p->pBt->nPage = 0; + rc = newDatabase(p->pBt); + sqlite3BtreeLeave(p); + return rc; +} + +/* +** 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. +*/ +SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ + sqlite3 *pBlock = 0; + BtShared *pBt = p->pBt; + int rc = SQLITE_OK; + + sqlite3BtreeEnter(p); + 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) ){ + goto trans_begun; + } + assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 ); + + /* Write transactions are not possible on a read-only database */ + if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){ + rc = SQLITE_READONLY; + goto trans_begun; + } + +#ifndef SQLITE_OMIT_SHARED_CACHE + /* If another database handle has already opened a write transaction + ** on this shared-btree structure and a second write transaction is + ** requested, return SQLITE_LOCKED. + */ + if( (wrflag && pBt->inTransaction==TRANS_WRITE) + || (pBt->btsFlags & BTS_PENDING)!=0 + ){ + pBlock = pBt->pWriter->db; + }else if( wrflag>1 ){ + BtLock *pIter; + for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ + if( pIter->pBtree!=p ){ + pBlock = pIter->pBtree->db; + break; + } + } + } + if( pBlock ){ + sqlite3ConnectionBlocked(p->db, pBlock); + rc = SQLITE_LOCKED_SHAREDCACHE; + goto trans_begun; + } +#endif + + /* Any read-only or read-write transaction implies a read-lock on + ** page 1. So if some other shared-cache client already has a write-lock + ** on page 1, the transaction cannot be opened. */ + rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK); + if( SQLITE_OK!=rc ) goto trans_begun; + + pBt->btsFlags &= ~BTS_INITIALLY_EMPTY; + if( pBt->nPage==0 ) pBt->btsFlags |= BTS_INITIALLY_EMPTY; + do { + /* Call lockBtree() until either pBt->pPage1 is populated or + ** lockBtree() returns something other than SQLITE_OK. lockBtree() + ** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after + ** reading page 1 it discovers that the page-size of the database + ** file is not pBt->pageSize. In this case lockBtree() will update + ** pBt->pageSize to the page-size of the file on disk. + */ + while( pBt->pPage1==0 && SQLITE_OK==(rc = lockBtree(pBt)) ); + + if( rc==SQLITE_OK && wrflag ){ + if( (pBt->btsFlags & BTS_READ_ONLY)!=0 ){ + rc = SQLITE_READONLY; + }else{ + rc = sqlite3PagerBegin(pBt->pPager,wrflag>1,sqlite3TempInMemory(p->db)); + if( rc==SQLITE_OK ){ + rc = newDatabase(pBt); + } + } + } + + if( rc!=SQLITE_OK ){ + unlockBtreeIfUnused(pBt); + } + }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE && + btreeInvokeBusyHandler(pBt) ); + + if( rc==SQLITE_OK ){ + if( p->inTrans==TRANS_NONE ){ + pBt->nTransaction++; +#ifndef SQLITE_OMIT_SHARED_CACHE + if( p->sharable ){ + assert( p->lock.pBtree==p && p->lock.iTable==1 ); + p->lock.eLock = READ_LOCK; + p->lock.pNext = pBt->pLock; + pBt->pLock = &p->lock; + } +#endif + } + p->inTrans = (wrflag?TRANS_WRITE:TRANS_READ); + if( p->inTrans>pBt->inTransaction ){ + pBt->inTransaction = p->inTrans; + } + if( wrflag ){ + MemPage *pPage1 = pBt->pPage1; +#ifndef SQLITE_OMIT_SHARED_CACHE + assert( !pBt->pWriter ); + pBt->pWriter = p; + pBt->btsFlags &= ~BTS_EXCLUSIVE; + if( wrflag>1 ) pBt->btsFlags |= BTS_EXCLUSIVE; +#endif + + /* If the db-size header field is incorrect (as it may be if an old + ** client has been writing the database file), update it now. Doing + ** this sooner rather than later means the database size can safely + ** re-read the database size from page 1 if a savepoint or transaction + ** rollback occurs within the transaction. + */ + if( pBt->nPage!=get4byte(&pPage1->aData[28]) ){ + rc = sqlite3PagerWrite(pPage1->pDbPage); + if( rc==SQLITE_OK ){ + put4byte(&pPage1->aData[28], pBt->nPage); + } + } + } + } + + +trans_begun: + if( rc==SQLITE_OK && wrflag ){ + /* This call makes sure that the pager has the correct number of + ** open savepoints. If the second parameter is greater than 0 and + ** the sub-journal is not already open, then it will be opened here. + */ + rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint); + } + + btreeIntegrity(p); + sqlite3BtreeLeave(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; /* Return code */ + BtShared *pBt = pPage->pBt; + u8 isInitOrig = pPage->isInit; + Pgno pgno = pPage->pgno; + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + rc = btreeInitPage(pPage); + if( rc!=SQLITE_OK ){ + goto set_child_ptrmaps_out; + } + nCell = pPage->nCell; + + for(i=0; ileaf ){ + Pgno childPgno = get4byte(pCell); + ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc); + } + } + + if( !pPage->leaf ){ + Pgno childPgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); + ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc); + } + +set_child_ptrmaps_out: + pPage->isInit = isInitOrig; + return rc; +} + +/* +** Somewhere on pPage is a pointer to page iFrom. Modify this pointer so +** that it points to iTo. Parameter eType describes the type of pointer to +** be modified, as follows: +** +** PTRMAP_BTREE: pPage is a btree-page. The pointer points at a child +** page of pPage. +** +** PTRMAP_OVERFLOW1: pPage is a btree-page. The pointer points at an overflow +** page pointed to by one of the cells on pPage. +** +** 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){ + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + 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{ + u8 isInitOrig = pPage->isInit; + int i; + int nCell; + + btreeInitPage(pPage); + nCell = pPage->nCell; + + for(i=0; iaData+pPage->maskPage + && iFrom==get4byte(&pCell[info.iOverflow]) + ){ + put4byte(&pCell[info.iOverflow], iTo); + break; + } + }else{ + if( get4byte(pCell)==iFrom ){ + put4byte(pCell, iTo); + break; + } + } + } + + 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. +** +** The isCommit flag indicates that there is no need to remember that +** the journal needs to be sync()ed before database page pDbPage->pgno +** can be written to. The caller has already promised not to write to that +** page. +*/ +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 */ + int isCommit /* isCommit flag passed to sqlite3PagerMovepage */ +){ + MemPage *pPtrPage; /* The page that contains a pointer to pDbPage */ + Pgno iDbPage = pDbPage->pgno; + Pager *pPager = pBt->pPager; + int rc; + + assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 || + eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ); + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( pDbPage->pBt==pBt ); + + /* Move page iDbPage from its current location to page number iFreePage */ + TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n", + iDbPage, iFreePage, iPtrPage, eType)); + rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage, isCommit); + if( rc!=SQLITE_OK ){ + return rc; + } + pDbPage->pgno = iFreePage; + + /* If pDbPage was a btree-page, then it may have child pages and/or cells + ** that point to overflow pages. The pointer map entries for all these + ** pages need to be changed. + ** + ** If pDbPage is an overflow page, then the first 4 bytes may store a + ** pointer to a subsequent overflow page. If this is the case, then + ** the pointer map needs to be updated for the subsequent overflow page. + */ + if( eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ){ + rc = setChildPtrmaps(pDbPage); + if( rc!=SQLITE_OK ){ + return rc; + } + }else{ + Pgno nextOvfl = get4byte(pDbPage->aData); + if( nextOvfl!=0 ){ + ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage, &rc); + if( rc!=SQLITE_OK ){ + return rc; + } + } + } + + /* Fix the database pointer on page iPtrPage that pointed at iDbPage so + ** that it points at iFreePage. Also fix the pointer map entry for + ** iPtrPage. + */ + if( eType!=PTRMAP_ROOTPAGE ){ + rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = sqlite3PagerWrite(pPtrPage->pDbPage); + if( rc!=SQLITE_OK ){ + releasePage(pPtrPage); + return rc; + } + rc = modifyPagePointer(pPtrPage, iDbPage, iFreePage, eType); + releasePage(pPtrPage); + if( rc==SQLITE_OK ){ + ptrmapPut(pBt, iFreePage, eType, iPtrPage, &rc); + } + } + return rc; +} + +/* Forward declaration required by incrVacuumStep(). */ +static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8); + +/* +** Perform a single step of an incremental-vacuum. If successful, return +** SQLITE_OK. If there is no work to do (and therefore no point in +** calling this function again), return SQLITE_DONE. Or, if an error +** occurs, return some other error code. +** +** More specifically, this function attempts to re-organize the database so +** that the last page of the file currently in use is no longer in use. +** +** Parameter nFin is the number of pages that this database would contain +** were this function called until it returns SQLITE_DONE. +** +** If the bCommit parameter is non-zero, this function assumes that the +** caller will keep calling incrVacuumStep() until it returns SQLITE_DONE +** or an error. bCommit is passed true for an auto-vacuum-on-commit +** operation, or false for an incremental vacuum. +*/ +static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg, int bCommit){ + Pgno nFreeList; /* Number of pages still on the free-list */ + int rc; + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( iLastPg>nFin ); + + if( !PTRMAP_ISPAGE(pBt, iLastPg) && iLastPg!=PENDING_BYTE_PAGE(pBt) ){ + u8 eType; + Pgno iPtrPage; + + nFreeList = get4byte(&pBt->pPage1->aData[36]); + if( nFreeList==0 ){ + return SQLITE_DONE; + } + + rc = ptrmapGet(pBt, iLastPg, &eType, &iPtrPage); + if( rc!=SQLITE_OK ){ + return rc; + } + if( eType==PTRMAP_ROOTPAGE ){ + return SQLITE_CORRUPT_BKPT; + } + + if( eType==PTRMAP_FREEPAGE ){ + if( bCommit==0 ){ + /* Remove the page from the files free-list. This is not required + ** if bCommit is non-zero. In that case, the free-list will be + ** truncated to zero after this function returns, so it doesn't + ** matter if it still contains some garbage entries. + */ + Pgno iFreePg; + MemPage *pFreePg; + rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iLastPg, BTALLOC_EXACT); + if( rc!=SQLITE_OK ){ + return rc; + } + assert( iFreePg==iLastPg ); + releasePage(pFreePg); + } + } else { + Pgno iFreePg; /* Index of free page to move pLastPg to */ + MemPage *pLastPg; + u8 eMode = BTALLOC_ANY; /* Mode parameter for allocateBtreePage() */ + Pgno iNear = 0; /* nearby parameter for allocateBtreePage() */ + + rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + + /* If bCommit is zero, this loop runs exactly once and page pLastPg + ** is swapped with the first free page pulled off the free list. + ** + ** On the other hand, if bCommit is greater than zero, then keep + ** looping until a free-page located within the first nFin pages + ** of the file is found. + */ + if( bCommit==0 ){ + eMode = BTALLOC_LE; + iNear = nFin; + } + do { + MemPage *pFreePg; + rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iNear, eMode); + if( rc!=SQLITE_OK ){ + releasePage(pLastPg); + return rc; + } + releasePage(pFreePg); + }while( bCommit && iFreePg>nFin ); + assert( iFreePgbDoTruncate = 1; + pBt->nPage = iLastPg; + } + return SQLITE_OK; +} + +/* +** The database opened by the first argument is an auto-vacuum database +** nOrig pages in size containing nFree free pages. Return the expected +** size of the database in pages following an auto-vacuum operation. +*/ +static Pgno finalDbSize(BtShared *pBt, Pgno nOrig, Pgno nFree){ + int nEntry; /* Number of entries on one ptrmap page */ + Pgno nPtrmap; /* Number of PtrMap pages to be freed */ + Pgno nFin; /* Return value */ + + nEntry = pBt->usableSize/5; + nPtrmap = (nFree-nOrig+PTRMAP_PAGENO(pBt, nOrig)+nEntry)/nEntry; + nFin = nOrig - nFree - nPtrmap; + if( nOrig>PENDING_BYTE_PAGE(pBt) && nFinpBt; + + sqlite3BtreeEnter(p); + assert( pBt->inTransaction==TRANS_WRITE && p->inTrans==TRANS_WRITE ); + if( !pBt->autoVacuum ){ + rc = SQLITE_DONE; + }else{ + Pgno nOrig = btreePagecount(pBt); + Pgno nFree = get4byte(&pBt->pPage1->aData[36]); + Pgno nFin = finalDbSize(pBt, nOrig, nFree); + + if( nOrig0 ){ + rc = saveAllCursors(pBt, 0, 0); + if( rc==SQLITE_OK ){ + invalidateAllOverflowCache(pBt); + rc = incrVacuumStep(pBt, nFin, nOrig, 0); + } + if( rc==SQLITE_OK ){ + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + put4byte(&pBt->pPage1->aData[28], pBt->nPage); + } + }else{ + rc = SQLITE_DONE; + } + } + sqlite3BtreeLeave(p); + return rc; +} + +/* +** This routine is called prior to sqlite3PagerCommit when a transaction +** is committed for an auto-vacuum database. +** +** If SQLITE_OK is returned, then *pnTrunc is set to the number of pages +** the database file should be truncated to during the commit process. +** i.e. the database has been reorganized so that only the first *pnTrunc +** pages are in use. +*/ +static int autoVacuumCommit(BtShared *pBt){ + int rc = SQLITE_OK; + Pager *pPager = pBt->pPager; + VVA_ONLY( int nRef = sqlite3PagerRefcount(pPager) ); + + assert( sqlite3_mutex_held(pBt->mutex) ); + invalidateAllOverflowCache(pBt); + assert(pBt->autoVacuum); + if( !pBt->incrVacuum ){ + Pgno nFin; /* Number of pages in database after autovacuuming */ + Pgno nFree; /* Number of pages on the freelist initially */ + Pgno iFree; /* The next page to be freed */ + Pgno nOrig; /* Database size before freeing */ + + nOrig = btreePagecount(pBt); + if( PTRMAP_ISPAGE(pBt, nOrig) || nOrig==PENDING_BYTE_PAGE(pBt) ){ + /* It is not possible to create a database for which the final page + ** is either a pointer-map page or the pending-byte page. If one + ** is encountered, this indicates corruption. + */ + return SQLITE_CORRUPT_BKPT; + } + + nFree = get4byte(&pBt->pPage1->aData[36]); + nFin = finalDbSize(pBt, nOrig, nFree); + if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT; + if( nFinnFin && rc==SQLITE_OK; iFree--){ + rc = incrVacuumStep(pBt, nFin, iFree, 1); + } + if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){ + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + put4byte(&pBt->pPage1->aData[32], 0); + put4byte(&pBt->pPage1->aData[36], 0); + put4byte(&pBt->pPage1->aData[28], nFin); + pBt->bDoTruncate = 1; + pBt->nPage = nFin; + } + if( rc!=SQLITE_OK ){ + sqlite3PagerRollback(pPager); + } + } + + assert( nRef>=sqlite3PagerRefcount(pPager) ); + return rc; +} + +#else /* ifndef SQLITE_OMIT_AUTOVACUUM */ +# define setChildPtrmaps(x) SQLITE_OK +#endif + +/* +** This routine does the first phase of a two-phase commit. This routine +** causes a rollback journal to be created (if it does not already exist) +** and populated with enough information so that if a power loss occurs +** the database can be restored to its original state by playing back +** the journal. Then the contents of the journal are flushed out to +** the disk. After the journal is safely on oxide, the changes to the +** database are written into the database file and flushed to oxide. +** At the end of this call, the rollback journal still exists on the +** disk and we are still holding all locks, so the transaction has not +** committed. See sqlite3BtreeCommitPhaseTwo() for the second phase of the +** commit process. +** +** 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. +*/ +SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){ + int rc = SQLITE_OK; + if( p->inTrans==TRANS_WRITE ){ + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + rc = autoVacuumCommit(pBt); + if( rc!=SQLITE_OK ){ + sqlite3BtreeLeave(p); + return rc; + } + } + if( pBt->bDoTruncate ){ + sqlite3PagerTruncateImage(pBt->pPager, pBt->nPage); + } +#endif + rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zMaster, 0); + sqlite3BtreeLeave(p); + } + return rc; +} + +/* +** This function is called from both BtreeCommitPhaseTwo() and BtreeRollback() +** at the conclusion of a transaction. +*/ +static void btreeEndTransaction(Btree *p){ + BtShared *pBt = p->pBt; + sqlite3 *db = p->db; + assert( sqlite3BtreeHoldsMutex(p) ); + +#ifndef SQLITE_OMIT_AUTOVACUUM + pBt->bDoTruncate = 0; +#endif + if( p->inTrans>TRANS_NONE && db->nVdbeRead>1 ){ + /* If there are other active statements that belong to this database + ** handle, downgrade to a read-only transaction. The other statements + ** may still be reading from the database. */ + downgradeAllSharedCacheTableLocks(p); + p->inTrans = TRANS_READ; + }else{ + /* If the handle had 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 ){ + clearAllSharedCacheTableLocks(p); + pBt->nTransaction--; + if( 0==pBt->nTransaction ){ + pBt->inTransaction = TRANS_NONE; + } + } + + /* Set the 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); +} + +/* +** Commit the transaction currently in progress. +** +** This routine implements the second phase of a 2-phase commit. The +** sqlite3BtreeCommitPhaseOne() routine does the first phase and should +** be invoked prior to calling this routine. The sqlite3BtreeCommitPhaseOne() +** routine did all the work of writing information out to disk and flushing the +** contents so that they are written onto the disk platter. All this +** routine has to do is delete or truncate or zero the header in the +** the rollback journal (which causes the transaction to commit) and +** drop locks. +** +** Normally, if an error occurs while the pager layer is attempting to +** finalize the underlying journal file, this function returns an error and +** the upper layer will attempt a rollback. However, if the second argument +** is non-zero then this b-tree transaction is part of a multi-file +** transaction. In this case, the transaction has already been committed +** (by deleting a master journal file) and the caller will ignore this +** functions return code. So, even if an error occurs in the pager layer, +** reset the b-tree objects internal state to indicate that the write +** transaction has been closed. This is quite safe, as the pager will have +** transitioned to the error state. +** +** This will release the write lock on the database file. If there +** are no active cursors, it also releases the read lock. +*/ +SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree *p, int bCleanup){ + + if( p->inTrans==TRANS_NONE ) return SQLITE_OK; + sqlite3BtreeEnter(p); + btreeIntegrity(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 ){ + int rc; + BtShared *pBt = p->pBt; + assert( pBt->inTransaction==TRANS_WRITE ); + assert( pBt->nTransaction>0 ); + rc = sqlite3PagerCommitPhaseTwo(pBt->pPager); + if( rc!=SQLITE_OK && bCleanup==0 ){ + sqlite3BtreeLeave(p); + return rc; + } + p->iDataVersion--; /* Compensate for pPager->iDataVersion++; */ + pBt->inTransaction = TRANS_READ; + btreeClearHasContent(pBt); + } + + btreeEndTransaction(p); + sqlite3BtreeLeave(p); + return SQLITE_OK; +} + +/* +** Do both phases of a commit. +*/ +SQLITE_PRIVATE int sqlite3BtreeCommit(Btree *p){ + int rc; + sqlite3BtreeEnter(p); + rc = sqlite3BtreeCommitPhaseOne(p, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeCommitPhaseTwo(p, 0); + } + sqlite3BtreeLeave(p); + return rc; +} + +/* +** This routine sets the state to CURSOR_FAULT and the error +** code to errCode for every cursor on any BtShared that pBtree +** references. Or if the writeOnly flag is set to 1, then only +** trip write cursors and leave read cursors unchanged. +** +** Every cursor is a candidate to be tripped, including cursors +** that belong to other database connections that happen to be +** sharing the cache with pBtree. +** +** This routine gets called when a rollback occurs. If the writeOnly +** flag is true, then only write-cursors need be tripped - read-only +** cursors save their current positions so that they may continue +** following the rollback. Or, if writeOnly is false, all cursors are +** tripped. In general, writeOnly is false if the transaction being +** rolled back modified the database schema. In this case b-tree root +** pages may be moved or deleted from the database altogether, making +** it unsafe for read cursors to continue. +** +** If the writeOnly flag is true and an error is encountered while +** saving the current position of a read-only cursor, all cursors, +** including all read-cursors are tripped. +** +** SQLITE_OK is returned if successful, or if an error occurs while +** saving a cursor position, an SQLite error code. +*/ +SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int writeOnly){ + BtCursor *p; + int rc = SQLITE_OK; + + assert( (writeOnly==0 || writeOnly==1) && BTCF_WriteFlag==1 ); + if( pBtree ){ + sqlite3BtreeEnter(pBtree); + for(p=pBtree->pBt->pCursor; p; p=p->pNext){ + int i; + if( writeOnly && (p->curFlags & BTCF_WriteFlag)==0 ){ + if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){ + rc = saveCursorPosition(p); + if( rc!=SQLITE_OK ){ + (void)sqlite3BtreeTripAllCursors(pBtree, rc, 0); + break; + } + } + }else{ + sqlite3BtreeClearCursor(p); + p->eState = CURSOR_FAULT; + p->skipNext = errCode; + } + for(i=0; i<=p->iPage; i++){ + releasePage(p->apPage[i]); + p->apPage[i] = 0; + } + } + sqlite3BtreeLeave(pBtree); + } + return rc; +} + +/* +** Rollback the transaction in progress. +** +** If tripCode is not SQLITE_OK then cursors will be invalidated (tripped). +** Only write cursors are tripped if writeOnly is true but all cursors are +** tripped if writeOnly is false. Any attempt to use +** a tripped cursor 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. +*/ +SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly){ + int rc; + BtShared *pBt = p->pBt; + MemPage *pPage1; + + assert( writeOnly==1 || writeOnly==0 ); + assert( tripCode==SQLITE_ABORT_ROLLBACK || tripCode==SQLITE_OK ); + sqlite3BtreeEnter(p); + if( tripCode==SQLITE_OK ){ + rc = tripCode = saveAllCursors(pBt, 0, 0); + if( rc ) writeOnly = 0; + }else{ + rc = SQLITE_OK; + } + if( tripCode ){ + int rc2 = sqlite3BtreeTripAllCursors(p, tripCode, writeOnly); + assert( rc==SQLITE_OK || (writeOnly==0 && rc2==SQLITE_OK) ); + if( rc2!=SQLITE_OK ) rc = rc2; + } + btreeIntegrity(p); + + if( p->inTrans==TRANS_WRITE ){ + int rc2; + + assert( TRANS_WRITE==pBt->inTransaction ); + rc2 = sqlite3PagerRollback(pBt->pPager); + if( rc2!=SQLITE_OK ){ + rc = rc2; + } + + /* The rollback may have destroyed the pPage1->aData value. So + ** call btreeGetPage() on page 1 again to make + ** sure pPage1->aData is set correctly. */ + if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){ + int nPage = get4byte(28+(u8*)pPage1->aData); + testcase( nPage==0 ); + if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage); + testcase( pBt->nPage!=nPage ); + pBt->nPage = nPage; + releasePage(pPage1); + } + assert( countValidCursors(pBt, 1)==0 ); + pBt->inTransaction = TRANS_READ; + btreeClearHasContent(pBt); + } + + btreeEndTransaction(p); + sqlite3BtreeLeave(p); + return rc; +} + +/* +** Start a statement subtransaction. The subtransaction 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. +** +** 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. +** +** A statement sub-transaction is implemented as an anonymous savepoint. The +** value passed as the second parameter is the total number of savepoints, +** including the new anonymous savepoint, open on the B-Tree. i.e. if there +** are no active savepoints and no other statement-transactions open, +** iStatement is 1. This anonymous savepoint can be released or rolled back +** using the sqlite3BtreeSavepoint() function. +*/ +SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree *p, int iStatement){ + int rc; + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); + assert( p->inTrans==TRANS_WRITE ); + assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); + assert( iStatement>0 ); + assert( iStatement>p->db->nSavepoint ); + assert( pBt->inTransaction==TRANS_WRITE ); + /* At the pager level, a statement transaction is a savepoint with + ** an index greater than all savepoints created explicitly using + ** SQL statements. It is illegal to open, release or rollback any + ** such savepoints while the statement transaction savepoint is active. + */ + rc = sqlite3PagerOpenSavepoint(pBt->pPager, iStatement); + sqlite3BtreeLeave(p); + return rc; +} + +/* +** The second argument to this function, op, is always SAVEPOINT_ROLLBACK +** or SAVEPOINT_RELEASE. This function either releases or rolls back the +** savepoint identified by parameter iSavepoint, depending on the value +** of op. +** +** Normally, iSavepoint is greater than or equal to zero. However, if op is +** SAVEPOINT_ROLLBACK, then iSavepoint may also be -1. In this case the +** contents of the entire transaction are rolled back. This is different +** from a normal transaction rollback, as no locks are released and the +** transaction remains open. +*/ +SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){ + int rc = SQLITE_OK; + if( p && p->inTrans==TRANS_WRITE ){ + BtShared *pBt = p->pBt; + assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK ); + assert( iSavepoint>=0 || (iSavepoint==-1 && op==SAVEPOINT_ROLLBACK) ); + sqlite3BtreeEnter(p); + rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint); + if( rc==SQLITE_OK ){ + if( iSavepoint<0 && (pBt->btsFlags & BTS_INITIALLY_EMPTY)!=0 ){ + pBt->nPage = 0; + } + rc = newDatabase(pBt); + pBt->nPage = get4byte(28 + pBt->pPage1->aData); + + /* The database size was written into the offset 28 of the header + ** when the transaction started, so we know that the value at offset + ** 28 is nonzero. */ + assert( pBt->nPage>0 ); + } + sqlite3BtreeLeave(p); + } + return rc; +} + +/* +** Create a new cursor for the BTree whose root is on the page +** iTable. If a read-only cursor is requested, it is assumed that +** the caller already has at least a read-only transaction open +** on the database already. If a write-cursor is requested, then +** the caller is assumed to have an open write transaction. +** +** If wrFlag==0, then the cursor can only be used for reading. +** If wrFlag==1, then the cursor can be used for reading or for +** writing if other conditions for writing are also met. These +** are the conditions that must be met in order for writing to +** be allowed: +** +** 1: The cursor must have been opened with wrFlag==1 +** +** 2: Other database connections that share the same pager cache +** but which are not in the READ_UNCOMMITTED state may not have +** cursors open with wrFlag==0 on the same table. Otherwise +** the changes made by this write cursor would be visible to +** the read cursors in the other database connection. +** +** 3: The database must be writable (not on read-only media) +** +** 4: There must be an active transaction. +** +** No checking is done to make sure that page iTable really is the +** root page of a b-tree. If it is not, then the cursor acquired +** will not work correctly. +** +** It is assumed that the sqlite3BtreeCursorZero() has been called +** on pCur to initialize the memory space prior to invoking this routine. +*/ +static int btreeCursor( + Btree *p, /* The btree */ + int iTable, /* Root page of table to open */ + int wrFlag, /* 1 to write. 0 read-only */ + struct KeyInfo *pKeyInfo, /* First arg to comparison function */ + BtCursor *pCur /* Space for new cursor */ +){ + BtShared *pBt = p->pBt; /* Shared b-tree handle */ + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( wrFlag==0 || wrFlag==1 ); + + /* The following assert statements verify that if this is a sharable + ** b-tree database, the connection is holding the required table locks, + ** and that no other connection has any open cursor that conflicts with + ** this lock. */ + assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, wrFlag+1) ); + assert( wrFlag==0 || !hasReadConflicts(p, iTable) ); + + /* Assert that the caller has opened the required transaction. */ + assert( p->inTrans>TRANS_NONE ); + assert( wrFlag==0 || p->inTrans==TRANS_WRITE ); + assert( pBt->pPage1 && pBt->pPage1->aData ); + + if( NEVER(wrFlag && (pBt->btsFlags & BTS_READ_ONLY)!=0) ){ + return SQLITE_READONLY; + } + if( wrFlag ){ + allocateTempSpace(pBt); + if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM; + } + if( iTable==1 && btreePagecount(pBt)==0 ){ + assert( wrFlag==0 ); + iTable = 0; + } + + /* Now that no other errors can occur, finish filling in the BtCursor + ** variables and link the cursor into the BtShared list. */ + pCur->pgnoRoot = (Pgno)iTable; + pCur->iPage = -1; + pCur->pKeyInfo = pKeyInfo; + pCur->pBtree = p; + pCur->pBt = pBt; + assert( wrFlag==0 || wrFlag==BTCF_WriteFlag ); + pCur->curFlags = wrFlag; + pCur->pNext = pBt->pCursor; + if( pCur->pNext ){ + pCur->pNext->pPrev = pCur; + } + pBt->pCursor = pCur; + pCur->eState = CURSOR_INVALID; + return SQLITE_OK; +} +SQLITE_PRIVATE int sqlite3BtreeCursor( + Btree *p, /* The btree */ + int iTable, /* Root page of table to open */ + int wrFlag, /* 1 to write. 0 read-only */ + struct KeyInfo *pKeyInfo, /* First arg to xCompare() */ + BtCursor *pCur /* Write new cursor here */ +){ + int rc; + sqlite3BtreeEnter(p); + rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur); + sqlite3BtreeLeave(p); + return rc; +} + +/* +** Return the size of a BtCursor object in bytes. +** +** This interfaces is needed so that users of cursors can preallocate +** sufficient storage to hold a cursor. The BtCursor object is opaque +** to users so they cannot do the sizeof() themselves - they must call +** this routine. +*/ +SQLITE_PRIVATE int sqlite3BtreeCursorSize(void){ + return ROUND8(sizeof(BtCursor)); +} + +/* +** Initialize memory that will be converted into a BtCursor object. +** +** The simple approach here would be to memset() the entire object +** to zero. But it turns out that the apPage[] and aiIdx[] arrays +** do not need to be zeroed and they are large, so we can save a lot +** of run-time by skipping the initialization of those elements. +*/ +SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor *p){ + memset(p, 0, offsetof(BtCursor, iPage)); +} + +/* +** Close a cursor. The read lock on the database file is released +** when the last cursor is closed. +*/ +SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){ + Btree *pBtree = pCur->pBtree; + if( pBtree ){ + int i; + BtShared *pBt = pCur->pBt; + sqlite3BtreeEnter(pBtree); + sqlite3BtreeClearCursor(pCur); + if( pCur->pPrev ){ + pCur->pPrev->pNext = pCur->pNext; + }else{ + pBt->pCursor = pCur->pNext; + } + if( pCur->pNext ){ + pCur->pNext->pPrev = pCur->pPrev; + } + for(i=0; i<=pCur->iPage; i++){ + releasePage(pCur->apPage[i]); + } + unlockBtreeIfUnused(pBt); + sqlite3_free(pCur->aOverflow); + /* sqlite3_free(pCur); */ + sqlite3BtreeLeave(pBtree); + } + return SQLITE_OK; +} + +/* +** Make sure the BtCursor* given in the argument has a valid +** BtCursor.info structure. If it is not already valid, call +** btreeParseCell() to fill it in. +** +** BtCursor.info is a cache of the information in the current cell. +** Using this cache reduces the number of calls to btreeParseCell(). +** +** 2007-06-25: There is a bug in some versions of MSVC that cause the +** compiler to crash when getCellInfo() is implemented as a macro. +** But there is a measureable speed advantage to using the macro on gcc +** (when less compiler optimizations like -Os or -O0 are used and the +** compiler is not doing aggressive inlining.) So we use a real function +** for MSVC and a macro for everything else. Ticket #2457. +*/ +#ifndef NDEBUG + static void assertCellInfo(BtCursor *pCur){ + CellInfo info; + int iPage = pCur->iPage; + memset(&info, 0, sizeof(info)); + btreeParseCell(pCur->apPage[iPage], pCur->aiIdx[iPage], &info); + assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 ); + } +#else + #define assertCellInfo(x) +#endif +#ifdef _MSC_VER + /* Use a real function in MSVC to work around bugs in that compiler. */ + static void getCellInfo(BtCursor *pCur){ + if( pCur->info.nSize==0 ){ + int iPage = pCur->iPage; + btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); + pCur->curFlags |= BTCF_ValidNKey; + }else{ + assertCellInfo(pCur); + } + } +#else /* if not _MSC_VER */ + /* Use a macro in all other compilers so that the function is inlined */ +#define getCellInfo(pCur) \ + if( pCur->info.nSize==0 ){ \ + int iPage = pCur->iPage; \ + btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); \ + pCur->curFlags |= BTCF_ValidNKey; \ + }else{ \ + assertCellInfo(pCur); \ + } +#endif /* _MSC_VER */ + +#ifndef NDEBUG /* The next routine used only within assert() statements */ +/* +** Return true if the given BtCursor is valid. A valid cursor is one +** that is currently pointing to a row in a (non-empty) table. +** This is a verification routine is used only within assert() statements. +*/ +SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor *pCur){ + return pCur && pCur->eState==CURSOR_VALID; +} +#endif /* NDEBUG */ + +/* +** Set *pSize to the size of the buffer needed to hold the value of +** 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. +** +** The caller must position the cursor prior to invoking this routine. +** +** This routine cannot fail. It always returns SQLITE_OK. +*/ +SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + 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. +** +** The caller must guarantee that the cursor is pointing to a non-NULL +** valid entry. In other words, the calling procedure must guarantee +** that the cursor has Cursor.eState==CURSOR_VALID. +** +** Failure is not possible. This function always returns SQLITE_OK. +** It might just as well be a procedure (returning void) but we continue +** to return an integer result code for historical reasons. +*/ +SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->iPage>=0 ); + assert( pCur->iPageapPage[pCur->iPage]->intKeyLeaf==1 ); + getCellInfo(pCur); + *pSize = pCur->info.nPayload; + return SQLITE_OK; +} + +/* +** Given the page number of an overflow page in the database (parameter +** ovfl), this function finds the page number of the next page in the +** linked list of overflow pages. If possible, it uses the auto-vacuum +** pointer-map data instead of reading the content of page ovfl to do so. +** +** If an error occurs an SQLite error code is returned. Otherwise: +** +** The page number of the next overflow page in the linked list is +** written to *pPgnoNext. If page ovfl is the last page in its linked +** list, *pPgnoNext is set to zero. +** +** If ppPage is not NULL, and a reference to the MemPage object corresponding +** to page number pOvfl was obtained, then *ppPage is set to point to that +** reference. It is the responsibility of the caller to call releasePage() +** on *ppPage to free the reference. In no reference was obtained (because +** the pointer-map was used to obtain the value for *pPgnoNext), then +** *ppPage is set to zero. +*/ +static int getOverflowPage( + BtShared *pBt, /* The database file */ + Pgno ovfl, /* Current overflow page number */ + MemPage **ppPage, /* OUT: MemPage handle (may be NULL) */ + Pgno *pPgnoNext /* OUT: Next overflow page number */ +){ + Pgno next = 0; + MemPage *pPage = 0; + int rc = SQLITE_OK; + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert(pPgnoNext); + +#ifndef SQLITE_OMIT_AUTOVACUUM + /* Try to find the next page in the overflow list using the + ** autovacuum pointer-map pages. Guess that the next page in + ** the overflow list is page number (ovfl+1). If that guess turns + ** out to be wrong, fall back to loading the data of page + ** number ovfl to determine the next page number. + */ + if( pBt->autoVacuum ){ + Pgno pgno; + Pgno iGuess = ovfl+1; + u8 eType; + + while( PTRMAP_ISPAGE(pBt, iGuess) || iGuess==PENDING_BYTE_PAGE(pBt) ){ + iGuess++; + } + + if( iGuess<=btreePagecount(pBt) ){ + rc = ptrmapGet(pBt, iGuess, &eType, &pgno); + if( rc==SQLITE_OK && eType==PTRMAP_OVERFLOW2 && pgno==ovfl ){ + next = iGuess; + rc = SQLITE_DONE; + } + } + } +#endif + + assert( next==0 || rc==SQLITE_DONE ); + if( rc==SQLITE_OK ){ + rc = btreeGetPage(pBt, ovfl, &pPage, (ppPage==0) ? PAGER_GET_READONLY : 0); + assert( rc==SQLITE_OK || pPage==0 ); + if( rc==SQLITE_OK ){ + next = get4byte(pPage->aData); + } + } + + *pPgnoNext = next; + if( ppPage ){ + *ppPage = pPage; + }else{ + releasePage(pPage); + } + return (rc==SQLITE_DONE ? SQLITE_OK : rc); +} + +/* +** Copy data from a buffer to a page, or from a page to a buffer. +** +** pPayload is a pointer to data stored on database page pDbPage. +** If argument eOp is false, then nByte bytes of data are copied +** from pPayload to the buffer pointed at by pBuf. If eOp is true, +** then sqlite3PagerWrite() is called on pDbPage and nByte bytes +** of data are copied from the buffer pBuf to pPayload. +** +** SQLITE_OK is returned on success, otherwise an error code. +*/ +static int copyPayload( + void *pPayload, /* Pointer to page data */ + void *pBuf, /* Pointer to buffer */ + int nByte, /* Number of bytes to copy */ + int eOp, /* 0 -> copy from page, 1 -> copy to page */ + DbPage *pDbPage /* Page containing pPayload */ +){ + if( eOp ){ + /* Copy data from buffer to page (a write operation) */ + int rc = sqlite3PagerWrite(pDbPage); + if( rc!=SQLITE_OK ){ + return rc; + } + memcpy(pPayload, pBuf, nByte); + }else{ + /* Copy data from page to buffer (a read operation) */ + memcpy(pBuf, pPayload, nByte); + } + return SQLITE_OK; +} + +/* +** This function is used to read or overwrite payload information +** for the entry that the pCur cursor is pointing to. The eOp +** argument is interpreted as follows: +** +** 0: The operation is a read. Populate the overflow cache. +** 1: The operation is a write. Populate the overflow cache. +** 2: The operation is a read. Do not populate the overflow cache. +** +** A total of "amt" bytes are read or written beginning at "offset". +** Data is read to or from the buffer pBuf. +** +** The content being read or written might appear on the main page +** or be scattered out on multiple overflow pages. +** +** If the current cursor entry uses one or more overflow pages and the +** eOp argument is not 2, this function may allocate space for and lazily +** populates the overflow page-list cache array (BtCursor.aOverflow). +** Subsequent calls use this cache to make seeking to the supplied offset +** more efficient. +** +** Once an overflow page-list cache has been allocated, it may be +** invalidated if some other cursor writes to the same table, or if +** the cursor is moved to a different row. Additionally, in auto-vacuum +** mode, the following events may invalidate an overflow page-list cache. +** +** * An incremental vacuum, +** * A commit in auto_vacuum="full" mode, +** * Creating a table (may require moving an overflow page). +*/ +static int accessPayload( + BtCursor *pCur, /* Cursor pointing to entry to read from */ + u32 offset, /* Begin reading this far into payload */ + u32 amt, /* Read this many bytes */ + unsigned char *pBuf, /* Write the bytes into this buffer */ + int eOp /* zero to read. non-zero to write. */ +){ + unsigned char *aPayload; + int rc = SQLITE_OK; + int iIdx = 0; + MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */ + BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */ +#ifdef SQLITE_DIRECT_OVERFLOW_READ + unsigned char * const pBufStart = pBuf; + int bEnd; /* True if reading to end of data */ +#endif + + assert( pPage ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->aiIdx[pCur->iPage]nCell ); + assert( cursorHoldsMutex(pCur) ); + assert( eOp!=2 || offset==0 ); /* Always start from beginning for eOp==2 */ + + getCellInfo(pCur); + aPayload = pCur->info.pPayload; +#ifdef SQLITE_DIRECT_OVERFLOW_READ + bEnd = offset+amt==pCur->info.nPayload; +#endif + assert( offset+amt <= pCur->info.nPayload ); + + if( &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] ){ + /* Trying to read or write past the end of the data is an error */ + return SQLITE_CORRUPT_BKPT; + } + + /* Check if data must be read/written to/from the btree page itself. */ + if( offsetinfo.nLocal ){ + int a = amt; + if( a+offset>pCur->info.nLocal ){ + a = pCur->info.nLocal - offset; + } + rc = copyPayload(&aPayload[offset], pBuf, a, (eOp & 0x01), pPage->pDbPage); + offset = 0; + pBuf += a; + amt -= a; + }else{ + offset -= pCur->info.nLocal; + } + + + if( rc==SQLITE_OK && amt>0 ){ + const u32 ovflSize = pBt->usableSize - 4; /* Bytes content per ovfl page */ + Pgno nextPage; + + nextPage = get4byte(&aPayload[pCur->info.nLocal]); + + /* If the BtCursor.aOverflow[] has not been allocated, allocate it now. + ** Except, do not allocate aOverflow[] for eOp==2. + ** + ** The aOverflow[] array is sized at one entry for each overflow page + ** in the overflow chain. The page number of the first overflow page is + ** stored in aOverflow[0], etc. A value of 0 in the aOverflow[] array + ** means "not yet known" (the cache is lazily populated). + */ + if( eOp!=2 && (pCur->curFlags & BTCF_ValidOvfl)==0 ){ + int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize; + if( nOvfl>pCur->nOvflAlloc ){ + Pgno *aNew = (Pgno*)sqlite3Realloc( + pCur->aOverflow, nOvfl*2*sizeof(Pgno) + ); + if( aNew==0 ){ + rc = SQLITE_NOMEM; + }else{ + pCur->nOvflAlloc = nOvfl*2; + pCur->aOverflow = aNew; + } + } + if( rc==SQLITE_OK ){ + memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno)); + pCur->curFlags |= BTCF_ValidOvfl; + } + } + + /* If the overflow page-list cache has been allocated and the + ** entry for the first required overflow page is valid, skip + ** directly to it. + */ + if( (pCur->curFlags & BTCF_ValidOvfl)!=0 + && pCur->aOverflow[offset/ovflSize] + ){ + iIdx = (offset/ovflSize); + nextPage = pCur->aOverflow[iIdx]; + offset = (offset%ovflSize); + } + + for( ; rc==SQLITE_OK && amt>0 && nextPage; iIdx++){ + + /* If required, populate the overflow page-list cache. */ + if( (pCur->curFlags & BTCF_ValidOvfl)!=0 ){ + assert(!pCur->aOverflow[iIdx] || pCur->aOverflow[iIdx]==nextPage); + pCur->aOverflow[iIdx] = nextPage; + } + + if( offset>=ovflSize ){ + /* The only reason to read this page is to obtain the page + ** number for the next page in the overflow chain. The page + ** data is not required. So first try to lookup the overflow + ** page-list cache, if any, then fall back to the getOverflowPage() + ** function. + ** + ** Note that the aOverflow[] array must be allocated because eOp!=2 + ** here. If eOp==2, then offset==0 and this branch is never taken. + */ + assert( eOp!=2 ); + assert( pCur->curFlags & BTCF_ValidOvfl ); + assert( pCur->pBtree->db==pBt->db ); + if( pCur->aOverflow[iIdx+1] ){ + nextPage = pCur->aOverflow[iIdx+1]; + }else{ + rc = getOverflowPage(pBt, nextPage, 0, &nextPage); + } + offset -= ovflSize; + }else{ + /* Need to read this page properly. It contains some of the + ** range of data that is being read (eOp==0) or written (eOp!=0). + */ +#ifdef SQLITE_DIRECT_OVERFLOW_READ + sqlite3_file *fd; +#endif + int a = amt; + if( a + offset > ovflSize ){ + a = ovflSize - offset; + } + +#ifdef SQLITE_DIRECT_OVERFLOW_READ + /* If all the following are true: + ** + ** 1) this is a read operation, and + ** 2) data is required from the start of this overflow page, and + ** 3) the database is file-backed, and + ** 4) there is no open write-transaction, and + ** 5) the database is not a WAL database, + ** 6) all data from the page is being read. + ** 7) at least 4 bytes have already been read into the output buffer + ** + ** then data can be read directly from the database file into the + ** output buffer, bypassing the page-cache altogether. This speeds + ** up loading large records that span many overflow pages. + */ + if( (eOp&0x01)==0 /* (1) */ + && offset==0 /* (2) */ + && (bEnd || a==ovflSize) /* (6) */ + && pBt->inTransaction==TRANS_READ /* (4) */ + && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */ + && pBt->pPage1->aData[19]==0x01 /* (5) */ + && &pBuf[-4]>=pBufStart /* (7) */ + ){ + u8 aSave[4]; + u8 *aWrite = &pBuf[-4]; + assert( aWrite>=pBufStart ); /* hence (7) */ + memcpy(aSave, aWrite, 4); + rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1)); + nextPage = get4byte(aWrite); + memcpy(aWrite, aSave, 4); + }else +#endif + + { + DbPage *pDbPage; + rc = sqlite3PagerAcquire(pBt->pPager, nextPage, &pDbPage, + ((eOp&0x01)==0 ? PAGER_GET_READONLY : 0) + ); + if( rc==SQLITE_OK ){ + aPayload = sqlite3PagerGetData(pDbPage); + nextPage = get4byte(aPayload); + rc = copyPayload(&aPayload[offset+4], pBuf, a, (eOp&0x01), pDbPage); + sqlite3PagerUnref(pDbPage); + offset = 0; + } + } + amt -= a; + pBuf += a; + } + } + } + + if( rc==SQLITE_OK && amt>0 ){ + return SQLITE_CORRUPT_BKPT; + } + return rc; +} + +/* +** Read part of the key associated with cursor pCur. Exactly +** "amt" bytes will be transferred into pBuf[]. The transfer +** begins at "offset". +** +** The caller must ensure that pCur is pointing to a valid row +** in the table. +** +** 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. +*/ +SQLITE_PRIVATE int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] ); + assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); + return accessPayload(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. +*/ +SQLITE_PRIVATE int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ + int rc; + +#ifndef SQLITE_OMIT_INCRBLOB + if ( pCur->eState==CURSOR_INVALID ){ + return SQLITE_ABORT; + } +#endif + + assert( cursorHoldsMutex(pCur) ); + rc = restoreCursorPosition(pCur); + if( rc==SQLITE_OK ){ + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] ); + assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); + rc = accessPayload(pCur, offset, amt, pBuf, 0); + } + 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 index btrees (pPage->intKey==0) and is the data for +** table btrees (pPage->intKey==1). The number of bytes of available +** key/data is written into *pAmt. If *pAmt==0, then the value +** returned will not be a valid pointer. +** +** This routine is an optimization. It is common for the entire key +** and data to fit on the local page and for there to be no overflow +** pages. When that is so, this routine can be used to access the +** key and data without making a copy. If the key and/or data spills +** onto overflow pages, then accessPayload() must be used to reassemble +** the key/data and copy it into a preallocated buffer. +** +** The pointer returned by this routine looks directly into the cached +** page of the database. The data might change or move the next time +** any btree routine is called. +*/ +static const void *fetchPayload( + BtCursor *pCur, /* Cursor pointing to entry to read from */ + u32 *pAmt /* Write the number of available bytes here */ +){ + u32 amt; + assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]); + assert( pCur->eState==CURSOR_VALID ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + assert( cursorHoldsMutex(pCur) ); + assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); + assert( pCur->info.nSize>0 ); + assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB ); + assert( pCur->info.pPayloadapPage[pCur->iPage]->aDataEnd ||CORRUPT_DB); + amt = (int)(pCur->apPage[pCur->iPage]->aDataEnd - pCur->info.pPayload); + if( pCur->info.nLocalinfo.nLocal; + *pAmt = amt; + return (void*)pCur->info.pPayload; +} + + +/* +** For the entry that cursor pCur is point to, return as +** many bytes of the key or data as are available on the local +** b-tree page. Write the number of available bytes into *pAmt. +** +** The pointer returned is ephemeral. The key/data may move +** or be destroyed on the next call to any Btree routine, +** including calls from other threads against the same cache. +** Hence, a mutex on the BtShared should be held prior to calling +** this routine. +** +** These routines is used to get quick access to key and data +** in the common case where no overflow pages are used. +*/ +SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor *pCur, u32 *pAmt){ + return fetchPayload(pCur, pAmt); +} +SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor *pCur, u32 *pAmt){ + return fetchPayload(pCur, pAmt); +} + + +/* +** Move the cursor down to a new child page. The newPgno argument is the +** page number of the child page to move to. +** +** This function returns SQLITE_CORRUPT if the page-header flags field of +** the new child page does not match the flags field of the parent (i.e. +** if an intkey page appears to be the parent of a non-intkey page, or +** vice-versa). +*/ +static int moveToChild(BtCursor *pCur, u32 newPgno){ + int rc; + int i = pCur->iPage; + MemPage *pNewPage; + BtShared *pBt = pCur->pBt; + + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->iPageiPage>=0 ); + if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){ + return SQLITE_CORRUPT_BKPT; + } + rc = getAndInitPage(pBt, newPgno, &pNewPage, + (pCur->curFlags & BTCF_WriteFlag)==0 ? PAGER_GET_READONLY : 0); + if( rc ) return rc; + pCur->apPage[i+1] = pNewPage; + pCur->aiIdx[i+1] = 0; + pCur->iPage++; + + pCur->info.nSize = 0; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); + if( pNewPage->nCell<1 || pNewPage->intKey!=pCur->apPage[i]->intKey ){ + return SQLITE_CORRUPT_BKPT; + } + return SQLITE_OK; +} + +#if SQLITE_DEBUG +/* +** Page pParent is an internal (non-leaf) tree page. This function +** asserts that page number iChild is the left-child if the iIdx'th +** cell in page pParent. Or, if iIdx is equal to the total number of +** cells in pParent, that page number iChild is the right-child of +** the page. +*/ +static void assertParentIndex(MemPage *pParent, int iIdx, Pgno iChild){ + if( CORRUPT_DB ) return; /* The conditions tested below might not be true + ** in a corrupt database */ + assert( iIdx<=pParent->nCell ); + if( iIdx==pParent->nCell ){ + assert( get4byte(&pParent->aData[pParent->hdrOffset+8])==iChild ); + }else{ + assert( get4byte(findCell(pParent, iIdx))==iChild ); + } +} +#else +# define assertParentIndex(x,y,z) +#endif + +/* +** Move the cursor up to the parent page. +** +** 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){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->iPage>0 ); + assert( pCur->apPage[pCur->iPage] ); + assertParentIndex( + pCur->apPage[pCur->iPage-1], + pCur->aiIdx[pCur->iPage-1], + pCur->apPage[pCur->iPage]->pgno + ); + testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell ); + + releasePage(pCur->apPage[pCur->iPage]); + pCur->iPage--; + pCur->info.nSize = 0; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); +} + +/* +** Move the cursor to point to the root page of its b-tree structure. +** +** If the table has a virtual root page, then the cursor is moved to point +** to the virtual root page instead of the actual root page. A table has a +** virtual root page when the actual root page contains no cells and a +** single child page. This can only happen with the table rooted at page 1. +** +** If the b-tree structure is empty, the cursor state is set to +** CURSOR_INVALID. Otherwise, the cursor is set to point to the first +** cell located on the root (or virtual root) page and the cursor state +** is set to CURSOR_VALID. +** +** If this function returns successfully, it may be assumed that the +** page-header flags indicate that the [virtual] root-page is the expected +** kind of b-tree page (i.e. if when opening the cursor the caller did not +** specify a KeyInfo structure the flags byte is set to 0x05 or 0x0D, +** indicating a table b-tree, or if the caller did specify a KeyInfo +** structure the flags byte is set to 0x02 or 0x0A, indicating an index +** b-tree). +*/ +static int moveToRoot(BtCursor *pCur){ + MemPage *pRoot; + int rc = SQLITE_OK; + + assert( cursorHoldsMutex(pCur) ); + assert( CURSOR_INVALID < CURSOR_REQUIRESEEK ); + assert( CURSOR_VALID < CURSOR_REQUIRESEEK ); + assert( CURSOR_FAULT > CURSOR_REQUIRESEEK ); + if( pCur->eState>=CURSOR_REQUIRESEEK ){ + if( pCur->eState==CURSOR_FAULT ){ + assert( pCur->skipNext!=SQLITE_OK ); + return pCur->skipNext; + } + sqlite3BtreeClearCursor(pCur); + } + + if( pCur->iPage>=0 ){ + while( pCur->iPage ) releasePage(pCur->apPage[pCur->iPage--]); + }else if( pCur->pgnoRoot==0 ){ + pCur->eState = CURSOR_INVALID; + return SQLITE_OK; + }else{ + rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->apPage[0], + (pCur->curFlags & BTCF_WriteFlag)==0 ? PAGER_GET_READONLY : 0); + if( rc!=SQLITE_OK ){ + pCur->eState = CURSOR_INVALID; + return rc; + } + pCur->iPage = 0; + } + pRoot = pCur->apPage[0]; + assert( pRoot->pgno==pCur->pgnoRoot ); + + /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor + ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is + ** NULL, the caller expects a table b-tree. If this is not the case, + ** return an SQLITE_CORRUPT error. + ** + ** Earlier versions of SQLite assumed that this test could not fail + ** if the root page was already loaded when this function was called (i.e. + ** if pCur->iPage>=0). But this is not so if the database is corrupted + ** in such a way that page pRoot is linked into a second b-tree table + ** (or the freelist). */ + assert( pRoot->intKey==1 || pRoot->intKey==0 ); + if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){ + return SQLITE_CORRUPT_BKPT; + } + + pCur->aiIdx[0] = 0; + pCur->info.nSize = 0; + pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl); + + if( pRoot->nCell>0 ){ + pCur->eState = CURSOR_VALID; + }else if( !pRoot->leaf ){ + Pgno subpage; + if( pRoot->pgno!=1 ) return SQLITE_CORRUPT_BKPT; + subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]); + pCur->eState = CURSOR_VALID; + rc = moveToChild(pCur, subpage); + }else{ + pCur->eState = 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 = SQLITE_OK; + MemPage *pPage; + + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){ + assert( pCur->aiIdx[pCur->iPage]nCell ); + pgno = get4byte(findCell(pPage, pCur->aiIdx[pCur->iPage])); + rc = moveToChild(pCur, pgno); + } + return rc; +} + +/* +** 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 = SQLITE_OK; + MemPage *pPage = 0; + + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){ + pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); + pCur->aiIdx[pCur->iPage] = pPage->nCell; + rc = moveToChild(pCur, pgno); + if( rc ) return rc; + } + pCur->aiIdx[pCur->iPage] = pPage->nCell-1; + assert( pCur->info.nSize==0 ); + assert( (pCur->curFlags & BTCF_ValidNKey)==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. +*/ +SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ + int rc; + + assert( cursorHoldsMutex(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + rc = moveToRoot(pCur); + if( rc==SQLITE_OK ){ + if( pCur->eState==CURSOR_INVALID ){ + assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); + *pRes = 1; + }else{ + assert( pCur->apPage[pCur->iPage]->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. +*/ +SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ + int rc; + + assert( cursorHoldsMutex(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + + /* If the cursor already points to the last entry, this is a no-op. */ + if( CURSOR_VALID==pCur->eState && (pCur->curFlags & BTCF_AtLast)!=0 ){ +#ifdef SQLITE_DEBUG + /* This block serves to assert() that the cursor really does point + ** to the last entry in the b-tree. */ + int ii; + for(ii=0; iiiPage; ii++){ + assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell ); + } + assert( pCur->aiIdx[pCur->iPage]==pCur->apPage[pCur->iPage]->nCell-1 ); + assert( pCur->apPage[pCur->iPage]->leaf ); +#endif + return SQLITE_OK; + } + + rc = moveToRoot(pCur); + if( rc==SQLITE_OK ){ + if( CURSOR_INVALID==pCur->eState ){ + assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); + *pRes = 1; + }else{ + assert( pCur->eState==CURSOR_VALID ); + *pRes = 0; + rc = moveToRightmost(pCur); + if( rc==SQLITE_OK ){ + pCur->curFlags |= BTCF_AtLast; + }else{ + pCur->curFlags &= ~BTCF_AtLast; + } + + } + } + return rc; +} + +/* Move the cursor so that it points to an entry near the key +** specified by pIdxKey or intKey. Return a success code. +** +** For INTKEY tables, the intKey parameter is used. pIdxKey +** must be NULL. For index tables, pIdxKey is used and intKey +** is ignored. +** +** 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. +** +** An integer is written into *pRes which is the result of +** comparing the key with the entry to which the cursor is +** pointing. The meaning of the integer written into +** *pRes is as follows: +** +** *pRes<0 The cursor is left pointing at an entry that +** is smaller than intKey/pIdxKey or if the table is empty +** and the cursor is therefore left point to nothing. +** +** *pRes==0 The cursor is left pointing at an entry that +** exactly matches intKey/pIdxKey. +** +** *pRes>0 The cursor is left pointing at an entry that +** is larger than intKey/pIdxKey. +** +*/ +SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( + BtCursor *pCur, /* The cursor to be moved */ + UnpackedRecord *pIdxKey, /* Unpacked index key */ + i64 intKey, /* The table key */ + int biasRight, /* If true, bias the search to the high end */ + int *pRes /* Write search results here */ +){ + int rc; + RecordCompare xRecordCompare; + + assert( cursorHoldsMutex(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + assert( pRes ); + assert( (pIdxKey==0)==(pCur->pKeyInfo==0) ); + + /* If the cursor is already positioned at the point we are trying + ** to move to, then just return without doing any work */ + if( pCur->eState==CURSOR_VALID && (pCur->curFlags & BTCF_ValidNKey)!=0 + && pCur->apPage[0]->intKey + ){ + if( pCur->info.nKey==intKey ){ + *pRes = 0; + return SQLITE_OK; + } + if( (pCur->curFlags & BTCF_AtLast)!=0 && pCur->info.nKeyerrCode = 0; + assert( pIdxKey->default_rc==1 + || pIdxKey->default_rc==0 + || pIdxKey->default_rc==-1 + ); + }else{ + xRecordCompare = 0; /* All keys are integers */ + } + + rc = moveToRoot(pCur); + if( rc ){ + return rc; + } + assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage] ); + assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->isInit ); + assert( pCur->eState==CURSOR_INVALID || pCur->apPage[pCur->iPage]->nCell>0 ); + if( pCur->eState==CURSOR_INVALID ){ + *pRes = -1; + assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); + return SQLITE_OK; + } + assert( pCur->apPage[0]->intKey || pIdxKey ); + for(;;){ + int lwr, upr, idx, c; + Pgno chldPg; + MemPage *pPage = pCur->apPage[pCur->iPage]; + u8 *pCell; /* Pointer to current cell in pPage */ + + /* pPage->nCell must be greater than zero. If this is the root-page + ** the cursor would have been INVALID above and this for(;;) loop + ** not run. If this is not the root-page, then the moveToChild() routine + ** would have already detected db corruption. Similarly, pPage must + ** be the right kind (index or table) of b-tree page. Otherwise + ** a moveToChild() or moveToRoot() call would have detected corruption. */ + assert( pPage->nCell>0 ); + assert( pPage->intKey==(pIdxKey==0) ); + lwr = 0; + upr = pPage->nCell-1; + assert( biasRight==0 || biasRight==1 ); + idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */ + pCur->aiIdx[pCur->iPage] = (u16)idx; + if( xRecordCompare==0 ){ + for(;;){ + i64 nCellKey; + pCell = findCell(pPage, idx) + pPage->childPtrSize; + if( pPage->intKeyLeaf ){ + while( 0x80 <= *(pCell++) ){ + if( pCell>=pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT; + } + } + getVarint(pCell, (u64*)&nCellKey); + if( nCellKeyupr ){ c = -1; break; } + }else if( nCellKey>intKey ){ + upr = idx-1; + if( lwr>upr ){ c = +1; break; } + }else{ + assert( nCellKey==intKey ); + pCur->curFlags |= BTCF_ValidNKey; + pCur->info.nKey = nCellKey; + pCur->aiIdx[pCur->iPage] = (u16)idx; + if( !pPage->leaf ){ + lwr = idx; + goto moveto_next_layer; + }else{ + *pRes = 0; + rc = SQLITE_OK; + goto moveto_finish; + } + } + assert( lwr+upr>=0 ); + idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2; */ + } + }else{ + for(;;){ + int nCell; + pCell = findCell(pPage, idx) + pPage->childPtrSize; + + /* The maximum supported page-size is 65536 bytes. This means that + ** the maximum number of record bytes stored on an index B-Tree + ** page is less than 16384 bytes and may be stored as a 2-byte + ** varint. This information is used to attempt to avoid parsing + ** the entire cell by checking for the cases where the record is + ** stored entirely within the b-tree page by inspecting the first + ** 2 bytes of the cell. + */ + nCell = pCell[0]; + if( nCell<=pPage->max1bytePayload ){ + /* This branch runs if the record-size field of the cell is a + ** single byte varint and the record fits entirely on the main + ** b-tree page. */ + testcase( pCell+nCell+1==pPage->aDataEnd ); + c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey); + }else if( !(pCell[1] & 0x80) + && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal + ){ + /* The record-size field is a 2 byte varint and the record + ** fits entirely on the main b-tree page. */ + testcase( pCell+nCell+2==pPage->aDataEnd ); + c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey); + }else{ + /* The record flows over onto one or more overflow pages. In + ** this case the whole cell needs to be parsed, a buffer allocated + ** and accessPayload() used to retrieve the record into the + ** buffer before VdbeRecordCompare() can be called. */ + void *pCellKey; + u8 * const pCellBody = pCell - pPage->childPtrSize; + btreeParseCellPtr(pPage, pCellBody, &pCur->info); + nCell = (int)pCur->info.nKey; + pCellKey = sqlite3Malloc( nCell ); + if( pCellKey==0 ){ + rc = SQLITE_NOMEM; + goto moveto_finish; + } + pCur->aiIdx[pCur->iPage] = (u16)idx; + rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 2); + if( rc ){ + sqlite3_free(pCellKey); + goto moveto_finish; + } + c = xRecordCompare(nCell, pCellKey, pIdxKey); + sqlite3_free(pCellKey); + } + assert( + (pIdxKey->errCode!=SQLITE_CORRUPT || c==0) + && (pIdxKey->errCode!=SQLITE_NOMEM || pCur->pBtree->db->mallocFailed) + ); + if( c<0 ){ + lwr = idx+1; + }else if( c>0 ){ + upr = idx-1; + }else{ + assert( c==0 ); + *pRes = 0; + rc = SQLITE_OK; + pCur->aiIdx[pCur->iPage] = (u16)idx; + if( pIdxKey->errCode ) rc = SQLITE_CORRUPT; + goto moveto_finish; + } + if( lwr>upr ) break; + assert( lwr+upr>=0 ); + idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2 */ + } + } + assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) ); + assert( pPage->isInit ); + if( pPage->leaf ){ + assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); + pCur->aiIdx[pCur->iPage] = (u16)idx; + *pRes = c; + rc = SQLITE_OK; + goto moveto_finish; + } +moveto_next_layer: + if( lwr>=pPage->nCell ){ + chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]); + }else{ + chldPg = get4byte(findCell(pPage, lwr)); + } + pCur->aiIdx[pCur->iPage] = (u16)lwr; + rc = moveToChild(pCur, chldPg); + if( rc ) break; + } +moveto_finish: + pCur->info.nSize = 0; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); + return rc; +} + + +/* +** 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. +*/ +SQLITE_PRIVATE 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. +** +** The main entry point is sqlite3BtreeNext(). That routine is optimized +** for the common case of merely incrementing the cell counter BtCursor.aiIdx +** to the next cell on the current page. The (slower) btreeNext() helper +** routine is called when it is necessary to move to a different page or +** to restore the cursor. +** +** The calling function will set *pRes to 0 or 1. The initial *pRes value +** will be 1 if the cursor being stepped corresponds to an SQL index and +** if this routine could have been skipped if that SQL index had been +** a unique index. Otherwise the caller will have set *pRes to zero. +** Zero is the common case. The btree implementation is free to use the +** initial *pRes value as a hint to improve performance, but the current +** SQLite btree implementation does not. (Note that the comdb2 btree +** implementation does use this hint, however.) +*/ +static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int *pRes){ + int rc; + int idx; + MemPage *pPage; + + assert( cursorHoldsMutex(pCur) ); + assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); + assert( *pRes==0 ); + if( pCur->eState!=CURSOR_VALID ){ + assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); + rc = restoreCursorPosition(pCur); + if( rc!=SQLITE_OK ){ + return rc; + } + if( CURSOR_INVALID==pCur->eState ){ + *pRes = 1; + return SQLITE_OK; + } + if( pCur->skipNext ){ + assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT ); + pCur->eState = CURSOR_VALID; + if( pCur->skipNext>0 ){ + pCur->skipNext = 0; + return SQLITE_OK; + } + pCur->skipNext = 0; + } + } + + pPage = pCur->apPage[pCur->iPage]; + idx = ++pCur->aiIdx[pCur->iPage]; + assert( pPage->isInit ); + + /* If the database file is corrupt, it is possible for the value of idx + ** to be invalid here. This can only occur if a second cursor modifies + ** the page while cursor pCur is holding a reference to it. Which can + ** only happen if the database is corrupt in such a way as to link the + ** page into more than one b-tree structure. */ + testcase( idx>pPage->nCell ); + + if( idx>=pPage->nCell ){ + if( !pPage->leaf ){ + rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8])); + if( rc ) return rc; + return moveToLeftmost(pCur); + } + do{ + if( pCur->iPage==0 ){ + *pRes = 1; + pCur->eState = CURSOR_INVALID; + return SQLITE_OK; + } + moveToParent(pCur); + pPage = pCur->apPage[pCur->iPage]; + }while( pCur->aiIdx[pCur->iPage]>=pPage->nCell ); + if( pPage->intKey ){ + return sqlite3BtreeNext(pCur, pRes); + }else{ + return SQLITE_OK; + } + } + if( pPage->leaf ){ + return SQLITE_OK; + }else{ + return moveToLeftmost(pCur); + } +} +SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ + MemPage *pPage; + assert( cursorHoldsMutex(pCur) ); + assert( pRes!=0 ); + assert( *pRes==0 || *pRes==1 ); + assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); + pCur->info.nSize = 0; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); + *pRes = 0; + if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur, pRes); + pPage = pCur->apPage[pCur->iPage]; + if( (++pCur->aiIdx[pCur->iPage])>=pPage->nCell ){ + pCur->aiIdx[pCur->iPage]--; + return btreeNext(pCur, pRes); + } + if( pPage->leaf ){ + return SQLITE_OK; + }else{ + return moveToLeftmost(pCur); + } +} + +/* +** Step the cursor to the back to the previous entry in the database. If +** successful then set *pRes=0. If the cursor +** was already pointing to the first entry in the database before +** this routine was called, then set *pRes=1. +** +** The main entry point is sqlite3BtreePrevious(). That routine is optimized +** for the common case of merely decrementing the cell counter BtCursor.aiIdx +** to the previous cell on the current page. The (slower) btreePrevious() +** helper routine is called when it is necessary to move to a different page +** or to restore the cursor. +** +** The calling function will set *pRes to 0 or 1. The initial *pRes value +** will be 1 if the cursor being stepped corresponds to an SQL index and +** if this routine could have been skipped if that SQL index had been +** a unique index. Otherwise the caller will have set *pRes to zero. +** Zero is the common case. The btree implementation is free to use the +** initial *pRes value as a hint to improve performance, but the current +** SQLite btree implementation does not. (Note that the comdb2 btree +** implementation does use this hint, however.) +*/ +static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){ + int rc; + MemPage *pPage; + + assert( cursorHoldsMutex(pCur) ); + assert( pRes!=0 ); + assert( *pRes==0 ); + assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); + assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 ); + assert( pCur->info.nSize==0 ); + if( pCur->eState!=CURSOR_VALID ){ + rc = restoreCursorPosition(pCur); + if( rc!=SQLITE_OK ){ + return rc; + } + if( CURSOR_INVALID==pCur->eState ){ + *pRes = 1; + return SQLITE_OK; + } + if( pCur->skipNext ){ + assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT ); + pCur->eState = CURSOR_VALID; + if( pCur->skipNext<0 ){ + pCur->skipNext = 0; + return SQLITE_OK; + } + pCur->skipNext = 0; + } + } + + pPage = pCur->apPage[pCur->iPage]; + assert( pPage->isInit ); + if( !pPage->leaf ){ + int idx = pCur->aiIdx[pCur->iPage]; + rc = moveToChild(pCur, get4byte(findCell(pPage, idx))); + if( rc ) return rc; + rc = moveToRightmost(pCur); + }else{ + while( pCur->aiIdx[pCur->iPage]==0 ){ + if( pCur->iPage==0 ){ + pCur->eState = CURSOR_INVALID; + *pRes = 1; + return SQLITE_OK; + } + moveToParent(pCur); + } + assert( pCur->info.nSize==0 ); + assert( (pCur->curFlags & (BTCF_ValidNKey|BTCF_ValidOvfl))==0 ); + + pCur->aiIdx[pCur->iPage]--; + pPage = pCur->apPage[pCur->iPage]; + if( pPage->intKey && !pPage->leaf ){ + rc = sqlite3BtreePrevious(pCur, pRes); + }else{ + rc = SQLITE_OK; + } + } + return rc; +} +SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ + assert( cursorHoldsMutex(pCur) ); + assert( pRes!=0 ); + assert( *pRes==0 || *pRes==1 ); + assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); + *pRes = 0; + pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey); + pCur->info.nSize = 0; + if( pCur->eState!=CURSOR_VALID + || pCur->aiIdx[pCur->iPage]==0 + || pCur->apPage[pCur->iPage]->leaf==0 + ){ + return btreePrevious(pCur, pRes); + } + pCur->aiIdx[pCur->iPage]--; + return SQLITE_OK; +} + +/* +** Allocate a new page from the database file. +** +** The new page is marked as dirty. (In other words, sqlite3PagerWrite() +** has already been called on the new page.) The new page has also +** been referenced and the calling routine is responsible for calling +** sqlite3PagerUnref() on the new page when it is done. +** +** SQLITE_OK is returned on success. Any other return value indicates +** an error. *ppPage and *pPgno are undefined in the event of an error. +** Do not invoke sqlite3PagerUnref() on *ppPage if an error is returned. +** +** If the "nearby" parameter is not 0, then an effort is made to +** locate a page close to the page number "nearby". This can be used in an +** attempt to keep related pages close to each other in the database file, +** which in turn can make database access faster. +** +** If the eMode parameter is BTALLOC_EXACT and the nearby page exists +** anywhere on the free-list, then it is guaranteed to be returned. If +** eMode is BTALLOC_LT then the page returned will be less than or equal +** to nearby if any such page exists. If eMode is BTALLOC_ANY then there +** are no restrictions on which page is returned. +*/ +static int allocateBtreePage( + BtShared *pBt, /* The btree */ + MemPage **ppPage, /* Store pointer to the allocated page here */ + Pgno *pPgno, /* Store the page number here */ + Pgno nearby, /* Search for a page near this one */ + u8 eMode /* BTALLOC_EXACT, BTALLOC_LT, or BTALLOC_ANY */ +){ + MemPage *pPage1; + int rc; + u32 n; /* Number of pages on the freelist */ + u32 k; /* Number of leaves on the trunk of the freelist */ + MemPage *pTrunk = 0; + MemPage *pPrevTrunk = 0; + Pgno mxPage; /* Total size of the database file */ + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( eMode==BTALLOC_ANY || (nearby>0 && IfNotOmitAV(pBt->autoVacuum)) ); + pPage1 = pBt->pPage1; + mxPage = btreePagecount(pBt); + /* EVIDENCE-OF: R-05119-02637 The 4-byte big-endian integer at offset 36 + ** stores stores the total number of pages on the freelist. */ + n = get4byte(&pPage1->aData[36]); + testcase( n==mxPage-1 ); + if( n>=mxPage ){ + return SQLITE_CORRUPT_BKPT; + } + if( n>0 ){ + /* There are pages on the freelist. Reuse one of those pages. */ + Pgno iTrunk; + u8 searchList = 0; /* If the free-list must be searched for 'nearby' */ + + /* If eMode==BTALLOC_EXACT and a query of the pointer-map + ** shows that the page 'nearby' is somewhere on the free-list, then + ** the entire-list will be searched for that page. + */ +#ifndef SQLITE_OMIT_AUTOVACUUM + if( eMode==BTALLOC_EXACT ){ + if( nearby<=mxPage ){ + u8 eType; + assert( nearby>0 ); + assert( pBt->autoVacuum ); + rc = ptrmapGet(pBt, nearby, &eType, 0); + if( rc ) return rc; + if( eType==PTRMAP_FREEPAGE ){ + searchList = 1; + } + } + }else if( eMode==BTALLOC_LE ){ + searchList = 1; + } +#endif + + /* Decrement the free-list count by 1. Set iTrunk to the index of the + ** first free-list trunk page. iPrevTrunk is initially 1. + */ + rc = sqlite3PagerWrite(pPage1->pDbPage); + if( rc ) return rc; + put4byte(&pPage1->aData[36], n-1); + + /* The code within this loop is run only once if the 'searchList' variable + ** is not true. Otherwise, it runs once for each trunk-page on the + ** free-list until the page 'nearby' is located (eMode==BTALLOC_EXACT) + ** or until a page less than 'nearby' is located (eMode==BTALLOC_LT) + */ + do { + pPrevTrunk = pTrunk; + if( pPrevTrunk ){ + /* EVIDENCE-OF: R-01506-11053 The first integer on a freelist trunk page + ** is the page number of the next freelist trunk page in the list or + ** zero if this is the last freelist trunk page. */ + iTrunk = get4byte(&pPrevTrunk->aData[0]); + }else{ + /* EVIDENCE-OF: R-59841-13798 The 4-byte big-endian integer at offset 32 + ** stores the page number of the first page of the freelist, or zero if + ** the freelist is empty. */ + iTrunk = get4byte(&pPage1->aData[32]); + } + testcase( iTrunk==mxPage ); + if( iTrunk>mxPage ){ + rc = SQLITE_CORRUPT_BKPT; + }else{ + rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0); + } + if( rc ){ + pTrunk = 0; + goto end_allocate_page; + } + assert( pTrunk!=0 ); + assert( pTrunk->aData!=0 ); + /* EVIDENCE-OF: R-13523-04394 The second integer on a freelist trunk page + ** is the number of leaf page pointers to follow. */ + k = get4byte(&pTrunk->aData[4]); + if( k==0 && !searchList ){ + /* The trunk has no leaves and the list is not being searched. + ** So extract the trunk page itself and use it as the newly + ** allocated page */ + assert( pPrevTrunk==0 ); + rc = sqlite3PagerWrite(pTrunk->pDbPage); + if( rc ){ + goto end_allocate_page; + } + *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>(u32)(pBt->usableSize/4 - 2) ){ + /* Value of k is out of range. Database corruption */ + rc = SQLITE_CORRUPT_BKPT; + goto end_allocate_page; +#ifndef SQLITE_OMIT_AUTOVACUUM + }else if( searchList + && (nearby==iTrunk || (iTrunkpDbPage); + if( rc ){ + goto end_allocate_page; + } + if( k==0 ){ + if( !pPrevTrunk ){ + memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); + }else{ + rc = sqlite3PagerWrite(pPrevTrunk->pDbPage); + if( rc!=SQLITE_OK ){ + goto end_allocate_page; + } + memcpy(&pPrevTrunk->aData[0], &pTrunk->aData[0], 4); + } + }else{ + /* The trunk page is required by the caller but it contains + ** pointers to free-list leaves. The first leaf becomes a trunk + ** page in this case. + */ + MemPage *pNewTrunk; + Pgno iNewTrunk = get4byte(&pTrunk->aData[8]); + if( iNewTrunk>mxPage ){ + rc = SQLITE_CORRUPT_BKPT; + goto end_allocate_page; + } + testcase( iNewTrunk==mxPage ); + rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0); + if( rc!=SQLITE_OK ){ + goto end_allocate_page; + } + rc = sqlite3PagerWrite(pNewTrunk->pDbPage); + if( rc!=SQLITE_OK ){ + releasePage(pNewTrunk); + goto end_allocate_page; + } + memcpy(&pNewTrunk->aData[0], &pTrunk->aData[0], 4); + put4byte(&pNewTrunk->aData[4], k-1); + memcpy(&pNewTrunk->aData[8], &pTrunk->aData[12], (k-1)*4); + releasePage(pNewTrunk); + if( !pPrevTrunk ){ + assert( sqlite3PagerIswriteable(pPage1->pDbPage) ); + put4byte(&pPage1->aData[32], iNewTrunk); + }else{ + rc = sqlite3PagerWrite(pPrevTrunk->pDbPage); + if( rc ){ + goto end_allocate_page; + } + put4byte(&pPrevTrunk->aData[0], iNewTrunk); + } + } + pTrunk = 0; + TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); +#endif + }else if( k>0 ){ + /* Extract a leaf from the trunk */ + u32 closest; + Pgno iPage; + unsigned char *aData = pTrunk->aData; + if( nearby>0 ){ + u32 i; + closest = 0; + if( eMode==BTALLOC_LE ){ + for(i=0; imxPage ){ + rc = SQLITE_CORRUPT_BKPT; + goto end_allocate_page; + } + testcase( iPage==mxPage ); + if( !searchList + || (iPage==nearby || (iPagepgno, n-1)); + rc = sqlite3PagerWrite(pTrunk->pDbPage); + if( rc ) goto end_allocate_page; + if( closestpDbPage); + if( rc!=SQLITE_OK ){ + releasePage(*ppPage); + } + } + searchList = 0; + } + } + releasePage(pPrevTrunk); + pPrevTrunk = 0; + }while( searchList ); + }else{ + /* There are no pages on the freelist, so append a new page to the + ** database image. + ** + ** Normally, new pages allocated by this block can be requested from the + ** pager layer with the 'no-content' flag set. This prevents the pager + ** from trying to read the pages content from disk. However, if the + ** current transaction has already run one or more incremental-vacuum + ** steps, then the page we are about to allocate may contain content + ** that is required in the event of a rollback. In this case, do + ** not set the no-content flag. This causes the pager to load and journal + ** the current page content before overwriting it. + ** + ** Note that the pager will not actually attempt to load or journal + ** content for any page that really does lie past the end of the database + ** file on disk. So the effects of disabling the no-content optimization + ** here are confined to those pages that lie between the end of the + ** database image and the end of the database file. + */ + int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate))? PAGER_GET_NOCONTENT:0; + + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + if( rc ) return rc; + pBt->nPage++; + if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ) pBt->nPage++; + +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, pBt->nPage) ){ + /* If *pPgno refers to a pointer-map page, allocate two new pages + ** at the end of the file instead of one. The first allocated page + ** becomes a new pointer-map page, the second is used by the caller. + */ + MemPage *pPg = 0; + TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage)); + assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) ); + rc = btreeGetPage(pBt, pBt->nPage, &pPg, bNoContent); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerWrite(pPg->pDbPage); + releasePage(pPg); + } + if( rc ) return rc; + pBt->nPage++; + if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ){ pBt->nPage++; } + } +#endif + put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage); + *pPgno = pBt->nPage; + + assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); + rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent); + if( rc ) return rc; + rc = sqlite3PagerWrite((*ppPage)->pDbPage); + if( rc!=SQLITE_OK ){ + releasePage(*ppPage); + } + TRACE(("ALLOCATE: %d from end of file\n", *pPgno)); + } + + assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); + +end_allocate_page: + releasePage(pTrunk); + releasePage(pPrevTrunk); + if( rc==SQLITE_OK ){ + if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){ + releasePage(*ppPage); + *ppPage = 0; + return SQLITE_CORRUPT_BKPT; + } + (*ppPage)->isInit = 0; + }else{ + *ppPage = 0; + } + assert( rc!=SQLITE_OK || sqlite3PagerIswriteable((*ppPage)->pDbPage) ); + return rc; +} + +/* +** This function is used to add page iPage to the database file free-list. +** It is assumed that the page is not already a part of the free-list. +** +** The value passed as the second argument to this function is optional. +** If the caller happens to have a pointer to the MemPage object +** corresponding to page iPage handy, it may pass it as the second value. +** Otherwise, it may pass NULL. +** +** If a pointer to a MemPage object is passed as the second argument, +** its reference count is not altered by this function. +*/ +static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ + MemPage *pTrunk = 0; /* Free-list trunk page */ + Pgno iTrunk = 0; /* Page number of free-list trunk page */ + MemPage *pPage1 = pBt->pPage1; /* Local reference to page 1 */ + MemPage *pPage; /* Page being freed. May be NULL. */ + int rc; /* Return Code */ + int nFree; /* Initial number of pages on free-list */ + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( iPage>1 ); + assert( !pMemPage || pMemPage->pgno==iPage ); + + if( pMemPage ){ + pPage = pMemPage; + sqlite3PagerRef(pPage->pDbPage); + }else{ + pPage = btreePageLookup(pBt, iPage); + } + + /* Increment the free page count on pPage1 */ + rc = sqlite3PagerWrite(pPage1->pDbPage); + if( rc ) goto freepage_out; + nFree = get4byte(&pPage1->aData[36]); + put4byte(&pPage1->aData[36], nFree+1); + + if( pBt->btsFlags & BTS_SECURE_DELETE ){ + /* If the secure_delete option is enabled, then + ** always fully overwrite deleted information with zeros. + */ + if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0) ) + || ((rc = sqlite3PagerWrite(pPage->pDbPage))!=0) + ){ + goto freepage_out; + } + memset(pPage->aData, 0, pPage->pBt->pageSize); + } + + /* If the database supports auto-vacuum, write an entry in the pointer-map + ** to indicate that the page is free. + */ + if( ISAUTOVACUUM ){ + ptrmapPut(pBt, iPage, PTRMAP_FREEPAGE, 0, &rc); + if( rc ) goto freepage_out; + } + + /* Now manipulate the actual database free-list structure. There are two + ** possibilities. If the free-list is currently empty, or if the first + ** trunk page in the free-list is full, then this page will become a + ** new free-list trunk page. Otherwise, it will become a leaf of the + ** first trunk page in the current free-list. This block tests if it + ** is possible to add the page as a new free-list leaf. + */ + if( nFree!=0 ){ + u32 nLeaf; /* Initial number of leaf cells on trunk page */ + + iTrunk = get4byte(&pPage1->aData[32]); + rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0); + if( rc!=SQLITE_OK ){ + goto freepage_out; + } + + nLeaf = get4byte(&pTrunk->aData[4]); + assert( pBt->usableSize>32 ); + if( nLeaf > (u32)pBt->usableSize/4 - 2 ){ + rc = SQLITE_CORRUPT_BKPT; + goto freepage_out; + } + if( nLeaf < (u32)pBt->usableSize/4 - 8 ){ + /* In this case there is room on the trunk page to insert the page + ** being freed as a new leaf. + ** + ** Note that the trunk page is not really full until it contains + ** usableSize/4 - 2 entries, not usableSize/4 - 8 entries as we have + ** coded. But due to a coding error in versions of SQLite prior to + ** 3.6.0, databases with freelist trunk pages holding more than + ** usableSize/4 - 8 entries will be reported as corrupt. In order + ** to maintain backwards compatibility with older versions of SQLite, + ** we will continue to restrict the number of entries to usableSize/4 - 8 + ** for now. At some point in the future (once everyone has upgraded + ** to 3.6.0 or later) we should consider fixing the conditional above + ** to read "usableSize/4-2" instead of "usableSize/4-8". + ** + ** EVIDENCE-OF: R-19920-11576 However, newer versions of SQLite still + ** avoid using the last six entries in the freelist trunk page array in + ** order that database files created by newer versions of SQLite can be + ** read by older versions of SQLite. + */ + rc = sqlite3PagerWrite(pTrunk->pDbPage); + if( rc==SQLITE_OK ){ + put4byte(&pTrunk->aData[4], nLeaf+1); + put4byte(&pTrunk->aData[8+nLeaf*4], iPage); + if( pPage && (pBt->btsFlags & BTS_SECURE_DELETE)==0 ){ + sqlite3PagerDontWrite(pPage->pDbPage); + } + rc = btreeSetHasContent(pBt, iPage); + } + TRACE(("FREE-PAGE: %d leaf on trunk page %d\n",pPage->pgno,pTrunk->pgno)); + goto freepage_out; + } + } + + /* If control flows to this point, then it was not possible to add the + ** the page being freed as a leaf page of the first trunk in the free-list. + ** Possibly because the free-list is empty, or possibly because the + ** first trunk in the free-list is full. Either way, the page being freed + ** will become the new first trunk page in the free-list. + */ + if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0)) ){ + goto freepage_out; + } + rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc!=SQLITE_OK ){ + goto freepage_out; + } + put4byte(pPage->aData, iTrunk); + put4byte(&pPage->aData[4], 0); + put4byte(&pPage1->aData[32], iPage); + TRACE(("FREE-PAGE: %d new trunk page replacing %d\n", pPage->pgno, iTrunk)); + +freepage_out: + if( pPage ){ + pPage->isInit = 0; + } + releasePage(pPage); + releasePage(pTrunk); + return rc; +} +static void freePage(MemPage *pPage, int *pRC){ + if( (*pRC)==SQLITE_OK ){ + *pRC = freePage2(pPage->pBt, pPage, pPage->pgno); + } +} + +/* +** Free any overflow pages associated with the given Cell. Write the +** local Cell size (the number of bytes on the original page, omitting +** overflow) into *pnSize. +*/ +static int clearCell( + MemPage *pPage, /* The page that contains the Cell */ + unsigned char *pCell, /* First byte of the Cell */ + u16 *pnSize /* Write the size of the Cell here */ +){ + BtShared *pBt = pPage->pBt; + CellInfo info; + Pgno ovflPgno; + int rc; + int nOvfl; + u32 ovflPageSize; + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + btreeParseCellPtr(pPage, pCell, &info); + *pnSize = info.nSize; + if( info.iOverflow==0 ){ + return SQLITE_OK; /* No overflow pages. Return without doing anything */ + } + if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){ + return SQLITE_CORRUPT_BKPT; /* Cell extends past end of page */ + } + ovflPgno = get4byte(&pCell[info.iOverflow]); + assert( pBt->usableSize > 4 ); + ovflPageSize = pBt->usableSize - 4; + nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize; + assert( ovflPgno==0 || nOvfl>0 ); + while( nOvfl-- ){ + Pgno iNext = 0; + MemPage *pOvfl = 0; + if( ovflPgno<2 || ovflPgno>btreePagecount(pBt) ){ + /* 0 is not a legal page number and page 1 cannot be an + ** overflow page. Therefore if ovflPgno<2 or past the end of the + ** file the database must be corrupt. */ + return SQLITE_CORRUPT_BKPT; + } + if( nOvfl ){ + rc = getOverflowPage(pBt, ovflPgno, &pOvfl, &iNext); + if( rc ) return rc; + } + + if( ( pOvfl || ((pOvfl = btreePageLookup(pBt, ovflPgno))!=0) ) + && sqlite3PagerPageRefcount(pOvfl->pDbPage)!=1 + ){ + /* There is no reason any cursor should have an outstanding reference + ** to an overflow page belonging to a cell that is being deleted/updated. + ** So if there exists more than one reference to this page, then it + ** must not really be an overflow page and the database must be corrupt. + ** It is helpful to detect this before calling freePage2(), as + ** freePage2() may zero the page contents if secure-delete mode is + ** enabled. If this 'overflow' page happens to be a page that the + ** caller is iterating through or using in some other way, this + ** can be problematic. + */ + rc = SQLITE_CORRUPT_BKPT; + }else{ + rc = freePage2(pBt, pOvfl, ovflPgno); + } + + if( pOvfl ){ + sqlite3PagerUnref(pOvfl->pDbPage); + } + if( rc ) return rc; + ovflPgno = iNext; + } + 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 +** allocated and filled in as necessary. The calling procedure +** is responsible for making sure sufficient space has been allocated +** for pCell[]. +** +** Note that pCell does not necessary need to point to the pPage->aData +** area. pCell might point to some temporary storage. The cell will +** be constructed in this temporary area then copied into pPage->aData +** later. +*/ +static int fillInCell( + MemPage *pPage, /* The page that contains the cell */ + unsigned char *pCell, /* Complete text of the cell */ + const void *pKey, i64 nKey, /* The key */ + const void *pData,int nData, /* The data */ + int nZero, /* Extra zero bytes to append to pData */ + int *pnSize /* Write cell size here */ +){ + int nPayload; + 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; + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + + /* pPage is not necessarily writeable since pCell might be auxiliary + ** buffer space that is separate from the pPage buffer area */ + assert( pCellaData || pCell>=&pPage->aData[pBt->pageSize] + || sqlite3PagerIswriteable(pPage->pDbPage) ); + + /* Fill in the header. */ + nHeader = pPage->childPtrSize; + nPayload = nData + nZero; + if( pPage->intKeyLeaf ){ + nHeader += putVarint32(&pCell[nHeader], nPayload); + }else{ + assert( nData==0 ); + assert( nZero==0 ); + } + nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey); + + /* Fill in the payload size */ + if( pPage->intKey ){ + pSrc = pData; + nSrc = nData; + nData = 0; + }else{ + if( NEVER(nKey>0x7fffffff || pKey==0) ){ + return SQLITE_CORRUPT_BKPT; + } + nPayload = (int)nKey; + pSrc = pKey; + nSrc = (int)nKey; + } + if( nPayload<=pPage->maxLocal ){ + n = nHeader + nPayload; + testcase( n==3 ); + testcase( n==4 ); + if( n<4 ) n = 4; + *pnSize = n; + spaceLeft = nPayload; + pPrior = pCell; + }else{ + int mn = pPage->minLocal; + n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4); + testcase( n==pPage->maxLocal ); + testcase( n==pPage->maxLocal+1 ); + if( n > pPage->maxLocal ) n = mn; + spaceLeft = n; + *pnSize = n + nHeader + 4; + pPrior = &pCell[nHeader+n]; + } + pPayload = &pCell[nHeader]; + + /* At this point variables should be set as follows: + ** + ** nPayload Total payload size in bytes + ** pPayload Begin writing payload here + ** spaceLeft Space available at pPayload. If nPayload>spaceLeft, + ** that means content must spill into overflow pages. + ** *pnSize Size of the local cell (not counting overflow pages) + ** pPrior Where to write the pgno of the first overflow page + ** + ** Use a call to btreeParseCellPtr() to verify that the values above + ** were computed correctly. + */ +#if SQLITE_DEBUG + { + CellInfo info; + btreeParseCellPtr(pPage, pCell, &info); + assert( nHeader=(int)(info.pPayload - pCell) ); + assert( info.nKey==nKey ); + assert( *pnSize == info.nSize ); + assert( spaceLeft == info.nLocal ); + assert( pPrior == &pCell[info.iOverflow] ); + } +#endif + + /* Write the payload into the local Cell and any extra into overflow pages */ + while( nPayload>0 ){ + if( spaceLeft==0 ){ +#ifndef SQLITE_OMIT_AUTOVACUUM + Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */ + if( pBt->autoVacuum ){ + do{ + pgnoOvfl++; + } while( + PTRMAP_ISPAGE(pBt, pgnoOvfl) || pgnoOvfl==PENDING_BYTE_PAGE(pBt) + ); + } +#endif + rc = allocateBtreePage(pBt, &pOvfl, &pgnoOvfl, pgnoOvfl, 0); +#ifndef SQLITE_OMIT_AUTOVACUUM + /* If the database supports auto-vacuum, and the second or subsequent + ** overflow page is being allocated, add an entry to the pointer-map + ** for that page now. + ** + ** If this is the first overflow page, then write a partial entry + ** to the pointer-map. If we write nothing to this pointer-map slot, + ** then the optimistic overflow chain processing in clearCell() + ** may misinterpret the uninitialized values and delete the + ** wrong pages from the database. + */ + if( pBt->autoVacuum && rc==SQLITE_OK ){ + u8 eType = (pgnoPtrmap?PTRMAP_OVERFLOW2:PTRMAP_OVERFLOW1); + ptrmapPut(pBt, pgnoOvfl, eType, pgnoPtrmap, &rc); + if( rc ){ + releasePage(pOvfl); + } + } +#endif + if( rc ){ + releasePage(pToRelease); + return rc; + } + + /* If pToRelease is not zero than pPrior points into the data area + ** of pToRelease. Make sure pToRelease is still writeable. */ + assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) ); + + /* If pPrior is part of the data area of pPage, then make sure pPage + ** is still writeable */ + assert( pPrioraData || pPrior>=&pPage->aData[pBt->pageSize] + || sqlite3PagerIswriteable(pPage->pDbPage) ); + + put4byte(pPrior, pgnoOvfl); + releasePage(pToRelease); + pToRelease = pOvfl; + pPrior = pOvfl->aData; + put4byte(pPrior, 0); + pPayload = &pOvfl->aData[4]; + spaceLeft = pBt->usableSize - 4; + } + n = nPayload; + if( n>spaceLeft ) n = spaceLeft; + + /* If pToRelease is not zero than pPayload points into the data area + ** of pToRelease. Make sure pToRelease is still writeable. */ + assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) ); + + /* If pPayload is part of the data area of pPage, then make sure pPage + ** is still writeable */ + assert( pPayloadaData || pPayload>=&pPage->aData[pBt->pageSize] + || sqlite3PagerIswriteable(pPage->pDbPage) ); + + if( nSrc>0 ){ + if( n>nSrc ) n = nSrc; + assert( pSrc ); + memcpy(pPayload, pSrc, n); + }else{ + memset(pPayload, 0, n); + } + nPayload -= n; + pPayload += n; + pSrc += n; + nSrc -= n; + spaceLeft -= n; + if( nSrc==0 ){ + nSrc = nData; + pSrc = pData; + } + } + releasePage(pToRelease); + return SQLITE_OK; +} + +/* +** Remove the i-th cell from pPage. This routine effects pPage only. +** The cell content is not freed or deallocated. It is assumed that +** the cell content has been copied someplace else. This routine just +** removes the reference to the cell from pPage. +** +** "sz" must be the number of bytes in the cell. +*/ +static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ + u32 pc; /* Offset to cell content of cell being deleted */ + u8 *data; /* pPage->aData */ + u8 *ptr; /* Used to move bytes around within data[] */ + int rc; /* The return code */ + int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */ + + if( *pRC ) return; + + assert( idx>=0 && idxnCell ); + assert( sz==cellSize(pPage, idx) ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + data = pPage->aData; + ptr = &pPage->aCellIdx[2*idx]; + pc = get2byte(ptr); + hdr = pPage->hdrOffset; + testcase( pc==get2byte(&data[hdr+5]) ); + testcase( pc+sz==pPage->pBt->usableSize ); + if( pc < (u32)get2byte(&data[hdr+5]) || pc+sz > pPage->pBt->usableSize ){ + *pRC = SQLITE_CORRUPT_BKPT; + return; + } + rc = freeSpace(pPage, pc, sz); + if( rc ){ + *pRC = rc; + return; + } + pPage->nCell--; + if( pPage->nCell==0 ){ + memset(&data[hdr+1], 0, 4); + data[hdr+7] = 0; + put2byte(&data[hdr+5], pPage->pBt->usableSize); + pPage->nFree = pPage->pBt->usableSize - pPage->hdrOffset + - pPage->childPtrSize - 8; + }else{ + memmove(ptr, ptr+2, 2*(pPage->nCell - idx)); + put2byte(&data[hdr+3], pPage->nCell); + pPage->nFree += 2; + } +} + +/* +** Insert a new cell on pPage at cell index "i". pCell points to the +** content of the cell. +** +** If the cell content will fit on the page, then put it there. If it +** will not fit, then make a copy of the cell content into pTemp if +** pTemp is not null. Regardless of pTemp, allocate a new entry +** in pPage->apOvfl[] and make it point to the cell content (either +** in pTemp or the original pCell) and also record its index. +** Allocating a new entry in pPage->aCell[] implies that +** pPage->nOverflow is incremented. +*/ +static void insertCell( + MemPage *pPage, /* Page into which we are copying */ + int i, /* New cell becomes the i-th cell of the page */ + u8 *pCell, /* Content of the new cell */ + int sz, /* Bytes of content in pCell */ + u8 *pTemp, /* Temp storage space for pCell, if needed */ + Pgno iChild, /* If non-zero, replace first 4 bytes with this value */ + int *pRC /* Read and write return code from here */ +){ + int idx = 0; /* Where to write new cell content in data[] */ + int j; /* Loop counter */ + int end; /* First byte past the last cell pointer in data[] */ + int ins; /* Index in data[] where new cell pointer is inserted */ + int cellOffset; /* Address of first cell pointer in data[] */ + u8 *data; /* The content of the whole page */ + + if( *pRC ) return; + + assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); + assert( MX_CELL(pPage->pBt)<=10921 ); + assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB ); + assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) ); + assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + /* The cell should normally be sized correctly. However, when moving a + ** malformed cell from a leaf page to an interior page, if the cell size + ** wanted to be less than 4 but got rounded up to 4 on the leaf, then size + ** might be less than 8 (leaf-size + pointer) on the interior node. Hence + ** the term after the || in the following assert(). */ + assert( sz==cellSizePtr(pPage, pCell) || (sz==8 && iChild>0) ); + if( pPage->nOverflow || sz+2>pPage->nFree ){ + if( pTemp ){ + memcpy(pTemp, pCell, sz); + pCell = pTemp; + } + if( iChild ){ + put4byte(pCell, iChild); + } + j = pPage->nOverflow++; + assert( j<(int)(sizeof(pPage->apOvfl)/sizeof(pPage->apOvfl[0])) ); + pPage->apOvfl[j] = pCell; + pPage->aiOvfl[j] = (u16)i; + }else{ + int rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc!=SQLITE_OK ){ + *pRC = rc; + return; + } + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + data = pPage->aData; + cellOffset = pPage->cellOffset; + end = cellOffset + 2*pPage->nCell; + ins = cellOffset + 2*i; + rc = allocateSpace(pPage, sz, &idx); + if( rc ){ *pRC = rc; return; } + /* The allocateSpace() routine guarantees the following two properties + ** if it returns success */ + assert( idx >= end+2 ); + assert( idx+sz <= (int)pPage->pBt->usableSize ); + pPage->nCell++; + pPage->nFree -= (u16)(2 + sz); + memcpy(&data[idx], pCell, sz); + if( iChild ){ + put4byte(&data[idx], iChild); + } + memmove(&data[ins+2], &data[ins], end-ins); + put2byte(&data[ins], idx); + put2byte(&data[pPage->hdrOffset+3], pPage->nCell); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pPage->pBt->autoVacuum ){ + /* The cell may contain a pointer to an overflow page. If so, write + ** the entry for the overflow page into the pointer map. + */ + ptrmapPutOvflPtr(pPage, pCell, pRC); + } +#endif + } +} + +/* +** Array apCell[] contains pointers to nCell b-tree page cells. The +** szCell[] array contains the size in bytes of each cell. This function +** replaces the current contents of page pPg with the contents of the cell +** array. +** +** Some of the cells in apCell[] may currently be stored in pPg. This +** function works around problems caused by this by making a copy of any +** such cells before overwriting the page data. +** +** The MemPage.nFree field is invalidated by this function. It is the +** responsibility of the caller to set it correctly. +*/ +static void rebuildPage( + MemPage *pPg, /* Edit this page */ + int nCell, /* Final number of cells on page */ + u8 **apCell, /* Array of cells */ + u16 *szCell /* Array of cell sizes */ +){ + const int hdr = pPg->hdrOffset; /* Offset of header on pPg */ + u8 * const aData = pPg->aData; /* Pointer to data for pPg */ + const int usableSize = pPg->pBt->usableSize; + u8 * const pEnd = &aData[usableSize]; + int i; + u8 *pCellptr = pPg->aCellIdx; + u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager); + u8 *pData; + + i = get2byte(&aData[hdr+5]); + memcpy(&pTmp[i], &aData[i], usableSize - i); + + pData = pEnd; + for(i=0; iaData && pCellnFree field is now set incorrectly. The caller will fix it. */ + pPg->nCell = nCell; + pPg->nOverflow = 0; + + put2byte(&aData[hdr+1], 0); + put2byte(&aData[hdr+3], pPg->nCell); + put2byte(&aData[hdr+5], pData - aData); + aData[hdr+7] = 0x00; +} + +/* +** Array apCell[] contains nCell pointers to b-tree cells. Array szCell +** contains the size in bytes of each such cell. This function attempts to +** add the cells stored in the array to page pPg. If it cannot (because +** the page needs to be defragmented before the cells will fit), non-zero +** is returned. Otherwise, if the cells are added successfully, zero is +** returned. +** +** Argument pCellptr points to the first entry in the cell-pointer array +** (part of page pPg) to populate. After cell apCell[0] is written to the +** page body, a 16-bit offset is written to pCellptr. And so on, for each +** cell in the array. It is the responsibility of the caller to ensure +** that it is safe to overwrite this part of the cell-pointer array. +** +** When this function is called, *ppData points to the start of the +** content area on page pPg. If the size of the content area is extended, +** *ppData is updated to point to the new start of the content area +** before returning. +** +** Finally, argument pBegin points to the byte immediately following the +** end of the space required by this page for the cell-pointer area (for +** all cells - not just those inserted by the current call). If the content +** area must be extended to before this point in order to accomodate all +** cells in apCell[], then the cells do not fit and non-zero is returned. +*/ +static int pageInsertArray( + MemPage *pPg, /* Page to add cells to */ + u8 *pBegin, /* End of cell-pointer array */ + u8 **ppData, /* IN/OUT: Page content -area pointer */ + u8 *pCellptr, /* Pointer to cell-pointer area */ + int nCell, /* Number of cells to add to pPg */ + u8 **apCell, /* Array of cells */ + u16 *szCell /* Array of cell sizes */ +){ + int i; + u8 *aData = pPg->aData; + u8 *pData = *ppData; + const int bFreelist = aData[1] || aData[2]; + assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */ + for(i=0; iaData; + u8 * const pEnd = &aData[pPg->pBt->usableSize]; + u8 * const pStart = &aData[pPg->hdrOffset + 8 + pPg->childPtrSize]; + int nRet = 0; + int i; + u8 *pFree = 0; + int szFree = 0; + + for(i=0; i=pStart && pCellaData && (pFree - aData)<65536 ); + freeSpace(pPg, (u16)(pFree - aData), szFree); + } + pFree = pCell; + szFree = sz; + if( pFree+sz>pEnd ) return 0; + }else{ + pFree = pCell; + szFree += sz; + } + nRet++; + } + } + if( pFree ){ + assert( pFree>aData && (pFree - aData)<65536 ); + freeSpace(pPg, (u16)(pFree - aData), szFree); + } + return nRet; +} + +/* +** apCell[] and szCell[] contains pointers to and sizes of all cells in the +** pages being balanced. The current page, pPg, has pPg->nCell cells starting +** with apCell[iOld]. After balancing, this page should hold nNew cells +** starting at apCell[iNew]. +** +** This routine makes the necessary adjustments to pPg so that it contains +** the correct cells after being balanced. +** +** The pPg->nFree field is invalid when this function returns. It is the +** responsibility of the caller to set it correctly. +*/ +static void editPage( + MemPage *pPg, /* Edit this page */ + int iOld, /* Index of first cell currently on page */ + int iNew, /* Index of new first cell on page */ + int nNew, /* Final number of cells on page */ + u8 **apCell, /* Array of cells */ + u16 *szCell /* Array of cell sizes */ +){ + u8 * const aData = pPg->aData; + const int hdr = pPg->hdrOffset; + u8 *pBegin = &pPg->aCellIdx[nNew * 2]; + int nCell = pPg->nCell; /* Cells stored on pPg */ + u8 *pData; + u8 *pCellptr; + int i; + int iOldEnd = iOld + pPg->nCell + pPg->nOverflow; + int iNewEnd = iNew + nNew; + +#ifdef SQLITE_DEBUG + u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager); + memcpy(pTmp, aData, pPg->pBt->usableSize); +#endif + + /* Remove cells from the start and end of the page */ + if( iOldaCellIdx, &pPg->aCellIdx[nShift*2], nCell*2); + nCell -= nShift; + } + if( iNewEnd < iOldEnd ){ + nCell -= pageFreeArray( + pPg, iOldEnd-iNewEnd, &apCell[iNewEnd], &szCell[iNewEnd] + ); + } + + pData = &aData[get2byteNotZero(&aData[hdr+5])]; + if( pDataaCellIdx; + memmove(&pCellptr[nAdd*2], pCellptr, nCell*2); + if( pageInsertArray( + pPg, pBegin, &pData, pCellptr, + nAdd, &apCell[iNew], &szCell[iNew] + ) ) goto editpage_fail; + nCell += nAdd; + } + + /* Add any overflow cells */ + for(i=0; inOverflow; i++){ + int iCell = (iOld + pPg->aiOvfl[i]) - iNew; + if( iCell>=0 && iCellaCellIdx[iCell * 2]; + memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2); + nCell++; + if( pageInsertArray( + pPg, pBegin, &pData, pCellptr, + 1, &apCell[iCell + iNew], &szCell[iCell + iNew] + ) ) goto editpage_fail; + } + } + + /* Append cells to the end of the page */ + pCellptr = &pPg->aCellIdx[nCell*2]; + if( pageInsertArray( + pPg, pBegin, &pData, pCellptr, + nNew-nCell, &apCell[iNew+nCell], &szCell[iNew+nCell] + ) ) goto editpage_fail; + + pPg->nCell = nNew; + pPg->nOverflow = 0; + + put2byte(&aData[hdr+3], pPg->nCell); + put2byte(&aData[hdr+5], pData - aData); + +#ifdef SQLITE_DEBUG + for(i=0; iaCellIdx[i*2]); + if( pCell>=aData && pCell<&aData[pPg->pBt->usableSize] ){ + pCell = &pTmp[pCell - aData]; + } + assert( 0==memcmp(pCell, &aData[iOff], szCell[i+iNew]) ); + } +#endif + + return; + editpage_fail: + /* Unable to edit this page. Rebuild it from scratch instead. */ + rebuildPage(pPg, nNew, &apCell[iNew], &szCell[iNew]); +} + +/* +** 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 +** total number of pages that participate, including the target page and +** NN neighbors on either side. +** +** The minimum value of NN is 1 (of course). Increasing NN above 1 +** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance +** in exchange for a larger degradation in INSERT and UPDATE performance. +** The value of NN appears to give the best results overall. +*/ +#define NN 1 /* Number of neighbors on either side of pPage */ +#define NB (NN*2+1) /* Total pages involved in the balance */ + + +#ifndef SQLITE_OMIT_QUICKBALANCE +/* +** This version of balance() handles the common special case where +** a new entry is being inserted on the extreme right-end of the +** tree, in other words, when the new entry will become the largest +** entry in the tree. +** +** Instead of trying to balance the 3 right-most leaf pages, just add +** a new page to the right-hand side and put the one new entry in +** that page. This leaves the right side of the tree somewhat +** unbalanced. But odds are that we will be inserting new entries +** at the end soon afterwards so the nearly empty page will quickly +** fill up. On average. +** +** pPage is the leaf page which is the right-most page in the tree. +** pParent is its parent. pPage must have a single overflow entry +** which is also the right-most entry on the page. +** +** The pSpace buffer is used to store a temporary copy of the divider +** cell that will be inserted into pParent. Such a cell consists of a 4 +** byte page number followed by a variable length integer. In other +** words, at most 13 bytes. Hence the pSpace buffer must be at +** least 13 bytes in size. +*/ +static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ + BtShared *const pBt = pPage->pBt; /* B-Tree Database */ + MemPage *pNew; /* Newly allocated page */ + int rc; /* Return Code */ + Pgno pgnoNew; /* Page number of pNew */ + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + assert( pPage->nOverflow==1 ); + + /* This error condition is now caught prior to reaching this function */ + if( NEVER(pPage->nCell==0) ) return SQLITE_CORRUPT_BKPT; + + /* Allocate a new page. This page will become the right-sibling of + ** pPage. Make the parent page writable, so that the new divider cell + ** may be inserted. If both these operations are successful, proceed. + */ + rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); + + if( rc==SQLITE_OK ){ + + u8 *pOut = &pSpace[4]; + u8 *pCell = pPage->apOvfl[0]; + u16 szCell = cellSizePtr(pPage, pCell); + u8 *pStop; + + assert( sqlite3PagerIswriteable(pNew->pDbPage) ); + assert( pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) ); + zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF); + rebuildPage(pNew, 1, &pCell, &szCell); + pNew->nFree = pBt->usableSize - pNew->cellOffset - 2 - szCell; + + /* If this is an auto-vacuum database, update the pointer map + ** with entries for the new page, and any pointer from the + ** cell on the page to an overflow page. If either of these + ** operations fails, the return code is set, but the contents + ** of the parent page are still manipulated by thh code below. + ** That is Ok, at this point the parent page is guaranteed to + ** be marked as dirty. Returning an error code will cause a + ** rollback, undoing any changes made to the parent page. + */ + if( ISAUTOVACUUM ){ + ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno, &rc); + if( szCell>pNew->minLocal ){ + ptrmapPutOvflPtr(pNew, pCell, &rc); + } + } + + /* Create a divider cell to insert into pParent. The divider cell + ** consists of a 4-byte page number (the page number of pPage) and + ** a variable length key value (which must be the same value as the + ** largest key on pPage). + ** + ** To find the largest key value on pPage, first find the right-most + ** cell on pPage. The first two fields of this cell are the + ** record-length (a variable length integer at most 32-bits in size) + ** and the key value (a variable length integer, may have any value). + ** The first of the while(...) loops below skips over the record-length + ** field. The second while(...) loop copies the key value from the + ** cell on pPage into the pSpace buffer. + */ + pCell = findCell(pPage, pPage->nCell-1); + pStop = &pCell[9]; + while( (*(pCell++)&0x80) && pCellnCell, pSpace, (int)(pOut-pSpace), + 0, pPage->pgno, &rc); + + /* Set the right-child pointer of pParent to point to the new page. */ + put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew); + + /* Release the reference to the new page. */ + releasePage(pNew); + } + + return rc; +} +#endif /* SQLITE_OMIT_QUICKBALANCE */ + +#if 0 +/* +** This function does not contribute anything to the operation of SQLite. +** it is sometimes activated temporarily while debugging code responsible +** for setting pointer-map entries. +*/ +static int ptrmapCheckPages(MemPage **apPage, int nPage){ + int i, j; + for(i=0; ipBt; + assert( pPage->isInit ); + + for(j=0; jnCell; j++){ + CellInfo info; + u8 *z; + + z = findCell(pPage, j); + btreeParseCellPtr(pPage, z, &info); + if( info.iOverflow ){ + Pgno ovfl = get4byte(&z[info.iOverflow]); + ptrmapGet(pBt, ovfl, &e, &n); + assert( n==pPage->pgno && e==PTRMAP_OVERFLOW1 ); + } + if( !pPage->leaf ){ + Pgno child = get4byte(z); + ptrmapGet(pBt, child, &e, &n); + assert( n==pPage->pgno && e==PTRMAP_BTREE ); + } + } + if( !pPage->leaf ){ + Pgno child = get4byte(&pPage->aData[pPage->hdrOffset+8]); + ptrmapGet(pBt, child, &e, &n); + assert( n==pPage->pgno && e==PTRMAP_BTREE ); + } + } + return 1; +} +#endif + +/* +** This function is used to copy the contents of the b-tree node stored +** on page pFrom to page pTo. If page pFrom was not a leaf page, then +** the pointer-map entries for each child page are updated so that the +** parent page stored in the pointer map is page pTo. If pFrom contained +** any cells with overflow page pointers, then the corresponding pointer +** map entries are also updated so that the parent page is page pTo. +** +** If pFrom is currently carrying any overflow cells (entries in the +** MemPage.apOvfl[] array), they are not copied to pTo. +** +** Before returning, page pTo is reinitialized using btreeInitPage(). +** +** The performance of this function is not critical. It is only used by +** the balance_shallower() and balance_deeper() procedures, neither of +** which are called often under normal circumstances. +*/ +static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){ + if( (*pRC)==SQLITE_OK ){ + BtShared * const pBt = pFrom->pBt; + u8 * const aFrom = pFrom->aData; + u8 * const aTo = pTo->aData; + int const iFromHdr = pFrom->hdrOffset; + int const iToHdr = ((pTo->pgno==1) ? 100 : 0); + int rc; + int iData; + + + assert( pFrom->isInit ); + assert( pFrom->nFree>=iToHdr ); + assert( get2byte(&aFrom[iFromHdr+5]) <= (int)pBt->usableSize ); + + /* Copy the b-tree node content from page pFrom to page pTo. */ + iData = get2byte(&aFrom[iFromHdr+5]); + memcpy(&aTo[iData], &aFrom[iData], pBt->usableSize-iData); + memcpy(&aTo[iToHdr], &aFrom[iFromHdr], pFrom->cellOffset + 2*pFrom->nCell); + + /* Reinitialize page pTo so that the contents of the MemPage structure + ** match the new data. The initialization of pTo can actually fail under + ** fairly obscure circumstances, even though it is a copy of initialized + ** page pFrom. + */ + pTo->isInit = 0; + rc = btreeInitPage(pTo); + if( rc!=SQLITE_OK ){ + *pRC = rc; + return; + } + + /* If this is an auto-vacuum database, update the pointer-map entries + ** for any b-tree or overflow pages that pTo now contains the pointers to. + */ + if( ISAUTOVACUUM ){ + *pRC = setChildPtrmaps(pTo); + } + } +} + +/* +** This routine redistributes cells on the iParentIdx'th child of pParent +** (hereafter "the page") and up to 2 siblings so that all pages have about the +** same amount of free space. Usually a single sibling on either side of the +** page are used in the balancing, though both siblings might come from one +** side if the page is the first or last child of its parent. If the page +** has fewer than 2 siblings (something which can only happen if the page +** is a root page or a child of a root page) then all available siblings +** participate in the balancing. +** +** The number of siblings of the page might be increased or decreased by +** one or two in an effort to keep pages nearly full but not over full. +** +** Note that when this routine is called, some of the cells on the page +** might not actually be stored in MemPage.aData[]. This can happen +** if the page is overfull. This routine ensures that all cells allocated +** to the page and its siblings fit into MemPage.aData[] before returning. +** +** In the course of balancing the page and its siblings, cells may be +** inserted into or removed from the parent page (pParent). Doing so +** may cause the parent page to become overfull or underfull. If this +** happens, it is the responsibility of the caller to invoke the correct +** balancing routine to fix this problem (see the balance() routine). +** +** 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. +** +** The third argument to this function, aOvflSpace, is a pointer to a +** buffer big enough to hold one page. If while inserting cells into the parent +** page (pParent) the parent page becomes overfull, this buffer is +** used to store the parent's overflow cells. Because this function inserts +** a maximum of four divider cells into the parent page, and the maximum +** size of a cell stored within an internal node is always less than 1/4 +** of the page-size, the aOvflSpace[] buffer is guaranteed to be large +** enough for all overflow cells. +** +** If aOvflSpace is set to a null pointer, this function returns +** SQLITE_NOMEM. +*/ +#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM) +#pragma optimize("", off) +#endif +static int balance_nonroot( + MemPage *pParent, /* Parent page of siblings being balanced */ + int iParentIdx, /* Index of "the page" in pParent */ + u8 *aOvflSpace, /* page-size bytes of space for parent ovfl */ + int isRoot, /* True if pParent is a root-page */ + int bBulk /* True if this call is part of a bulk load */ +){ + BtShared *pBt; /* The whole database */ + int nCell = 0; /* Number of cells in apCell[] */ + int nMaxCells = 0; /* Allocated size of apCell, szCell, aFrom. */ + int nNew = 0; /* Number of pages in apNew[] */ + int nOld; /* Number of pages in apOld[] */ + int i, j, k; /* Loop counters */ + int nxDiv; /* Next divider slot in pParent->aCell[] */ + int rc = SQLITE_OK; /* The return code */ + u16 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 iSpace1 = 0; /* First unused byte of aSpace1[] */ + int iOvflSpace = 0; /* First unused byte of aOvflSpace[] */ + int szScratch; /* Size of scratch memory requested */ + MemPage *apOld[NB]; /* pPage and up to two siblings */ + MemPage *apNew[NB+2]; /* pPage and up to NB siblings after balancing */ + u8 *pRight; /* Location in parent of right-sibling pointer */ + u8 *apDiv[NB-1]; /* Divider cells in pParent */ + int cntNew[NB+2]; /* Index in aCell[] of cell after i-th page */ + int cntOld[NB+2]; /* Old index in aCell[] after i-th page */ + int szNew[NB+2]; /* Combined size of cells placed on i-th page */ + u8 **apCell = 0; /* All cells begin balanced */ + u16 *szCell; /* Local size of all cells in apCell[] */ + u8 *aSpace1; /* Space for copies of dividers cells */ + Pgno pgno; /* Temp var to store a page number in */ + u8 abDone[NB+2]; /* True after i'th new page is populated */ + Pgno aPgno[NB+2]; /* Page numbers of new pages before shuffling */ + Pgno aPgOrder[NB+2]; /* Copy of aPgno[] used for sorting pages */ + u16 aPgFlags[NB+2]; /* flags field of new pages before shuffling */ + + memset(abDone, 0, sizeof(abDone)); + pBt = pParent->pBt; + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + +#if 0 + TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno)); +#endif + + /* At this point pParent may have at most one overflow cell. And if + ** this overflow cell is present, it must be the cell with + ** index iParentIdx. This scenario comes about when this function + ** is called (indirectly) from sqlite3BtreeDelete(). + */ + assert( pParent->nOverflow==0 || pParent->nOverflow==1 ); + assert( pParent->nOverflow==0 || pParent->aiOvfl[0]==iParentIdx ); + + if( !aOvflSpace ){ + return SQLITE_NOMEM; + } + + /* Find the sibling pages to balance. Also locate the cells in pParent + ** that divide the siblings. An attempt is made to find NN siblings on + ** either side of pPage. More siblings are taken from one side, however, + ** if there are fewer than NN siblings on the other side. If pParent + ** has NB or fewer children then all children of pParent are taken. + ** + ** This loop also drops the divider cells from the parent page. This + ** way, the remainder of the function does not have to deal with any + ** overflow cells in the parent page, since if any existed they will + ** have already been removed. + */ + i = pParent->nOverflow + pParent->nCell; + if( i<2 ){ + nxDiv = 0; + }else{ + assert( bBulk==0 || bBulk==1 ); + if( iParentIdx==0 ){ + nxDiv = 0; + }else if( iParentIdx==i ){ + nxDiv = i-2+bBulk; + }else{ + nxDiv = iParentIdx-1; + } + i = 2-bBulk; + } + nOld = i+1; + if( (i+nxDiv-pParent->nOverflow)==pParent->nCell ){ + pRight = &pParent->aData[pParent->hdrOffset+8]; + }else{ + pRight = findCell(pParent, i+nxDiv-pParent->nOverflow); + } + pgno = get4byte(pRight); + while( 1 ){ + rc = getAndInitPage(pBt, pgno, &apOld[i], 0); + if( rc ){ + memset(apOld, 0, (i+1)*sizeof(MemPage*)); + goto balance_cleanup; + } + nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow; + if( (i--)==0 ) break; + + if( i+nxDiv==pParent->aiOvfl[0] && pParent->nOverflow ){ + apDiv[i] = pParent->apOvfl[0]; + pgno = get4byte(apDiv[i]); + szNew[i] = cellSizePtr(pParent, apDiv[i]); + pParent->nOverflow = 0; + }else{ + apDiv[i] = findCell(pParent, i+nxDiv-pParent->nOverflow); + pgno = get4byte(apDiv[i]); + szNew[i] = cellSizePtr(pParent, apDiv[i]); + + /* Drop the cell from the parent page. apDiv[i] still points to + ** the cell within the parent, even though it has been dropped. + ** This is safe because dropping a cell only overwrites the first + ** four bytes of it, and this function does not need the first + ** four bytes of the divider cell. So the pointer is safe to use + ** later on. + ** + ** But not if we are in secure-delete mode. In secure-delete mode, + ** the dropCell() routine will overwrite the entire cell with zeroes. + ** In this case, temporarily copy the cell into the aOvflSpace[] + ** buffer. It will be copied out again as soon as the aSpace[] buffer + ** is allocated. */ + if( pBt->btsFlags & BTS_SECURE_DELETE ){ + int iOff; + + iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData); + if( (iOff+szNew[i])>(int)pBt->usableSize ){ + rc = SQLITE_CORRUPT_BKPT; + memset(apOld, 0, (i+1)*sizeof(MemPage*)); + goto balance_cleanup; + }else{ + memcpy(&aOvflSpace[iOff], apDiv[i], szNew[i]); + apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData]; + } + } + dropCell(pParent, i+nxDiv-pParent->nOverflow, szNew[i], &rc); + } + } + + /* Make nMaxCells a multiple of 4 in order to preserve 8-byte + ** alignment */ + nMaxCells = (nMaxCells + 3)&~3; + + /* + ** Allocate space for memory structures + */ + szScratch = + nMaxCells*sizeof(u8*) /* apCell */ + + nMaxCells*sizeof(u16) /* szCell */ + + pBt->pageSize; /* aSpace1 */ + + /* EVIDENCE-OF: R-28375-38319 SQLite will never request a scratch buffer + ** that is more than 6 times the database page size. */ + assert( szScratch<=6*(int)pBt->pageSize ); + apCell = sqlite3ScratchMalloc( szScratch ); + if( apCell==0 ){ + rc = SQLITE_NOMEM; + goto balance_cleanup; + } + szCell = (u16*)&apCell[nMaxCells]; + aSpace1 = (u8*)&szCell[nMaxCells]; + assert( EIGHT_BYTE_ALIGNMENT(aSpace1) ); + + /* + ** 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 from aSpace1[]. The divider cells have already + ** been removed from pParent. + ** + ** If the siblings are on leaf pages, then the child pointers of the + ** divider cells are stripped from the cells before they are copied + ** into aSpace1[]. In this way, all cells in apCell[] are without + ** child pointers. If siblings are not leaves, then all cell in + ** apCell[] include child pointers. Either way, all cells in apCell[] + ** are alike. + ** + ** leafCorrection: 4 if pPage is a leaf. 0 if pPage is not a leaf. + ** leafData: 1 if pPage holds key+data and pParent holds only keys. + */ + leafCorrection = apOld[0]->leaf*4; + leafData = apOld[0]->intKeyLeaf; + for(i=0; inCell+pOld->nOverflow; + if( pOld->nOverflow>0 ){ + for(j=0; jaData; + u16 maskPage = pOld->maskPage; + u16 cellOffset = pOld->cellOffset; + for(j=0; jmaxLocal+23 ); + assert( iSpace1 <= (int)pBt->pageSize ); + memcpy(pTemp, apDiv[i], sz); + apCell[nCell] = pTemp+leafCorrection; + assert( leafCorrection==0 || leafCorrection==4 ); + szCell[nCell] = szCell[nCell] - leafCorrection; + if( !pOld->leaf ){ + assert( leafCorrection==0 ); + assert( pOld->hdrOffset==0 ); + /* The right pointer of the child page pOld becomes the left + ** pointer of the divider cell */ + memcpy(apCell[nCell], &pOld->aData[8], 4); + }else{ + assert( leafCorrection==4 ); + if( szCell[nCell]<4 ){ + /* Do not allow any cells smaller than 4 bytes. If a smaller cell + ** does exist, pad it with 0x00 bytes. */ + assert( szCell[nCell]==3 ); + assert( apCell[nCell]==&aSpace1[iSpace1-3] ); + aSpace1[iSpace1++] = 0x00; + szCell[nCell] = 4; + } + } + nCell++; + } + } + + /* + ** Figure out the number of pages needed to hold all nCell cells. + ** Store this number in "k". Also compute szNew[] which is the total + ** size of all cells on the i-th page and cntNew[] which is the index + ** in apCell[] of the cell that divides page i from page i+1. + ** cntNew[k] should equal nCell. + ** + ** Values computed by this block: + ** + ** k: The total number of sibling pages + ** szNew[i]: Spaced used on the i-th sibling page. + ** 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 usableSpace ){ + szNew[k] = subtotal - szCell[i] - 2; + cntNew[k] = i; + if( leafData ){ i--; } + subtotal = 0; + k++; + if( k>NB+1 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; } + } + } + szNew[k] = subtotal; + cntNew[k] = nCell; + k++; + + /* + ** The packing computed by the previous block is biased toward the siblings + ** on the left side (siblings with smaller keys). The left siblings are + ** always nearly full, while the right-most sibling might be nearly empty. + ** The next block of code attempts to adjust the packing of siblings to + ** get a better balance. + ** + ** This adjustment is more than an optimization. The packing above might + ** be so out of balance as to be illegal. For example, the right-most + ** sibling might be completely empty. This adjustment is not optional. + */ + for(i=k-1; i>0; i--){ + 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( d0), or + ** (2) pPage is 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) || CORRUPT_DB); + TRACE(("BALANCE: old: %d(nc=%d) %d(nc=%d) %d(nc=%d)\n", + apOld[0]->pgno, apOld[0]->nCell, + nOld>=2 ? apOld[1]->pgno : 0, nOld>=2 ? apOld[1]->nCell : 0, + nOld>=3 ? apOld[2]->pgno : 0, nOld>=3 ? apOld[2]->nCell : 0 + )); + + /* + ** Allocate k new pages. Reuse old pages where possible. + */ + if( apOld[0]->pgno<=1 ){ + rc = SQLITE_CORRUPT_BKPT; + goto balance_cleanup; + } + pageFlags = apOld[0]->aData[0]; + for(i=0; ipDbPage); + nNew++; + if( rc ) goto balance_cleanup; + }else{ + assert( i>0 ); + rc = allocateBtreePage(pBt, &pNew, &pgno, (bBulk ? 1 : pgno), 0); + if( rc ) goto balance_cleanup; + zeroPage(pNew, pageFlags); + apNew[i] = pNew; + nNew++; + cntOld[i] = nCell; + + /* Set the pointer-map entry for the new sibling page. */ + if( ISAUTOVACUUM ){ + ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno, &rc); + if( rc!=SQLITE_OK ){ + goto balance_cleanup; + } + } + } + } + + /* + ** Reassign page numbers so that the new pages are in ascending order. + ** This helps to keep entries in the disk file in order so that a scan + ** of the table is closer to a linear scan through the file. That in turn + ** helps the operating system to deliver pages from the disk more rapidly. + ** + ** An O(n^2) insertion sort algorithm is used, but since n is never more + ** than (NB+2) (a small constant), that should not be a problem. + ** + ** When NB==3, this one optimization makes the database about 25% faster + ** for large insertions and deletions. + */ + for(i=0; ipgno; + aPgFlags[i] = apNew[i]->pDbPage->flags; + for(j=0; ji ){ + sqlite3PagerRekey(apNew[iBest]->pDbPage, pBt->nPage+iBest+1, 0); + } + sqlite3PagerRekey(apNew[i]->pDbPage, pgno, aPgFlags[iBest]); + apNew[i]->pgno = pgno; + } + } + + TRACE(("BALANCE: new: %d(%d nc=%d) %d(%d nc=%d) %d(%d nc=%d) " + "%d(%d nc=%d) %d(%d nc=%d)\n", + apNew[0]->pgno, szNew[0], cntNew[0], + nNew>=2 ? apNew[1]->pgno : 0, nNew>=2 ? szNew[1] : 0, + nNew>=2 ? cntNew[1] - cntNew[0] - !leafData : 0, + nNew>=3 ? apNew[2]->pgno : 0, nNew>=3 ? szNew[2] : 0, + nNew>=3 ? cntNew[2] - cntNew[1] - !leafData : 0, + nNew>=4 ? apNew[3]->pgno : 0, nNew>=4 ? szNew[3] : 0, + nNew>=4 ? cntNew[3] - cntNew[2] - !leafData : 0, + nNew>=5 ? apNew[4]->pgno : 0, nNew>=5 ? szNew[4] : 0, + nNew>=5 ? cntNew[4] - cntNew[3] - !leafData : 0 + )); + + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + put4byte(pRight, apNew[nNew-1]->pgno); + + /* If the sibling pages are not leaves, ensure that the right-child pointer + ** of the right-most new sibling page is set to the value that was + ** originally in the same field of the right-most old sibling page. */ + if( (pageFlags & PTF_LEAF)==0 && nOld!=nNew ){ + MemPage *pOld = (nNew>nOld ? apNew : apOld)[nOld-1]; + memcpy(&apNew[nNew-1]->aData[8], &pOld->aData[8], 4); + } + + /* Make any required updates to pointer map entries associated with + ** cells stored on sibling pages following the balance operation. Pointer + ** map entries associated with divider cells are set by the insertCell() + ** routine. The associated pointer map entries are: + ** + ** a) if the cell contains a reference to an overflow chain, the + ** entry associated with the first page in the overflow chain, and + ** + ** b) if the sibling pages are not leaves, the child page associated + ** with the cell. + ** + ** If the sibling pages are not leaves, then the pointer map entry + ** associated with the right-child of each sibling may also need to be + ** updated. This happens below, after the sibling pages have been + ** populated, not here. + */ + if( ISAUTOVACUUM ){ + MemPage *pNew = apNew[0]; + u8 *aOld = pNew->aData; + int cntOldNext = pNew->nCell + pNew->nOverflow; + int usableSize = pBt->usableSize; + int iNew = 0; + int iOld = 0; + + for(i=0; inCell + pOld->nOverflow + !leafData; + aOld = pOld->aData; + } + if( i==cntNew[iNew] ){ + pNew = apNew[++iNew]; + if( !leafData ) continue; + } + + /* Cell pCell is destined for new sibling page pNew. Originally, it + ** was either part of sibling page iOld (possibly an overflow cell), + ** or else the divider cell to the left of sibling page iOld. So, + ** if sibling page iOld had the same page number as pNew, and if + ** pCell really was a part of sibling page iOld (not a divider or + ** overflow cell), we can skip updating the pointer map entries. */ + if( iOld>=nNew + || pNew->pgno!=aPgno[iOld] + || pCell=&aOld[usableSize] + ){ + if( !leafCorrection ){ + ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc); + } + if( szCell[i]>pNew->minLocal ){ + ptrmapPutOvflPtr(pNew, pCell, &rc); + } + } + } + } + + /* Insert new divider cells into pParent. */ + for(i=0; ileaf ){ + memcpy(&pNew->aData[8], pCell, 4); + }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--; + btreeParseCellPtr(pNew, apCell[j], &info); + pCell = pTemp; + sz = 4 + putVarint(&pCell[4], info.nKey); + pTemp = 0; + }else{ + pCell -= 4; + /* Obscure case for non-leaf-data trees: If the cell at pCell was + ** previously stored on a leaf node, and its reported size was 4 + ** bytes, then it may actually be smaller than this + ** (see btreeParseCellPtr(), 4 bytes is the minimum size of + ** any cell). But it is important to pass the correct size to + ** insertCell(), so reparse the cell now. + ** + ** Note that this can never happen in an SQLite data file, as all + ** cells are at least 4 bytes. It only happens in b-trees used + ** to evaluate "IN (SELECT ...)" and similar clauses. + */ + if( szCell[j]==4 ){ + assert(leafCorrection==4); + sz = cellSizePtr(pParent, pCell); + } + } + iOvflSpace += sz; + assert( sz<=pBt->maxLocal+23 ); + assert( iOvflSpace <= (int)pBt->pageSize ); + insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno, &rc); + if( rc!=SQLITE_OK ) goto balance_cleanup; + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + } + + /* Now update the actual sibling pages. The order in which they are updated + ** is important, as this code needs to avoid disrupting any page from which + ** cells may still to be read. In practice, this means: + ** + ** (1) If cells are moving left (from apNew[iPg] to apNew[iPg-1]) + ** then it is not safe to update page apNew[iPg] until after + ** the left-hand sibling apNew[iPg-1] has been updated. + ** + ** (2) If cells are moving right (from apNew[iPg] to apNew[iPg+1]) + ** then it is not safe to update page apNew[iPg] until after + ** the right-hand sibling apNew[iPg+1] has been updated. + ** + ** If neither of the above apply, the page is safe to update. + ** + ** The iPg value in the following loop starts at nNew-1 goes down + ** to 0, then back up to nNew-1 again, thus making two passes over + ** the pages. On the initial downward pass, only condition (1) above + ** needs to be tested because (2) will always be true from the previous + ** step. On the upward pass, both conditions are always true, so the + ** upwards pass simply processes pages that were missed on the downward + ** pass. + */ + for(i=1-nNew; i=0 && iPg=0 /* On the upwards pass, or... */ + || cntOld[iPg-1]>=cntNew[iPg-1] /* Condition (1) is true */ + ){ + int iNew; + int iOld; + int nNewCell; + + /* Verify condition (1): If cells are moving left, update iPg + ** only after iPg-1 has already been updated. */ + assert( iPg==0 || cntOld[iPg-1]>=cntNew[iPg-1] || abDone[iPg-1] ); + + /* Verify condition (2): If cells are moving right, update iPg + ** only after iPg+1 has already been updated. */ + assert( cntNew[iPg]>=cntOld[iPg] || abDone[iPg+1] ); + + if( iPg==0 ){ + iNew = iOld = 0; + nNewCell = cntNew[0]; + }else{ + iOld = iPgnFree = usableSpace-szNew[iPg]; + assert( apNew[iPg]->nOverflow==0 ); + assert( apNew[iPg]->nCell==nNewCell ); + } + } + + /* All pages have been processed exactly once */ + assert( memcmp(abDone, "\01\01\01\01\01", nNew)==0 ); + + assert( nOld>0 ); + assert( nNew>0 ); + + if( isRoot && pParent->nCell==0 && pParent->hdrOffset<=apNew[0]->nFree ){ + /* The root page of the b-tree now contains no cells. The only sibling + ** page is the right-child of the parent. Copy the contents of the + ** child page into the parent, decreasing the overall height of the + ** b-tree structure by one. This is described as the "balance-shallower" + ** sub-algorithm in some documentation. + ** + ** If this is an auto-vacuum database, the call to copyNodeContent() + ** sets all pointer-map entries corresponding to database image pages + ** for which the pointer is stored within the content being copied. + ** + ** It is critical that the child page be defragmented before being + ** copied into the parent, because if the parent is page 1 then it will + ** by smaller than the child due to the database header, and so all the + ** free space needs to be up front. + */ + assert( nNew==1 ); + rc = defragmentPage(apNew[0]); + testcase( rc!=SQLITE_OK ); + assert( apNew[0]->nFree == + (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2) + || rc!=SQLITE_OK + ); + copyNodeContent(apNew[0], pParent, &rc); + freePage(apNew[0], &rc); + }else if( ISAUTOVACUUM && !leafCorrection ){ + /* Fix the pointer map entries associated with the right-child of each + ** sibling page. All other pointer map entries have already been taken + ** care of. */ + for(i=0; iaData[8]); + ptrmapPut(pBt, key, PTRMAP_BTREE, apNew[i]->pgno, &rc); + } + } + + assert( pParent->isInit ); + TRACE(("BALANCE: finished: old=%d new=%d cells=%d\n", + nOld, nNew, nCell)); + + /* Free any old pages that were not reused as new pages. + */ + for(i=nNew; iisInit ){ + /* The ptrmapCheckPages() contains assert() statements that verify that + ** all pointer map pages are set correctly. This is helpful while + ** debugging. This is usually disabled because a corrupt database may + ** cause an assert() statement to fail. */ + ptrmapCheckPages(apNew, nNew); + ptrmapCheckPages(&pParent, 1); + } +#endif + + /* + ** Cleanup before returning. + */ +balance_cleanup: + sqlite3ScratchFree(apCell); + for(i=0; i= 1700 && defined(_M_ARM) +#pragma optimize("", on) +#endif + + +/* +** This function is called when the root page of a b-tree structure is +** overfull (has one or more overflow pages). +** +** A new child page is allocated and the contents of the current root +** page, including overflow cells, are copied into the child. The root +** page is then overwritten to make it an empty page with the right-child +** pointer pointing to the new page. +** +** Before returning, all pointer-map entries corresponding to pages +** that the new child-page now contains pointers to are updated. The +** entry corresponding to the new right-child pointer of the root +** page is also updated. +** +** If successful, *ppChild is set to contain a reference to the child +** page and SQLITE_OK is returned. In this case the caller is required +** to call releasePage() on *ppChild exactly once. If an error occurs, +** an error code is returned and *ppChild is set to 0. +*/ +static int balance_deeper(MemPage *pRoot, MemPage **ppChild){ + int rc; /* Return value from subprocedures */ + MemPage *pChild = 0; /* Pointer to a new child page */ + Pgno pgnoChild = 0; /* Page number of the new child page */ + BtShared *pBt = pRoot->pBt; /* The BTree */ + + assert( pRoot->nOverflow>0 ); + assert( sqlite3_mutex_held(pBt->mutex) ); + + /* Make pRoot, the root page of the b-tree, writable. Allocate a new + ** page that will become the new right-child of pPage. Copy the contents + ** of the node stored on pRoot into the new child page. + */ + rc = sqlite3PagerWrite(pRoot->pDbPage); + if( rc==SQLITE_OK ){ + rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0); + copyNodeContent(pRoot, pChild, &rc); + if( ISAUTOVACUUM ){ + ptrmapPut(pBt, pgnoChild, PTRMAP_BTREE, pRoot->pgno, &rc); + } + } + if( rc ){ + *ppChild = 0; + releasePage(pChild); + return rc; + } + assert( sqlite3PagerIswriteable(pChild->pDbPage) ); + assert( sqlite3PagerIswriteable(pRoot->pDbPage) ); + assert( pChild->nCell==pRoot->nCell ); + + TRACE(("BALANCE: copy root %d into %d\n", pRoot->pgno, pChild->pgno)); + + /* Copy the overflow cells from pRoot to pChild */ + memcpy(pChild->aiOvfl, pRoot->aiOvfl, + pRoot->nOverflow*sizeof(pRoot->aiOvfl[0])); + memcpy(pChild->apOvfl, pRoot->apOvfl, + pRoot->nOverflow*sizeof(pRoot->apOvfl[0])); + pChild->nOverflow = pRoot->nOverflow; + + /* Zero the contents of pRoot. Then install pChild as the right-child. */ + zeroPage(pRoot, pChild->aData[0] & ~PTF_LEAF); + put4byte(&pRoot->aData[pRoot->hdrOffset+8], pgnoChild); + + *ppChild = pChild; + return SQLITE_OK; +} + +/* +** The page that pCur currently points to has just been modified in +** some way. This function figures out if this modification means the +** tree needs to be balanced, and if so calls the appropriate balancing +** routine. Balancing routines are: +** +** balance_quick() +** balance_deeper() +** balance_nonroot() +*/ +static int balance(BtCursor *pCur){ + int rc = SQLITE_OK; + const int nMin = pCur->pBt->usableSize * 2 / 3; + u8 aBalanceQuickSpace[13]; + u8 *pFree = 0; + + TESTONLY( int balance_quick_called = 0 ); + TESTONLY( int balance_deeper_called = 0 ); + + do { + int iPage = pCur->iPage; + MemPage *pPage = pCur->apPage[iPage]; + + if( iPage==0 ){ + if( pPage->nOverflow ){ + /* The root page of the b-tree is overfull. In this case call the + ** balance_deeper() function to create a new child for the root-page + ** and copy the current contents of the root-page to it. The + ** next iteration of the do-loop will balance the child page. + */ + assert( (balance_deeper_called++)==0 ); + rc = balance_deeper(pPage, &pCur->apPage[1]); + if( rc==SQLITE_OK ){ + pCur->iPage = 1; + pCur->aiIdx[0] = 0; + pCur->aiIdx[1] = 0; + assert( pCur->apPage[1]->nOverflow ); + } + }else{ + break; + } + }else if( pPage->nOverflow==0 && pPage->nFree<=nMin ){ + break; + }else{ + MemPage * const pParent = pCur->apPage[iPage-1]; + int const iIdx = pCur->aiIdx[iPage-1]; + + rc = sqlite3PagerWrite(pParent->pDbPage); + if( rc==SQLITE_OK ){ +#ifndef SQLITE_OMIT_QUICKBALANCE + if( pPage->intKeyLeaf + && pPage->nOverflow==1 + && pPage->aiOvfl[0]==pPage->nCell + && pParent->pgno!=1 + && pParent->nCell==iIdx + ){ + /* Call balance_quick() to create a new sibling of pPage on which + ** to store the overflow cell. balance_quick() inserts a new cell + ** into pParent, which may cause pParent overflow. If this + ** happens, the next iteration of the do-loop will balance pParent + ** use either balance_nonroot() or balance_deeper(). Until this + ** happens, the overflow cell is stored in the aBalanceQuickSpace[] + ** buffer. + ** + ** The purpose of the following assert() is to check that only a + ** single call to balance_quick() is made for each call to this + ** function. If this were not verified, a subtle bug involving reuse + ** of the aBalanceQuickSpace[] might sneak in. + */ + assert( (balance_quick_called++)==0 ); + rc = balance_quick(pParent, pPage, aBalanceQuickSpace); + }else +#endif + { + /* In this case, call balance_nonroot() to redistribute cells + ** between pPage and up to 2 of its sibling pages. This involves + ** modifying the contents of pParent, which may cause pParent to + ** become overfull or underfull. The next iteration of the do-loop + ** will balance the parent page to correct this. + ** + ** If the parent page becomes overfull, the overflow cell or cells + ** are stored in the pSpace buffer allocated immediately below. + ** A subsequent iteration of the do-loop will deal with this by + ** calling balance_nonroot() (balance_deeper() may be called first, + ** but it doesn't deal with overflow cells - just moves them to a + ** different page). Once this subsequent call to balance_nonroot() + ** has completed, it is safe to release the pSpace buffer used by + ** the previous call, as the overflow cell data will have been + ** copied either into the body of a database page or into the new + ** pSpace buffer passed to the latter call to balance_nonroot(). + */ + u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize); + rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1, + pCur->hints&BTREE_BULKLOAD); + if( pFree ){ + /* If pFree is not NULL, it points to the pSpace buffer used + ** by a previous call to balance_nonroot(). Its contents are + ** now stored either on real database pages or within the + ** new pSpace buffer, so it may be safely freed here. */ + sqlite3PageFree(pFree); + } + + /* The pSpace buffer will be freed after the next call to + ** balance_nonroot(), or just before this function returns, whichever + ** comes first. */ + pFree = pSpace; + } + } + + pPage->nOverflow = 0; + + /* The next iteration of the do-loop balances the parent page. */ + releasePage(pPage); + pCur->iPage--; + assert( pCur->iPage>=0 ); + } + }while( rc==SQLITE_OK ); + + if( pFree ){ + sqlite3PageFree(pFree); + } + return rc; +} + + +/* +** Insert a new record into the BTree. The key is given by (pKey,nKey) +** and the data is given by (pData,nData). The cursor is used only to +** define what table the record should be inserted into. The cursor +** is left pointing at a random location. +** +** For an INTKEY table, only the nKey value of the key is used. pKey is +** ignored. For a ZERODATA table, the pData and nData are both ignored. +** +** If the seekResult parameter is non-zero, then a successful call to +** MovetoUnpacked() to seek cursor pCur to (pKey, nKey) has already +** been performed. seekResult is the search result returned (a negative +** number if pCur points at an entry that is smaller than (pKey, nKey), or +** a positive value if pCur points at an entry that is larger than +** (pKey, nKey)). +** +** If the seekResult parameter is non-zero, then the caller guarantees that +** cursor pCur is pointing at the existing copy of a row that is to be +** overwritten. If the seekResult parameter is 0, then cursor pCur may +** point to any entry or to no entry at all and so this function has to seek +** the cursor before the new key can be inserted. +*/ +SQLITE_PRIVATE int sqlite3BtreeInsert( + BtCursor *pCur, /* Insert data into the table of this cursor */ + const void *pKey, i64 nKey, /* The key of the new record */ + const void *pData, int nData, /* The data of the new record */ + int nZero, /* Number of extra 0 bytes to append to data */ + int appendBias, /* True if this is likely an append */ + int seekResult /* Result of prior MovetoUnpacked() call */ +){ + int rc; + int loc = seekResult; /* -1: before desired location +1: after */ + int szNew = 0; + int idx; + MemPage *pPage; + Btree *p = pCur->pBtree; + BtShared *pBt = p->pBt; + unsigned char *oldCell; + unsigned char *newCell = 0; + + if( pCur->eState==CURSOR_FAULT ){ + assert( pCur->skipNext!=SQLITE_OK ); + return pCur->skipNext; + } + + assert( cursorHoldsMutex(pCur) ); + assert( (pCur->curFlags & BTCF_WriteFlag)!=0 + && pBt->inTransaction==TRANS_WRITE + && (pBt->btsFlags & BTS_READ_ONLY)==0 ); + assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); + + /* Assert that the caller has been consistent. If this cursor was opened + ** expecting an index b-tree, then the caller should be inserting blob + ** keys with no associated data. If the cursor was opened expecting an + ** intkey table, the caller should be inserting integer keys with a + ** blob of associated data. */ + assert( (pKey==0)==(pCur->pKeyInfo==0) ); + + /* Save the positions of any other cursors open on this table. + ** + ** In some cases, the call to btreeMoveto() below is a no-op. For + ** example, when inserting data into a table with auto-generated integer + ** keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the + ** integer key to use. It then calls this function to actually insert the + ** data into the intkey B-Tree. In this case btreeMoveto() recognizes + ** that the cursor is already where it needs to be and returns without + ** doing any work. To avoid thwarting these optimizations, it is important + ** not to clear the cursor here. + */ + rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur); + if( rc ) return rc; + + if( pCur->pKeyInfo==0 ){ + /* If this is an insert into a table b-tree, invalidate any incrblob + ** cursors open on the row being replaced */ + invalidateIncrblobCursors(p, nKey, 0); + + /* If the cursor is currently on the last row and we are appending a + ** new row onto the end, set the "loc" to avoid an unnecessary btreeMoveto() + ** call */ + if( (pCur->curFlags&BTCF_ValidNKey)!=0 && nKey>0 + && pCur->info.nKey==nKey-1 ){ + loc = -1; + } + } + + if( !loc ){ + rc = btreeMoveto(pCur, pKey, nKey, appendBias, &loc); + if( rc ) return rc; + } + assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) ); + + pPage = pCur->apPage[pCur->iPage]; + assert( pPage->intKey || nKey>=0 ); + assert( pPage->leaf || !pPage->intKey ); + + 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 ); + newCell = pBt->pTmpSpace; + assert( newCell!=0 ); + rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew); + if( rc ) goto end_insert; + assert( szNew==cellSizePtr(pPage, newCell) ); + assert( szNew <= MX_CELL_SIZE(pBt) ); + idx = pCur->aiIdx[pCur->iPage]; + if( loc==0 ){ + u16 szOld; + assert( idxnCell ); + rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc ){ + goto end_insert; + } + oldCell = findCell(pPage, idx); + if( !pPage->leaf ){ + memcpy(newCell, oldCell, 4); + } + rc = clearCell(pPage, oldCell, &szOld); + dropCell(pPage, idx, szOld, &rc); + if( rc ) goto end_insert; + }else if( loc<0 && pPage->nCell>0 ){ + assert( pPage->leaf ); + idx = ++pCur->aiIdx[pCur->iPage]; + }else{ + assert( pPage->leaf ); + } + insertCell(pPage, idx, newCell, szNew, 0, 0, &rc); + assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 ); + + /* If no error has occurred and pPage has an overflow cell, call balance() + ** to redistribute the cells within the tree. Since balance() may move + ** the cursor, zero the BtCursor.info.nSize and BTCF_ValidNKey + ** variables. + ** + ** Previous versions of SQLite called moveToRoot() to move the cursor + ** back to the root page as balance() used to invalidate the contents + ** of BtCursor.apPage[] and BtCursor.aiIdx[]. Instead of doing that, + ** set the cursor state to "invalid". This makes common insert operations + ** slightly faster. + ** + ** There is a subtle but important optimization here too. When inserting + ** multiple records into an intkey b-tree using a single cursor (as can + ** happen while processing an "INSERT INTO ... SELECT" statement), it + ** is advantageous to leave the cursor pointing to the last entry in + ** the b-tree if possible. If the cursor is left pointing to the last + ** entry in the table, and the next row inserted has an integer key + ** larger than the largest existing key, it is possible to insert the + ** row without seeking the cursor. This can be a big performance boost. + */ + pCur->info.nSize = 0; + if( rc==SQLITE_OK && pPage->nOverflow ){ + pCur->curFlags &= ~(BTCF_ValidNKey); + rc = balance(pCur); + + /* Must make sure nOverflow is reset to zero even if the balance() + ** fails. Internal data structure corruption will result otherwise. + ** Also, set the cursor state to invalid. This stops saveCursorPosition() + ** from trying to save the current position of the cursor. */ + pCur->apPage[pCur->iPage]->nOverflow = 0; + pCur->eState = CURSOR_INVALID; + } + assert( pCur->apPage[pCur->iPage]->nOverflow==0 ); + +end_insert: + return rc; +} + +/* +** Delete the entry that the cursor is pointing to. The cursor +** is left pointing at an arbitrary location. +*/ +SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){ + Btree *p = pCur->pBtree; + BtShared *pBt = p->pBt; + int rc; /* Return code */ + MemPage *pPage; /* Page to delete cell from */ + unsigned char *pCell; /* Pointer to cell to delete */ + int iCellIdx; /* Index of cell to delete */ + int iCellDepth; /* Depth of node containing pCell */ + u16 szCell; /* Size of the cell being deleted */ + + assert( cursorHoldsMutex(pCur) ); + assert( pBt->inTransaction==TRANS_WRITE ); + assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); + assert( pCur->curFlags & BTCF_WriteFlag ); + assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); + assert( !hasReadConflicts(p, pCur->pgnoRoot) ); + + if( NEVER(pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell) + || NEVER(pCur->eState!=CURSOR_VALID) + ){ + return SQLITE_ERROR; /* Something has gone awry. */ + } + + iCellDepth = pCur->iPage; + iCellIdx = pCur->aiIdx[iCellDepth]; + pPage = pCur->apPage[iCellDepth]; + pCell = findCell(pPage, iCellIdx); + + /* If the page containing the entry to delete is not a leaf page, move + ** the cursor to the largest entry in the tree that is smaller than + ** the entry being deleted. This cell will replace the cell being deleted + ** from the internal node. The 'previous' entry is used for this instead + ** of the 'next' entry, as the previous entry is always a part of the + ** sub-tree headed by the child page of the cell being deleted. This makes + ** balancing the tree following the delete operation easier. */ + if( !pPage->leaf ){ + int notUsed = 0; + rc = sqlite3BtreePrevious(pCur, ¬Used); + if( rc ) return rc; + } + + /* Save the positions of any other cursors open on this table before + ** making any modifications. Make the page containing the entry to be + ** deleted writable. Then free any overflow pages associated with the + ** entry and finally remove the cell itself from within the page. + */ + rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur); + if( rc ) return rc; + + /* If this is a delete operation to remove a row from a table b-tree, + ** invalidate any incrblob cursors open on the row being deleted. */ + if( pCur->pKeyInfo==0 ){ + invalidateIncrblobCursors(p, pCur->info.nKey, 0); + } + + rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc ) return rc; + rc = clearCell(pPage, pCell, &szCell); + dropCell(pPage, iCellIdx, szCell, &rc); + if( rc ) return rc; + + /* If the cell deleted was not located on a leaf page, then the cursor + ** is currently pointing to the largest entry in the sub-tree headed + ** by the child-page of the cell that was just deleted from an internal + ** node. The cell from the leaf node needs to be moved to the internal + ** node to replace the deleted cell. */ + if( !pPage->leaf ){ + MemPage *pLeaf = pCur->apPage[pCur->iPage]; + int nCell; + Pgno n = pCur->apPage[iCellDepth+1]->pgno; + unsigned char *pTmp; + + pCell = findCell(pLeaf, pLeaf->nCell-1); + nCell = cellSizePtr(pLeaf, pCell); + assert( MX_CELL_SIZE(pBt) >= nCell ); + pTmp = pBt->pTmpSpace; + assert( pTmp!=0 ); + rc = sqlite3PagerWrite(pLeaf->pDbPage); + insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc); + dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc); + if( rc ) return rc; + } + + /* Balance the tree. If the entry deleted was located on a leaf page, + ** then the cursor still points to that page. In this case the first + ** call to balance() repairs the tree, and the if(...) condition is + ** never true. + ** + ** Otherwise, if the entry deleted was on an internal node page, then + ** pCur is pointing to the leaf page from which a cell was removed to + ** replace the cell deleted from the internal node. This is slightly + ** tricky as the leaf node may be underfull, and the internal node may + ** be either under or overfull. In this case run the balancing algorithm + ** on the leaf node first. If the balance proceeds far enough up the + ** tree that we can be sure that any problem in the internal node has + ** been corrected, so be it. Otherwise, after balancing the leaf node, + ** walk the cursor up the tree to the internal node and balance it as + ** well. */ + rc = balance(pCur); + if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){ + while( pCur->iPage>iCellDepth ){ + releasePage(pCur->apPage[pCur->iPage--]); + } + rc = balance(pCur); + } + + 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 +*/ +static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){ + BtShared *pBt = p->pBt; + MemPage *pRoot; + Pgno pgnoRoot; + int rc; + int ptfFlags; /* Page-type flage for the root page of new table */ + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( pBt->inTransaction==TRANS_WRITE ); + assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); + +#ifdef SQLITE_OMIT_AUTOVACUUM + rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0); + if( rc ){ + return rc; + } +#else + if( pBt->autoVacuum ){ + Pgno pgnoMove; /* Move a page here to make room for the root-page */ + MemPage *pPageMove; /* The page to move to. */ + + /* Creating a new table may probably require moving an existing database + ** to make room for the new tables root page. In case this page turns + ** out to be an overflow page, delete all overflow page-map caches + ** held by open cursors. + */ + invalidateAllOverflowCache(pBt); + + /* 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). + */ + sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot); + pgnoRoot++; + + /* The new root-page may not be allocated on a pointer-map page, or the + ** PENDING_BYTE page. + */ + while( pgnoRoot==PTRMAP_PAGENO(pBt, pgnoRoot) || + pgnoRoot==PENDING_BYTE_PAGE(pBt) ){ + pgnoRoot++; + } + assert( pgnoRoot>=3 ); + + /* Allocate a page. The page that currently resides at pgnoRoot will + ** be moved to the allocated page (unless the allocated page happens + ** to reside at pgnoRoot). + */ + rc = allocateBtreePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, BTALLOC_EXACT); + if( rc!=SQLITE_OK ){ + return rc; + } + + if( pgnoMove!=pgnoRoot ){ + /* pgnoRoot is the page that will be used for the root-page of + ** the new table (assuming an error did not occur). But we were + ** allocated pgnoMove. If required (i.e. if it was not allocated + ** by extending the file), the current page at position pgnoMove + ** is already journaled. + */ + u8 eType = 0; + Pgno iPtrPage = 0; + + /* Save the positions of any open cursors. This is required in + ** case they are holding a reference to an xFetch reference + ** corresponding to page pgnoRoot. */ + rc = saveAllCursors(pBt, 0, 0); + releasePage(pPageMove); + if( rc!=SQLITE_OK ){ + return rc; + } + + /* Move the page currently at pgnoRoot to pgnoMove. */ + rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage); + if( eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){ + rc = SQLITE_CORRUPT_BKPT; + } + if( rc!=SQLITE_OK ){ + releasePage(pRoot); + return rc; + } + assert( eType!=PTRMAP_ROOTPAGE ); + assert( eType!=PTRMAP_FREEPAGE ); + rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove, 0); + releasePage(pRoot); + + /* Obtain the page at pgnoRoot */ + if( rc!=SQLITE_OK ){ + return rc; + } + rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = sqlite3PagerWrite(pRoot->pDbPage); + if( rc!=SQLITE_OK ){ + releasePage(pRoot); + return rc; + } + }else{ + pRoot = pPageMove; + } + + /* Update the pointer-map and meta-data with the new root-page number. */ + ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0, &rc); + if( rc ){ + releasePage(pRoot); + return rc; + } + + /* When the new root page was allocated, page 1 was made writable in + ** order either to increase the database filesize, or to decrement the + ** freelist count. Hence, the sqlite3BtreeUpdateMeta() call cannot fail. + */ + assert( sqlite3PagerIswriteable(pBt->pPage1->pDbPage) ); + rc = sqlite3BtreeUpdateMeta(p, 4, pgnoRoot); + if( NEVER(rc) ){ + releasePage(pRoot); + return rc; + } + + }else{ + rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0); + if( rc ) return rc; + } +#endif + assert( sqlite3PagerIswriteable(pRoot->pDbPage) ); + if( createTabFlags & BTREE_INTKEY ){ + ptfFlags = PTF_INTKEY | PTF_LEAFDATA | PTF_LEAF; + }else{ + ptfFlags = PTF_ZERODATA | PTF_LEAF; + } + zeroPage(pRoot, ptfFlags); + sqlite3PagerUnref(pRoot->pDbPage); + assert( (pBt->openFlags & BTREE_SINGLE)==0 || pgnoRoot==2 ); + *piTable = (int)pgnoRoot; + return SQLITE_OK; +} +SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){ + int rc; + sqlite3BtreeEnter(p); + rc = btreeCreateTable(p, piTable, flags); + sqlite3BtreeLeave(p); + return rc; +} + +/* +** 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 */ + int freePageFlag, /* Deallocate page if true */ + int *pnChange /* Add number of Cells freed to this counter */ +){ + MemPage *pPage; + int rc; + unsigned char *pCell; + int i; + int hdr; + u16 szCell; + + assert( sqlite3_mutex_held(pBt->mutex) ); + if( pgno>btreePagecount(pBt) ){ + return SQLITE_CORRUPT_BKPT; + } + rc = getAndInitPage(pBt, pgno, &pPage, 0); + if( rc ) return rc; + if( pPage->bBusy ){ + rc = SQLITE_CORRUPT_BKPT; + goto cleardatabasepage_out; + } + pPage->bBusy = 1; + hdr = pPage->hdrOffset; + for(i=0; inCell; i++){ + pCell = findCell(pPage, i); + if( !pPage->leaf ){ + rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange); + if( rc ) goto cleardatabasepage_out; + } + rc = clearCell(pPage, pCell, &szCell); + if( rc ) goto cleardatabasepage_out; + } + if( !pPage->leaf ){ + rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange); + if( rc ) goto cleardatabasepage_out; + }else if( pnChange ){ + assert( pPage->intKey ); + *pnChange += pPage->nCell; + } + if( freePageFlag ){ + freePage(pPage, &rc); + }else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){ + zeroPage(pPage, pPage->aData[hdr] | PTF_LEAF); + } + +cleardatabasepage_out: + pPage->bBusy = 0; + 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. +** +** If pnChange is not NULL, then table iTable must be an intkey table. The +** integer value pointed to by pnChange is incremented by the number of +** entries in the table. +*/ +SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){ + int rc; + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); + assert( p->inTrans==TRANS_WRITE ); + + rc = saveAllCursors(pBt, (Pgno)iTable, 0); + + if( SQLITE_OK==rc ){ + /* Invalidate all incrblob cursors open on table iTable (assuming iTable + ** is the root of a table b-tree - if it is not, the following call is + ** a no-op). */ + invalidateIncrblobCursors(p, 0, 1); + rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange); + } + sqlite3BtreeLeave(p); + return rc; +} + +/* +** Delete all information from the single table that pCur is open on. +** +** This routine only work for pCur on an ephemeral table. +*/ +SQLITE_PRIVATE int sqlite3BtreeClearTableOfCursor(BtCursor *pCur){ + return sqlite3BtreeClearTable(pCur->pBtree, pCur->pgnoRoot, 0); +} + +/* +** 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. +** +** This routine will fail with SQLITE_LOCKED if there are any open +** cursors on the table. +** +** If AUTOVACUUM is enabled and the page at iTable is not the last +** root page in the database file, then the last root page +** in the database file is moved into the slot formerly occupied by +** iTable and that last slot formerly occupied by the last root page +** is added to the freelist instead of iTable. In this say, all +** 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. +*/ +static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ + int rc; + MemPage *pPage = 0; + BtShared *pBt = p->pBt; + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( p->inTrans==TRANS_WRITE ); + + /* 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. + ** + ** This error is caught long before control reaches this point. + */ + if( NEVER(pBt->pCursor) ){ + sqlite3ConnectionBlocked(p->db, pBt->pCursor->pBtree->db); + return SQLITE_LOCKED_SHAREDCACHE; + } + + rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0); + if( rc ) return rc; + rc = sqlite3BtreeClearTable(p, iTable, 0); + if( rc ){ + releasePage(pPage); + return rc; + } + + *piMoved = 0; + + if( iTable>1 ){ +#ifdef SQLITE_OMIT_AUTOVACUUM + freePage(pPage, &rc); + releasePage(pPage); +#else + if( pBt->autoVacuum ){ + Pgno maxRootPgno; + sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno); + + if( iTable==maxRootPgno ){ + /* If the table being dropped is the table with the largest root-page + ** number in the database, put the root page on the free list. + */ + freePage(pPage, &rc); + releasePage(pPage); + if( rc!=SQLITE_OK ){ + return rc; + } + }else{ + /* The table being dropped does not have the largest root-page + ** number in the database. So move the page that does into the + ** gap left by the deleted root-page. + */ + MemPage *pMove; + releasePage(pPage); + rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0); + releasePage(pMove); + if( rc!=SQLITE_OK ){ + return rc; + } + pMove = 0; + rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); + freePage(pMove, &rc); + releasePage(pMove); + if( rc!=SQLITE_OK ){ + return rc; + } + *piMoved = maxRootPgno; + } + + /* Set the new 'max-root-page' value in the database header. This + ** is the old value less one, less one more if that happens to + ** be a root-page number, less one again if that is the + ** PENDING_BYTE_PAGE. + */ + maxRootPgno--; + while( maxRootPgno==PENDING_BYTE_PAGE(pBt) + || PTRMAP_ISPAGE(pBt, maxRootPgno) ){ + maxRootPgno--; + } + assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) ); + + rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno); + }else{ + freePage(pPage, &rc); + releasePage(pPage); + } +#endif + }else{ + /* If sqlite3BtreeDropTable was called on page 1. + ** This really never should happen except in a corrupt + ** database. + */ + zeroPage(pPage, PTF_INTKEY|PTF_LEAF ); + releasePage(pPage); + } + return rc; +} +SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){ + int rc; + sqlite3BtreeEnter(p); + rc = btreeDropTable(p, iTable, piMoved); + sqlite3BtreeLeave(p); + return rc; +} + + +/* +** This function may only be called if the b-tree connection already +** has a read or write transaction open on the database. +** +** Read the meta-information out of a database file. Meta[0] +** is the number of free pages currently in the database. Meta[1] +** 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]. +** +** This routine treats Meta[BTREE_DATA_VERSION] as a special case. Instead +** of reading the value out of the header, it instead loads the "DataVersion" +** from the pager. The BTREE_DATA_VERSION value is not actually stored in the +** database file. It is a number computed by the pager. But its access +** pattern is the same as header meta values, and so it is convenient to +** read it from this routine. +*/ +SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){ + BtShared *pBt = p->pBt; + + sqlite3BtreeEnter(p); + assert( p->inTrans>TRANS_NONE ); + assert( SQLITE_OK==querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK) ); + assert( pBt->pPage1 ); + assert( idx>=0 && idx<=15 ); + + if( idx==BTREE_DATA_VERSION ){ + *pMeta = sqlite3PagerDataVersion(pBt->pPager) + p->iDataVersion; + }else{ + *pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]); + } + + /* If auto-vacuum is disabled in this build and this is an auto-vacuum + ** database, mark the database as read-only. */ +#ifdef SQLITE_OMIT_AUTOVACUUM + if( idx==BTREE_LARGEST_ROOT_PAGE && *pMeta>0 ){ + pBt->btsFlags |= BTS_READ_ONLY; + } +#endif + + sqlite3BtreeLeave(p); +} + +/* +** Write meta-information back into the database. Meta[0] is +** read-only and may not be written. +*/ +SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){ + BtShared *pBt = p->pBt; + unsigned char *pP1; + int rc; + assert( idx>=1 && idx<=15 ); + sqlite3BtreeEnter(p); + assert( p->inTrans==TRANS_WRITE ); + assert( pBt->pPage1!=0 ); + pP1 = pBt->pPage1->aData; + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + if( rc==SQLITE_OK ){ + put4byte(&pP1[36 + idx*4], iMeta); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( idx==BTREE_INCR_VACUUM ){ + assert( pBt->autoVacuum || iMeta==0 ); + assert( iMeta==0 || iMeta==1 ); + pBt->incrVacuum = (u8)iMeta; + } +#endif + } + sqlite3BtreeLeave(p); + return rc; +} + +#ifndef SQLITE_OMIT_BTREECOUNT +/* +** The first argument, pCur, is a cursor opened on some b-tree. Count the +** number of entries in the b-tree and write the result to *pnEntry. +** +** SQLITE_OK is returned if the operation is successfully executed. +** Otherwise, if an error is encountered (i.e. an IO error or database +** corruption) an SQLite error code is returned. +*/ +SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){ + i64 nEntry = 0; /* Value to return in *pnEntry */ + int rc; /* Return code */ + + if( pCur->pgnoRoot==0 ){ + *pnEntry = 0; + return SQLITE_OK; + } + rc = moveToRoot(pCur); + + /* Unless an error occurs, the following loop runs one iteration for each + ** page in the B-Tree structure (not including overflow pages). + */ + while( rc==SQLITE_OK ){ + int iIdx; /* Index of child node in parent */ + MemPage *pPage; /* Current page of the b-tree */ + + /* If this is a leaf page or the tree is not an int-key tree, then + ** this page contains countable entries. Increment the entry counter + ** accordingly. + */ + pPage = pCur->apPage[pCur->iPage]; + if( pPage->leaf || !pPage->intKey ){ + nEntry += pPage->nCell; + } + + /* pPage is a leaf node. This loop navigates the cursor so that it + ** points to the first interior cell that it points to the parent of + ** the next page in the tree that has not yet been visited. The + ** pCur->aiIdx[pCur->iPage] value is set to the index of the parent cell + ** of the page, or to the number of cells in the page if the next page + ** to visit is the right-child of its parent. + ** + ** If all pages in the tree have been visited, return SQLITE_OK to the + ** caller. + */ + if( pPage->leaf ){ + do { + if( pCur->iPage==0 ){ + /* All pages of the b-tree have been visited. Return successfully. */ + *pnEntry = nEntry; + return moveToRoot(pCur); + } + moveToParent(pCur); + }while ( pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell ); + + pCur->aiIdx[pCur->iPage]++; + pPage = pCur->apPage[pCur->iPage]; + } + + /* Descend to the child node of the cell that the cursor currently + ** points at. This is the right-child if (iIdx==pPage->nCell). + */ + iIdx = pCur->aiIdx[pCur->iPage]; + if( iIdx==pPage->nCell ){ + rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8])); + }else{ + rc = moveToChild(pCur, get4byte(findCell(pPage, iIdx))); + } + } + + /* An error has occurred. Return an error code. */ + return rc; +} +#endif + +/* +** Return the pager associated with a BTree. This routine is used for +** testing and debugging only. +*/ +SQLITE_PRIVATE Pager *sqlite3BtreePager(Btree *p){ + return p->pBt->pPager; +} + +#ifndef SQLITE_OMIT_INTEGRITY_CHECK +/* +** Append a message to the error message string. +*/ +static void checkAppendMsg( + IntegrityCk *pCheck, + const char *zFormat, + ... +){ + va_list ap; + char zBuf[200]; + if( !pCheck->mxErr ) return; + pCheck->mxErr--; + pCheck->nErr++; + va_start(ap, zFormat); + if( pCheck->errMsg.nChar ){ + sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1); + } + if( pCheck->zPfx ){ + sqlite3_snprintf(sizeof(zBuf), zBuf, pCheck->zPfx, pCheck->v1, pCheck->v2); + sqlite3StrAccumAppendAll(&pCheck->errMsg, zBuf); + } + sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap); + va_end(ap); + if( pCheck->errMsg.accError==STRACCUM_NOMEM ){ + pCheck->mallocFailed = 1; + } +} +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +#ifndef SQLITE_OMIT_INTEGRITY_CHECK + +/* +** Return non-zero if the bit in the IntegrityCk.aPgRef[] array that +** corresponds to page iPg is already set. +*/ +static int getPageReferenced(IntegrityCk *pCheck, Pgno iPg){ + assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 ); + return (pCheck->aPgRef[iPg/8] & (1 << (iPg & 0x07))); +} + +/* +** Set the bit in the IntegrityCk.aPgRef[] array that corresponds to page iPg. +*/ +static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){ + assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 ); + pCheck->aPgRef[iPg/8] |= (1 << (iPg & 0x07)); +} + + +/* +** Add 1 to the reference count for page iPage. If this is the second +** reference to the page, add an error message to pCheck->zErrMsg. +** Return 1 if there are 2 or more references to the page and 0 if +** if this is the first reference to the page. +** +** Also check that the page number is in bounds. +*/ +static int checkRef(IntegrityCk *pCheck, Pgno iPage){ + if( iPage==0 ) return 1; + if( iPage>pCheck->nPage ){ + checkAppendMsg(pCheck, "invalid page number %d", iPage); + return 1; + } + if( getPageReferenced(pCheck, iPage) ){ + checkAppendMsg(pCheck, "2nd reference to page %d", iPage); + return 1; + } + setPageReferenced(pCheck, iPage); + return 0; +} + +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** Check that the entry in the pointer-map for page iChild maps to +** page iParent, pointer type ptrType. If not, append an error message +** to pCheck. +*/ +static void checkPtrmap( + IntegrityCk *pCheck, /* Integrity check context */ + Pgno iChild, /* Child page number */ + u8 eType, /* Expected pointer map type */ + Pgno iParent /* Expected pointer map parent page number */ +){ + int rc; + u8 ePtrmapType; + Pgno iPtrmapParent; + + rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) pCheck->mallocFailed = 1; + checkAppendMsg(pCheck, "Failed to read ptrmap key=%d", iChild); + return; + } + + if( ePtrmapType!=eType || iPtrmapParent!=iParent ){ + checkAppendMsg(pCheck, + "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)", + iChild, eType, iParent, ePtrmapType, iPtrmapParent); + } +} +#endif + +/* +** Check the integrity of the freelist or of an overflow page list. +** Verify that the number of pages on the list is N. +*/ +static void checkList( + IntegrityCk *pCheck, /* Integrity checking context */ + int isFreeList, /* True for a freelist. False for overflow page list */ + int iPage, /* Page number for first page in the list */ + int N /* Expected number of pages in the list */ +){ + int i; + int expected = N; + int iFirst = iPage; + while( N-- > 0 && pCheck->mxErr ){ + DbPage *pOvflPage; + unsigned char *pOvflData; + if( iPage<1 ){ + checkAppendMsg(pCheck, + "%d of %d pages missing from overflow list starting at %d", + N+1, expected, iFirst); + break; + } + if( checkRef(pCheck, iPage) ) break; + if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage) ){ + checkAppendMsg(pCheck, "failed to get page %d", iPage); + break; + } + pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage); + if( isFreeList ){ + int n = get4byte(&pOvflData[4]); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pCheck->pBt->autoVacuum ){ + checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0); + } +#endif + if( n>(int)pCheck->pBt->usableSize/4-2 ){ + checkAppendMsg(pCheck, + "freelist leaf count too big on page %d", iPage); + N--; + }else{ + for(i=0; ipBt->autoVacuum ){ + checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0); + } +#endif + checkRef(pCheck, iFreePage); + } + N -= n; + } + } +#ifndef SQLITE_OMIT_AUTOVACUUM + else{ + /* If this database supports auto-vacuum and iPage is not the last + ** page in this overflow list, check that the pointer-map entry for + ** the following page matches iPage. + */ + if( pCheck->pBt->autoVacuum && N>0 ){ + i = get4byte(pOvflData); + checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage); + } + } +#endif + iPage = get4byte(pOvflData); + sqlite3PagerUnref(pOvflPage); + } +} +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +/* +** An implementation of a min-heap. +** +** aHeap[0] is the number of elements on the heap. aHeap[1] is the +** root element. The daughter nodes of aHeap[N] are aHeap[N*2] +** and aHeap[N*2+1]. +** +** The heap property is this: Every node is less than or equal to both +** of its daughter nodes. A consequence of the heap property is that the +** root node aHeap[1] is always the minimum value currently in the heap. +** +** The btreeHeapInsert() routine inserts an unsigned 32-bit number onto +** the heap, preserving the heap property. The btreeHeapPull() routine +** removes the root element from the heap (the minimum value in the heap) +** and then moves other nodes around as necessary to preserve the heap +** property. +** +** This heap is used for cell overlap and coverage testing. Each u32 +** entry represents the span of a cell or freeblock on a btree page. +** The upper 16 bits are the index of the first byte of a range and the +** lower 16 bits are the index of the last byte of that range. +*/ +static void btreeHeapInsert(u32 *aHeap, u32 x){ + u32 j, i = ++aHeap[0]; + aHeap[i] = x; + while( (j = i/2)>0 && aHeap[j]>aHeap[i] ){ + x = aHeap[j]; + aHeap[j] = aHeap[i]; + aHeap[i] = x; + i = j; + } +} +static int btreeHeapPull(u32 *aHeap, u32 *pOut){ + u32 j, i, x; + if( (x = aHeap[0])==0 ) return 0; + *pOut = aHeap[1]; + aHeap[1] = aHeap[x]; + aHeap[x] = 0xffffffff; + aHeap[0]--; + i = 1; + while( (j = i*2)<=aHeap[0] ){ + if( aHeap[j]>aHeap[j+1] ) j++; + if( aHeap[i]zPfx; + int saved_v1 = pCheck->v1; + int saved_v2 = pCheck->v2; + + /* Check that the page exists + */ + pBt = pCheck->pBt; + usableSize = pBt->usableSize; + if( iPage==0 ) return 0; + if( checkRef(pCheck, iPage) ) return 0; + pCheck->zPfx = "Page %d: "; + pCheck->v1 = iPage; + if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){ + checkAppendMsg(pCheck, + "unable to get the page. error code=%d", rc); + depth = -1; + goto end_of_check; + } + + /* Clear MemPage.isInit to make sure the corruption detection code in + ** btreeInitPage() is executed. */ + pPage->isInit = 0; + if( (rc = btreeInitPage(pPage))!=0 ){ + assert( rc==SQLITE_CORRUPT ); /* The only possible error from InitPage */ + checkAppendMsg(pCheck, + "btreeInitPage() returns error code %d", rc); + releasePage(pPage); + depth = -1; + goto end_of_check; + } + + /* Check out all the cells. + */ + depth = 0; + for(i=0; inCell && pCheck->mxErr; i++){ + u8 *pCell; + u32 sz; + CellInfo info; + + /* Check payload overflow pages + */ + pCheck->zPfx = "On tree page %d cell %d: "; + pCheck->v1 = iPage; + pCheck->v2 = i; + pCell = findCell(pPage,i); + btreeParseCellPtr(pPage, pCell, &info); + sz = info.nPayload; + /* For intKey pages, check that the keys are in order. + */ + if( pPage->intKey ){ + if( i==0 ){ + nMinKey = nMaxKey = info.nKey; + }else if( info.nKey <= nMaxKey ){ + checkAppendMsg(pCheck, + "Rowid %lld out of order (previous was %lld)", info.nKey, nMaxKey); + } + nMaxKey = info.nKey; + } + if( (sz>info.nLocal) + && (&pCell[info.iOverflow]<=&pPage->aData[pBt->usableSize]) + ){ + int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4); + Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage); + } +#endif + checkList(pCheck, 0, pgnoOvfl, nPage); + } + + /* Check sanity of left child page. + */ + if( !pPage->leaf ){ + pgno = get4byte(pCell); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage); + } +#endif + d2 = checkTreePage(pCheck, pgno, &nMinKey, i==0?NULL:&nMaxKey); + if( i>0 && d2!=depth ){ + checkAppendMsg(pCheck, "Child page depth differs"); + } + depth = d2; + } + } + + if( !pPage->leaf ){ + pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); + pCheck->zPfx = "On page %d at right child: "; + pCheck->v1 = iPage; +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage); + } +#endif + checkTreePage(pCheck, pgno, NULL, !pPage->nCell?NULL:&nMaxKey); + } + + /* For intKey leaf pages, check that the min/max keys are in order + ** with any left/parent/right pages. + */ + pCheck->zPfx = "Page %d: "; + pCheck->v1 = iPage; + if( pPage->leaf && pPage->intKey ){ + /* if we are a left child page */ + if( pnParentMinKey ){ + /* if we are the left most child page */ + if( !pnParentMaxKey ){ + if( nMaxKey > *pnParentMinKey ){ + checkAppendMsg(pCheck, + "Rowid %lld out of order (max larger than parent min of %lld)", + nMaxKey, *pnParentMinKey); + } + }else{ + if( nMinKey <= *pnParentMinKey ){ + checkAppendMsg(pCheck, + "Rowid %lld out of order (min less than parent min of %lld)", + nMinKey, *pnParentMinKey); + } + if( nMaxKey > *pnParentMaxKey ){ + checkAppendMsg(pCheck, + "Rowid %lld out of order (max larger than parent max of %lld)", + nMaxKey, *pnParentMaxKey); + } + *pnParentMinKey = nMaxKey; + } + /* else if we're a right child page */ + } else if( pnParentMaxKey ){ + if( nMinKey <= *pnParentMaxKey ){ + checkAppendMsg(pCheck, + "Rowid %lld out of order (min less than parent max of %lld)", + nMinKey, *pnParentMaxKey); + } + } + } + + /* Check for complete coverage of the page + */ + data = pPage->aData; + hdr = pPage->hdrOffset; + heap = (u32*)sqlite3PageMalloc( pBt->pageSize ); + pCheck->zPfx = 0; + if( heap==0 ){ + pCheck->mallocFailed = 1; + }else{ + int contentOffset = get2byteNotZero(&data[hdr+5]); + assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */ + heap[0] = 0; + btreeHeapInsert(heap, contentOffset-1); + /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the + ** number of cells on the page. */ + nCell = get2byte(&data[hdr+3]); + /* EVIDENCE-OF: R-23882-45353 The cell pointer array of a b-tree page + ** immediately follows the b-tree page header. */ + cellStart = hdr + 12 - 4*pPage->leaf; + /* EVIDENCE-OF: R-02776-14802 The cell pointer array consists of K 2-byte + ** integer offsets to the cell contents. */ + for(i=0; i=usableSize ){ + pCheck->zPfx = 0; + checkAppendMsg(pCheck, + "Corruption detected in cell %d on page %d",i,iPage); + }else{ + btreeHeapInsert(heap, (pc<<16)|(pc+size-1)); + } + } + /* EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header + ** is the offset of the first freeblock, or zero if there are no + ** freeblocks on the page. */ + i = get2byte(&data[hdr+1]); + while( i>0 ){ + int size, j; + assert( i<=usableSize-4 ); /* Enforced by btreeInitPage() */ + size = get2byte(&data[i+2]); + assert( i+size<=usableSize ); /* Enforced by btreeInitPage() */ + btreeHeapInsert(heap, (i<<16)|(i+size-1)); + /* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a + ** big-endian integer which is the offset in the b-tree page of the next + ** freeblock in the chain, or zero if the freeblock is the last on the + ** chain. */ + j = get2byte(&data[i]); + /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of + ** increasing offset. */ + assert( j==0 || j>i+size ); /* Enforced by btreeInitPage() */ + assert( j<=usableSize-4 ); /* Enforced by btreeInitPage() */ + i = j; + } + cnt = 0; + assert( heap[0]>0 ); + assert( (heap[1]>>16)==0 ); + btreeHeapPull(heap,&prev); + while( btreeHeapPull(heap,&x) ){ + if( (prev&0xffff)+1>(x>>16) ){ + checkAppendMsg(pCheck, + "Multiple uses for byte %u of page %d", x>>16, iPage); + break; + }else{ + cnt += (x>>16) - (prev&0xffff) - 1; + prev = x; + } + } + cnt += usableSize - (prev&0xffff) - 1; + /* EVIDENCE-OF: R-43263-13491 The total number of bytes in all fragments + ** is stored in the fifth field of the b-tree page header. + ** EVIDENCE-OF: R-07161-27322 The one-byte integer at offset 7 gives the + ** number of fragmented free bytes within the cell content area. + */ + if( heap[0]==0 && cnt!=data[hdr+7] ){ + checkAppendMsg(pCheck, + "Fragmentation of %d bytes reported as %d on page %d", + cnt, data[hdr+7], iPage); + } + } + sqlite3PageFree(heap); + releasePage(pPage); + +end_of_check: + pCheck->zPfx = saved_zPfx; + pCheck->v1 = saved_v1; + pCheck->v2 = saved_v2; + return depth+1; +} +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +#ifndef SQLITE_OMIT_INTEGRITY_CHECK +/* +** This routine does a complete check of the given BTree file. aRoot[] is +** an array of pages numbers were each page number is the root page of +** a table. nRoot is the number of entries in aRoot. +** +** A read-only or read-write transaction must be opened before calling +** this function. +** +** Write the number of error seen in *pnErr. Except for some memory +** allocation errors, an error message held in memory obtained from +** malloc is returned if *pnErr is non-zero. If *pnErr==0 then NULL is +** returned. If a memory allocation error occurs, NULL is returned. +*/ +SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( + Btree *p, /* The btree to be checked */ + int *aRoot, /* An array of root pages numbers for individual trees */ + int nRoot, /* Number of entries in aRoot[] */ + int mxErr, /* Stop reporting errors after this many */ + int *pnErr /* Write number of errors seen to this variable */ +){ + Pgno i; + int nRef; + IntegrityCk sCheck; + BtShared *pBt = p->pBt; + char zErr[100]; + + sqlite3BtreeEnter(p); + assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE ); + nRef = sqlite3PagerRefcount(pBt->pPager); + sCheck.pBt = pBt; + sCheck.pPager = pBt->pPager; + sCheck.nPage = btreePagecount(sCheck.pBt); + sCheck.mxErr = mxErr; + sCheck.nErr = 0; + sCheck.mallocFailed = 0; + sCheck.zPfx = 0; + sCheck.v1 = 0; + sCheck.v2 = 0; + *pnErr = 0; + if( sCheck.nPage==0 ){ + sqlite3BtreeLeave(p); + return 0; + } + + sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1); + if( !sCheck.aPgRef ){ + *pnErr = 1; + sqlite3BtreeLeave(p); + return 0; + } + i = PENDING_BYTE_PAGE(pBt); + if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i); + sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH); + + /* Check the integrity of the freelist + */ + sCheck.zPfx = "Main freelist: "; + checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]), + get4byte(&pBt->pPage1->aData[36])); + sCheck.zPfx = 0; + + /* Check all the tables. + */ + for(i=0; (int)iautoVacuum && aRoot[i]>1 ){ + checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0); + } +#endif + sCheck.zPfx = "List of tree roots: "; + checkTreePage(&sCheck, aRoot[i], NULL, NULL); + sCheck.zPfx = 0; + } + + /* Make sure every page in the file is referenced + */ + for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){ +#ifdef SQLITE_OMIT_AUTOVACUUM + if( getPageReferenced(&sCheck, i)==0 ){ + checkAppendMsg(&sCheck, "Page %d is never used", i); + } +#else + /* If the database supports auto-vacuum, make sure no tables contain + ** references to pointer-map pages. + */ + if( getPageReferenced(&sCheck, i)==0 && + (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){ + checkAppendMsg(&sCheck, "Page %d is never used", i); + } + if( getPageReferenced(&sCheck, i)!=0 && + (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){ + checkAppendMsg(&sCheck, "Pointer map page %d is referenced", i); + } +#endif + } + + /* Make sure this analysis did not leave any unref() pages. + ** This is an internal consistency check; an integrity check + ** of the integrity check. + */ + if( NEVER(nRef != sqlite3PagerRefcount(pBt->pPager)) ){ + checkAppendMsg(&sCheck, + "Outstanding page count goes from %d to %d during this analysis", + nRef, sqlite3PagerRefcount(pBt->pPager) + ); + } + + /* Clean up and report errors. + */ + sqlite3BtreeLeave(p); + sqlite3_free(sCheck.aPgRef); + if( sCheck.mallocFailed ){ + sqlite3StrAccumReset(&sCheck.errMsg); + *pnErr = sCheck.nErr+1; + return 0; + } + *pnErr = sCheck.nErr; + if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg); + return sqlite3StrAccumFinish(&sCheck.errMsg); +} +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +/* +** Return the full pathname of the underlying database file. Return +** an empty string if the database is in-memory or a TEMP database. +** +** The pager filename is invariant as long as the pager is +** open so it is safe to access without the BtShared mutex. +*/ +SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *p){ + assert( p->pBt->pPager!=0 ); + return sqlite3PagerFilename(p->pBt->pPager, 1); +} + +/* +** 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. +** +** The pager journal filename is invariant as long as the pager is +** open so it is safe to access without the BtShared mutex. +*/ +SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *p){ + assert( p->pBt->pPager!=0 ); + return sqlite3PagerJournalname(p->pBt->pPager); +} + +/* +** Return non-zero if a transaction is active. +*/ +SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree *p){ + assert( p==0 || sqlite3_mutex_held(p->db->mutex) ); + return (p && (p->inTrans==TRANS_WRITE)); +} + +#ifndef SQLITE_OMIT_WAL +/* +** Run a checkpoint on the Btree passed as the first argument. +** +** Return SQLITE_LOCKED if this or any other connection has an open +** transaction on the shared-cache the argument Btree is connected to. +** +** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. +*/ +SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree *p, int eMode, int *pnLog, int *pnCkpt){ + int rc = SQLITE_OK; + if( p ){ + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); + if( pBt->inTransaction!=TRANS_NONE ){ + rc = SQLITE_LOCKED; + }else{ + rc = sqlite3PagerCheckpoint(pBt->pPager, eMode, pnLog, pnCkpt); + } + sqlite3BtreeLeave(p); + } + return rc; +} +#endif + +/* +** Return non-zero if a read (or write) transaction is active. +*/ +SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree *p){ + assert( p ); + assert( sqlite3_mutex_held(p->db->mutex) ); + return p->inTrans!=TRANS_NONE; +} + +SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree *p){ + assert( p ); + assert( sqlite3_mutex_held(p->db->mutex) ); + return p->nBackup!=0; +} + +/* +** This function returns a pointer to a blob of memory associated with +** a single shared-btree. The memory is used by client code for its 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. +** +** If the nBytes parameter is 0 and the blob of memory has not yet been +** allocated, a null pointer is returned. If the blob has already been +** allocated, it is returned as normal. +** +** 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. The xFree function should not call sqlite3_free() +** on the memory, the btree layer does that. +*/ +SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){ + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); + if( !pBt->pSchema && nBytes ){ + pBt->pSchema = sqlite3DbMallocZero(0, nBytes); + pBt->xFreeSchema = xFree; + } + sqlite3BtreeLeave(p); + return pBt->pSchema; +} + +/* +** Return SQLITE_LOCKED_SHAREDCACHE if another user of the same shared +** btree as the argument handle holds an exclusive lock on the +** sqlite_master table. Otherwise SQLITE_OK. +*/ +SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *p){ + int rc; + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK); + assert( rc==SQLITE_OK || rc==SQLITE_LOCKED_SHAREDCACHE ); + sqlite3BtreeLeave(p); + return rc; +} + + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** Obtain a lock on the table whose root page is iTab. The +** lock is a write lock if isWritelock is true or a read lock +** if it is false. +*/ +SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){ + int rc = SQLITE_OK; + assert( p->inTrans!=TRANS_NONE ); + if( p->sharable ){ + u8 lockType = READ_LOCK + isWriteLock; + assert( READ_LOCK+1==WRITE_LOCK ); + assert( isWriteLock==0 || isWriteLock==1 ); + + sqlite3BtreeEnter(p); + rc = querySharedCacheTableLock(p, iTab, lockType); + if( rc==SQLITE_OK ){ + rc = setSharedCacheTableLock(p, iTab, lockType); + } + sqlite3BtreeLeave(p); + } + return rc; +} +#endif + +#ifndef SQLITE_OMIT_INCRBLOB +/* +** Argument pCsr must be a cursor opened for writing on an +** INTKEY table currently pointing at a valid table entry. +** This function modifies the data stored as part of that entry. +** +** Only the data content may only be modified, it is not possible to +** change the length of the data stored. If this function is called with +** parameters that attempt to write past the end of the existing data, +** no modifications are made and SQLITE_CORRUPT is returned. +*/ +SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){ + int rc; + assert( cursorHoldsMutex(pCsr) ); + assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) ); + assert( pCsr->curFlags & BTCF_Incrblob ); + + rc = restoreCursorPosition(pCsr); + if( rc!=SQLITE_OK ){ + return rc; + } + assert( pCsr->eState!=CURSOR_REQUIRESEEK ); + if( pCsr->eState!=CURSOR_VALID ){ + return SQLITE_ABORT; + } + + /* Save the positions of all other cursors open on this table. This is + ** required in case any of them are holding references to an xFetch + ** version of the b-tree page modified by the accessPayload call below. + ** + ** Note that pCsr must be open on a INTKEY table and saveCursorPosition() + ** and hence saveAllCursors() cannot fail on a BTREE_INTKEY table, hence + ** saveAllCursors can only return SQLITE_OK. + */ + VVA_ONLY(rc =) saveAllCursors(pCsr->pBt, pCsr->pgnoRoot, pCsr); + assert( rc==SQLITE_OK ); + + /* Check some assumptions: + ** (a) the cursor is open for writing, + ** (b) there is a read/write transaction open, + ** (c) the connection holds a write-lock on the table (if required), + ** (d) there are no conflicting read-locks, and + ** (e) the cursor points at a valid row of an intKey table. + */ + if( (pCsr->curFlags & BTCF_WriteFlag)==0 ){ + return SQLITE_READONLY; + } + assert( (pCsr->pBt->btsFlags & BTS_READ_ONLY)==0 + && pCsr->pBt->inTransaction==TRANS_WRITE ); + assert( hasSharedCacheTableLock(pCsr->pBtree, pCsr->pgnoRoot, 0, 2) ); + assert( !hasReadConflicts(pCsr->pBtree, pCsr->pgnoRoot) ); + assert( pCsr->apPage[pCsr->iPage]->intKey ); + + return accessPayload(pCsr, offset, amt, (unsigned char *)z, 1); +} + +/* +** Mark this cursor as an incremental blob cursor. +*/ +SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *pCur){ + pCur->curFlags |= BTCF_Incrblob; +} +#endif + +/* +** Set both the "read version" (single byte at byte offset 18) and +** "write version" (single byte at byte offset 19) fields in the database +** header to iVersion. +*/ +SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){ + BtShared *pBt = pBtree->pBt; + int rc; /* Return code */ + + assert( iVersion==1 || iVersion==2 ); + + /* If setting the version fields to 1, do not automatically open the + ** WAL connection, even if the version fields are currently set to 2. + */ + pBt->btsFlags &= ~BTS_NO_WAL; + if( iVersion==1 ) pBt->btsFlags |= BTS_NO_WAL; + + rc = sqlite3BtreeBeginTrans(pBtree, 0); + if( rc==SQLITE_OK ){ + u8 *aData = pBt->pPage1->aData; + if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){ + rc = sqlite3BtreeBeginTrans(pBtree, 2); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + if( rc==SQLITE_OK ){ + aData[18] = (u8)iVersion; + aData[19] = (u8)iVersion; + } + } + } + } + + pBt->btsFlags &= ~BTS_NO_WAL; + return rc; +} + +/* +** set the mask of hint flags for cursor pCsr. +*/ +SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){ + assert( mask==BTREE_BULKLOAD || mask==BTREE_SEEK_EQ || mask==0 ); + pCsr->hints = mask; +} + +#ifdef SQLITE_DEBUG +/* +** Return true if the cursor has a hint specified. This routine is +** only used from within assert() statements +*/ +SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor *pCsr, unsigned int mask){ + return (pCsr->hints & mask)!=0; +} +#endif + +/* +** Return true if the given Btree is read-only. +*/ +SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *p){ + return (p->pBt->btsFlags & BTS_READ_ONLY)!=0; +} + +/* +** Return the size of the header added to each page by this module. +*/ +SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); } + +/************** End of btree.c ***********************************************/ +/************** Begin file backup.c ******************************************/ +/* +** 2009 January 28 +** +** 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_backup_XXX() +** API functions and the related features. +*/ + +/* +** Structure allocated for each backup operation. +*/ +struct sqlite3_backup { + sqlite3* pDestDb; /* Destination database handle */ + Btree *pDest; /* Destination b-tree file */ + u32 iDestSchema; /* Original schema cookie in destination */ + int bDestLocked; /* True once a write-transaction is open on pDest */ + + Pgno iNext; /* Page number of the next source page to copy */ + sqlite3* pSrcDb; /* Source database handle */ + Btree *pSrc; /* Source b-tree file */ + + int rc; /* Backup process error code */ + + /* These two variables are set by every call to backup_step(). They are + ** read by calls to backup_remaining() and backup_pagecount(). + */ + Pgno nRemaining; /* Number of pages left to copy */ + Pgno nPagecount; /* Total number of pages to copy */ + + int isAttached; /* True once backup has been registered with pager */ + sqlite3_backup *pNext; /* Next backup associated with source pager */ +}; + +/* +** THREAD SAFETY NOTES: +** +** Once it has been created using backup_init(), a single sqlite3_backup +** structure may be accessed via two groups of thread-safe entry points: +** +** * Via the sqlite3_backup_XXX() API function backup_step() and +** backup_finish(). Both these functions obtain the source database +** handle mutex and the mutex associated with the source BtShared +** structure, in that order. +** +** * Via the BackupUpdate() and BackupRestart() functions, which are +** invoked by the pager layer to report various state changes in +** the page cache associated with the source database. The mutex +** associated with the source database BtShared structure will always +** be held when either of these functions are invoked. +** +** The other sqlite3_backup_XXX() API functions, backup_remaining() and +** backup_pagecount() are not thread-safe functions. If they are called +** while some other thread is calling backup_step() or backup_finish(), +** the values returned may be invalid. There is no way for a call to +** BackupUpdate() or BackupRestart() to interfere with backup_remaining() +** or backup_pagecount(). +** +** Depending on the SQLite configuration, the database handles and/or +** the Btree objects may have their own mutexes that require locking. +** Non-sharable Btrees (in-memory databases for example), do not have +** associated mutexes. +*/ + +/* +** Return a pointer corresponding to database zDb (i.e. "main", "temp") +** in connection handle pDb. If such a database cannot be found, return +** a NULL pointer and write an error message to pErrorDb. +** +** If the "temp" database is requested, it may need to be opened by this +** function. If an error occurs while doing so, return 0 and write an +** error message to pErrorDb. +*/ +static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){ + int i = sqlite3FindDbName(pDb, zDb); + + if( i==1 ){ + Parse *pParse; + int rc = 0; + pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse)); + if( pParse==0 ){ + sqlite3ErrorWithMsg(pErrorDb, SQLITE_NOMEM, "out of memory"); + rc = SQLITE_NOMEM; + }else{ + pParse->db = pDb; + if( sqlite3OpenTempDatabase(pParse) ){ + sqlite3ErrorWithMsg(pErrorDb, pParse->rc, "%s", pParse->zErrMsg); + rc = SQLITE_ERROR; + } + sqlite3DbFree(pErrorDb, pParse->zErrMsg); + sqlite3ParserReset(pParse); + sqlite3StackFree(pErrorDb, pParse); + } + if( rc ){ + return 0; + } + } + + if( i<0 ){ + sqlite3ErrorWithMsg(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb); + return 0; + } + + return pDb->aDb[i].pBt; +} + +/* +** Attempt to set the page size of the destination to match the page size +** of the source. +*/ +static int setDestPgsz(sqlite3_backup *p){ + int rc; + rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),-1,0); + return rc; +} + +/* +** Check that there is no open read-transaction on the b-tree passed as the +** second argument. If there is not, return SQLITE_OK. Otherwise, if there +** is an open read-transaction, return SQLITE_ERROR and leave an error +** message in database handle db. +*/ +static int checkReadTransaction(sqlite3 *db, Btree *p){ + if( sqlite3BtreeIsInReadTrans(p) ){ + sqlite3ErrorWithMsg(db, SQLITE_ERROR, "destination database is in use"); + return SQLITE_ERROR; + } + return SQLITE_OK; +} + +/* +** Create an sqlite3_backup process to copy the contents of zSrcDb from +** connection handle pSrcDb to zDestDb in pDestDb. If successful, return +** a pointer to the new sqlite3_backup object. +** +** If an error occurs, NULL is returned and an error code and error message +** stored in database handle pDestDb. +*/ +SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init( + sqlite3* pDestDb, /* Database to write to */ + const char *zDestDb, /* Name of database within pDestDb */ + sqlite3* pSrcDb, /* Database connection to read from */ + const char *zSrcDb /* Name of database within pSrcDb */ +){ + sqlite3_backup *p; /* Value to return */ + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(pSrcDb)||!sqlite3SafetyCheckOk(pDestDb) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + + /* Lock the source database handle. The destination database + ** handle is not locked in this routine, but it is locked in + ** sqlite3_backup_step(). The user is required to ensure that no + ** other thread accesses the destination handle for the duration + ** of the backup operation. Any attempt to use the destination + ** database connection while a backup is in progress may cause + ** a malfunction or a deadlock. + */ + sqlite3_mutex_enter(pSrcDb->mutex); + sqlite3_mutex_enter(pDestDb->mutex); + + if( pSrcDb==pDestDb ){ + sqlite3ErrorWithMsg( + pDestDb, SQLITE_ERROR, "source and destination must be distinct" + ); + p = 0; + }else { + /* Allocate space for a new sqlite3_backup object... + ** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a + ** call to sqlite3_backup_init() and is destroyed by a call to + ** sqlite3_backup_finish(). */ + p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup)); + if( !p ){ + sqlite3Error(pDestDb, SQLITE_NOMEM); + } + } + + /* If the allocation succeeded, populate the new object. */ + if( p ){ + p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb); + p->pDest = findBtree(pDestDb, pDestDb, zDestDb); + p->pDestDb = pDestDb; + p->pSrcDb = pSrcDb; + p->iNext = 1; + p->isAttached = 0; + + if( 0==p->pSrc || 0==p->pDest + || setDestPgsz(p)==SQLITE_NOMEM + || checkReadTransaction(pDestDb, p->pDest)!=SQLITE_OK + ){ + /* One (or both) of the named databases did not exist or an OOM + ** error was hit. Or there is a transaction open on the destination + ** database. The error has already been written into the pDestDb + ** handle. All that is left to do here is free the sqlite3_backup + ** structure. */ + sqlite3_free(p); + p = 0; + } + } + if( p ){ + p->pSrc->nBackup++; + } + + sqlite3_mutex_leave(pDestDb->mutex); + sqlite3_mutex_leave(pSrcDb->mutex); + return p; +} + +/* +** Argument rc is an SQLite error code. Return true if this error is +** considered fatal if encountered during a backup operation. All errors +** are considered fatal except for SQLITE_BUSY and SQLITE_LOCKED. +*/ +static int isFatalError(int rc){ + return (rc!=SQLITE_OK && rc!=SQLITE_BUSY && ALWAYS(rc!=SQLITE_LOCKED)); +} + +/* +** Parameter zSrcData points to a buffer containing the data for +** page iSrcPg from the source database. Copy this data into the +** destination database. +*/ +static int backupOnePage( + sqlite3_backup *p, /* Backup handle */ + Pgno iSrcPg, /* Source database page to backup */ + const u8 *zSrcData, /* Source database page data */ + int bUpdate /* True for an update, false otherwise */ +){ + Pager * const pDestPager = sqlite3BtreePager(p->pDest); + const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc); + int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest); + const int nCopy = MIN(nSrcPgsz, nDestPgsz); + const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz; +#ifdef SQLITE_HAS_CODEC + /* Use BtreeGetReserveNoMutex() for the source b-tree, as although it is + ** guaranteed that the shared-mutex is held by this thread, handle + ** p->pSrc may not actually be the owner. */ + int nSrcReserve = sqlite3BtreeGetReserveNoMutex(p->pSrc); + int nDestReserve = sqlite3BtreeGetOptimalReserve(p->pDest); +#endif + int rc = SQLITE_OK; + i64 iOff; + + assert( sqlite3BtreeGetReserveNoMutex(p->pSrc)>=0 ); + assert( p->bDestLocked ); + assert( !isFatalError(p->rc) ); + assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ); + assert( zSrcData ); + + /* Catch the case where the destination is an in-memory database and the + ** page sizes of the source and destination differ. + */ + if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(pDestPager) ){ + rc = SQLITE_READONLY; + } + +#ifdef SQLITE_HAS_CODEC + /* Backup is not possible if the page size of the destination is changing + ** and a codec is in use. + */ + if( nSrcPgsz!=nDestPgsz && sqlite3PagerGetCodec(pDestPager)!=0 ){ + rc = SQLITE_READONLY; + } + + /* Backup is not possible if the number of bytes of reserve space differ + ** between source and destination. If there is a difference, try to + ** fix the destination to agree with the source. If that is not possible, + ** then the backup cannot proceed. + */ + if( nSrcReserve!=nDestReserve ){ + u32 newPgsz = nSrcPgsz; + rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve); + if( rc==SQLITE_OK && newPgsz!=nSrcPgsz ) rc = SQLITE_READONLY; + } +#endif + + /* This loop runs once for each destination page spanned by the source + ** page. For each iteration, variable iOff is set to the byte offset + ** of the destination page. + */ + for(iOff=iEnd-(i64)nSrcPgsz; rc==SQLITE_OK && iOffpDest->pBt) ) continue; + if( SQLITE_OK==(rc = sqlite3PagerGet(pDestPager, iDest, &pDestPg)) + && SQLITE_OK==(rc = sqlite3PagerWrite(pDestPg)) + ){ + const u8 *zIn = &zSrcData[iOff%nSrcPgsz]; + u8 *zDestData = sqlite3PagerGetData(pDestPg); + u8 *zOut = &zDestData[iOff%nDestPgsz]; + + /* Copy the data from the source page into the destination page. + ** Then clear the Btree layer MemPage.isInit flag. Both this module + ** and the pager code use this trick (clearing the first byte + ** of the page 'extra' space to invalidate the Btree layers + ** cached parse of the page). MemPage.isInit is marked + ** "MUST BE FIRST" for this purpose. + */ + memcpy(zOut, zIn, nCopy); + ((u8 *)sqlite3PagerGetExtra(pDestPg))[0] = 0; + if( iOff==0 && bUpdate==0 ){ + sqlite3Put4byte(&zOut[28], sqlite3BtreeLastPage(p->pSrc)); + } + } + sqlite3PagerUnref(pDestPg); + } + + return rc; +} + +/* +** If pFile is currently larger than iSize bytes, then truncate it to +** exactly iSize bytes. If pFile is not larger than iSize bytes, then +** this function is a no-op. +** +** Return SQLITE_OK if everything is successful, or an SQLite error +** code if an error occurs. +*/ +static int backupTruncateFile(sqlite3_file *pFile, i64 iSize){ + i64 iCurrent; + int rc = sqlite3OsFileSize(pFile, &iCurrent); + if( rc==SQLITE_OK && iCurrent>iSize ){ + rc = sqlite3OsTruncate(pFile, iSize); + } + return rc; +} + +/* +** Register this backup object with the associated source pager for +** callbacks when pages are changed or the cache invalidated. +*/ +static void attachBackupObject(sqlite3_backup *p){ + sqlite3_backup **pp; + assert( sqlite3BtreeHoldsMutex(p->pSrc) ); + pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc)); + p->pNext = *pp; + *pp = p; + p->isAttached = 1; +} + +/* +** Copy nPage pages from the source b-tree to the destination. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage){ + int rc; + int destMode; /* Destination journal mode */ + int pgszSrc = 0; /* Source page size */ + int pgszDest = 0; /* Destination page size */ + +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(p->pSrcDb->mutex); + sqlite3BtreeEnter(p->pSrc); + if( p->pDestDb ){ + sqlite3_mutex_enter(p->pDestDb->mutex); + } + + rc = p->rc; + if( !isFatalError(rc) ){ + Pager * const pSrcPager = sqlite3BtreePager(p->pSrc); /* Source pager */ + Pager * const pDestPager = sqlite3BtreePager(p->pDest); /* Dest pager */ + int ii; /* Iterator variable */ + int nSrcPage = -1; /* Size of source db in pages */ + int bCloseTrans = 0; /* True if src db requires unlocking */ + + /* If the source pager is currently in a write-transaction, return + ** SQLITE_BUSY immediately. + */ + if( p->pDestDb && p->pSrc->pBt->inTransaction==TRANS_WRITE ){ + rc = SQLITE_BUSY; + }else{ + rc = SQLITE_OK; + } + + /* Lock the destination database, if it is not locked already. */ + if( SQLITE_OK==rc && p->bDestLocked==0 + && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2)) + ){ + p->bDestLocked = 1; + sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema); + } + + /* If there is no open read-transaction on the source database, open + ** one now. If a transaction is opened here, then it will be closed + ** before this function exits. + */ + if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){ + rc = sqlite3BtreeBeginTrans(p->pSrc, 0); + bCloseTrans = 1; + } + + /* Do not allow backup if the destination database is in WAL mode + ** and the page sizes are different between source and destination */ + pgszSrc = sqlite3BtreeGetPageSize(p->pSrc); + pgszDest = sqlite3BtreeGetPageSize(p->pDest); + destMode = sqlite3PagerGetJournalMode(sqlite3BtreePager(p->pDest)); + if( SQLITE_OK==rc && destMode==PAGER_JOURNALMODE_WAL && pgszSrc!=pgszDest ){ + rc = SQLITE_READONLY; + } + + /* Now that there is a read-lock on the source database, query the + ** source pager for the number of pages in the database. + */ + nSrcPage = (int)sqlite3BtreeLastPage(p->pSrc); + assert( nSrcPage>=0 ); + for(ii=0; (nPage<0 || iiiNext<=(Pgno)nSrcPage && !rc; ii++){ + const Pgno iSrcPg = p->iNext; /* Source page number */ + if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){ + DbPage *pSrcPg; /* Source page object */ + rc = sqlite3PagerAcquire(pSrcPager, iSrcPg, &pSrcPg, + PAGER_GET_READONLY); + if( rc==SQLITE_OK ){ + rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0); + sqlite3PagerUnref(pSrcPg); + } + } + p->iNext++; + } + if( rc==SQLITE_OK ){ + p->nPagecount = nSrcPage; + p->nRemaining = nSrcPage+1-p->iNext; + if( p->iNext>(Pgno)nSrcPage ){ + rc = SQLITE_DONE; + }else if( !p->isAttached ){ + attachBackupObject(p); + } + } + + /* Update the schema version field in the destination database. This + ** is to make sure that the schema-version really does change in + ** the case where the source and destination databases have the + ** same schema version. + */ + if( rc==SQLITE_DONE ){ + if( nSrcPage==0 ){ + rc = sqlite3BtreeNewDb(p->pDest); + nSrcPage = 1; + } + if( rc==SQLITE_OK || rc==SQLITE_DONE ){ + rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1); + } + if( rc==SQLITE_OK ){ + if( p->pDestDb ){ + sqlite3ResetAllSchemasOfConnection(p->pDestDb); + } + if( destMode==PAGER_JOURNALMODE_WAL ){ + rc = sqlite3BtreeSetVersion(p->pDest, 2); + } + } + if( rc==SQLITE_OK ){ + int nDestTruncate; + /* Set nDestTruncate to the final number of pages in the destination + ** database. The complication here is that the destination page + ** size may be different to the source page size. + ** + ** If the source page size is smaller than the destination page size, + ** round up. In this case the call to sqlite3OsTruncate() below will + ** fix the size of the file. However it is important to call + ** sqlite3PagerTruncateImage() here so that any pages in the + ** destination file that lie beyond the nDestTruncate page mark are + ** journalled by PagerCommitPhaseOne() before they are destroyed + ** by the file truncation. + */ + assert( pgszSrc==sqlite3BtreeGetPageSize(p->pSrc) ); + assert( pgszDest==sqlite3BtreeGetPageSize(p->pDest) ); + if( pgszSrcpDest->pBt) ){ + nDestTruncate--; + } + }else{ + nDestTruncate = nSrcPage * (pgszSrc/pgszDest); + } + assert( nDestTruncate>0 ); + + if( pgszSrc= iSize || ( + nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1) + && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest + )); + + /* This block ensures that all data required to recreate the original + ** database has been stored in the journal for pDestPager and the + ** journal synced to disk. So at this point we may safely modify + ** the database file in any way, knowing that if a power failure + ** occurs, the original database will be reconstructed from the + ** journal file. */ + sqlite3PagerPagecount(pDestPager, &nDstPage); + for(iPg=nDestTruncate; rc==SQLITE_OK && iPg<=(Pgno)nDstPage; iPg++){ + if( iPg!=PENDING_BYTE_PAGE(p->pDest->pBt) ){ + DbPage *pPg; + rc = sqlite3PagerGet(pDestPager, iPg, &pPg); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerWrite(pPg); + sqlite3PagerUnref(pPg); + } + } + } + if( rc==SQLITE_OK ){ + rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1); + } + + /* Write the extra pages and truncate the database file as required */ + iEnd = MIN(PENDING_BYTE + pgszDest, iSize); + for( + iOff=PENDING_BYTE+pgszSrc; + rc==SQLITE_OK && iOffpDest, 0)) + ){ + rc = SQLITE_DONE; + } + } + } + + /* If bCloseTrans is true, then this function opened a read transaction + ** on the source database. Close the read transaction here. There is + ** no need to check the return values of the btree methods here, as + ** "committing" a read-only transaction cannot fail. + */ + if( bCloseTrans ){ + TESTONLY( int rc2 ); + TESTONLY( rc2 = ) sqlite3BtreeCommitPhaseOne(p->pSrc, 0); + TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc, 0); + assert( rc2==SQLITE_OK ); + } + + if( rc==SQLITE_IOERR_NOMEM ){ + rc = SQLITE_NOMEM; + } + p->rc = rc; + } + if( p->pDestDb ){ + sqlite3_mutex_leave(p->pDestDb->mutex); + } + sqlite3BtreeLeave(p->pSrc); + sqlite3_mutex_leave(p->pSrcDb->mutex); + return rc; +} + +/* +** Release all resources associated with an sqlite3_backup* handle. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p){ + sqlite3_backup **pp; /* Ptr to head of pagers backup list */ + sqlite3 *pSrcDb; /* Source database connection */ + int rc; /* Value to return */ + + /* Enter the mutexes */ + if( p==0 ) return SQLITE_OK; + pSrcDb = p->pSrcDb; + sqlite3_mutex_enter(pSrcDb->mutex); + sqlite3BtreeEnter(p->pSrc); + if( p->pDestDb ){ + sqlite3_mutex_enter(p->pDestDb->mutex); + } + + /* Detach this backup from the source pager. */ + if( p->pDestDb ){ + p->pSrc->nBackup--; + } + if( p->isAttached ){ + pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc)); + while( *pp!=p ){ + pp = &(*pp)->pNext; + } + *pp = p->pNext; + } + + /* If a transaction is still open on the Btree, roll it back. */ + sqlite3BtreeRollback(p->pDest, SQLITE_OK, 0); + + /* Set the error code of the destination database handle. */ + rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc; + if( p->pDestDb ){ + sqlite3Error(p->pDestDb, rc); + + /* Exit the mutexes and free the backup context structure. */ + sqlite3LeaveMutexAndCloseZombie(p->pDestDb); + } + sqlite3BtreeLeave(p->pSrc); + if( p->pDestDb ){ + /* EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a + ** call to sqlite3_backup_init() and is destroyed by a call to + ** sqlite3_backup_finish(). */ + sqlite3_free(p); + } + sqlite3LeaveMutexAndCloseZombie(pSrcDb); + return rc; +} + +/* +** Return the number of pages still to be backed up as of the most recent +** call to sqlite3_backup_step(). +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + return p->nRemaining; +} + +/* +** Return the total number of pages in the source database as of the most +** recent call to sqlite3_backup_step(). +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + return p->nPagecount; +} + +/* +** This function is called after the contents of page iPage of the +** source database have been modified. If page iPage has already been +** copied into the destination database, then the data written to the +** destination is now invalidated. The destination copy of iPage needs +** to be updated with the new data before the backup operation is +** complete. +** +** It is assumed that the mutex associated with the BtShared object +** corresponding to the source database is held when this function is +** called. +*/ +SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *pBackup, Pgno iPage, const u8 *aData){ + sqlite3_backup *p; /* Iterator variable */ + for(p=pBackup; p; p=p->pNext){ + assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) ); + if( !isFatalError(p->rc) && iPageiNext ){ + /* The backup process p has already copied page iPage. But now it + ** has been modified by a transaction on the source pager. Copy + ** the new data into the backup. + */ + int rc; + assert( p->pDestDb ); + sqlite3_mutex_enter(p->pDestDb->mutex); + rc = backupOnePage(p, iPage, aData, 1); + sqlite3_mutex_leave(p->pDestDb->mutex); + assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED ); + if( rc!=SQLITE_OK ){ + p->rc = rc; + } + } + } +} + +/* +** Restart the backup process. This is called when the pager layer +** detects that the database has been modified by an external database +** connection. In this case there is no way of knowing which of the +** pages that have been copied into the destination database are still +** valid and which are not, so the entire process needs to be restarted. +** +** It is assumed that the mutex associated with the BtShared object +** corresponding to the source database is held when this function is +** called. +*/ +SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *pBackup){ + sqlite3_backup *p; /* Iterator variable */ + for(p=pBackup; p; p=p->pNext){ + assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) ); + p->iNext = 1; + } +} + +#ifndef SQLITE_OMIT_VACUUM +/* +** Copy the complete content of pBtFrom into pBtTo. A transaction +** must be active for both files. +** +** The size of file pTo may be reduced by this operation. If anything +** goes wrong, the transaction on pTo is rolled back. If successful, the +** transaction is committed before returning. +*/ +SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ + int rc; + sqlite3_file *pFd; /* File descriptor for database pTo */ + sqlite3_backup b; + sqlite3BtreeEnter(pTo); + sqlite3BtreeEnter(pFrom); + + assert( sqlite3BtreeIsInTrans(pTo) ); + pFd = sqlite3PagerFile(sqlite3BtreePager(pTo)); + if( pFd->pMethods ){ + i64 nByte = sqlite3BtreeGetPageSize(pFrom)*(i64)sqlite3BtreeLastPage(pFrom); + rc = sqlite3OsFileControl(pFd, SQLITE_FCNTL_OVERWRITE, &nByte); + if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; + if( rc ) goto copy_finished; + } + + /* Set up an sqlite3_backup object. sqlite3_backup.pDestDb must be set + ** to 0. This is used by the implementations of sqlite3_backup_step() + ** and sqlite3_backup_finish() to detect that they are being called + ** from this function, not directly by the user. + */ + memset(&b, 0, sizeof(b)); + b.pSrcDb = pFrom->db; + b.pSrc = pFrom; + b.pDest = pTo; + b.iNext = 1; + + /* 0x7FFFFFFF is the hard limit for the number of pages in a database + ** file. By passing this as the number of pages to copy to + ** sqlite3_backup_step(), we can guarantee that the copy finishes + ** within a single call (unless an error occurs). The assert() statement + ** checks this assumption - (p->rc) should be set to either SQLITE_DONE + ** or an error code. + */ + sqlite3_backup_step(&b, 0x7FFFFFFF); + assert( b.rc!=SQLITE_OK ); + rc = sqlite3_backup_finish(&b); + if( rc==SQLITE_OK ){ + pTo->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED; + }else{ + sqlite3PagerClearCache(sqlite3BtreePager(b.pDest)); + } + + assert( sqlite3BtreeIsInTrans(pTo)==0 ); +copy_finished: + sqlite3BtreeLeave(pFrom); + sqlite3BtreeLeave(pTo); + return rc; +} +#endif /* SQLITE_OMIT_VACUUM */ + +/************** End of backup.c **********************************************/ +/************** Begin file vdbemem.c *****************************************/ +/* +** 2004 May 26 +** +** 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 use to manipulate "Mem" structure. A "Mem" +** stores a single value in the VDBE. Mem is an opaque structure visible +** only within the VDBE. Interface routines refer to a Mem using the +** name sqlite_value +*/ + +#ifdef SQLITE_DEBUG +/* +** Check invariants on a Mem object. +** +** This routine is intended for use inside of assert() statements, like +** this: assert( sqlite3VdbeCheckMemInvariants(pMem) ); +*/ +SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){ + /* If MEM_Dyn is set then Mem.xDel!=0. + ** Mem.xDel is might not be initialized if MEM_Dyn is clear. + */ + assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 ); + + /* MEM_Dyn may only be set if Mem.szMalloc==0. In this way we + ** ensure that if Mem.szMalloc>0 then it is safe to do + ** Mem.z = Mem.zMalloc without having to check Mem.flags&MEM_Dyn. + ** That saves a few cycles in inner loops. */ + assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 ); + + /* Cannot be both MEM_Int and MEM_Real at the same time */ + assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) ); + + /* The szMalloc field holds the correct memory allocation size */ + assert( p->szMalloc==0 + || p->szMalloc==sqlite3DbMallocSize(p->db,p->zMalloc) ); + + /* If p holds a string or blob, the Mem.z must point to exactly + ** one of the following: + ** + ** (1) Memory in Mem.zMalloc and managed by the Mem object + ** (2) Memory to be freed using Mem.xDel + ** (3) An ephemeral string or blob + ** (4) A static string or blob + */ + if( (p->flags & (MEM_Str|MEM_Blob)) && p->n>0 ){ + assert( + ((p->szMalloc>0 && p->z==p->zMalloc)? 1 : 0) + + ((p->flags&MEM_Dyn)!=0 ? 1 : 0) + + ((p->flags&MEM_Ephem)!=0 ? 1 : 0) + + ((p->flags&MEM_Static)!=0 ? 1 : 0) == 1 + ); + } + return 1; +} +#endif + + +/* +** If pMem is an object with a valid string representation, this routine +** ensures the internal encoding for the string representation is +** 'desiredEnc', one of SQLITE_UTF8, SQLITE_UTF16LE or SQLITE_UTF16BE. +** +** If pMem is not a string object, or the encoding of the string +** representation is already stored using the requested encoding, then this +** routine is a no-op. +** +** SQLITE_OK is returned if the conversion is successful (or not required). +** SQLITE_NOMEM may be returned if a malloc() fails during conversion +** between formats. +*/ +SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ +#ifndef SQLITE_OMIT_UTF16 + int rc; +#endif + assert( (pMem->flags&MEM_RowSet)==0 ); + assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE + || desiredEnc==SQLITE_UTF16BE ); + if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){ + return SQLITE_OK; + } + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); +#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, (u8)desiredEnc); + assert(rc==SQLITE_OK || rc==SQLITE_NOMEM); + assert(rc==SQLITE_OK || pMem->enc!=desiredEnc); + assert(rc==SQLITE_NOMEM || pMem->enc==desiredEnc); + return rc; +#endif +} + +/* +** Make sure pMem->z points to a writable allocation of at least +** min(n,32) bytes. +** +** If the bPreserve argument is true, then copy of the content of +** pMem->z into the new allocation. pMem must be either a string or +** blob if bPreserve is true. If bPreserve is false, any prior content +** in pMem->z is discarded. +*/ +SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ + assert( sqlite3VdbeCheckMemInvariants(pMem) ); + assert( (pMem->flags&MEM_RowSet)==0 ); + + /* If the bPreserve flag is set to true, then the memory cell must already + ** contain a valid string or blob value. */ + assert( bPreserve==0 || pMem->flags&(MEM_Blob|MEM_Str) ); + testcase( bPreserve && pMem->z==0 ); + + assert( pMem->szMalloc==0 + || pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) ); + if( pMem->szMallocszMalloc>0 && pMem->z==pMem->zMalloc ){ + pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n); + bPreserve = 0; + }else{ + if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc); + pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n); + } + if( pMem->zMalloc==0 ){ + sqlite3VdbeMemSetNull(pMem); + pMem->z = 0; + pMem->szMalloc = 0; + return SQLITE_NOMEM; + }else{ + pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); + } + } + + if( bPreserve && pMem->z && pMem->z!=pMem->zMalloc ){ + memcpy(pMem->zMalloc, pMem->z, pMem->n); + } + if( (pMem->flags&MEM_Dyn)!=0 ){ + assert( pMem->xDel!=0 && pMem->xDel!=SQLITE_DYNAMIC ); + pMem->xDel((void *)(pMem->z)); + } + + pMem->z = pMem->zMalloc; + pMem->flags &= ~(MEM_Dyn|MEM_Ephem|MEM_Static); + return SQLITE_OK; +} + +/* +** Change the pMem->zMalloc allocation to be at least szNew bytes. +** If pMem->zMalloc already meets or exceeds the requested size, this +** routine is a no-op. +** +** Any prior string or blob content in the pMem object may be discarded. +** The pMem->xDel destructor is called, if it exists. Though MEM_Str +** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, and MEM_Null +** values are preserved. +** +** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM) +** if unable to complete the resizing. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ + assert( szNew>0 ); + assert( (pMem->flags & MEM_Dyn)==0 || pMem->szMalloc==0 ); + if( pMem->szMallocflags & MEM_Dyn)==0 ); + pMem->z = pMem->zMalloc; + pMem->flags &= (MEM_Null|MEM_Int|MEM_Real); + return SQLITE_OK; +} + +/* +** Change pMem so that its MEM_Str or MEM_Blob value is stored in +** MEM.zMalloc, where it can be safely written. +** +** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){ + int f; + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( (pMem->flags&MEM_RowSet)==0 ); + ExpandBlob(pMem); + f = pMem->flags; + if( (f&(MEM_Str|MEM_Blob)) && (pMem->szMalloc==0 || pMem->z!=pMem->zMalloc) ){ + if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){ + return SQLITE_NOMEM; + } + pMem->z[pMem->n] = 0; + pMem->z[pMem->n+1] = 0; + pMem->flags |= MEM_Term; + } + pMem->flags &= ~MEM_Ephem; +#ifdef SQLITE_DEBUG + pMem->pScopyFrom = 0; +#endif + + return SQLITE_OK; +} + +/* +** If the given Mem* has a zero-filled tail, turn it into an ordinary +** blob stored in dynamically allocated space. +*/ +#ifndef SQLITE_OMIT_INCRBLOB +SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){ + if( pMem->flags & MEM_Zero ){ + int nByte; + assert( pMem->flags&MEM_Blob ); + assert( (pMem->flags&MEM_RowSet)==0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + + /* Set nByte to the number of bytes required to store the expanded blob. */ + nByte = pMem->n + pMem->u.nZero; + if( nByte<=0 ){ + nByte = 1; + } + if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){ + return SQLITE_NOMEM; + } + + memset(&pMem->z[pMem->n], 0, pMem->u.nZero); + pMem->n += pMem->u.nZero; + pMem->flags &= ~(MEM_Zero|MEM_Term); + } + return SQLITE_OK; +} +#endif + +/* +** It is already known that pMem contains an unterminated string. +** Add the zero terminator. +*/ +static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){ + if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){ + return SQLITE_NOMEM; + } + pMem->z[pMem->n] = 0; + pMem->z[pMem->n+1] = 0; + pMem->flags |= MEM_Term; + return SQLITE_OK; +} + +/* +** Make sure the given Mem is \u0000 terminated. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){ + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + testcase( (pMem->flags & (MEM_Term|MEM_Str))==(MEM_Term|MEM_Str) ); + testcase( (pMem->flags & (MEM_Term|MEM_Str))==0 ); + if( (pMem->flags & (MEM_Term|MEM_Str))!=MEM_Str ){ + return SQLITE_OK; /* Nothing to do */ + }else{ + return vdbeMemAddTerminator(pMem); + } +} + +/* +** Add MEM_Str to the set of representations for the given Mem. Numbers +** are converted using sqlite3_snprintf(). Converting a BLOB to a string +** is a no-op. +** +** Existing representations MEM_Int and MEM_Real are invalidated if +** bForce is true but are retained if bForce is false. +** +** A MEM_Null value will never be passed to this function. This function is +** used for converting values to text for returning to the user (i.e. via +** 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 latter is an internal programming error. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ + int fg = pMem->flags; + const int nByte = 32; + + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( !(fg&MEM_Zero) ); + assert( !(fg&(MEM_Str|MEM_Blob)) ); + assert( fg&(MEM_Int|MEM_Real) ); + assert( (pMem->flags&MEM_RowSet)==0 ); + assert( EIGHT_BYTE_ALIGNMENT(pMem) ); + + + if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){ + return SQLITE_NOMEM; + } + + /* 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(nByte, pMem->z, "%lld", pMem->u.i); + }else{ + assert( fg & MEM_Real ); + sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r); + } + pMem->n = sqlite3Strlen30(pMem->z); + pMem->enc = SQLITE_UTF8; + pMem->flags |= MEM_Str|MEM_Term; + if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real); + sqlite3VdbeChangeEncoding(pMem, enc); + return SQLITE_OK; +} + +/* +** 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. +** +** Return SQLITE_ERROR if the finalizer reports an error. SQLITE_OK +** otherwise. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ + int rc = SQLITE_OK; + if( ALWAYS(pFunc && pFunc->xFinalize) ){ + sqlite3_context ctx; + Mem t; + assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + memset(&ctx, 0, sizeof(ctx)); + memset(&t, 0, sizeof(t)); + t.flags = MEM_Null; + t.db = pMem->db; + ctx.pOut = &t; + ctx.pMem = pMem; + ctx.pFunc = pFunc; + pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */ + assert( (pMem->flags & MEM_Dyn)==0 ); + if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc); + memcpy(pMem, &t, sizeof(t)); + rc = ctx.isError; + } + return rc; +} + +/* +** If the memory cell contains a value that must be freed by +** invoking the external callback in Mem.xDel, then this routine +** will free that value. It also sets Mem.flags to MEM_Null. +** +** This is a helper routine for sqlite3VdbeMemSetNull() and +** for sqlite3VdbeMemRelease(). Use those other routines as the +** entry point for releasing Mem resources. +*/ +static SQLITE_NOINLINE void vdbeMemClearExternAndSetNull(Mem *p){ + assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) ); + assert( VdbeMemDynamic(p) ); + if( p->flags&MEM_Agg ){ + sqlite3VdbeMemFinalize(p, p->u.pDef); + assert( (p->flags & MEM_Agg)==0 ); + testcase( p->flags & MEM_Dyn ); + } + if( p->flags&MEM_Dyn ){ + assert( (p->flags&MEM_RowSet)==0 ); + assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 ); + p->xDel((void *)p->z); + }else if( p->flags&MEM_RowSet ){ + sqlite3RowSetClear(p->u.pRowSet); + }else if( p->flags&MEM_Frame ){ + VdbeFrame *pFrame = p->u.pFrame; + pFrame->pParent = pFrame->v->pDelFrame; + pFrame->v->pDelFrame = pFrame; + } + p->flags = MEM_Null; +} + +/* +** Release memory held by the Mem p, both external memory cleared +** by p->xDel and memory in p->zMalloc. +** +** This is a helper routine invoked by sqlite3VdbeMemRelease() in +** the unusual case where there really is memory in p that needs +** to be freed. +*/ +static SQLITE_NOINLINE void vdbeMemClear(Mem *p){ + if( VdbeMemDynamic(p) ){ + vdbeMemClearExternAndSetNull(p); + } + if( p->szMalloc ){ + sqlite3DbFree(p->db, p->zMalloc); + p->szMalloc = 0; + } + p->z = 0; +} + +/* +** Release any memory resources held by the Mem. Both the memory that is +** free by Mem.xDel and the Mem.zMalloc allocation are freed. +** +** Use this routine prior to clean up prior to abandoning a Mem, or to +** reset a Mem back to its minimum memory utilization. +** +** Use sqlite3VdbeMemSetNull() to release just the Mem.xDel space +** prior to inserting new content into the Mem. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){ + assert( sqlite3VdbeCheckMemInvariants(p) ); + if( VdbeMemDynamic(p) || p->szMalloc ){ + vdbeMemClear(p); + } +} + +/* +** Convert a 64-bit IEEE double into a 64-bit signed integer. +** If the double is out of range of a 64-bit signed integer then +** return the closest available 64-bit signed integer. +*/ +static i64 doubleToInt64(double r){ +#ifdef SQLITE_OMIT_FLOATING_POINT + /* When floating-point is omitted, double and int64 are the same thing */ + return r; +#else + /* + ** Many compilers we encounter do not define constants for the + ** minimum and maximum 64-bit integers, or they define them + ** inconsistently. And many do not understand the "LL" notation. + ** So we define our own static constants here using nothing + ** larger than a 32-bit integer constant. + */ + static const i64 maxInt = LARGEST_INT64; + static const i64 minInt = SMALLEST_INT64; + + if( r<=(double)minInt ){ + return minInt; + }else if( r>=(double)maxInt ){ + return maxInt; + }else{ + return (i64)r; + } +#endif +} + +/* +** Return some kind of integer value which is the best we can do +** at representing the value that *pMem describes as an integer. +** If pMem is an integer, then the value is exact. If pMem is +** a floating-point then the value returned is the integer part. +** If pMem is a string or blob, then we make an attempt to convert +** it into an integer and return that. If pMem represents an +** an SQL-NULL value, return 0. +** +** If pMem represents a string value, its encoding might be changed. +*/ +SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){ + int flags; + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( EIGHT_BYTE_ALIGNMENT(pMem) ); + flags = pMem->flags; + if( flags & MEM_Int ){ + return pMem->u.i; + }else if( flags & MEM_Real ){ + return doubleToInt64(pMem->u.r); + }else if( flags & (MEM_Str|MEM_Blob) ){ + i64 value = 0; + assert( pMem->z || pMem->n==0 ); + sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc); + 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. +*/ +SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){ + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( EIGHT_BYTE_ALIGNMENT(pMem) ); + if( pMem->flags & MEM_Real ){ + return pMem->u.r; + }else if( pMem->flags & MEM_Int ){ + return (double)pMem->u.i; + }else if( pMem->flags & (MEM_Str|MEM_Blob) ){ + /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ + double val = (double)0; + sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc); + return val; + }else{ + /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ + return (double)0; + } +} + +/* +** The MEM structure is already a MEM_Real. Try to also make it a +** MEM_Int if we can. +*/ +SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){ + i64 ix; + assert( pMem->flags & MEM_Real ); + assert( (pMem->flags & MEM_RowSet)==0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( EIGHT_BYTE_ALIGNMENT(pMem) ); + + ix = doubleToInt64(pMem->u.r); + + /* Only mark the value as an integer if + ** + ** (1) the round-trip conversion real->int->real is a no-op, and + ** (2) The integer is neither the largest nor the smallest + ** possible integer (ticket #3922) + ** + ** The second and third terms in the following conditional enforces + ** the second condition under the assumption that addition overflow causes + ** values to wrap around. + */ + if( pMem->u.r==ix && ix>SMALLEST_INT64 && ixu.i = ix; + MemSetTypeFlag(pMem, MEM_Int); + } +} + +/* +** Convert pMem to type integer. Invalidate any prior representations. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){ + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( (pMem->flags & MEM_RowSet)==0 ); + assert( EIGHT_BYTE_ALIGNMENT(pMem) ); + + pMem->u.i = sqlite3VdbeIntValue(pMem); + MemSetTypeFlag(pMem, MEM_Int); + return SQLITE_OK; +} + +/* +** Convert pMem so that it is of type MEM_Real. +** Invalidate any prior representations. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem *pMem){ + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( EIGHT_BYTE_ALIGNMENT(pMem) ); + + pMem->u.r = sqlite3VdbeRealValue(pMem); + MemSetTypeFlag(pMem, MEM_Real); + return SQLITE_OK; +} + +/* +** Convert pMem so that it has types MEM_Real or MEM_Int or both. +** Invalidate any prior representations. +** +** Every effort is made to force the conversion, even if the input +** is a string that does not look completely like a number. Convert +** as much of the string as we can and ignore the rest. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){ + if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){ + assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + if( 0==sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc) ){ + MemSetTypeFlag(pMem, MEM_Int); + }else{ + pMem->u.r = sqlite3VdbeRealValue(pMem); + MemSetTypeFlag(pMem, MEM_Real); + sqlite3VdbeIntegerAffinity(pMem); + } + } + assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 ); + pMem->flags &= ~(MEM_Str|MEM_Blob); + return SQLITE_OK; +} + +/* +** Cast the datatype of the value in pMem according to the affinity +** "aff". Casting is different from applying affinity in that a cast +** is forced. In other words, the value is converted into the desired +** affinity even if that results in loss of data. This routine is +** used (for example) to implement the SQL "cast()" operator. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){ + if( pMem->flags & MEM_Null ) return; + switch( aff ){ + case SQLITE_AFF_NONE: { /* Really a cast to BLOB */ + if( (pMem->flags & MEM_Blob)==0 ){ + sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding); + assert( pMem->flags & MEM_Str || pMem->db->mallocFailed ); + MemSetTypeFlag(pMem, MEM_Blob); + }else{ + pMem->flags &= ~(MEM_TypeMask&~MEM_Blob); + } + break; + } + case SQLITE_AFF_NUMERIC: { + sqlite3VdbeMemNumerify(pMem); + break; + } + case SQLITE_AFF_INTEGER: { + sqlite3VdbeMemIntegerify(pMem); + break; + } + case SQLITE_AFF_REAL: { + sqlite3VdbeMemRealify(pMem); + break; + } + default: { + assert( aff==SQLITE_AFF_TEXT ); + assert( MEM_Str==(MEM_Blob>>3) ); + pMem->flags |= (pMem->flags&MEM_Blob)>>3; + sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding); + assert( pMem->flags & MEM_Str || pMem->db->mallocFailed ); + pMem->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero); + break; + } + } +} + +/* +** Initialize bulk memory to be a consistent Mem object. +** +** The minimum amount of initialization feasible is performed. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem *pMem, sqlite3 *db, u16 flags){ + assert( (flags & ~MEM_TypeMask)==0 ); + pMem->flags = flags; + pMem->db = db; + pMem->szMalloc = 0; +} + + +/* +** Delete any previous value and set the value stored in *pMem to NULL. +** +** This routine calls the Mem.xDel destructor to dispose of values that +** require the destructor. But it preserves the Mem.zMalloc memory allocation. +** To free all resources, use sqlite3VdbeMemRelease(), which both calls this +** routine to invoke the destructor and deallocates Mem.zMalloc. +** +** Use this routine to reset the Mem prior to insert a new value. +** +** Use sqlite3VdbeMemRelease() to complete erase the Mem prior to abandoning it. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem *pMem){ + if( VdbeMemDynamic(pMem) ){ + vdbeMemClearExternAndSetNull(pMem); + }else{ + pMem->flags = MEM_Null; + } +} +SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value *p){ + sqlite3VdbeMemSetNull((Mem*)p); +} + +/* +** Delete any previous value and set the value to be a BLOB of length +** n containing all zeros. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){ + sqlite3VdbeMemRelease(pMem); + pMem->flags = MEM_Blob|MEM_Zero; + pMem->n = 0; + if( n<0 ) n = 0; + pMem->u.nZero = n; + pMem->enc = SQLITE_UTF8; + pMem->z = 0; +} + +/* +** The pMem is known to contain content that needs to be destroyed prior +** to a value change. So invoke the destructor, then set the value to +** a 64-bit integer. +*/ +static SQLITE_NOINLINE void vdbeReleaseAndSetInt64(Mem *pMem, i64 val){ + sqlite3VdbeMemSetNull(pMem); + pMem->u.i = val; + pMem->flags = MEM_Int; +} + +/* +** Delete any previous value and set the value stored in *pMem to val, +** manifest type INTEGER. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){ + if( VdbeMemDynamic(pMem) ){ + vdbeReleaseAndSetInt64(pMem, val); + }else{ + pMem->u.i = val; + pMem->flags = MEM_Int; + } +} + +#ifndef SQLITE_OMIT_FLOATING_POINT +/* +** Delete any previous value and set the value stored in *pMem to val, +** manifest type REAL. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem *pMem, double val){ + sqlite3VdbeMemSetNull(pMem); + if( !sqlite3IsNaN(val) ){ + pMem->u.r = val; + pMem->flags = MEM_Real; + } +} +#endif + +/* +** Delete any previous value and set the value of pMem to be an +** empty boolean index. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem *pMem){ + sqlite3 *db = pMem->db; + assert( db!=0 ); + assert( (pMem->flags & MEM_RowSet)==0 ); + sqlite3VdbeMemRelease(pMem); + pMem->zMalloc = sqlite3DbMallocRaw(db, 64); + if( db->mallocFailed ){ + pMem->flags = MEM_Null; + pMem->szMalloc = 0; + }else{ + assert( pMem->zMalloc ); + pMem->szMalloc = sqlite3DbMallocSize(db, pMem->zMalloc); + pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc, pMem->szMalloc); + assert( pMem->u.pRowSet!=0 ); + pMem->flags = MEM_RowSet; + } +} + +/* +** Return true if the Mem object contains a TEXT or BLOB that is +** too large - whose size exceeds SQLITE_MAX_LENGTH. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem *p){ + assert( p->db!=0 ); + if( p->flags & (MEM_Str|MEM_Blob) ){ + int n = p->n; + if( p->flags & MEM_Zero ){ + n += p->u.nZero; + } + return n>p->db->aLimit[SQLITE_LIMIT_LENGTH]; + } + return 0; +} + +#ifdef SQLITE_DEBUG +/* +** This routine prepares a memory cell for modification by breaking +** its link to a shallow copy and by marking any current shallow +** copies of this cell as invalid. +** +** This is used for testing and debugging only - to make sure shallow +** copies are not misused. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ + int i; + Mem *pX; + for(i=1, pX=&pVdbe->aMem[1]; i<=pVdbe->nMem; i++, pX++){ + if( pX->pScopyFrom==pMem ){ + pX->flags |= MEM_Undefined; + pX->pScopyFrom = 0; + } + } + pMem->pScopyFrom = 0; +} +#endif /* SQLITE_DEBUG */ + +/* +** Size of struct Mem not including the Mem.zMalloc member. +*/ +#define MEMCELLSIZE offsetof(Mem,zMalloc) + +/* +** Make an shallow copy of pFrom into pTo. Prior contents of +** pTo are freed. The pFrom->z field is not duplicated. If +** pFrom->z is used, then pTo->z points to the same thing as pFrom->z +** and flags gets srcType (either MEM_Ephem or MEM_Static). +*/ +SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ + assert( (pFrom->flags & MEM_RowSet)==0 ); + assert( pTo->db==pFrom->db ); + if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo); + memcpy(pTo, pFrom, MEMCELLSIZE); + if( (pFrom->flags&MEM_Static)==0 ){ + pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem); + assert( srcType==MEM_Ephem || srcType==MEM_Static ); + pTo->flags |= srcType; + } +} + +/* +** Make a full copy of pFrom into pTo. Prior contents of pTo are +** freed before the copy is made. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ + int rc = SQLITE_OK; + + assert( pTo->db==pFrom->db ); + assert( (pFrom->flags & MEM_RowSet)==0 ); + if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo); + memcpy(pTo, pFrom, MEMCELLSIZE); + pTo->flags &= ~MEM_Dyn; + if( pTo->flags&(MEM_Str|MEM_Blob) ){ + if( 0==(pFrom->flags&MEM_Static) ){ + pTo->flags |= MEM_Ephem; + rc = sqlite3VdbeMemMakeWriteable(pTo); + } + } + + return rc; +} + +/* +** Transfer the contents of pFrom to pTo. Any existing value in pTo is +** freed. If pFrom contains ephemeral data, a copy is made. +** +** pFrom contains an SQL NULL when this routine returns. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){ + assert( pFrom->db==0 || sqlite3_mutex_held(pFrom->db->mutex) ); + assert( pTo->db==0 || sqlite3_mutex_held(pTo->db->mutex) ); + assert( pFrom->db==0 || pTo->db==0 || pFrom->db==pTo->db ); + + sqlite3VdbeMemRelease(pTo); + memcpy(pTo, pFrom, sizeof(Mem)); + pFrom->flags = MEM_Null; + pFrom->szMalloc = 0; +} + +/* +** Change the value of a Mem to be a string or a BLOB. +** +** The memory management strategy depends on the value of the xDel +** parameter. If the value passed is SQLITE_TRANSIENT, then the +** string is copied into a (possibly existing) buffer managed by the +** Mem structure. Otherwise, any existing buffer is freed and the +** pointer copied. +** +** If the string is too large (if it exceeds the SQLITE_LIMIT_LENGTH +** size limit) then no memory allocation occurs. If the string can be +** stored without allocating memory, then it is. If a memory allocation +** is required to store the string, then value of pMem is unchanged. In +** either case, SQLITE_TOOBIG is returned. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemSetStr( + Mem *pMem, /* Memory cell to set to string value */ + const char *z, /* String pointer */ + int n, /* Bytes in string, or negative */ + u8 enc, /* Encoding of z. 0 for BLOBs */ + void (*xDel)(void*) /* Destructor function */ +){ + int nByte = n; /* New value for pMem->n */ + int iLimit; /* Maximum allowed string or blob size */ + u16 flags = 0; /* New value for pMem->flags */ + + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( (pMem->flags & MEM_RowSet)==0 ); + + /* If z is a NULL pointer, set pMem to contain an SQL NULL. */ + if( !z ){ + sqlite3VdbeMemSetNull(pMem); + return SQLITE_OK; + } + + if( pMem->db ){ + iLimit = pMem->db->aLimit[SQLITE_LIMIT_LENGTH]; + }else{ + iLimit = SQLITE_MAX_LENGTH; + } + flags = (enc==0?MEM_Blob:MEM_Str); + if( nByte<0 ){ + assert( enc!=0 ); + if( enc==SQLITE_UTF8 ){ + nByte = sqlite3Strlen30(z); + if( nByte>iLimit ) nByte = iLimit+1; + }else{ + for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){} + } + flags |= MEM_Term; + } + + /* The following block sets the new values of Mem.z and Mem.xDel. It + ** also sets a flag in local variable "flags" to indicate the memory + ** management (one of MEM_Dyn or MEM_Static). + */ + if( xDel==SQLITE_TRANSIENT ){ + int nAlloc = nByte; + if( flags&MEM_Term ){ + nAlloc += (enc==SQLITE_UTF8?1:2); + } + if( nByte>iLimit ){ + return SQLITE_TOOBIG; + } + testcase( nAlloc==0 ); + testcase( nAlloc==31 ); + testcase( nAlloc==32 ); + if( sqlite3VdbeMemClearAndResize(pMem, MAX(nAlloc,32)) ){ + return SQLITE_NOMEM; + } + memcpy(pMem->z, z, nAlloc); + }else if( xDel==SQLITE_DYNAMIC ){ + sqlite3VdbeMemRelease(pMem); + pMem->zMalloc = pMem->z = (char *)z; + pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); + }else{ + sqlite3VdbeMemRelease(pMem); + pMem->z = (char *)z; + pMem->xDel = xDel; + flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn); + } + + pMem->n = nByte; + pMem->flags = flags; + pMem->enc = (enc==0 ? SQLITE_UTF8 : enc); + +#ifndef SQLITE_OMIT_UTF16 + if( pMem->enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){ + return SQLITE_NOMEM; + } +#endif + + if( nByte>iLimit ){ + return SQLITE_TOOBIG; + } + + return SQLITE_OK; +} + +/* +** Move data out of a btree key or data field and into a Mem structure. +** The data or key is taken from the entry that pCur is currently pointing +** to. offset and amt determine what portion of the data or key to retrieve. +** key is true to get the key or false to get data. The result is written +** into the pMem element. +** +** The pMem object must have been initialized. This routine will use +** pMem->zMalloc to hold the content from the btree, if possible. New +** pMem->zMalloc space will be allocated if necessary. The calling routine +** is responsible for making sure that the pMem object is eventually +** destroyed. +** +** If this routine fails for any reason (malloc returns NULL or unable +** to read from the disk) then the pMem is left in an inconsistent state. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemFromBtree( + BtCursor *pCur, /* Cursor pointing at record to retrieve. */ + u32 offset, /* Offset from the start of data to return bytes from. */ + u32 amt, /* Number of bytes to return. */ + int key, /* If true, retrieve from the btree key, not data. */ + Mem *pMem /* OUT: Return data in this Mem structure. */ +){ + char *zData; /* Data from the btree layer */ + u32 available = 0; /* Number of bytes available on the local btree page */ + int rc = SQLITE_OK; /* Return code */ + + assert( sqlite3BtreeCursorIsValid(pCur) ); + assert( !VdbeMemDynamic(pMem) ); + + /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() + ** that both the BtShared and database handle mutexes are held. */ + assert( (pMem->flags & MEM_RowSet)==0 ); + if( key ){ + zData = (char *)sqlite3BtreeKeyFetch(pCur, &available); + }else{ + zData = (char *)sqlite3BtreeDataFetch(pCur, &available); + } + assert( zData!=0 ); + + if( offset+amt<=available ){ + pMem->z = &zData[offset]; + pMem->flags = MEM_Blob|MEM_Ephem; + pMem->n = (int)amt; + }else{ + pMem->flags = MEM_Null; + if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+2)) ){ + if( key ){ + rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z); + }else{ + rc = sqlite3BtreeData(pCur, offset, amt, pMem->z); + } + if( rc==SQLITE_OK ){ + pMem->z[amt] = 0; + pMem->z[amt+1] = 0; + pMem->flags = MEM_Blob|MEM_Term; + pMem->n = (int)amt; + }else{ + sqlite3VdbeMemRelease(pMem); + } + } + } + + return rc; +} + +/* +** The pVal argument is known to be a value other than NULL. +** Convert it into a string with encoding enc and return a pointer +** to a zero-terminated version of that string. +*/ +static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){ + assert( pVal!=0 ); + assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); + assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); + assert( (pVal->flags & MEM_RowSet)==0 ); + assert( (pVal->flags & (MEM_Null))==0 ); + if( pVal->flags & (MEM_Blob|MEM_Str) ){ + pVal->flags |= MEM_Str; + if( pVal->flags & MEM_Zero ){ + sqlite3VdbeMemExpandBlob(pVal); + } + if( pVal->enc != (enc & ~SQLITE_UTF16_ALIGNED) ){ + sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED); + } + if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&SQLITE_PTR_TO_INT(pVal->z)) ){ + assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 ); + if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){ + return 0; + } + } + sqlite3VdbeMemNulTerminate(pVal); /* IMP: R-31275-44060 */ + }else{ + sqlite3VdbeMemStringify(pVal, enc, 0); + assert( 0==(1&SQLITE_PTR_TO_INT(pVal->z)) ); + } + assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0 + || pVal->db->mallocFailed ); + if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){ + return pVal->z; + }else{ + return 0; + } +} + +/* 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. +** +** (2006-02-16:) The enc value can be or-ed with SQLITE_UTF16_ALIGNED. +** If that is the case, then the result must be aligned on an even byte +** boundary. +*/ +SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){ + if( !pVal ) return 0; + assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); + assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); + assert( (pVal->flags & MEM_RowSet)==0 ); + if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){ + return pVal->z; + } + if( pVal->flags&MEM_Null ){ + return 0; + } + return valueToText(pVal, enc); +} + +/* +** Create a new sqlite3_value object. +*/ +SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *db){ + Mem *p = sqlite3DbMallocZero(db, sizeof(*p)); + if( p ){ + p->flags = MEM_Null; + p->db = db; + } + return p; +} + +/* +** Context object passed by sqlite3Stat4ProbeSetValue() through to +** valueNew(). See comments above valueNew() for details. +*/ +struct ValueNewStat4Ctx { + Parse *pParse; + Index *pIdx; + UnpackedRecord **ppRec; + int iVal; +}; + +/* +** Allocate and return a pointer to a new sqlite3_value object. If +** the second argument to this function is NULL, the object is allocated +** by calling sqlite3ValueNew(). +** +** Otherwise, if the second argument is non-zero, then this function is +** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not +** already been allocated, allocate the UnpackedRecord structure that +** that function will return to its caller here. Then return a pointer to +** an sqlite3_value within the UnpackedRecord.a[] array. +*/ +static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + if( p ){ + UnpackedRecord *pRec = p->ppRec[0]; + + if( pRec==0 ){ + Index *pIdx = p->pIdx; /* Index being probed */ + int nByte; /* Bytes of space to allocate */ + int i; /* Counter variable */ + int nCol = pIdx->nColumn; /* Number of index columns including rowid */ + + nByte = sizeof(Mem) * nCol + ROUND8(sizeof(UnpackedRecord)); + pRec = (UnpackedRecord*)sqlite3DbMallocZero(db, nByte); + if( pRec ){ + pRec->pKeyInfo = sqlite3KeyInfoOfIndex(p->pParse, pIdx); + if( pRec->pKeyInfo ){ + assert( pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField==nCol ); + assert( pRec->pKeyInfo->enc==ENC(db) ); + pRec->aMem = (Mem *)((u8*)pRec + ROUND8(sizeof(UnpackedRecord))); + for(i=0; iaMem[i].flags = MEM_Null; + pRec->aMem[i].db = db; + } + }else{ + sqlite3DbFree(db, pRec); + pRec = 0; + } + } + if( pRec==0 ) return 0; + p->ppRec[0] = pRec; + } + + pRec->nField = p->iVal+1; + return &pRec->aMem[p->iVal]; + } +#else + UNUSED_PARAMETER(p); +#endif /* defined(SQLITE_ENABLE_STAT3_OR_STAT4) */ + return sqlite3ValueNew(db); +} + +/* +** The expression object indicated by the second argument is guaranteed +** to be a scalar SQL function. If +** +** * all function arguments are SQL literals, +** * the SQLITE_FUNC_CONSTANT function flag is set, and +** * the SQLITE_FUNC_NEEDCOLL function flag is not set, +** +** then this routine attempts to invoke the SQL function. Assuming no +** error occurs, output parameter (*ppVal) is set to point to a value +** object containing the result before returning SQLITE_OK. +** +** Affinity aff is applied to the result of the function before returning. +** If the result is a text value, the sqlite3_value object uses encoding +** enc. +** +** If the conditions above are not met, this function returns SQLITE_OK +** and sets (*ppVal) to NULL. Or, if an error occurs, (*ppVal) is set to +** NULL and an SQLite error code returned. +*/ +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 +static int valueFromFunction( + sqlite3 *db, /* The database connection */ + Expr *p, /* The expression to evaluate */ + u8 enc, /* Encoding to use */ + u8 aff, /* Affinity to use */ + sqlite3_value **ppVal, /* Write the new value here */ + struct ValueNewStat4Ctx *pCtx /* Second argument for valueNew() */ +){ + sqlite3_context ctx; /* Context object for function invocation */ + sqlite3_value **apVal = 0; /* Function arguments */ + int nVal = 0; /* Size of apVal[] array */ + FuncDef *pFunc = 0; /* Function definition */ + sqlite3_value *pVal = 0; /* New value */ + int rc = SQLITE_OK; /* Return code */ + int nName; /* Size of function name in bytes */ + ExprList *pList = 0; /* Function arguments */ + int i; /* Iterator variable */ + + assert( pCtx!=0 ); + assert( (p->flags & EP_TokenOnly)==0 ); + pList = p->x.pList; + if( pList ) nVal = pList->nExpr; + nName = sqlite3Strlen30(p->u.zToken); + pFunc = sqlite3FindFunction(db, p->u.zToken, nName, nVal, enc, 0); + assert( pFunc ); + if( (pFunc->funcFlags & SQLITE_FUNC_CONSTANT)==0 + || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL) + ){ + return SQLITE_OK; + } + + if( pList ){ + apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal); + if( apVal==0 ){ + rc = SQLITE_NOMEM; + goto value_from_function_out; + } + for(i=0; ia[i].pExpr, enc, aff, &apVal[i]); + if( apVal[i]==0 || rc!=SQLITE_OK ) goto value_from_function_out; + } + } + + pVal = valueNew(db, pCtx); + if( pVal==0 ){ + rc = SQLITE_NOMEM; + goto value_from_function_out; + } + + assert( pCtx->pParse->rc==SQLITE_OK ); + memset(&ctx, 0, sizeof(ctx)); + ctx.pOut = pVal; + ctx.pFunc = pFunc; + pFunc->xFunc(&ctx, nVal, apVal); + if( ctx.isError ){ + rc = ctx.isError; + sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal)); + }else{ + sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8); + assert( rc==SQLITE_OK ); + rc = sqlite3VdbeChangeEncoding(pVal, enc); + if( rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal) ){ + rc = SQLITE_TOOBIG; + pCtx->pParse->nErr++; + } + } + pCtx->pParse->rc = rc; + + value_from_function_out: + if( rc!=SQLITE_OK ){ + pVal = 0; + } + if( apVal ){ + for(i=0; iop)==TK_UPLUS ) pExpr = pExpr->pLeft; + if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; + + /* Compressed expressions only appear when parsing the DEFAULT clause + ** on a table column definition, and hence only when pCtx==0. This + ** check ensures that an EP_TokenOnly expression is never passed down + ** into valueFromFunction(). */ + assert( (pExpr->flags & EP_TokenOnly)==0 || pCtx==0 ); + + if( op==TK_CAST ){ + u8 aff = sqlite3AffinityType(pExpr->u.zToken,0); + rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx); + testcase( rc!=SQLITE_OK ); + if( *ppVal ){ + sqlite3VdbeMemCast(*ppVal, aff, SQLITE_UTF8); + sqlite3ValueApplyAffinity(*ppVal, affinity, SQLITE_UTF8); + } + return rc; + } + + /* Handle negative integers in a single step. This is needed in the + ** case when the value is -9223372036854775808. + */ + if( op==TK_UMINUS + && (pExpr->pLeft->op==TK_INTEGER || pExpr->pLeft->op==TK_FLOAT) ){ + pExpr = pExpr->pLeft; + op = pExpr->op; + negInt = -1; + zNeg = "-"; + } + + if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ + pVal = valueNew(db, pCtx); + if( pVal==0 ) goto no_mem; + if( ExprHasProperty(pExpr, EP_IntValue) ){ + sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt); + }else{ + zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); + if( zVal==0 ) goto no_mem; + sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC); + } + if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){ + sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8); + }else{ + sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); + } + if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str; + if( enc!=SQLITE_UTF8 ){ + rc = sqlite3VdbeChangeEncoding(pVal, enc); + } + }else if( op==TK_UMINUS ) { + /* This branch happens for multiple negative signs. Ex: -(-5) */ + if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) + && pVal!=0 + ){ + sqlite3VdbeMemNumerify(pVal); + if( pVal->flags & MEM_Real ){ + pVal->u.r = -pVal->u.r; + }else if( pVal->u.i==SMALLEST_INT64 ){ + pVal->u.r = -(double)SMALLEST_INT64; + MemSetTypeFlag(pVal, MEM_Real); + }else{ + pVal->u.i = -pVal->u.i; + } + sqlite3ValueApplyAffinity(pVal, affinity, enc); + } + }else if( op==TK_NULL ){ + pVal = valueNew(db, pCtx); + if( pVal==0 ) goto no_mem; + } +#ifndef SQLITE_OMIT_BLOB_LITERAL + else if( op==TK_BLOB ){ + int nVal; + assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' ); + assert( pExpr->u.zToken[1]=='\'' ); + pVal = valueNew(db, pCtx); + if( !pVal ) goto no_mem; + zVal = &pExpr->u.zToken[2]; + nVal = sqlite3Strlen30(zVal)-1; + assert( zVal[nVal]=='\'' ); + sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2, + 0, SQLITE_DYNAMIC); + } +#endif + +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + else if( op==TK_FUNCTION && pCtx!=0 ){ + rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx); + } +#endif + + *ppVal = pVal; + return rc; + +no_mem: + db->mallocFailed = 1; + sqlite3DbFree(db, zVal); + assert( *ppVal==0 ); +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + if( pCtx==0 ) sqlite3ValueFree(pVal); +#else + assert( pCtx==0 ); sqlite3ValueFree(pVal); +#endif + return SQLITE_NOMEM; +} + +/* +** 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", "'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. +*/ +SQLITE_PRIVATE int sqlite3ValueFromExpr( + sqlite3 *db, /* The database connection */ + Expr *pExpr, /* The expression to evaluate */ + u8 enc, /* Encoding to use */ + u8 affinity, /* Affinity to use */ + sqlite3_value **ppVal /* Write the new value here */ +){ + return valueFromExpr(db, pExpr, enc, affinity, ppVal, 0); +} + +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 +/* +** The implementation of the sqlite_record() function. This function accepts +** a single argument of any type. The return value is a formatted database +** record (a blob) containing the argument value. +** +** This is used to convert the value stored in the 'sample' column of the +** sqlite_stat3 table to the record format SQLite uses internally. +*/ +static void recordFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const int file_format = 1; + int iSerial; /* Serial type */ + int nSerial; /* Bytes of space for iSerial as varint */ + int nVal; /* Bytes of space required for argv[0] */ + int nRet; + sqlite3 *db; + u8 *aRet; + + UNUSED_PARAMETER( argc ); + iSerial = sqlite3VdbeSerialType(argv[0], file_format); + nSerial = sqlite3VarintLen(iSerial); + nVal = sqlite3VdbeSerialTypeLen(iSerial); + db = sqlite3_context_db_handle(context); + + nRet = 1 + nSerial + nVal; + aRet = sqlite3DbMallocRaw(db, nRet); + if( aRet==0 ){ + sqlite3_result_error_nomem(context); + }else{ + aRet[0] = nSerial+1; + putVarint32(&aRet[1], iSerial); + sqlite3VdbeSerialPut(&aRet[1+nSerial], argv[0], iSerial); + sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT); + sqlite3DbFree(db, aRet); + } +} + +/* +** Register built-in functions used to help read ANALYZE data. +*/ +SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void){ + static SQLITE_WSD FuncDef aAnalyzeTableFuncs[] = { + FUNCTION(sqlite_record, 1, 0, 0, recordFunc), + }; + int i; + FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions); + FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAnalyzeTableFuncs); + for(i=0; idb; + + /* Skip over any TK_COLLATE nodes */ + pExpr = sqlite3ExprSkipCollate(pExpr); + + if( !pExpr ){ + pVal = valueNew(db, pAlloc); + if( pVal ){ + sqlite3VdbeMemSetNull((Mem*)pVal); + } + }else if( pExpr->op==TK_VARIABLE + || NEVER(pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE) + ){ + Vdbe *v; + int iBindVar = pExpr->iColumn; + sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar); + if( (v = pParse->pReprepare)!=0 ){ + pVal = valueNew(db, pAlloc); + if( pVal ){ + rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]); + if( rc==SQLITE_OK ){ + sqlite3ValueApplyAffinity(pVal, affinity, ENC(db)); + } + pVal->db = pParse->db; + } + } + }else{ + rc = valueFromExpr(db, pExpr, ENC(db), affinity, &pVal, pAlloc); + } + + assert( pVal==0 || pVal->db==db ); + *ppVal = pVal; + return rc; +} + +/* +** This function is used to allocate and populate UnpackedRecord +** structures intended to be compared against sample index keys stored +** in the sqlite_stat4 table. +** +** A single call to this function attempts to populates field iVal (leftmost +** is 0 etc.) of the unpacked record with a value extracted from expression +** pExpr. Extraction of values is possible if: +** +** * (pExpr==0). In this case the value is assumed to be an SQL NULL, +** +** * The expression is a bound variable, and this is a reprepare, or +** +** * The sqlite3ValueFromExpr() function is able to extract a value +** from the expression (i.e. the expression is a literal value). +** +** If a value can be extracted, the affinity passed as the 5th argument +** is applied to it before it is copied into the UnpackedRecord. Output +** parameter *pbOk is set to true if a value is extracted, or false +** otherwise. +** +** When this function is called, *ppRec must either point to an object +** allocated by an earlier call to this function, or must be NULL. If it +** is NULL and a value can be successfully extracted, a new UnpackedRecord +** is allocated (and *ppRec set to point to it) before returning. +** +** Unless an error is encountered, SQLITE_OK is returned. It is not an +** error if a value cannot be extracted from pExpr. If an error does +** occur, an SQLite error code is returned. +*/ +SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue( + Parse *pParse, /* Parse context */ + Index *pIdx, /* Index being probed */ + UnpackedRecord **ppRec, /* IN/OUT: Probe record */ + Expr *pExpr, /* The expression to extract a value from */ + u8 affinity, /* Affinity to use */ + int iVal, /* Array element to populate */ + int *pbOk /* OUT: True if value was extracted */ +){ + int rc; + sqlite3_value *pVal = 0; + struct ValueNewStat4Ctx alloc; + + alloc.pParse = pParse; + alloc.pIdx = pIdx; + alloc.ppRec = ppRec; + alloc.iVal = iVal; + + rc = stat4ValueFromExpr(pParse, pExpr, affinity, &alloc, &pVal); + assert( pVal==0 || pVal->db==pParse->db ); + *pbOk = (pVal!=0); + return rc; +} + +/* +** Attempt to extract a value from expression pExpr using the methods +** as described for sqlite3Stat4ProbeSetValue() above. +** +** If successful, set *ppVal to point to a new value object and return +** SQLITE_OK. If no value can be extracted, but no other error occurs +** (e.g. OOM), return SQLITE_OK and set *ppVal to NULL. Or, if an error +** does occur, return an SQLite error code. The final value of *ppVal +** is undefined in this case. +*/ +SQLITE_PRIVATE int sqlite3Stat4ValueFromExpr( + Parse *pParse, /* Parse context */ + Expr *pExpr, /* The expression to extract a value from */ + u8 affinity, /* Affinity to use */ + sqlite3_value **ppVal /* OUT: New value object (or NULL) */ +){ + return stat4ValueFromExpr(pParse, pExpr, affinity, 0, ppVal); +} + +/* +** Extract the iCol-th column from the nRec-byte record in pRec. Write +** the column value into *ppVal. If *ppVal is initially NULL then a new +** sqlite3_value object is allocated. +** +** If *ppVal is initially NULL then the caller is responsible for +** ensuring that the value written into *ppVal is eventually freed. +*/ +SQLITE_PRIVATE int sqlite3Stat4Column( + sqlite3 *db, /* Database handle */ + const void *pRec, /* Pointer to buffer containing record */ + int nRec, /* Size of buffer pRec in bytes */ + int iCol, /* Column to extract */ + sqlite3_value **ppVal /* OUT: Extracted value */ +){ + u32 t; /* a column type code */ + int nHdr; /* Size of the header in the record */ + int iHdr; /* Next unread header byte */ + int iField; /* Next unread data byte */ + int szField; /* Size of the current data field */ + int i; /* Column index */ + u8 *a = (u8*)pRec; /* Typecast byte array */ + Mem *pMem = *ppVal; /* Write result into this Mem object */ + + assert( iCol>0 ); + iHdr = getVarint32(a, nHdr); + if( nHdr>nRec || iHdr>=nHdr ) return SQLITE_CORRUPT_BKPT; + iField = nHdr; + for(i=0; i<=iCol; i++){ + iHdr += getVarint32(&a[iHdr], t); + testcase( iHdr==nHdr ); + testcase( iHdr==nHdr+1 ); + if( iHdr>nHdr ) return SQLITE_CORRUPT_BKPT; + szField = sqlite3VdbeSerialTypeLen(t); + iField += szField; + } + testcase( iField==nRec ); + testcase( iField==nRec+1 ); + if( iField>nRec ) return SQLITE_CORRUPT_BKPT; + if( pMem==0 ){ + pMem = *ppVal = sqlite3ValueNew(db); + if( pMem==0 ) return SQLITE_NOMEM; + } + sqlite3VdbeSerialGet(&a[iField-szField], t, pMem); + pMem->enc = ENC(db); + return SQLITE_OK; +} + +/* +** Unless it is NULL, the argument must be an UnpackedRecord object returned +** by an earlier call to sqlite3Stat4ProbeSetValue(). This call deletes +** the object. +*/ +SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){ + if( pRec ){ + int i; + int nCol = pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField; + Mem *aMem = pRec->aMem; + sqlite3 *db = aMem[0].db; + for(i=0; ipKeyInfo); + sqlite3DbFree(db, pRec); + } +} +#endif /* ifdef SQLITE_ENABLE_STAT4 */ + +/* +** Change the string value of an sqlite3_value object +*/ +SQLITE_PRIVATE void sqlite3ValueSetStr( + sqlite3_value *v, /* Value to be set */ + int n, /* Length of string z */ + const void *z, /* Text of the new string */ + u8 enc, /* Encoding to use */ + void (*xDel)(void*) /* Destructor for the string */ +){ + if( v ) sqlite3VdbeMemSetStr((Mem *)v, z, n, enc, xDel); +} + +/* +** Free an sqlite3_value object +*/ +SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value *v){ + if( !v ) return; + sqlite3VdbeMemRelease((Mem *)v); + sqlite3DbFree(((Mem*)v)->db, v); +} + +/* +** Return the number of bytes in the sqlite3_value object assuming +** that it uses the encoding "enc" +*/ +SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){ + Mem *p = (Mem*)pVal; + if( (p->flags & MEM_Blob)!=0 || sqlite3ValueText(pVal, enc) ){ + if( p->flags & MEM_Zero ){ + return p->n + p->u.nZero; + }else{ + return p->n; + } + } + return 0; +} + +/************** End of vdbemem.c *********************************************/ +/************** Begin file vdbeaux.c *****************************************/ +/* +** 2003 September 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 for creating, destroying, and populating +** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) +*/ + +/* +** Create a new virtual database engine. +*/ +SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){ + sqlite3 *db = pParse->db; + Vdbe *p; + p = sqlite3DbMallocZero(db, sizeof(Vdbe) ); + if( p==0 ) return 0; + p->db = db; + if( db->pVdbe ){ + db->pVdbe->pPrev = p; + } + p->pNext = db->pVdbe; + p->pPrev = 0; + db->pVdbe = p; + p->magic = VDBE_MAGIC_INIT; + p->pParse = pParse; + assert( pParse->aLabel==0 ); + assert( pParse->nLabel==0 ); + assert( pParse->nOpAlloc==0 ); + return p; +} + +/* +** Remember the SQL string for a prepared statement. +*/ +SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){ + assert( isPrepareV2==1 || isPrepareV2==0 ); + if( p==0 ) return; +#if defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_ENABLE_SQLLOG) + if( !isPrepareV2 ) return; +#endif + assert( p->zSql==0 ); + p->zSql = sqlite3DbStrNDup(p->db, z, n); + p->isPrepareV2 = (u8)isPrepareV2; +} + +/* +** Return the SQL associated with a prepared statement +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt){ + Vdbe *p = (Vdbe *)pStmt; + return (p && p->isPrepareV2) ? p->zSql : 0; +} + +/* +** Swap all content between two VDBE structures. +*/ +SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){ + Vdbe tmp, *pTmp; + char *zTmp; + tmp = *pA; + *pA = *pB; + *pB = tmp; + pTmp = pA->pNext; + pA->pNext = pB->pNext; + pB->pNext = pTmp; + pTmp = pA->pPrev; + pA->pPrev = pB->pPrev; + pB->pPrev = pTmp; + zTmp = pA->zSql; + pA->zSql = pB->zSql; + pB->zSql = zTmp; + pB->isPrepareV2 = pA->isPrepareV2; +} + +/* +** Resize the Vdbe.aOp array so that it is at least nOp elements larger +** than its current size. nOp is guaranteed to be less than or equal +** to 1024/sizeof(Op). +** +** If an out-of-memory error occurs while resizing the array, return +** SQLITE_NOMEM. In this case Vdbe.aOp and Parse.nOpAlloc remain +** unchanged (this is so that any opcodes already allocated can be +** correctly deallocated along with the rest of the Vdbe). +*/ +static int growOpArray(Vdbe *v, int nOp){ + VdbeOp *pNew; + Parse *p = v->pParse; + + /* The SQLITE_TEST_REALLOC_STRESS compile-time option is designed to force + ** more frequent reallocs and hence provide more opportunities for + ** simulated OOM faults. SQLITE_TEST_REALLOC_STRESS is generally used + ** during testing only. With SQLITE_TEST_REALLOC_STRESS grow the op array + ** by the minimum* amount required until the size reaches 512. Normal + ** operation (without SQLITE_TEST_REALLOC_STRESS) is to double the current + ** size of the op array or add 1KB of space, whichever is smaller. */ +#ifdef SQLITE_TEST_REALLOC_STRESS + int nNew = (p->nOpAlloc>=512 ? p->nOpAlloc*2 : p->nOpAlloc+nOp); +#else + int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op))); + UNUSED_PARAMETER(nOp); +#endif + + assert( nOp<=(1024/sizeof(Op)) ); + assert( nNew>=(p->nOpAlloc+nOp) ); + pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op)); + if( pNew ){ + p->nOpAlloc = sqlite3DbMallocSize(p->db, pNew)/sizeof(Op); + v->aOp = pNew; + } + return (pNew ? SQLITE_OK : SQLITE_NOMEM); +} + +#ifdef SQLITE_DEBUG +/* This routine is just a convenient place to set a breakpoint that will +** fire after each opcode is inserted and displayed using +** "PRAGMA vdbe_addoptrace=on". +*/ +static void test_addop_breakpoint(void){ + static int n = 0; + n++; +} +#endif + +/* +** Add a new instruction to the list of instructions current in the +** VDBE. Return the address of the new instruction. +** +** Parameters: +** +** p Pointer to the VDBE +** +** op The opcode for this instruction +** +** p1, p2, p3 Operands +** +** Use the sqlite3VdbeResolveLabel() function to fix an address and +** the sqlite3VdbeChangeP4() function to change the value of the P4 +** operand. +*/ +SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ + int i; + VdbeOp *pOp; + + i = p->nOp; + assert( p->magic==VDBE_MAGIC_INIT ); + assert( op>0 && op<0xff ); + if( p->pParse->nOpAlloc<=i ){ + if( growOpArray(p, 1) ){ + return 1; + } + } + p->nOp++; + pOp = &p->aOp[i]; + pOp->opcode = (u8)op; + pOp->p5 = 0; + pOp->p1 = p1; + pOp->p2 = p2; + pOp->p3 = p3; + pOp->p4.p = 0; + pOp->p4type = P4_NOTUSED; +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + pOp->zComment = 0; +#endif +#ifdef SQLITE_DEBUG + if( p->db->flags & SQLITE_VdbeAddopTrace ){ + int jj, kk; + Parse *pParse = p->pParse; + for(jj=kk=0; jjaColCache + jj; + if( x->iLevel>pParse->iCacheLevel || x->iReg==0 ) continue; + printf(" r[%d]={%d:%d}", x->iReg, x->iTable, x->iColumn); + kk++; + } + if( kk ) printf("\n"); + sqlite3VdbePrintOp(0, i, &p->aOp[i]); + test_addop_breakpoint(); + } +#endif +#ifdef VDBE_PROFILE + pOp->cycles = 0; + pOp->cnt = 0; +#endif +#ifdef SQLITE_VDBE_COVERAGE + pOp->iSrcLine = 0; +#endif + return i; +} +SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe *p, int op){ + return sqlite3VdbeAddOp3(p, op, 0, 0, 0); +} +SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe *p, int op, int p1){ + return sqlite3VdbeAddOp3(p, op, p1, 0, 0); +} +SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe *p, int op, int p1, int p2){ + return sqlite3VdbeAddOp3(p, op, p1, p2, 0); +} + + +/* +** Add an opcode that includes the p4 value as a pointer. +*/ +SQLITE_PRIVATE int sqlite3VdbeAddOp4( + Vdbe *p, /* Add the opcode to this VM */ + int op, /* The new opcode */ + int p1, /* The P1 operand */ + int p2, /* The P2 operand */ + int p3, /* The P3 operand */ + const char *zP4, /* The P4 operand */ + int p4type /* P4 operand type */ +){ + int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3); + sqlite3VdbeChangeP4(p, addr, zP4, p4type); + return addr; +} + +/* +** Add an OP_ParseSchema opcode. This routine is broken out from +** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees +** as having been used. +** +** The zWhere string must have been obtained from sqlite3_malloc(). +** This routine will take ownership of the allocated memory. +*/ +SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere){ + int j; + int addr = sqlite3VdbeAddOp3(p, OP_ParseSchema, iDb, 0, 0); + sqlite3VdbeChangeP4(p, addr, zWhere, P4_DYNAMIC); + for(j=0; jdb->nDb; j++) sqlite3VdbeUsesBtree(p, j); +} + +/* +** Add an opcode that includes the p4 value as an integer. +*/ +SQLITE_PRIVATE int sqlite3VdbeAddOp4Int( + Vdbe *p, /* Add the opcode to this VM */ + int op, /* The new opcode */ + int p1, /* The P1 operand */ + int p2, /* The P2 operand */ + int p3, /* The P3 operand */ + int p4 /* The P4 operand as an integer */ +){ + int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3); + sqlite3VdbeChangeP4(p, addr, SQLITE_INT_TO_PTR(p4), P4_INT32); + return addr; +} + +/* +** Create a new symbolic label for an instruction that has yet to be +** coded. The symbolic label is really just a negative number. The +** label can be used as the P2 value of an operation. Later, when +** the label is resolved to a specific address, the VDBE will scan +** through its operation list and change all values of P2 which match +** the label into the resolved address. +** +** The VDBE knows that a P2 value is a label because labels are +** always negative and P2 values are suppose to be non-negative. +** Hence, a negative P2 value is a label that has yet to be resolved. +** +** Zero is returned if a malloc() fails. +*/ +SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *v){ + Parse *p = v->pParse; + int i = p->nLabel++; + assert( v->magic==VDBE_MAGIC_INIT ); + if( (i & (i-1))==0 ){ + p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel, + (i*2+1)*sizeof(p->aLabel[0])); + } + if( p->aLabel ){ + p->aLabel[i] = -1; + } + return -1-i; +} + +/* +** Resolve label "x" to be the address of the next instruction to +** be inserted. The parameter "x" must have been obtained from +** a prior call to sqlite3VdbeMakeLabel(). +*/ +SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){ + Parse *p = v->pParse; + int j = -1-x; + assert( v->magic==VDBE_MAGIC_INIT ); + assert( jnLabel ); + if( ALWAYS(j>=0) && p->aLabel ){ + p->aLabel[j] = v->nOp; + } + p->iFixedOp = v->nOp - 1; +} + +/* +** Mark the VDBE as one that can only be run one time. +*/ +SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe *p){ + p->runOnlyOnce = 1; +} + +#ifdef SQLITE_DEBUG /* sqlite3AssertMayAbort() logic */ + +/* +** The following type and function are used to iterate through all opcodes +** in a Vdbe main program and each of the sub-programs (triggers) it may +** invoke directly or indirectly. It should be used as follows: +** +** Op *pOp; +** VdbeOpIter sIter; +** +** memset(&sIter, 0, sizeof(sIter)); +** sIter.v = v; // v is of type Vdbe* +** while( (pOp = opIterNext(&sIter)) ){ +** // Do something with pOp +** } +** sqlite3DbFree(v->db, sIter.apSub); +** +*/ +typedef struct VdbeOpIter VdbeOpIter; +struct VdbeOpIter { + Vdbe *v; /* Vdbe to iterate through the opcodes of */ + SubProgram **apSub; /* Array of subprograms */ + int nSub; /* Number of entries in apSub */ + int iAddr; /* Address of next instruction to return */ + int iSub; /* 0 = main program, 1 = first sub-program etc. */ +}; +static Op *opIterNext(VdbeOpIter *p){ + Vdbe *v = p->v; + Op *pRet = 0; + Op *aOp; + int nOp; + + if( p->iSub<=p->nSub ){ + + if( p->iSub==0 ){ + aOp = v->aOp; + nOp = v->nOp; + }else{ + aOp = p->apSub[p->iSub-1]->aOp; + nOp = p->apSub[p->iSub-1]->nOp; + } + assert( p->iAddriAddr]; + p->iAddr++; + if( p->iAddr==nOp ){ + p->iSub++; + p->iAddr = 0; + } + + if( pRet->p4type==P4_SUBPROGRAM ){ + int nByte = (p->nSub+1)*sizeof(SubProgram*); + int j; + for(j=0; jnSub; j++){ + if( p->apSub[j]==pRet->p4.pProgram ) break; + } + if( j==p->nSub ){ + p->apSub = sqlite3DbReallocOrFree(v->db, p->apSub, nByte); + if( !p->apSub ){ + pRet = 0; + }else{ + p->apSub[p->nSub++] = pRet->p4.pProgram; + } + } + } + } + + return pRet; +} + +/* +** Check if the program stored in the VM associated with pParse may +** throw an ABORT exception (causing the statement, but not entire transaction +** to be rolled back). This condition is true if the main program or any +** sub-programs contains any of the following: +** +** * OP_Halt with P1=SQLITE_CONSTRAINT and P2=OE_Abort. +** * OP_HaltIfNull with P1=SQLITE_CONSTRAINT and P2=OE_Abort. +** * OP_Destroy +** * OP_VUpdate +** * OP_VRename +** * OP_FkCounter with P2==0 (immediate foreign key constraint) +** +** Then check that the value of Parse.mayAbort is true if an +** ABORT may be thrown, or false otherwise. Return true if it does +** match, or false otherwise. This function is intended to be used as +** part of an assert statement in the compiler. Similar to: +** +** assert( sqlite3VdbeAssertMayAbort(pParse->pVdbe, pParse->mayAbort) ); +*/ +SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ + int hasAbort = 0; + int hasFkCounter = 0; + Op *pOp; + VdbeOpIter sIter; + memset(&sIter, 0, sizeof(sIter)); + sIter.v = v; + + while( (pOp = opIterNext(&sIter))!=0 ){ + int opcode = pOp->opcode; + if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename + || ((opcode==OP_Halt || opcode==OP_HaltIfNull) + && ((pOp->p1&0xff)==SQLITE_CONSTRAINT && pOp->p2==OE_Abort)) + ){ + hasAbort = 1; + break; + } +#ifndef SQLITE_OMIT_FOREIGN_KEY + if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){ + hasFkCounter = 1; + } +#endif + } + sqlite3DbFree(v->db, sIter.apSub); + + /* Return true if hasAbort==mayAbort. Or if a malloc failure occurred. + ** If malloc failed, then the while() loop above may not have iterated + ** through all opcodes and hasAbort may be set incorrectly. Return + ** true for this case to prevent the assert() in the callers frame + ** from failing. */ + return ( v->db->mallocFailed || hasAbort==mayAbort || hasFkCounter ); +} +#endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */ + +/* +** Loop through the program looking for P2 values that are negative +** on jump instructions. 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, OP_AggStep or OP_VFilter opcode. This is used by +** sqlite3VdbeMakeReady() to size the Vdbe.apArg[] array. +** +** The Op.opflags field is set on all opcodes. +*/ +static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ + int i; + int nMaxArgs = *pMaxFuncArgs; + Op *pOp; + Parse *pParse = p->pParse; + int *aLabel = pParse->aLabel; + p->readOnly = 1; + p->bIsReader = 0; + for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){ + u8 opcode = pOp->opcode; + + /* NOTE: Be sure to update mkopcodeh.awk when adding or removing + ** cases from this switch! */ + switch( opcode ){ + case OP_Function: + case OP_AggStep: { + if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5; + break; + } + case OP_Transaction: { + if( pOp->p2!=0 ) p->readOnly = 0; + /* fall thru */ + } + case OP_AutoCommit: + case OP_Savepoint: { + p->bIsReader = 1; + break; + } +#ifndef SQLITE_OMIT_WAL + case OP_Checkpoint: +#endif + case OP_Vacuum: + case OP_JournalMode: { + p->readOnly = 0; + p->bIsReader = 1; + break; + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + case OP_VUpdate: { + if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; + break; + } + case OP_VFilter: { + int n; + assert( p->nOp - i >= 3 ); + assert( pOp[-1].opcode==OP_Integer ); + n = pOp[-1].p1; + if( n>nMaxArgs ) nMaxArgs = n; + break; + } +#endif + case OP_Next: + case OP_NextIfOpen: + case OP_SorterNext: { + pOp->p4.xAdvance = sqlite3BtreeNext; + pOp->p4type = P4_ADVANCE; + break; + } + case OP_Prev: + case OP_PrevIfOpen: { + pOp->p4.xAdvance = sqlite3BtreePrevious; + pOp->p4type = P4_ADVANCE; + break; + } + } + + pOp->opflags = sqlite3OpcodeProperty[opcode]; + if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){ + assert( -1-pOp->p2nLabel ); + pOp->p2 = aLabel[-1-pOp->p2]; + } + } + sqlite3DbFree(p->db, pParse->aLabel); + pParse->aLabel = 0; + pParse->nLabel = 0; + *pMaxFuncArgs = nMaxArgs; + assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) ); +} + +/* +** Return the address of the next instruction to be inserted. +*/ +SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe *p){ + assert( p->magic==VDBE_MAGIC_INIT ); + return p->nOp; +} + +/* +** This function returns a pointer to the array of opcodes associated with +** the Vdbe passed as the first argument. It is the callers responsibility +** to arrange for the returned array to be eventually freed using the +** vdbeFreeOpArray() function. +** +** Before returning, *pnOp is set to the number of entries in the returned +** array. Also, *pnMaxArg is set to the larger of its current value and +** the number of entries in the Vdbe.apArg[] array required to execute the +** returned program. +*/ +SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){ + VdbeOp *aOp = p->aOp; + assert( aOp && !p->db->mallocFailed ); + + /* Check that sqlite3VdbeUsesBtree() was not called on this VM */ + assert( DbMaskAllZero(p->btreeMask) ); + + resolveP2Values(p, pnMaxArg); + *pnOp = p->nOp; + p->aOp = 0; + return aOp; +} + +/* +** Add a whole list of operations to the operation stack. Return the +** address of the first operation added. +*/ +SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp, int iLineno){ + int addr; + assert( p->magic==VDBE_MAGIC_INIT ); + if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p, nOp) ){ + return 0; + } + addr = p->nOp; + if( ALWAYS(nOp>0) ){ + int i; + VdbeOpList const *pIn = aOp; + for(i=0; ip2; + VdbeOp *pOut = &p->aOp[i+addr]; + pOut->opcode = pIn->opcode; + pOut->p1 = pIn->p1; + if( p2<0 ){ + assert( sqlite3OpcodeProperty[pOut->opcode] & OPFLG_JUMP ); + pOut->p2 = addr + ADDR(p2); + }else{ + pOut->p2 = p2; + } + pOut->p3 = pIn->p3; + pOut->p4type = P4_NOTUSED; + pOut->p4.p = 0; + pOut->p5 = 0; +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + pOut->zComment = 0; +#endif +#ifdef SQLITE_VDBE_COVERAGE + pOut->iSrcLine = iLineno+i; +#else + (void)iLineno; +#endif +#ifdef SQLITE_DEBUG + if( p->db->flags & SQLITE_VdbeAddopTrace ){ + sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]); + } +#endif + } + p->nOp += nOp; + } + return addr; +} + +#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) +/* +** Add an entry to the array of counters managed by sqlite3_stmt_scanstatus(). +*/ +SQLITE_PRIVATE void sqlite3VdbeScanStatus( + Vdbe *p, /* VM to add scanstatus() to */ + int addrExplain, /* Address of OP_Explain (or 0) */ + int addrLoop, /* Address of loop counter */ + int addrVisit, /* Address of rows visited counter */ + LogEst nEst, /* Estimated number of output rows */ + const char *zName /* Name of table or index being scanned */ +){ + int nByte = (p->nScan+1) * sizeof(ScanStatus); + ScanStatus *aNew; + aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte); + if( aNew ){ + ScanStatus *pNew = &aNew[p->nScan++]; + pNew->addrExplain = addrExplain; + pNew->addrLoop = addrLoop; + pNew->addrVisit = addrVisit; + pNew->nEst = nEst; + pNew->zName = sqlite3DbStrDup(p->db, zName); + p->aScan = aNew; + } +} +#endif + + +/* +** Change the value of the P1 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. +*/ +SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe *p, u32 addr, int val){ + assert( p!=0 ); + if( ((u32)p->nOp)>addr ){ + p->aOp[addr].p1 = val; + } +} + +/* +** Change the value of the P2 operand for a specific instruction. +** This routine is useful for setting a jump destination. +*/ +SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, u32 addr, int val){ + assert( p!=0 ); + if( ((u32)p->nOp)>addr ){ + p->aOp[addr].p2 = val; + } +} + +/* +** Change the value of the P3 operand for a specific instruction. +*/ +SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){ + assert( p!=0 ); + if( ((u32)p->nOp)>addr ){ + p->aOp[addr].p3 = val; + } +} + +/* +** Change the value of the P5 operand for the most recently +** added operation. +*/ +SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u8 val){ + assert( p!=0 ); + if( p->aOp ){ + assert( p->nOp>0 ); + p->aOp[p->nOp-1].p5 = val; + } +} + +/* +** Change the P2 operand of instruction addr so that it points to +** the address of the next instruction to be coded. +*/ +SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){ + sqlite3VdbeChangeP2(p, addr, p->nOp); + p->pParse->iFixedOp = p->nOp - 1; +} + + +/* +** If the input FuncDef structure is ephemeral, then free it. If +** the FuncDef is not ephermal, then do nothing. +*/ +static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){ + if( ALWAYS(pDef) && (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){ + sqlite3DbFree(db, pDef); + } +} + +static void vdbeFreeOpArray(sqlite3 *, Op *, int); + +/* +** Delete a P4 value if necessary. +*/ +static void freeP4(sqlite3 *db, int p4type, void *p4){ + if( p4 ){ + assert( db ); + switch( p4type ){ + case P4_REAL: + case P4_INT64: + case P4_DYNAMIC: + case P4_INTARRAY: { + sqlite3DbFree(db, p4); + break; + } + case P4_KEYINFO: { + if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4); + break; + } + case P4_MPRINTF: { + if( db->pnBytesFreed==0 ) sqlite3_free(p4); + break; + } + case P4_FUNCDEF: { + freeEphemeralFunction(db, (FuncDef*)p4); + break; + } + case P4_MEM: { + if( db->pnBytesFreed==0 ){ + sqlite3ValueFree((sqlite3_value*)p4); + }else{ + Mem *p = (Mem*)p4; + if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); + sqlite3DbFree(db, p); + } + break; + } + case P4_VTAB : { + if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4); + break; + } + } + } +} + +/* +** Free the space allocated for aOp and any p4 values allocated for the +** opcodes contained within. If aOp is not NULL it is assumed to contain +** nOp entries. +*/ +static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){ + if( aOp ){ + Op *pOp; + for(pOp=aOp; pOp<&aOp[nOp]; pOp++){ + freeP4(db, pOp->p4type, pOp->p4.p); +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + sqlite3DbFree(db, pOp->zComment); +#endif + } + } + sqlite3DbFree(db, aOp); +} + +/* +** Link the SubProgram object passed as the second argument into the linked +** list at Vdbe.pSubProgram. This list is used to delete all sub-program +** objects when the VM is no longer required. +*/ +SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){ + p->pNext = pVdbe->pProgram; + pVdbe->pProgram = p; +} + +/* +** Change the opcode at addr into OP_Noop +*/ +SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){ + if( addrnOp ){ + VdbeOp *pOp = &p->aOp[addr]; + sqlite3 *db = p->db; + freeP4(db, pOp->p4type, pOp->p4.p); + memset(pOp, 0, sizeof(pOp[0])); + pOp->opcode = OP_Noop; + if( addr==p->nOp-1 ) p->nOp--; + } +} + +/* +** If the last opcode is "op" and it is not a jump destination, +** then remove it. Return true if and only if an opcode was removed. +*/ +SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){ + if( (p->nOp-1)>(p->pParse->iFixedOp) && p->aOp[p->nOp-1].opcode==op ){ + sqlite3VdbeChangeToNoop(p, p->nOp-1); + return 1; + }else{ + return 0; + } +} + +/* +** Change the value of the P4 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 P4 operand is dynamic, meaning that a copy of +** the string is made into memory obtained from sqlite3_malloc(). +** A value of n==0 means copy bytes of zP4 up to and including the +** first null byte. If n>0 then copy n+1 bytes of zP4. +** +** Other values of n (P4_STATIC, P4_COLLSEQ etc.) indicate that zP4 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 P4 on the most recently inserted instruction. +*/ +SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){ + Op *pOp; + sqlite3 *db; + assert( p!=0 ); + db = p->db; + assert( p->magic==VDBE_MAGIC_INIT ); + if( p->aOp==0 || db->mallocFailed ){ + if( n!=P4_VTAB ){ + freeP4(db, n, (void*)*(char**)&zP4); + } + return; + } + assert( p->nOp>0 ); + assert( addrnOp ); + if( addr<0 ){ + addr = p->nOp - 1; + } + pOp = &p->aOp[addr]; + assert( pOp->p4type==P4_NOTUSED + || pOp->p4type==P4_INT32 + || pOp->p4type==P4_KEYINFO ); + freeP4(db, pOp->p4type, pOp->p4.p); + pOp->p4.p = 0; + if( n==P4_INT32 ){ + /* Note: this cast is safe, because the origin data point was an int + ** that was cast to a (const char *). */ + pOp->p4.i = SQLITE_PTR_TO_INT(zP4); + pOp->p4type = P4_INT32; + }else if( zP4==0 ){ + pOp->p4.p = 0; + pOp->p4type = P4_NOTUSED; + }else if( n==P4_KEYINFO ){ + pOp->p4.p = (void*)zP4; + pOp->p4type = P4_KEYINFO; + }else if( n==P4_VTAB ){ + pOp->p4.p = (void*)zP4; + pOp->p4type = P4_VTAB; + sqlite3VtabLock((VTable *)zP4); + assert( ((VTable *)zP4)->db==p->db ); + }else if( n<0 ){ + pOp->p4.p = (void*)zP4; + pOp->p4type = (signed char)n; + }else{ + if( n==0 ) n = sqlite3Strlen30(zP4); + pOp->p4.z = sqlite3DbStrNDup(p->db, zP4, n); + pOp->p4type = P4_DYNAMIC; + } +} + +/* +** Set the P4 on the most recently added opcode to the KeyInfo for the +** index given. +*/ +SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){ + Vdbe *v = pParse->pVdbe; + assert( v!=0 ); + assert( pIdx!=0 ); + sqlite3VdbeChangeP4(v, -1, (char*)sqlite3KeyInfoOfIndex(pParse, pIdx), + P4_KEYINFO); +} + +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS +/* +** Change the comment on the most recently coded instruction. Or +** insert a No-op and add the comment to that new instruction. This +** makes the code easier to read during debugging. None of this happens +** in a production build. +*/ +static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){ + assert( p->nOp>0 || p->aOp==0 ); + assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed ); + if( p->nOp ){ + assert( p->aOp ); + sqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment); + p->aOp[p->nOp-1].zComment = sqlite3VMPrintf(p->db, zFormat, ap); + } +} +SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){ + va_list ap; + if( p ){ + va_start(ap, zFormat); + vdbeVComment(p, zFormat, ap); + va_end(ap); + } +} +SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){ + va_list ap; + if( p ){ + sqlite3VdbeAddOp0(p, OP_Noop); + va_start(ap, zFormat); + vdbeVComment(p, zFormat, ap); + va_end(ap); + } +} +#endif /* NDEBUG */ + +#ifdef SQLITE_VDBE_COVERAGE +/* +** Set the value if the iSrcLine field for the previously coded instruction. +*/ +SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe *v, int iLine){ + sqlite3VdbeGetOp(v,-1)->iSrcLine = iLine; +} +#endif /* SQLITE_VDBE_COVERAGE */ + +/* +** Return the opcode for a given address. If the address is -1, then +** return the most recently inserted opcode. +** +** If a memory allocation error has occurred prior to the calling of this +** routine, then a pointer to a dummy VdbeOp will be returned. That opcode +** is readable but not writable, though it is cast to a writable value. +** The return of a dummy opcode allows the call to continue functioning +** after an OOM fault without having to check to see if the return from +** this routine is a valid pointer. But because the dummy.opcode is 0, +** dummy will never be written to. This is verified by code inspection and +** by running with Valgrind. +*/ +SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ + /* C89 specifies that the constant "dummy" will be initialized to all + ** zeros, which is correct. MSVC generates a warning, nevertheless. */ + static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */ + assert( p->magic==VDBE_MAGIC_INIT ); + if( addr<0 ){ + addr = p->nOp - 1; + } + assert( (addr>=0 && addrnOp) || p->db->mallocFailed ); + if( p->db->mallocFailed ){ + return (VdbeOp*)&dummy; + }else{ + return &p->aOp[addr]; + } +} + +#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) +/* +** Return an integer value for one of the parameters to the opcode pOp +** determined by character c. +*/ +static int translateP(char c, const Op *pOp){ + if( c=='1' ) return pOp->p1; + if( c=='2' ) return pOp->p2; + if( c=='3' ) return pOp->p3; + if( c=='4' ) return pOp->p4.i; + return pOp->p5; +} + +/* +** Compute a string for the "comment" field of a VDBE opcode listing. +** +** The Synopsis: field in comments in the vdbe.c source file gets converted +** to an extra string that is appended to the sqlite3OpcodeName(). In the +** absence of other comments, this synopsis becomes the comment on the opcode. +** Some translation occurs: +** +** "PX" -> "r[X]" +** "PX@PY" -> "r[X..X+Y-1]" or "r[x]" if y is 0 or 1 +** "PX@PY+1" -> "r[X..X+Y]" or "r[x]" if y is 0 +** "PY..PY" -> "r[X..Y]" or "r[x]" if y<=x +*/ +static int displayComment( + const Op *pOp, /* The opcode to be commented */ + const char *zP4, /* Previously obtained value for P4 */ + char *zTemp, /* Write result here */ + int nTemp /* Space available in zTemp[] */ +){ + const char *zOpName; + const char *zSynopsis; + int nOpName; + int ii, jj; + zOpName = sqlite3OpcodeName(pOp->opcode); + nOpName = sqlite3Strlen30(zOpName); + if( zOpName[nOpName+1] ){ + int seenCom = 0; + char c; + zSynopsis = zOpName += nOpName + 1; + for(ii=jj=0; jjzComment); + seenCom = 1; + }else{ + int v1 = translateP(c, pOp); + int v2; + sqlite3_snprintf(nTemp-jj, zTemp+jj, "%d", v1); + if( strncmp(zSynopsis+ii+1, "@P", 2)==0 ){ + ii += 3; + jj += sqlite3Strlen30(zTemp+jj); + v2 = translateP(zSynopsis[ii], pOp); + if( strncmp(zSynopsis+ii+1,"+1",2)==0 ){ + ii += 2; + v2++; + } + if( v2>1 ){ + sqlite3_snprintf(nTemp-jj, zTemp+jj, "..%d", v1+v2-1); + } + }else if( strncmp(zSynopsis+ii+1, "..P3", 4)==0 && pOp->p3==0 ){ + ii += 4; + } + } + jj += sqlite3Strlen30(zTemp+jj); + }else{ + zTemp[jj++] = c; + } + } + if( !seenCom && jjzComment ){ + sqlite3_snprintf(nTemp-jj, zTemp+jj, "; %s", pOp->zComment); + jj += sqlite3Strlen30(zTemp+jj); + } + if( jjzComment ){ + sqlite3_snprintf(nTemp, zTemp, "%s", pOp->zComment); + jj = sqlite3Strlen30(zTemp); + }else{ + zTemp[0] = 0; + jj = 0; + } + return jj; +} +#endif /* SQLITE_DEBUG */ + + +#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \ + || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) +/* +** Compute a string that describes the P4 parameter for an opcode. +** Use zTemp for any required temporary buffer space. +*/ +static char *displayP4(Op *pOp, char *zTemp, int nTemp){ + char *zP4 = zTemp; + assert( nTemp>=20 ); + switch( pOp->p4type ){ + case P4_KEYINFO: { + int i, j; + KeyInfo *pKeyInfo = pOp->p4.pKeyInfo; + assert( pKeyInfo->aSortOrder!=0 ); + sqlite3_snprintf(nTemp, zTemp, "k(%d", pKeyInfo->nField); + i = sqlite3Strlen30(zTemp); + for(j=0; jnField; j++){ + CollSeq *pColl = pKeyInfo->aColl[j]; + const char *zColl = pColl ? pColl->zName : "nil"; + int n = sqlite3Strlen30(zColl); + if( n==6 && memcmp(zColl,"BINARY",6)==0 ){ + zColl = "B"; + n = 1; + } + if( i+n>nTemp-6 ){ + memcpy(&zTemp[i],",...",4); + break; + } + zTemp[i++] = ','; + if( pKeyInfo->aSortOrder[j] ){ + zTemp[i++] = '-'; + } + memcpy(&zTemp[i], zColl, n+1); + i += n; + } + zTemp[i++] = ')'; + zTemp[i] = 0; + assert( ip4.pColl; + sqlite3_snprintf(nTemp, zTemp, "(%.20s)", pColl->zName); + break; + } + case P4_FUNCDEF: { + FuncDef *pDef = pOp->p4.pFunc; + sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg); + break; + } + case P4_INT64: { + sqlite3_snprintf(nTemp, zTemp, "%lld", *pOp->p4.pI64); + break; + } + case P4_INT32: { + sqlite3_snprintf(nTemp, zTemp, "%d", pOp->p4.i); + break; + } + case P4_REAL: { + sqlite3_snprintf(nTemp, zTemp, "%.16g", *pOp->p4.pReal); + break; + } + case P4_MEM: { + Mem *pMem = pOp->p4.pMem; + if( pMem->flags & MEM_Str ){ + zP4 = pMem->z; + }else if( pMem->flags & MEM_Int ){ + sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i); + }else if( pMem->flags & MEM_Real ){ + sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->u.r); + }else if( pMem->flags & MEM_Null ){ + sqlite3_snprintf(nTemp, zTemp, "NULL"); + }else{ + assert( pMem->flags & MEM_Blob ); + zP4 = "(blob)"; + } + break; + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + case P4_VTAB: { + sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab; + sqlite3_snprintf(nTemp, zTemp, "vtab:%p", pVtab); + break; + } +#endif + case P4_INTARRAY: { + sqlite3_snprintf(nTemp, zTemp, "intarray"); + break; + } + case P4_SUBPROGRAM: { + sqlite3_snprintf(nTemp, zTemp, "program"); + break; + } + case P4_ADVANCE: { + zTemp[0] = 0; + break; + } + default: { + zP4 = pOp->p4.z; + if( zP4==0 ){ + zP4 = zTemp; + zTemp[0] = 0; + } + } + } + assert( zP4!=0 ); + return zP4; +} +#endif + +/* +** Declare to the Vdbe that the BTree object at db->aDb[i] is used. +** +** The prepared statements need to know in advance the complete set of +** attached databases that will be use. A mask of these databases +** is maintained in p->btreeMask. The p->lockMask value is the subset of +** p->btreeMask of databases that will require a lock. +*/ +SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe *p, int i){ + assert( i>=0 && idb->nDb && i<(int)sizeof(yDbMask)*8 ); + assert( i<(int)sizeof(p->btreeMask)*8 ); + DbMaskSet(p->btreeMask, i); + if( i!=1 && sqlite3BtreeSharable(p->db->aDb[i].pBt) ){ + DbMaskSet(p->lockMask, i); + } +} + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 +/* +** If SQLite is compiled to support shared-cache mode and to be threadsafe, +** this routine obtains the mutex associated with each BtShared structure +** that may be accessed by the VM passed as an argument. In doing so it also +** sets the BtShared.db member of each of the BtShared structures, ensuring +** that the correct busy-handler callback is invoked if required. +** +** If SQLite is not threadsafe but does support shared-cache mode, then +** sqlite3BtreeEnter() is invoked to set the BtShared.db variables +** of all of BtShared structures accessible via the database handle +** associated with the VM. +** +** If SQLite is not threadsafe and does not support shared-cache mode, this +** function is a no-op. +** +** The p->btreeMask field is a bitmask of all btrees that the prepared +** statement p will ever use. Let N be the number of bits in p->btreeMask +** corresponding to btrees that use shared cache. Then the runtime of +** this routine is N*N. But as N is rarely more than 1, this should not +** be a problem. +*/ +SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe *p){ + int i; + sqlite3 *db; + Db *aDb; + int nDb; + if( DbMaskAllZero(p->lockMask) ) return; /* The common case */ + db = p->db; + aDb = db->aDb; + nDb = db->nDb; + for(i=0; ilockMask,i) && ALWAYS(aDb[i].pBt!=0) ){ + sqlite3BtreeEnter(aDb[i].pBt); + } + } +} +#endif + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 +/* +** Unlock all of the btrees previously locked by a call to sqlite3VdbeEnter(). +*/ +SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe *p){ + int i; + sqlite3 *db; + Db *aDb; + int nDb; + if( DbMaskAllZero(p->lockMask) ) return; /* The common case */ + db = p->db; + aDb = db->aDb; + nDb = db->nDb; + for(i=0; ilockMask,i) && ALWAYS(aDb[i].pBt!=0) ){ + sqlite3BtreeLeave(aDb[i].pBt); + } + } +} +#endif + +#if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) +/* +** Print a single opcode. This routine is used for debugging only. +*/ +SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){ + char *zP4; + char zPtr[50]; + char zCom[100]; + static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-13s %.2X %s\n"; + if( pOut==0 ) pOut = stdout; + zP4 = displayP4(pOp, zPtr, sizeof(zPtr)); +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + displayComment(pOp, zP4, zCom, sizeof(zCom)); +#else + zCom[0] = 0; +#endif + /* NB: The sqlite3OpcodeName() function is implemented by code created + ** by the mkopcodeh.awk and mkopcodec.awk scripts which extract the + ** information from the vdbe.c source text */ + fprintf(pOut, zFormat1, pc, + sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5, + zCom + ); + fflush(pOut); +} +#endif + +/* +** Release an array of N Mem elements +*/ +static void releaseMemArray(Mem *p, int N){ + if( p && N ){ + Mem *pEnd = &p[N]; + sqlite3 *db = p->db; + u8 malloc_failed = db->mallocFailed; + if( db->pnBytesFreed ){ + do{ + if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); + }while( (++p)flags & MEM_Agg ); + testcase( p->flags & MEM_Dyn ); + testcase( p->flags & MEM_Frame ); + testcase( p->flags & MEM_RowSet ); + if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){ + sqlite3VdbeMemRelease(p); + }else if( p->szMalloc ){ + sqlite3DbFree(db, p->zMalloc); + p->szMalloc = 0; + } + + p->flags = MEM_Undefined; + }while( (++p)mallocFailed = malloc_failed; + } +} + +/* +** Delete a VdbeFrame object and its contents. VdbeFrame objects are +** allocated by the OP_Program opcode in sqlite3VdbeExec(). +*/ +SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame *p){ + int i; + Mem *aMem = VdbeFrameMem(p); + VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem]; + for(i=0; inChildCsr; i++){ + sqlite3VdbeFreeCursor(p->v, apCsr[i]); + } + releaseMemArray(aMem, p->nChildMem); + sqlite3DbFree(p->v->db, p); +} + +#ifndef SQLITE_OMIT_EXPLAIN +/* +** Give a listing of the program in the virtual machine. +** +** The interface is the same as sqlite3VdbeExec(). But instead of +** running the code, it invokes the callback once for each instruction. +** This feature is used to implement "EXPLAIN". +** +** When p->explain==1, each instruction is listed. When +** p->explain==2, only OP_Explain instructions are listed and these +** are shown in a different format. p->explain==2 is used to implement +** EXPLAIN QUERY PLAN. +** +** When p->explain==1, first the main program is listed, then each of +** the trigger subprograms are listed one by one. +*/ +SQLITE_PRIVATE int sqlite3VdbeList( + Vdbe *p /* The VDBE */ +){ + int nRow; /* Stop when row count reaches this */ + int nSub = 0; /* Number of sub-vdbes seen so far */ + SubProgram **apSub = 0; /* Array of sub-vdbes */ + Mem *pSub = 0; /* Memory cell hold array of subprogs */ + sqlite3 *db = p->db; /* The database connection */ + int i; /* Loop counter */ + int rc = SQLITE_OK; /* Return code */ + Mem *pMem = &p->aMem[1]; /* First Mem of result set */ + + assert( p->explain ); + assert( p->magic==VDBE_MAGIC_RUN ); + assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM ); + + /* Even though this opcode does not use dynamic strings for + ** the result, result columns may become dynamic if the user calls + ** sqlite3_column_text16(), causing a translation to UTF-16 encoding. + */ + releaseMemArray(pMem, 8); + p->pResultSet = 0; + + if( p->rc==SQLITE_NOMEM ){ + /* This happens if a malloc() inside a call to sqlite3_column_text() or + ** sqlite3_column_text16() failed. */ + db->mallocFailed = 1; + return SQLITE_ERROR; + } + + /* When the number of output rows reaches nRow, that means the + ** listing has finished and sqlite3_step() should return SQLITE_DONE. + ** nRow is the sum of the number of rows in the main program, plus + ** the sum of the number of rows in all trigger subprograms encountered + ** so far. The nRow value will increase as new trigger subprograms are + ** encountered, but p->pc will eventually catch up to nRow. + */ + nRow = p->nOp; + if( p->explain==1 ){ + /* The first 8 memory cells are used for the result set. So we will + ** commandeer the 9th cell to use as storage for an array of pointers + ** to trigger subprograms. The VDBE is guaranteed to have at least 9 + ** cells. */ + assert( p->nMem>9 ); + pSub = &p->aMem[9]; + if( pSub->flags&MEM_Blob ){ + /* On the first call to sqlite3_step(), pSub will hold a NULL. It is + ** initialized to a BLOB by the P4_SUBPROGRAM processing logic below */ + nSub = pSub->n/sizeof(Vdbe*); + apSub = (SubProgram **)pSub->z; + } + for(i=0; inOp; + } + } + + do{ + i = p->pc++; + }while( iexplain==2 && p->aOp[i].opcode!=OP_Explain ); + if( i>=nRow ){ + p->rc = SQLITE_OK; + rc = SQLITE_DONE; + }else if( db->u1.isInterrupted ){ + p->rc = SQLITE_INTERRUPT; + rc = SQLITE_ERROR; + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(p->rc)); + }else{ + char *zP4; + Op *pOp; + if( inOp ){ + /* The output line number is small enough that we are still in the + ** main program. */ + pOp = &p->aOp[i]; + }else{ + /* We are currently listing subprograms. Figure out which one and + ** pick up the appropriate opcode. */ + int j; + i -= p->nOp; + for(j=0; i>=apSub[j]->nOp; j++){ + i -= apSub[j]->nOp; + } + pOp = &apSub[j]->aOp[i]; + } + if( p->explain==1 ){ + pMem->flags = MEM_Int; + pMem->u.i = i; /* Program counter */ + pMem++; + + pMem->flags = MEM_Static|MEM_Str|MEM_Term; + pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */ + assert( pMem->z!=0 ); + pMem->n = sqlite3Strlen30(pMem->z); + pMem->enc = SQLITE_UTF8; + pMem++; + + /* When an OP_Program opcode is encounter (the only opcode that has + ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms + ** kept in p->aMem[9].z to hold the new program - assuming this subprogram + ** has not already been seen. + */ + if( pOp->p4type==P4_SUBPROGRAM ){ + int nByte = (nSub+1)*sizeof(SubProgram*); + int j; + for(j=0; jp4.pProgram ) break; + } + if( j==nSub && SQLITE_OK==sqlite3VdbeMemGrow(pSub, nByte, nSub!=0) ){ + apSub = (SubProgram **)pSub->z; + apSub[nSub++] = pOp->p4.pProgram; + pSub->flags |= MEM_Blob; + pSub->n = nSub*sizeof(SubProgram*); + } + } + } + + pMem->flags = MEM_Int; + pMem->u.i = pOp->p1; /* P1 */ + pMem++; + + pMem->flags = MEM_Int; + pMem->u.i = pOp->p2; /* P2 */ + pMem++; + + pMem->flags = MEM_Int; + pMem->u.i = pOp->p3; /* P3 */ + pMem++; + + if( sqlite3VdbeMemClearAndResize(pMem, 32) ){ /* P4 */ + assert( p->db->mallocFailed ); + return SQLITE_ERROR; + } + pMem->flags = MEM_Str|MEM_Term; + zP4 = displayP4(pOp, pMem->z, 32); + if( zP4!=pMem->z ){ + sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0); + }else{ + assert( pMem->z!=0 ); + pMem->n = sqlite3Strlen30(pMem->z); + pMem->enc = SQLITE_UTF8; + } + pMem++; + + if( p->explain==1 ){ + if( sqlite3VdbeMemClearAndResize(pMem, 4) ){ + assert( p->db->mallocFailed ); + return SQLITE_ERROR; + } + pMem->flags = MEM_Str|MEM_Term; + pMem->n = 2; + sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */ + pMem->enc = SQLITE_UTF8; + pMem++; + +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + if( sqlite3VdbeMemClearAndResize(pMem, 500) ){ + assert( p->db->mallocFailed ); + return SQLITE_ERROR; + } + pMem->flags = MEM_Str|MEM_Term; + pMem->n = displayComment(pOp, zP4, pMem->z, 500); + pMem->enc = SQLITE_UTF8; +#else + pMem->flags = MEM_Null; /* Comment */ +#endif + } + + p->nResColumn = 8 - 4*(p->explain-1); + p->pResultSet = &p->aMem[1]; + p->rc = SQLITE_OK; + rc = SQLITE_ROW; + } + return rc; +} +#endif /* SQLITE_OMIT_EXPLAIN */ + +#ifdef SQLITE_DEBUG +/* +** Print the SQL that was used to generate a VDBE program. +*/ +SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe *p){ + const char *z = 0; + if( p->zSql ){ + z = p->zSql; + }else if( p->nOp>=1 ){ + const VdbeOp *pOp = &p->aOp[0]; + if( pOp->opcode==OP_Init && pOp->p4.z!=0 ){ + z = pOp->p4.z; + while( sqlite3Isspace(*z) ) z++; + } + } + if( z ) printf("SQL: [%s]\n", z); +} +#endif + +#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE) +/* +** Print an IOTRACE message showing SQL content. +*/ +SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe *p){ + int nOp = p->nOp; + VdbeOp *pOp; + if( sqlite3IoTrace==0 ) return; + if( nOp<1 ) return; + pOp = &p->aOp[0]; + if( pOp->opcode==OP_Init && pOp->p4.z!=0 ){ + int i, j; + char z[1000]; + sqlite3_snprintf(sizeof(z), z, "%s", pOp->p4.z); + for(i=0; sqlite3Isspace(z[i]); i++){} + for(j=0; z[i]; i++){ + if( sqlite3Isspace(z[i]) ){ + if( z[i-1]!=' ' ){ + z[j++] = ' '; + } + }else{ + z[j++] = z[i]; + } + } + z[j] = 0; + sqlite3IoTrace("SQL %s\n", z); + } +} +#endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */ + +/* +** Allocate space from a fixed size buffer and return a pointer to +** that space. If insufficient space is available, return NULL. +** +** The pBuf parameter is the initial value of a pointer which will +** receive the new memory. pBuf is normally NULL. If pBuf is not +** NULL, it means that memory space has already been allocated and that +** this routine should not allocate any new memory. When pBuf is not +** NULL simply return pBuf. Only allocate new memory space when pBuf +** is NULL. +** +** nByte is the number of bytes of space needed. +** +** *ppFrom points to available space and pEnd points to the end of the +** available space. When space is allocated, *ppFrom is advanced past +** the end of the allocated space. +** +** *pnByte is a counter of the number of bytes of space that have failed +** to allocate. If there is insufficient space in *ppFrom to satisfy the +** request, then increment *pnByte by the amount of the request. +*/ +static void *allocSpace( + void *pBuf, /* Where return pointer will be stored */ + int nByte, /* Number of bytes to allocate */ + u8 **ppFrom, /* IN/OUT: Allocate from *ppFrom */ + u8 *pEnd, /* Pointer to 1 byte past the end of *ppFrom buffer */ + int *pnByte /* If allocation cannot be made, increment *pnByte */ +){ + assert( EIGHT_BYTE_ALIGNMENT(*ppFrom) ); + if( pBuf ) return pBuf; + nByte = ROUND8(nByte); + if( &(*ppFrom)[nByte] <= pEnd ){ + pBuf = (void*)*ppFrom; + *ppFrom += nByte; + }else{ + *pnByte += nByte; + } + return pBuf; +} + +/* +** Rewind the VDBE back to the beginning in preparation for +** running it. +*/ +SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){ +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) + int i; +#endif + 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. */ + p->magic = VDBE_MAGIC_RUN; + +#ifdef SQLITE_DEBUG + for(i=1; inMem; i++){ + assert( p->aMem[i].db==p->db ); + } +#endif + p->pc = -1; + p->rc = SQLITE_OK; + p->errorAction = OE_Abort; + p->magic = VDBE_MAGIC_RUN; + p->nChange = 0; + p->cacheCtr = 1; + p->minWriteFileFormat = 255; + p->iStatement = 0; + p->nFkConstraint = 0; +#ifdef VDBE_PROFILE + for(i=0; inOp; i++){ + p->aOp[i].cnt = 0; + p->aOp[i].cycles = 0; + } +#endif +} + +/* +** Prepare a virtual machine for execution for the first time after +** creating the virtual machine. This involves things such +** as allocating registers and initializing the program counter. +** After the VDBE has be prepped, it can be executed by one or more +** calls to sqlite3VdbeExec(). +** +** This function may be called exactly once on each virtual machine. +** After this routine is called the VM has been "packaged" and is ready +** to run. After this routine is called, further calls to +** sqlite3VdbeAddOp() functions are prohibited. This routine disconnects +** the Vdbe from the Parse object that helped generate it so that the +** the Vdbe becomes an independent entity and the Parse object can be +** destroyed. +** +** Use the sqlite3VdbeRewind() procedure to restore a virtual machine back +** to its initial state after it has been run. +*/ +SQLITE_PRIVATE void sqlite3VdbeMakeReady( + Vdbe *p, /* The VDBE */ + Parse *pParse /* Parsing context */ +){ + sqlite3 *db; /* The database connection */ + int nVar; /* Number of parameters */ + int nMem; /* Number of VM memory registers */ + int nCursor; /* Number of cursors required */ + int nArg; /* Number of arguments in subprograms */ + int nOnce; /* Number of OP_Once instructions */ + int n; /* Loop counter */ + u8 *zCsr; /* Memory available for allocation */ + u8 *zEnd; /* First byte past allocated memory */ + int nByte; /* How much extra memory is needed */ + + assert( p!=0 ); + assert( p->nOp>0 ); + assert( pParse!=0 ); + assert( p->magic==VDBE_MAGIC_INIT ); + assert( pParse==p->pParse ); + db = p->db; + assert( db->mallocFailed==0 ); + nVar = pParse->nVar; + nMem = pParse->nMem; + nCursor = pParse->nTab; + nArg = pParse->nMaxArg; + nOnce = pParse->nOnce; + if( nOnce==0 ) nOnce = 1; /* Ensure at least one byte in p->aOnceFlag[] */ + + /* For each cursor required, also allocate a memory cell. Memory + ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by + ** the vdbe program. Instead they are used to allocate space for + ** VdbeCursor/BtCursor structures. The blob of memory associated with + ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1) + ** stores the blob of memory associated with cursor 1, etc. + ** + ** See also: allocateCursor(). + */ + nMem += nCursor; + + /* Allocate space for memory registers, SQL variables, VDBE cursors and + ** an array to marshal SQL function arguments in. + */ + zCsr = (u8*)&p->aOp[p->nOp]; /* Memory avaliable for allocation */ + zEnd = (u8*)&p->aOp[pParse->nOpAlloc]; /* First byte past end of zCsr[] */ + + resolveP2Values(p, &nArg); + p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort); + if( pParse->explain && nMem<10 ){ + nMem = 10; + } + memset(zCsr, 0, zEnd-zCsr); + zCsr += (zCsr - (u8*)0)&7; + assert( EIGHT_BYTE_ALIGNMENT(zCsr) ); + p->expired = 0; + + /* Memory for registers, parameters, cursor, etc, is allocated in two + ** passes. On the first pass, we try to reuse unused space at the + ** end of the opcode array. If we are unable to satisfy all memory + ** requirements by reusing the opcode array tail, then the second + ** pass will fill in the rest using a fresh allocation. + ** + ** This two-pass approach that reuses as much memory as possible from + ** the leftover space at the end of the opcode array can significantly + ** reduce the amount of memory held by a prepared statement. + */ + do { + nByte = 0; + p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte); + p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte); + p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte); + p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte); + p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*), + &zCsr, zEnd, &nByte); + p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, &zCsr, zEnd, &nByte); +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + p->anExec = allocSpace(p->anExec, p->nOp*sizeof(i64), &zCsr, zEnd, &nByte); +#endif + if( nByte ){ + p->pFree = sqlite3DbMallocZero(db, nByte); + } + zCsr = p->pFree; + zEnd = &zCsr[nByte]; + }while( nByte && !db->mallocFailed ); + + p->nCursor = nCursor; + p->nOnceFlag = nOnce; + if( p->aVar ){ + p->nVar = (ynVar)nVar; + for(n=0; naVar[n].flags = MEM_Null; + p->aVar[n].db = db; + } + } + if( p->azVar && pParse->nzVar>0 ){ + p->nzVar = pParse->nzVar; + memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0])); + memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0])); + } + if( p->aMem ){ + p->aMem--; /* aMem[] goes from 1..nMem */ + p->nMem = nMem; /* not from 0..nMem-1 */ + for(n=1; n<=nMem; n++){ + p->aMem[n].flags = MEM_Undefined; + p->aMem[n].db = db; + } + } + p->explain = pParse->explain; + sqlite3VdbeRewind(p); +} + +/* +** Close a VDBE cursor and release all the resources that cursor +** happens to hold. +*/ +SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ + if( pCx==0 ){ + return; + } + sqlite3VdbeSorterClose(p->db, pCx); + if( pCx->pBt ){ + sqlite3BtreeClose(pCx->pBt); + /* The pCx->pCursor will be close automatically, if it exists, by + ** the call above. */ + }else if( pCx->pCursor ){ + sqlite3BtreeCloseCursor(pCx->pCursor); + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + else if( pCx->pVtabCursor ){ + sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor; + const sqlite3_module *pModule = pVtabCursor->pVtab->pModule; + assert( pVtabCursor->pVtab->nRef>0 ); + pVtabCursor->pVtab->nRef--; + pModule->xClose(pVtabCursor); + } +#endif +} + +/* +** Close all cursors in the current frame. +*/ +static void closeCursorsInFrame(Vdbe *p){ + if( p->apCsr ){ + int i; + for(i=0; inCursor; i++){ + VdbeCursor *pC = p->apCsr[i]; + if( pC ){ + sqlite3VdbeFreeCursor(p, pC); + p->apCsr[i] = 0; + } + } + } +} + +/* +** Copy the values stored in the VdbeFrame structure to its Vdbe. This +** is used, for example, when a trigger sub-program is halted to restore +** control to the main program. +*/ +SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){ + Vdbe *v = pFrame->v; + closeCursorsInFrame(v); +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + v->anExec = pFrame->anExec; +#endif + v->aOnceFlag = pFrame->aOnceFlag; + v->nOnceFlag = pFrame->nOnceFlag; + v->aOp = pFrame->aOp; + v->nOp = pFrame->nOp; + v->aMem = pFrame->aMem; + v->nMem = pFrame->nMem; + v->apCsr = pFrame->apCsr; + v->nCursor = pFrame->nCursor; + v->db->lastRowid = pFrame->lastRowid; + v->nChange = pFrame->nChange; + v->db->nChange = pFrame->nDbChange; + return pFrame->pc; +} + +/* +** Close all cursors. +** +** Also release any dynamic memory held by the VM in the Vdbe.aMem memory +** cell array. This is necessary as the memory cell array may contain +** pointers to VdbeFrame objects, which may in turn contain pointers to +** open cursors. +*/ +static void closeAllCursors(Vdbe *p){ + if( p->pFrame ){ + VdbeFrame *pFrame; + for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); + sqlite3VdbeFrameRestore(pFrame); + p->pFrame = 0; + p->nFrame = 0; + } + assert( p->nFrame==0 ); + closeCursorsInFrame(p); + if( p->aMem ){ + releaseMemArray(&p->aMem[1], p->nMem); + } + while( p->pDelFrame ){ + VdbeFrame *pDel = p->pDelFrame; + p->pDelFrame = pDel->pParent; + sqlite3VdbeFrameDelete(pDel); + } + + /* Delete any auxdata allocations made by the VM */ + if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p, -1, 0); + assert( p->pAuxData==0 ); +} + +/* +** Clean up the VM after a single run. +*/ +static void Cleanup(Vdbe *p){ + sqlite3 *db = p->db; + +#ifdef SQLITE_DEBUG + /* Execute assert() statements to ensure that the Vdbe.apCsr[] and + ** Vdbe.aMem[] arrays have already been cleaned up. */ + int i; + if( p->apCsr ) for(i=0; inCursor; i++) assert( p->apCsr[i]==0 ); + if( p->aMem ){ + for(i=1; i<=p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined ); + } +#endif + + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = 0; + p->pResultSet = 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(). +*/ +SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ + Mem *pColName; + int n; + sqlite3 *db = p->db; + + releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); + sqlite3DbFree(db, p->aColName); + n = nResColumn*COLNAME_N; + p->nResColumn = (u16)nResColumn; + p->aColName = pColName = (Mem*)sqlite3DbMallocZero(db, sizeof(Mem)*n ); + if( p->aColName==0 ) return; + while( n-- > 0 ){ + pColName->flags = MEM_Null; + pColName->db = p->db; + pColName++; + } +} + +/* +** Set the name of the idx'th column to be returned by the SQL statement. +** zName must be a pointer to a nul terminated string. +** +** This call must be made after a call to sqlite3VdbeSetNumCols(). +** +** The final parameter, xDel, must be one of SQLITE_DYNAMIC, SQLITE_STATIC +** or SQLITE_TRANSIENT. If it is SQLITE_DYNAMIC, then the buffer pointed +** to by zName will be freed by sqlite3DbFree() when the vdbe is destroyed. +*/ +SQLITE_PRIVATE int sqlite3VdbeSetColName( + Vdbe *p, /* Vdbe being configured */ + int idx, /* Index of column zName applies to */ + int var, /* One of the COLNAME_* constants */ + const char *zName, /* Pointer to buffer containing name */ + void (*xDel)(void*) /* Memory management strategy for zName */ +){ + int rc; + Mem *pColName; + assert( idxnResColumn ); + assert( vardb->mallocFailed ){ + assert( !zName || xDel!=SQLITE_DYNAMIC ); + return SQLITE_NOMEM; + } + assert( p->aColName!=0 ); + pColName = &(p->aColName[idx+var*p->nResColumn]); + rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, xDel); + assert( rc!=0 || !zName || (pColName->flags&MEM_Term)!=0 ); + return rc; +} + +/* +** A read or write transaction may or may not be active on database handle +** db. If a transaction is active, commit it. If there is a +** write-transaction spanning more than one database file, this routine +** takes care of the master journal trickery. +*/ +static int vdbeCommit(sqlite3 *db, Vdbe *p){ + int i; + int nTrans = 0; /* Number of databases with an active write-transaction */ + int rc = SQLITE_OK; + int needXcommit = 0; + +#ifdef SQLITE_OMIT_VIRTUALTABLE + /* With this option, sqlite3VtabSync() is defined to be simply + ** SQLITE_OK so p is not used. + */ + UNUSED_PARAMETER(p); +#endif + + /* Before doing anything else, call the xSync() callback for any + ** virtual module tables written in this transaction. This has to + ** be done before determining whether a master journal file is + ** required, as an xSync() callback may add an attached database + ** to the transaction. + */ + rc = sqlite3VtabSync(db, p); + + /* This loop determines (a) if the commit hook should be invoked and + ** (b) how many database files have open write transactions, not + ** including the temp database. (b) is important because if more than + ** one database file has an open write transaction, a master journal + ** file is required for an atomic commit. + */ + for(i=0; rc==SQLITE_OK && inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( sqlite3BtreeIsInTrans(pBt) ){ + needXcommit = 1; + if( i!=1 ) nTrans++; + sqlite3BtreeEnter(pBt); + rc = sqlite3PagerExclusiveLock(sqlite3BtreePager(pBt)); + sqlite3BtreeLeave(pBt); + } + } + if( rc!=SQLITE_OK ){ + return rc; + } + + /* If there are any write-transactions at all, invoke the commit hook */ + if( needXcommit && db->xCommitCallback ){ + rc = db->xCommitCallback(db->pCommitArg); + if( rc ){ + return SQLITE_CONSTRAINT_COMMITHOOK; + } + } + + /* The simple case - no more than one database file (not counting the + ** TEMP database) has a transaction active. There is no need for the + ** master-journal. + ** + ** If the return value of sqlite3BtreeGetFilename() is a zero length + ** string, it means the main database is :memory: or a temp file. In + ** that case we do not support atomic multi-file commits, so use the + ** simple case then too. + */ + if( 0==sqlite3Strlen30(sqlite3BtreeGetFilename(db->aDb[0].pBt)) + || nTrans<=1 + ){ + for(i=0; rc==SQLITE_OK && inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + rc = sqlite3BtreeCommitPhaseOne(pBt, 0); + } + } + + /* Do the commit only if all databases successfully complete phase 1. + ** If one of the BtreeCommitPhaseOne() calls fails, this indicates an + ** IO error while deleting or truncating a journal file. It is unlikely, + ** but could happen. In this case abandon processing and return the error. + */ + for(i=0; rc==SQLITE_OK && inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + rc = sqlite3BtreeCommitPhaseTwo(pBt, 0); + } + } + if( rc==SQLITE_OK ){ + sqlite3VtabCommit(db); + } + } + + /* The complex case - There is a multi-file write-transaction active. + ** This requires a master journal file to ensure the transaction is + ** committed atomically. + */ +#ifndef SQLITE_OMIT_DISKIO + else{ + sqlite3_vfs *pVfs = db->pVfs; + int needSync = 0; + char *zMaster = 0; /* File-name for the master journal */ + char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt); + sqlite3_file *pMaster = 0; + i64 offset = 0; + int res; + int retryCount = 0; + int nMainFile; + + /* Select a master journal file name */ + nMainFile = sqlite3Strlen30(zMainFile); + zMaster = sqlite3MPrintf(db, "%s-mjXXXXXX9XXz", zMainFile); + if( zMaster==0 ) return SQLITE_NOMEM; + do { + u32 iRandom; + if( retryCount ){ + if( retryCount>100 ){ + sqlite3_log(SQLITE_FULL, "MJ delete: %s", zMaster); + sqlite3OsDelete(pVfs, zMaster, 0); + break; + }else if( retryCount==1 ){ + sqlite3_log(SQLITE_FULL, "MJ collide: %s", zMaster); + } + } + retryCount++; + sqlite3_randomness(sizeof(iRandom), &iRandom); + sqlite3_snprintf(13, &zMaster[nMainFile], "-mj%06X9%02X", + (iRandom>>8)&0xffffff, iRandom&0xff); + /* The antipenultimate character of the master journal name must + ** be "9" to avoid name collisions when using 8+3 filenames. */ + assert( zMaster[sqlite3Strlen30(zMaster)-3]=='9' ); + sqlite3FileSuffix3(zMainFile, zMaster); + rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res); + }while( rc==SQLITE_OK && res ); + if( rc==SQLITE_OK ){ + /* Open the master journal. */ + rc = sqlite3OsOpenMalloc(pVfs, zMaster, &pMaster, + SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE| + SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL, 0 + ); + } + if( rc!=SQLITE_OK ){ + sqlite3DbFree(db, 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; inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( sqlite3BtreeIsInTrans(pBt) ){ + char const *zFile = sqlite3BtreeGetJournalname(pBt); + if( zFile==0 ){ + continue; /* Ignore TEMP and :memory: databases */ + } + assert( zFile[0]!=0 ); + if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){ + needSync = 1; + } + rc = sqlite3OsWrite(pMaster, zFile, sqlite3Strlen30(zFile)+1, offset); + offset += sqlite3Strlen30(zFile)+1; + if( rc!=SQLITE_OK ){ + sqlite3OsCloseFree(pMaster); + sqlite3OsDelete(pVfs, zMaster, 0); + sqlite3DbFree(db, zMaster); + return rc; + } + } + } + + /* Sync the master journal file. If the IOCAP_SEQUENTIAL device + ** flag is set this is not required. + */ + if( needSync + && 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL) + && SQLITE_OK!=(rc = sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL)) + ){ + sqlite3OsCloseFree(pMaster); + sqlite3OsDelete(pVfs, zMaster, 0); + sqlite3DbFree(db, zMaster); + return rc; + } + + /* Sync all the db files involved in the transaction. The same call + ** sets the master journal pointer in each individual journal. If + ** an error occurs here, do not delete the master journal file. + ** + ** If the error occurs during the first call to + ** sqlite3BtreeCommitPhaseOne(), then there is a chance that the + ** master journal file will be orphaned. But we cannot delete it, + ** in case the master journal file name was written into the journal + ** file before the failure occurred. + */ + for(i=0; rc==SQLITE_OK && inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + rc = sqlite3BtreeCommitPhaseOne(pBt, zMaster); + } + } + sqlite3OsCloseFree(pMaster); + assert( rc!=SQLITE_BUSY ); + if( rc!=SQLITE_OK ){ + sqlite3DbFree(db, zMaster); + return rc; + } + + /* Delete the master journal file. This commits the transaction. After + ** doing this the directory is synced again before any individual + ** transaction files are deleted. + */ + rc = sqlite3OsDelete(pVfs, zMaster, needSync); + sqlite3DbFree(db, zMaster); + zMaster = 0; + if( rc ){ + return rc; + } + + /* All files and directories have already been synced, so the following + ** calls to sqlite3BtreeCommitPhaseTwo() are only closing files and + ** deleting or truncating journals. If something goes wrong while + ** this is happening we don't really care. The integrity of the + ** transaction is already guaranteed, but some stray 'cold' journals + ** may be lying around. Returning an error code won't help matters. + */ + disable_simulated_io_errors(); + sqlite3BeginBenignMalloc(); + for(i=0; inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + sqlite3BtreeCommitPhaseTwo(pBt, 1); + } + } + sqlite3EndBenignMalloc(); + enable_simulated_io_errors(); + + sqlite3VtabCommit(db); + } +#endif + + return rc; +} + +/* +** This routine checks that the sqlite3.nVdbeActive count variable +** matches the number of vdbe's in the list sqlite3.pVdbe that are +** currently active. An assertion fails if the two counts do not match. +** This is an internal self-check only - it is not an essential processing +** step. +** +** This is a no-op if NDEBUG is defined. +*/ +#ifndef NDEBUG +static void checkActiveVdbeCnt(sqlite3 *db){ + Vdbe *p; + int cnt = 0; + int nWrite = 0; + int nRead = 0; + p = db->pVdbe; + while( p ){ + if( sqlite3_stmt_busy((sqlite3_stmt*)p) ){ + cnt++; + if( p->readOnly==0 ) nWrite++; + if( p->bIsReader ) nRead++; + } + p = p->pNext; + } + assert( cnt==db->nVdbeActive ); + assert( nWrite==db->nVdbeWrite ); + assert( nRead==db->nVdbeRead ); +} +#else +#define checkActiveVdbeCnt(x) +#endif + +/* +** If the Vdbe passed as the first argument opened a statement-transaction, +** close it now. Argument eOp must be either SAVEPOINT_ROLLBACK or +** SAVEPOINT_RELEASE. If it is SAVEPOINT_ROLLBACK, then the statement +** transaction is rolled back. If eOp is SAVEPOINT_RELEASE, then the +** statement transaction is committed. +** +** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned. +** Otherwise SQLITE_OK. +*/ +SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){ + sqlite3 *const db = p->db; + int rc = SQLITE_OK; + + /* If p->iStatement is greater than zero, then this Vdbe opened a + ** statement transaction that should be closed here. The only exception + ** is that an IO error may have occurred, causing an emergency rollback. + ** In this case (db->nStatement==0), and there is nothing to do. + */ + if( db->nStatement && p->iStatement ){ + int i; + const int iSavepoint = p->iStatement-1; + + assert( eOp==SAVEPOINT_ROLLBACK || eOp==SAVEPOINT_RELEASE); + assert( db->nStatement>0 ); + assert( p->iStatement==(db->nStatement+db->nSavepoint) ); + + for(i=0; inDb; i++){ + int rc2 = SQLITE_OK; + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + if( eOp==SAVEPOINT_ROLLBACK ){ + rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_ROLLBACK, iSavepoint); + } + if( rc2==SQLITE_OK ){ + rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_RELEASE, iSavepoint); + } + if( rc==SQLITE_OK ){ + rc = rc2; + } + } + } + db->nStatement--; + p->iStatement = 0; + + if( rc==SQLITE_OK ){ + if( eOp==SAVEPOINT_ROLLBACK ){ + rc = sqlite3VtabSavepoint(db, SAVEPOINT_ROLLBACK, iSavepoint); + } + if( rc==SQLITE_OK ){ + rc = sqlite3VtabSavepoint(db, SAVEPOINT_RELEASE, iSavepoint); + } + } + + /* If the statement transaction is being rolled back, also restore the + ** database handles deferred constraint counter to the value it had when + ** the statement transaction was opened. */ + if( eOp==SAVEPOINT_ROLLBACK ){ + db->nDeferredCons = p->nStmtDefCons; + db->nDeferredImmCons = p->nStmtDefImmCons; + } + } + return rc; +} + +/* +** This function is called when a transaction opened by the database +** handle associated with the VM passed as an argument is about to be +** committed. If there are outstanding deferred foreign key constraint +** violations, return SQLITE_ERROR. Otherwise, SQLITE_OK. +** +** If there are outstanding FK violations and this function returns +** SQLITE_ERROR, set the result of the VM to SQLITE_CONSTRAINT_FOREIGNKEY +** and write an error message to it. Then return SQLITE_ERROR. +*/ +#ifndef SQLITE_OMIT_FOREIGN_KEY +SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *p, int deferred){ + sqlite3 *db = p->db; + if( (deferred && (db->nDeferredCons+db->nDeferredImmCons)>0) + || (!deferred && p->nFkConstraint>0) + ){ + p->rc = SQLITE_CONSTRAINT_FOREIGNKEY; + p->errorAction = OE_Abort; + sqlite3SetString(&p->zErrMsg, db, "FOREIGN KEY constraint failed"); + return SQLITE_ERROR; + } + return SQLITE_OK; +} +#endif + +/* +** This routine is called the when a VDBE tries to halt. If the VDBE +** has made changes and is in autocommit mode, then commit those +** changes. If a rollback is needed, then do the rollback. +** +** This routine is the only way to move the state of a VM from +** SQLITE_MAGIC_RUN to SQLITE_MAGIC_HALT. It is harmless to +** call this on a VM that is in the SQLITE_MAGIC_HALT state. +** +** Return an error code. If the commit could not complete because of +** lock contention, return SQLITE_BUSY. If SQLITE_BUSY is returned, it +** means the close did not happen and needs to be repeated. +*/ +SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ + int rc; /* Used to store transient return codes */ + sqlite3 *db = p->db; + + /* This function contains the logic that determines if a statement or + ** transaction will be committed or rolled back as a result of the + ** execution of this virtual machine. + ** + ** If any of the following errors occur: + ** + ** SQLITE_NOMEM + ** SQLITE_IOERR + ** SQLITE_FULL + ** SQLITE_INTERRUPT + ** + ** Then the internal cache might have been left in an inconsistent + ** state. We need to rollback the statement transaction, if there is + ** one, or the complete transaction if there is no statement transaction. + */ + + if( p->db->mallocFailed ){ + p->rc = SQLITE_NOMEM; + } + if( p->aOnceFlag ) memset(p->aOnceFlag, 0, p->nOnceFlag); + closeAllCursors(p); + if( p->magic!=VDBE_MAGIC_RUN ){ + return SQLITE_OK; + } + checkActiveVdbeCnt(db); + + /* No commit or rollback needed if the program never started or if the + ** SQL statement does not read or write a database file. */ + if( p->pc>=0 && p->bIsReader ){ + int mrc; /* Primary error code from p->rc */ + int eStatementOp = 0; + int isSpecialError; /* Set to true if a 'special' error */ + + /* Lock all btrees used by the statement */ + sqlite3VdbeEnter(p); + + /* Check for one of the special errors */ + mrc = p->rc & 0xff; + isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR + || mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL; + if( isSpecialError ){ + /* If the query was read-only and the error code is SQLITE_INTERRUPT, + ** no rollback is necessary. Otherwise, at least a savepoint + ** transaction must be rolled back to restore the database to a + ** consistent state. + ** + ** Even if the statement is read-only, it is important to perform + ** a statement or transaction rollback operation. If the error + ** occurred while writing to the journal, sub-journal or database + ** file as part of an effort to free up cache space (see function + ** pagerStress() in pager.c), the rollback is required to restore + ** the pager to a consistent state. + */ + if( !p->readOnly || mrc!=SQLITE_INTERRUPT ){ + if( (mrc==SQLITE_NOMEM || mrc==SQLITE_FULL) && p->usesStmtJournal ){ + eStatementOp = SAVEPOINT_ROLLBACK; + }else{ + /* We are forced to roll back the active transaction. Before doing + ** so, abort any other statements this handle currently has active. + */ + sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); + sqlite3CloseSavepoints(db); + db->autoCommit = 1; + p->nChange = 0; + } + } + } + + /* Check for immediate foreign key violations. */ + if( p->rc==SQLITE_OK ){ + sqlite3VdbeCheckFk(p, 0); + } + + /* If the auto-commit flag is set and this is the only active writer + ** VM, then we do either a commit or rollback of the current transaction. + ** + ** Note: This block also runs if one of the special errors handled + ** above has occurred. + */ + if( !sqlite3VtabInSync(db) + && db->autoCommit + && db->nVdbeWrite==(p->readOnly==0) + ){ + if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ + rc = sqlite3VdbeCheckFk(p, 1); + if( rc!=SQLITE_OK ){ + if( NEVER(p->readOnly) ){ + sqlite3VdbeLeave(p); + return SQLITE_ERROR; + } + rc = SQLITE_CONSTRAINT_FOREIGNKEY; + }else{ + /* The auto-commit flag is true, the vdbe program was successful + ** or hit an 'OR FAIL' constraint and there are no deferred foreign + ** key constraints to hold up the transaction. This means a commit + ** is required. */ + rc = vdbeCommit(db, p); + } + if( rc==SQLITE_BUSY && p->readOnly ){ + sqlite3VdbeLeave(p); + return SQLITE_BUSY; + }else if( rc!=SQLITE_OK ){ + p->rc = rc; + sqlite3RollbackAll(db, SQLITE_OK); + p->nChange = 0; + }else{ + db->nDeferredCons = 0; + db->nDeferredImmCons = 0; + db->flags &= ~SQLITE_DeferFKs; + sqlite3CommitInternalChanges(db); + } + }else{ + sqlite3RollbackAll(db, SQLITE_OK); + p->nChange = 0; + } + db->nStatement = 0; + }else if( eStatementOp==0 ){ + if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){ + eStatementOp = SAVEPOINT_RELEASE; + }else if( p->errorAction==OE_Abort ){ + eStatementOp = SAVEPOINT_ROLLBACK; + }else{ + sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); + sqlite3CloseSavepoints(db); + db->autoCommit = 1; + p->nChange = 0; + } + } + + /* If eStatementOp is non-zero, then a statement transaction needs to + ** be committed or rolled back. Call sqlite3VdbeCloseStatement() to + ** do so. If this operation returns an error, and the current statement + ** error code is SQLITE_OK or SQLITE_CONSTRAINT, then promote the + ** current statement error code. + */ + if( eStatementOp ){ + rc = sqlite3VdbeCloseStatement(p, eStatementOp); + if( rc ){ + if( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ){ + p->rc = rc; + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = 0; + } + sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); + sqlite3CloseSavepoints(db); + db->autoCommit = 1; + p->nChange = 0; + } + } + + /* If this was an INSERT, UPDATE or DELETE and no statement transaction + ** has been rolled back, update the database connection change-counter. + */ + if( p->changeCntOn ){ + if( eStatementOp!=SAVEPOINT_ROLLBACK ){ + sqlite3VdbeSetChanges(db, p->nChange); + }else{ + sqlite3VdbeSetChanges(db, 0); + } + p->nChange = 0; + } + + /* Release the locks */ + sqlite3VdbeLeave(p); + } + + /* We have successfully halted and closed the VM. Record this fact. */ + if( p->pc>=0 ){ + db->nVdbeActive--; + if( !p->readOnly ) db->nVdbeWrite--; + if( p->bIsReader ) db->nVdbeRead--; + assert( db->nVdbeActive>=db->nVdbeRead ); + assert( db->nVdbeRead>=db->nVdbeWrite ); + assert( db->nVdbeWrite>=0 ); + } + p->magic = VDBE_MAGIC_HALT; + checkActiveVdbeCnt(db); + if( p->db->mallocFailed ){ + p->rc = SQLITE_NOMEM; + } + + /* If the auto-commit flag is set to true, then any locks that were held + ** by connection db have now been released. Call sqlite3ConnectionUnlocked() + ** to invoke any required unlock-notify callbacks. + */ + if( db->autoCommit ){ + sqlite3ConnectionUnlocked(db); + } + + assert( db->nVdbeActive>0 || db->autoCommit==0 || db->nStatement==0 ); + return (p->rc==SQLITE_BUSY ? SQLITE_BUSY : SQLITE_OK); +} + + +/* +** Each VDBE holds the result of the most recent sqlite3_step() call +** in p->rc. This routine sets that result back to SQLITE_OK. +*/ +SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe *p){ + p->rc = SQLITE_OK; +} + +/* +** Copy the error code and error message belonging to the VDBE passed +** as the first argument to its database handle (so that they will be +** returned by calls to sqlite3_errcode() and sqlite3_errmsg()). +** +** This function does not clear the VDBE error code or message, just +** copies them to the database handle. +*/ +SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p){ + sqlite3 *db = p->db; + int rc = p->rc; + if( p->zErrMsg ){ + u8 mallocFailed = db->mallocFailed; + sqlite3BeginBenignMalloc(); + if( db->pErr==0 ) db->pErr = sqlite3ValueNew(db); + sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT); + sqlite3EndBenignMalloc(); + db->mallocFailed = mallocFailed; + db->errCode = rc; + }else{ + sqlite3Error(db, rc); + } + return rc; +} + +#ifdef SQLITE_ENABLE_SQLLOG +/* +** If an SQLITE_CONFIG_SQLLOG hook is registered and the VM has been run, +** invoke it. +*/ +static void vdbeInvokeSqllog(Vdbe *v){ + if( sqlite3GlobalConfig.xSqllog && v->rc==SQLITE_OK && v->zSql && v->pc>=0 ){ + char *zExpanded = sqlite3VdbeExpandSql(v, v->zSql); + assert( v->db->init.busy==0 ); + if( zExpanded ){ + sqlite3GlobalConfig.xSqllog( + sqlite3GlobalConfig.pSqllogArg, v->db, zExpanded, 1 + ); + sqlite3DbFree(v->db, zExpanded); + } + } +} +#else +# define vdbeInvokeSqllog(x) +#endif + +/* +** Clean up a VDBE after execution but do not delete the VDBE just yet. +** Write any error messages into *pzErrMsg. Return the result code. +** +** After this routine is run, the VDBE should be ready to be executed +** again. +** +** To look at it another way, this routine resets the state of the +** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to +** VDBE_MAGIC_INIT. +*/ +SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){ + sqlite3 *db; + db = p->db; + + /* If the VM did not run to completion or if it encountered an + ** error, then it might not have been halted properly. So halt + ** it now. + */ + sqlite3VdbeHalt(p); + + /* If the VDBE has be run even partially, then transfer the error code + ** and error message from the VDBE into the main database structure. But + ** if the VDBE has just been set to run but has not actually executed any + ** instructions yet, leave the main database error information unchanged. + */ + if( p->pc>=0 ){ + vdbeInvokeSqllog(p); + sqlite3VdbeTransferError(p); + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = 0; + if( p->runOnlyOnce ) p->expired = 1; + }else if( p->rc && p->expired ){ + /* The expired flag was set on the VDBE before the first call + ** to sqlite3_step(). For consistency (since sqlite3_step() was + ** called), set the database error in this case as well. + */ + sqlite3ErrorWithMsg(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg); + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = 0; + } + + /* Reclaim all memory used by the VDBE + */ + Cleanup(p); + + /* Save profiling information from this VDBE run. + */ +#ifdef VDBE_PROFILE + { + FILE *out = fopen("vdbe_profile.out", "a"); + if( out ){ + int i; + fprintf(out, "---- "); + for(i=0; inOp; i++){ + fprintf(out, "%02x", p->aOp[i].opcode); + } + fprintf(out, "\n"); + if( p->zSql ){ + char c, pc = 0; + fprintf(out, "-- "); + for(i=0; (c = p->zSql[i])!=0; i++){ + if( pc=='\n' ) fprintf(out, "-- "); + putc(c, out); + pc = c; + } + if( pc!='\n' ) fprintf(out, "\n"); + } + for(i=0; inOp; i++){ + char zHdr[100]; + sqlite3_snprintf(sizeof(zHdr), zHdr, "%6u %12llu %8llu ", + p->aOp[i].cnt, + p->aOp[i].cycles, + p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0 + ); + fprintf(out, "%s", zHdr); + sqlite3VdbePrintOp(out, i, &p->aOp[i]); + } + fclose(out); + } + } +#endif + p->iCurrentTime = 0; + p->magic = VDBE_MAGIC_INIT; + return p->rc & db->errMask; +} + +/* +** Clean up and delete a VDBE after execution. Return an integer which is +** the result code. Write any error message text into *pzErrMsg. +*/ +SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){ + int rc = SQLITE_OK; + if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){ + rc = sqlite3VdbeReset(p); + assert( (rc & p->db->errMask)==rc ); + } + sqlite3VdbeDelete(p); + return rc; +} + +/* +** If parameter iOp is less than zero, then invoke the destructor for +** all auxiliary data pointers currently cached by the VM passed as +** the first argument. +** +** Or, if iOp is greater than or equal to zero, then the destructor is +** only invoked for those auxiliary data pointers created by the user +** function invoked by the OP_Function opcode at instruction iOp of +** VM pVdbe, and only then if: +** +** * the associated function parameter is the 32nd or later (counting +** from left to right), or +** +** * the corresponding bit in argument mask is clear (where the first +** function parameter corresponds to bit 0 etc.). +*/ +SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){ + AuxData **pp = &pVdbe->pAuxData; + while( *pp ){ + AuxData *pAux = *pp; + if( (iOp<0) + || (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & MASKBIT32(pAux->iArg)))) + ){ + testcase( pAux->iArg==31 ); + if( pAux->xDelete ){ + pAux->xDelete(pAux->pAux); + } + *pp = pAux->pNext; + sqlite3DbFree(pVdbe->db, pAux); + }else{ + pp= &pAux->pNext; + } + } +} + +/* +** Free all memory associated with the Vdbe passed as the second argument, +** except for object itself, which is preserved. +** +** The difference between this function and sqlite3VdbeDelete() is that +** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with +** the database connection and frees the object itself. +*/ +SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ + SubProgram *pSub, *pNext; + int i; + assert( p->db==0 || p->db==db ); + releaseMemArray(p->aVar, p->nVar); + releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); + for(pSub=p->pProgram; pSub; pSub=pNext){ + pNext = pSub->pNext; + vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); + sqlite3DbFree(db, pSub); + } + for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]); + vdbeFreeOpArray(db, p->aOp, p->nOp); + sqlite3DbFree(db, p->aColName); + sqlite3DbFree(db, p->zSql); + sqlite3DbFree(db, p->pFree); +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + for(i=0; inScan; i++){ + sqlite3DbFree(db, p->aScan[i].zName); + } + sqlite3DbFree(db, p->aScan); +#endif +} + +/* +** Delete an entire VDBE. +*/ +SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){ + sqlite3 *db; + + if( NEVER(p==0) ) return; + db = p->db; + assert( sqlite3_mutex_held(db->mutex) ); + sqlite3VdbeClearObject(db, p); + if( p->pPrev ){ + p->pPrev->pNext = p->pNext; + }else{ + assert( db->pVdbe==p ); + db->pVdbe = p->pNext; + } + if( p->pNext ){ + p->pNext->pPrev = p->pPrev; + } + p->magic = VDBE_MAGIC_DEAD; + p->db = 0; + sqlite3DbFree(db, p); +} + +/* +** The cursor "p" has a pending seek operation that has not yet been +** carried out. Seek the cursor now. If an error occurs, return +** the appropriate error code. +*/ +static int SQLITE_NOINLINE handleDeferredMoveto(VdbeCursor *p){ + int res, rc; +#ifdef SQLITE_TEST + extern int sqlite3_search_count; +#endif + assert( p->deferredMoveto ); + assert( p->isTable ); + rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res); + if( rc ) return rc; + if( res!=0 ) return SQLITE_CORRUPT_BKPT; +#ifdef SQLITE_TEST + sqlite3_search_count++; +#endif + p->deferredMoveto = 0; + p->cacheStatus = CACHE_STALE; + return SQLITE_OK; +} + +/* +** Something has moved cursor "p" out of place. Maybe the row it was +** pointed to was deleted out from under it. Or maybe the btree was +** rebalanced. Whatever the cause, try to restore "p" to the place it +** is supposed to be pointing. If the row was deleted out from under the +** cursor, set the cursor to point to a NULL row. +*/ +static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){ + int isDifferentRow, rc; + assert( p->pCursor!=0 ); + assert( sqlite3BtreeCursorHasMoved(p->pCursor) ); + rc = sqlite3BtreeCursorRestore(p->pCursor, &isDifferentRow); + p->cacheStatus = CACHE_STALE; + if( isDifferentRow ) p->nullRow = 1; + return rc; +} + +/* +** Check to ensure that the cursor is valid. Restore the cursor +** if need be. Return any I/O error from the restore operation. +*/ +SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){ + if( sqlite3BtreeCursorHasMoved(p->pCursor) ){ + return handleMovedCursor(p); + } + return SQLITE_OK; +} + +/* +** Make sure the cursor p is ready to read or write the row to which it +** was last positioned. Return an error code if an OOM fault or I/O error +** prevents us from positioning the cursor to its correct position. +** +** If a MoveTo operation is pending on the given cursor, then do that +** MoveTo now. If no move is pending, check to see if the row has been +** deleted out from under the cursor and if it has, mark the row as +** a NULL row. +** +** If the cursor is already pointing to the correct row and that row has +** not been deleted out from under the cursor, then this routine is a no-op. +*/ +SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){ + if( p->deferredMoveto ){ + return handleDeferredMoveto(p); + } + if( p->pCursor && sqlite3BtreeCursorHasMoved(p->pCursor) ){ + return handleMovedCursor(p); + } + return SQLITE_OK; +} + +/* +** The following functions: +** +** sqlite3VdbeSerialType() +** sqlite3VdbeSerialTypeLen() +** sqlite3VdbeSerialLen() +** sqlite3VdbeSerialPut() +** sqlite3VdbeSerialGet() +** +** encapsulate the code that serializes values for storage in SQLite +** data and index records. Each serialized value consists of a +** 'serial-type' and a blob of data. The serial type is an 8-byte unsigned +** integer, stored as a varint. +** +** In an SQLite index record, the serial type is stored directly before +** the blob of data that it corresponds to. In a table record, all serial +** types are stored at the start of the record, and the blobs of data at +** the end. Hence these functions allow the caller to handle the +** serial-type and data blob separately. +** +** The following table describes the various storage classes for data: +** +** serial type bytes of data type +** -------------- --------------- --------------- +** 0 0 NULL +** 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. +*/ +SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){ + int flags = pMem->flags; + u32 n; + + 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)0x00008000)<<32)-1) + i64 i = pMem->u.i; + u64 u; + if( i<0 ){ + u = ~i; + }else{ + u = i; + } + if( u<=127 ){ + return ((i&1)==i && file_format>=4) ? 8+(u32)u : 1; + } + if( u<=32767 ) return 2; + if( u<=8388607 ) return 3; + if( u<=2147483647 ) return 4; + if( u<=MAX_6BYTE ) return 5; + return 6; + } + if( flags&MEM_Real ){ + return 7; + } + assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) ); + assert( pMem->n>=0 ); + n = (u32)pMem->n; + if( flags & MEM_Zero ){ + n += pMem->u.nZero; + } + return ((n*2) + 12 + ((flags&MEM_Str)!=0)); +} + +/* +** Return the length of the data corresponding to the supplied serial-type. +*/ +SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32 serial_type){ + if( serial_type>=12 ){ + return (serial_type-12)/2; + }else{ + static const u8 aSize[] = { 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, 0, 0 }; + return aSize[serial_type]; + } +} + +/* +** If we are on an architecture with mixed-endian floating +** points (ex: ARM7) then swap the lower 4 bytes with the +** upper 4 bytes. Return the result. +** +** For most architectures, this is a no-op. +** +** (later): It is reported to me that the mixed-endian problem +** on ARM7 is an issue with GCC, not with the ARM7 chip. It seems +** that early versions of GCC stored the two words of a 64-bit +** float in the wrong order. And that error has been propagated +** ever since. The blame is not necessarily with GCC, though. +** GCC might have just copying the problem from a prior compiler. +** I am also told that newer versions of GCC that follow a different +** ABI get the byte order right. +** +** Developers using SQLite on an ARM7 should compile and run their +** application using -DSQLITE_DEBUG=1 at least once. With DEBUG +** enabled, some asserts below will ensure that the byte order of +** floating point values is correct. +** +** (2007-08-30) Frank van Vugt has studied this problem closely +** and has send his findings to the SQLite developers. Frank +** writes that some Linux kernels offer floating point hardware +** emulation that uses only 32-bit mantissas instead of a full +** 48-bits as required by the IEEE standard. (This is the +** CONFIG_FPE_FASTFPE option.) On such systems, floating point +** byte swapping becomes very complicated. To avoid problems, +** the necessary byte swapping is carried out using a 64-bit integer +** rather than a 64-bit float. Frank assures us that the code here +** works for him. We, the developers, have no way to independently +** verify this, but Frank seems to know what he is talking about +** so we trust him. +*/ +#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT +static u64 floatSwap(u64 in){ + union { + u64 r; + u32 i[2]; + } u; + u32 t; + + u.r = in; + t = u.i[0]; + u.i[0] = u.i[1]; + u.i[1] = t; + return u.r; +} +# define swapMixedEndianFloat(X) X = floatSwap(X) +#else +# define swapMixedEndianFloat(X) +#endif + +/* +** 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. +** +** nBuf is the amount of space left in buf[]. The caller is responsible +** for allocating enough space to buf[] to hold the entire field, exclusive +** of the pMem->u.nZero bytes for a MEM_Zero value. +** +** Return the number of bytes actually written into buf[]. The number +** of bytes in the zero-filled tail is included in the return value only +** if those bytes were zeroed in buf[]. +*/ +SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){ + u32 len; + + /* Integer and Real */ + if( serial_type<=7 && serial_type>0 ){ + u64 v; + u32 i; + if( serial_type==7 ){ + assert( sizeof(v)==sizeof(pMem->u.r) ); + memcpy(&v, &pMem->u.r, sizeof(v)); + swapMixedEndianFloat(v); + }else{ + v = pMem->u.i; + } + len = i = sqlite3VdbeSerialTypeLen(serial_type); + assert( i>0 ); + do{ + buf[--i] = (u8)(v&0xFF); + v >>= 8; + }while( i ); + return len; + } + + /* String or blob */ + if( serial_type>=12 ){ + assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0) + == (int)sqlite3VdbeSerialTypeLen(serial_type) ); + len = pMem->n; + memcpy(buf, pMem->z, len); + return len; + } + + /* NULL or constants 0 or 1 */ + return 0; +} + +/* Input "x" is a sequence of unsigned characters that represent a +** big-endian integer. Return the equivalent native integer +*/ +#define ONE_BYTE_INT(x) ((i8)(x)[0]) +#define TWO_BYTE_INT(x) (256*(i8)((x)[0])|(x)[1]) +#define THREE_BYTE_INT(x) (65536*(i8)((x)[0])|((x)[1]<<8)|(x)[2]) +#define FOUR_BYTE_UINT(x) (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3]) +#define FOUR_BYTE_INT(x) (16777216*(i8)((x)[0])|((x)[1]<<16)|((x)[2]<<8)|(x)[3]) + +/* +** 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. +** +** This function is implemented as two separate routines for performance. +** The few cases that require local variables are broken out into a separate +** routine so that in most cases the overhead of moving the stack pointer +** is avoided. +*/ +static u32 SQLITE_NOINLINE serialGet( + const unsigned char *buf, /* Buffer to deserialize from */ + u32 serial_type, /* Serial type to deserialize */ + Mem *pMem /* Memory cell to write value into */ +){ + u64 x = FOUR_BYTE_UINT(buf); + u32 y = FOUR_BYTE_UINT(buf+4); + x = (x<<32) + y; + if( serial_type==6 ){ + /* EVIDENCE-OF: R-29851-52272 Value is a big-endian 64-bit + ** twos-complement integer. */ + pMem->u.i = *(i64*)&x; + pMem->flags = MEM_Int; + testcase( pMem->u.i<0 ); + }else{ + /* EVIDENCE-OF: R-57343-49114 Value is a big-endian IEEE 754-2008 64-bit + ** floating point number. */ +#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT) + /* Verify that integers and floating point values use the same + ** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is + ** defined that 64-bit floating point values really are mixed + ** endian. + */ + static const u64 t1 = ((u64)0x3ff00000)<<32; + static const double r1 = 1.0; + u64 t2 = t1; + swapMixedEndianFloat(t2); + assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 ); +#endif + assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 ); + swapMixedEndianFloat(x); + memcpy(&pMem->u.r, &x, sizeof(x)); + pMem->flags = sqlite3IsNaN(pMem->u.r) ? MEM_Null : MEM_Real; + } + return 8; +} +SQLITE_PRIVATE u32 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 */ + /* EVIDENCE-OF: R-24078-09375 Value is a NULL. */ + pMem->flags = MEM_Null; + break; + } + case 1: { + /* EVIDENCE-OF: R-44885-25196 Value is an 8-bit twos-complement + ** integer. */ + pMem->u.i = ONE_BYTE_INT(buf); + pMem->flags = MEM_Int; + testcase( pMem->u.i<0 ); + return 1; + } + case 2: { /* 2-byte signed integer */ + /* EVIDENCE-OF: R-49794-35026 Value is a big-endian 16-bit + ** twos-complement integer. */ + pMem->u.i = TWO_BYTE_INT(buf); + pMem->flags = MEM_Int; + testcase( pMem->u.i<0 ); + return 2; + } + case 3: { /* 3-byte signed integer */ + /* EVIDENCE-OF: R-37839-54301 Value is a big-endian 24-bit + ** twos-complement integer. */ + pMem->u.i = THREE_BYTE_INT(buf); + pMem->flags = MEM_Int; + testcase( pMem->u.i<0 ); + return 3; + } + case 4: { /* 4-byte signed integer */ + /* EVIDENCE-OF: R-01849-26079 Value is a big-endian 32-bit + ** twos-complement integer. */ + pMem->u.i = FOUR_BYTE_INT(buf); + pMem->flags = MEM_Int; + testcase( pMem->u.i<0 ); + return 4; + } + case 5: { /* 6-byte signed integer */ + /* EVIDENCE-OF: R-50385-09674 Value is a big-endian 48-bit + ** twos-complement integer. */ + pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf); + pMem->flags = MEM_Int; + testcase( pMem->u.i<0 ); + return 6; + } + case 6: /* 8-byte signed integer */ + case 7: { /* IEEE floating point */ + /* These use local variables, so do them in a separate routine + ** to avoid having to move the frame pointer in the common case */ + return serialGet(buf,serial_type,pMem); + } + case 8: /* Integer 0 */ + case 9: { /* Integer 1 */ + /* EVIDENCE-OF: R-12976-22893 Value is the integer 0. */ + /* EVIDENCE-OF: R-18143-12121 Value is the integer 1. */ + pMem->u.i = serial_type-8; + pMem->flags = MEM_Int; + return 0; + } + default: { + /* EVIDENCE-OF: R-14606-31564 Value is a BLOB that is (N-12)/2 bytes in + ** length. + ** EVIDENCE-OF: R-28401-00140 Value is a string in the text encoding and + ** (N-13)/2 bytes in length. */ + static const u16 aFlag[] = { MEM_Blob|MEM_Ephem, MEM_Str|MEM_Ephem }; + pMem->z = (char *)buf; + pMem->n = (serial_type-12)/2; + pMem->flags = aFlag[serial_type&1]; + return pMem->n; + } + } + return 0; +} +/* +** This routine is used to allocate sufficient space for an UnpackedRecord +** structure large enough to be used with sqlite3VdbeRecordUnpack() if +** the first argument is a pointer to KeyInfo structure pKeyInfo. +** +** The space is either allocated using sqlite3DbMallocRaw() or from within +** the unaligned buffer passed via the second and third arguments (presumably +** stack space). If the former, then *ppFree is set to a pointer that should +** be eventually freed by the caller using sqlite3DbFree(). Or, if the +** allocation comes from the pSpace/szSpace buffer, *ppFree is set to NULL +** before returning. +** +** If an OOM error occurs, NULL is returned. +*/ +SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( + KeyInfo *pKeyInfo, /* Description of the record */ + char *pSpace, /* Unaligned space available */ + int szSpace, /* Size of pSpace[] in bytes */ + char **ppFree /* OUT: Caller should free this pointer */ +){ + UnpackedRecord *p; /* Unpacked record to return */ + int nOff; /* Increment pSpace by nOff to align it */ + int nByte; /* Number of bytes required for *p */ + + /* We want to shift the pointer pSpace up such that it is 8-byte aligned. + ** Thus, we need to calculate a value, nOff, between 0 and 7, to shift + ** it by. If pSpace is already 8-byte aligned, nOff should be zero. + */ + nOff = (8 - (SQLITE_PTR_TO_INT(pSpace) & 7)) & 7; + nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nField+1); + if( nByte>szSpace+nOff ){ + p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); + *ppFree = (char *)p; + if( !p ) return 0; + }else{ + p = (UnpackedRecord*)&pSpace[nOff]; + *ppFree = 0; + } + + p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))]; + assert( pKeyInfo->aSortOrder!=0 ); + p->pKeyInfo = pKeyInfo; + p->nField = pKeyInfo->nField + 1; + return p; +} + +/* +** Given the nKey-byte encoding of a record in pKey[], populate the +** UnpackedRecord structure indicated by the fourth argument with the +** contents of the decoded record. +*/ +SQLITE_PRIVATE void sqlite3VdbeRecordUnpack( + KeyInfo *pKeyInfo, /* Information about the record format */ + int nKey, /* Size of the binary record */ + const void *pKey, /* The binary record */ + UnpackedRecord *p /* Populate this structure before returning. */ +){ + const unsigned char *aKey = (const unsigned char *)pKey; + int d; + u32 idx; /* Offset in aKey[] to read from */ + u16 u; /* Unsigned loop counter */ + u32 szHdr; + Mem *pMem = p->aMem; + + p->default_rc = 0; + assert( EIGHT_BYTE_ALIGNMENT(pMem) ); + idx = getVarint32(aKey, szHdr); + d = szHdr; + u = 0; + while( idxenc = pKeyInfo->enc; + pMem->db = pKeyInfo->db; + /* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */ + pMem->szMalloc = 0; + d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); + pMem++; + if( (++u)>=p->nField ) break; + } + assert( u<=pKeyInfo->nField + 1 ); + p->nField = u; +} + +#if SQLITE_DEBUG +/* +** This function compares two index or table record keys in the same way +** as the sqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(), +** this function deserializes and compares values using the +** sqlite3VdbeSerialGet() and sqlite3MemCompare() functions. It is used +** in assert() statements to ensure that the optimized code in +** sqlite3VdbeRecordCompare() returns results with these two primitives. +** +** Return true if the result of comparison is equivalent to desiredResult. +** Return false if there is a disagreement. +*/ +static int vdbeRecordCompareDebug( + int nKey1, const void *pKey1, /* Left key */ + const UnpackedRecord *pPKey2, /* Right key */ + int desiredResult /* Correct answer */ +){ + u32 d1; /* Offset into aKey[] of next data element */ + u32 idx1; /* Offset into aKey[] of next header element */ + u32 szHdr1; /* Number of bytes in header */ + int i = 0; + int rc = 0; + const unsigned char *aKey1 = (const unsigned char *)pKey1; + KeyInfo *pKeyInfo; + Mem mem1; + + pKeyInfo = pPKey2->pKeyInfo; + if( pKeyInfo->db==0 ) return 1; + mem1.enc = pKeyInfo->enc; + mem1.db = pKeyInfo->db; + /* mem1.flags = 0; // Will be initialized by sqlite3VdbeSerialGet() */ + VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */ + + /* Compilers may complain that mem1.u.i is potentially uninitialized. + ** We could initialize it, as shown here, to silence those complaints. + ** But in fact, mem1.u.i will never actually be used uninitialized, and doing + ** the unnecessary initialization has a measurable negative performance + ** impact, since this routine is a very high runner. And so, we choose + ** to ignore the compiler warnings and leave this variable uninitialized. + */ + /* mem1.u.i = 0; // not needed, here to silence compiler warning */ + + idx1 = getVarint32(aKey1, szHdr1); + d1 = szHdr1; + assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField || CORRUPT_DB ); + assert( pKeyInfo->aSortOrder!=0 ); + assert( pKeyInfo->nField>0 ); + assert( idx1<=szHdr1 || CORRUPT_DB ); + do{ + u32 serial_type1; + + /* Read the serial types for the next element in each key. */ + idx1 += getVarint32( aKey1+idx1, serial_type1 ); + + /* Verify that there is enough key space remaining to avoid + ** a buffer overread. The "d1+serial_type1+2" subexpression will + ** always be greater than or equal to the amount of required key space. + ** Use that approximation to avoid the more expensive call to + ** sqlite3VdbeSerialTypeLen() in the common case. + */ + if( d1+serial_type1+2>(u32)nKey1 + && d1+sqlite3VdbeSerialTypeLen(serial_type1)>(u32)nKey1 + ){ + break; + } + + /* Extract the values to be compared. + */ + d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1); + + /* Do the comparison + */ + rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->aColl[i]); + if( rc!=0 ){ + assert( mem1.szMalloc==0 ); /* See comment below */ + if( pKeyInfo->aSortOrder[i] ){ + rc = -rc; /* Invert the result for DESC sort order. */ + } + goto debugCompareEnd; + } + i++; + }while( idx1nField ); + + /* No memory allocation is ever used on mem1. Prove this using + ** the following assert(). If the assert() fails, it indicates a + ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1). + */ + assert( mem1.szMalloc==0 ); + + /* rc==0 here means that one of the keys ran out of fields and + ** all the fields up to that point were equal. Return the default_rc + ** value. */ + rc = pPKey2->default_rc; + +debugCompareEnd: + if( desiredResult==0 && rc==0 ) return 1; + if( desiredResult<0 && rc<0 ) return 1; + if( desiredResult>0 && rc>0 ) return 1; + if( CORRUPT_DB ) return 1; + if( pKeyInfo->db->mallocFailed ) return 1; + return 0; +} +#endif + +#if SQLITE_DEBUG +/* +** Count the number of fields (a.k.a. columns) in the record given by +** pKey,nKey. The verify that this count is less than or equal to the +** limit given by pKeyInfo->nField + pKeyInfo->nXField. +** +** If this constraint is not satisfied, it means that the high-speed +** vdbeRecordCompareInt() and vdbeRecordCompareString() routines will +** not work correctly. If this assert() ever fires, it probably means +** that the KeyInfo.nField or KeyInfo.nXField values were computed +** incorrectly. +*/ +static void vdbeAssertFieldCountWithinLimits( + int nKey, const void *pKey, /* The record to verify */ + const KeyInfo *pKeyInfo /* Compare size with this KeyInfo */ +){ + int nField = 0; + u32 szHdr; + u32 idx; + u32 notUsed; + const unsigned char *aKey = (const unsigned char*)pKey; + + if( CORRUPT_DB ) return; + idx = getVarint32(aKey, szHdr); + assert( nKey>=0 ); + assert( szHdr<=(u32)nKey ); + while( idxnField+pKeyInfo->nXField ); +} +#else +# define vdbeAssertFieldCountWithinLimits(A,B,C) +#endif + +/* +** Both *pMem1 and *pMem2 contain string values. Compare the two values +** using the collation sequence pColl. As usual, return a negative , zero +** or positive value if *pMem1 is less than, equal to or greater than +** *pMem2, respectively. Similar in spirit to "rc = (*pMem1) - (*pMem2);". +*/ +static int vdbeCompareMemString( + const Mem *pMem1, + const Mem *pMem2, + const CollSeq *pColl, + u8 *prcErr /* If an OOM occurs, set to SQLITE_NOMEM */ +){ + if( pMem1->enc==pColl->enc ){ + /* The strings are already in the correct encoding. Call the + ** comparison function directly */ + return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z); + }else{ + int rc; + const void *v1, *v2; + int n1, n2; + Mem c1; + Mem c2; + sqlite3VdbeMemInit(&c1, pMem1->db, MEM_Null); + sqlite3VdbeMemInit(&c2, pMem1->db, MEM_Null); + sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem); + sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem); + v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc); + n1 = v1==0 ? 0 : c1.n; + v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc); + n2 = v2==0 ? 0 : c2.n; + rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2); + sqlite3VdbeMemRelease(&c1); + sqlite3VdbeMemRelease(&c2); + if( (v1==0 || v2==0) && prcErr ) *prcErr = SQLITE_NOMEM; + return rc; + } +} + +/* +** Compare two blobs. Return negative, zero, or positive if the first +** is less than, equal to, or greater than the second, respectively. +** If one blob is a prefix of the other, then the shorter is the lessor. +*/ +static SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){ + int c = memcmp(pB1->z, pB2->z, pB1->n>pB2->n ? pB2->n : pB1->n); + if( c ) return c; + return pB1->n - pB2->n; +} + + +/* +** Compare the values contained by the two memory cells, returning +** negative, zero or positive if pMem1 is less than, equal to, or greater +** than pMem2. Sorting order is NULL's first, followed by numbers (integers +** and reals) sorted numerically, followed by text ordered by the collating +** sequence pColl and finally blob's ordered by memcmp(). +** +** Two NULL values are considered equal by this function. +*/ +SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){ + int f1, f2; + int combined_flags; + + f1 = pMem1->flags; + f2 = pMem2->flags; + combined_flags = f1|f2; + assert( (combined_flags & MEM_RowSet)==0 ); + + /* If one value is NULL, it is less than the other. If both values + ** are NULL, return 0. + */ + if( combined_flags&MEM_Null ){ + return (f2&MEM_Null) - (f1&MEM_Null); + } + + /* If one value is a number and the other is not, the number is less. + ** If both are numbers, compare as reals if one is a real, or as integers + ** if both values are integers. + */ + if( combined_flags&(MEM_Int|MEM_Real) ){ + double r1, r2; + if( (f1 & f2 & MEM_Int)!=0 ){ + if( pMem1->u.i < pMem2->u.i ) return -1; + if( pMem1->u.i > pMem2->u.i ) return 1; + return 0; + } + if( (f1&MEM_Real)!=0 ){ + r1 = pMem1->u.r; + }else if( (f1&MEM_Int)!=0 ){ + r1 = (double)pMem1->u.i; + }else{ + return 1; + } + if( (f2&MEM_Real)!=0 ){ + r2 = pMem2->u.r; + }else if( (f2&MEM_Int)!=0 ){ + r2 = (double)pMem2->u.i; + }else{ + return -1; + } + if( r1r2 ) return 1; + return 0; + } + + /* If one value is a string and the other is a blob, the string is less. + ** If both are strings, compare using the collating functions. + */ + if( combined_flags&MEM_Str ){ + if( (f1 & MEM_Str)==0 ){ + return 1; + } + if( (f2 & MEM_Str)==0 ){ + 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 ){ + return vdbeCompareMemString(pMem1, pMem2, pColl, 0); + } + /* If a NULL pointer was passed as the collate function, fall through + ** to the blob case and use memcmp(). */ + } + + /* Both values must be blobs. Compare using memcmp(). */ + return sqlite3BlobCompare(pMem1, pMem2); +} + + +/* +** The first argument passed to this function is a serial-type that +** corresponds to an integer - all values between 1 and 9 inclusive +** except 7. The second points to a buffer containing an integer value +** serialized according to serial_type. This function deserializes +** and returns the value. +*/ +static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){ + u32 y; + assert( CORRUPT_DB || (serial_type>=1 && serial_type<=9 && serial_type!=7) ); + switch( serial_type ){ + case 0: + case 1: + testcase( aKey[0]&0x80 ); + return ONE_BYTE_INT(aKey); + case 2: + testcase( aKey[0]&0x80 ); + return TWO_BYTE_INT(aKey); + case 3: + testcase( aKey[0]&0x80 ); + return THREE_BYTE_INT(aKey); + case 4: { + testcase( aKey[0]&0x80 ); + y = FOUR_BYTE_UINT(aKey); + return (i64)*(int*)&y; + } + case 5: { + testcase( aKey[0]&0x80 ); + return FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey); + } + case 6: { + u64 x = FOUR_BYTE_UINT(aKey); + testcase( aKey[0]&0x80 ); + x = (x<<32) | FOUR_BYTE_UINT(aKey+4); + return (i64)*(i64*)&x; + } + } + + return (serial_type - 8); +} + +/* +** This function compares the two table rows or index records +** specified by {nKey1, pKey1} and pPKey2. It returns a negative, zero +** or positive integer if key1 is less than, equal to or +** greater than key2. The {nKey1, pKey1} key must be a blob +** created by the OP_MakeRecord opcode of the VDBE. The pPKey2 +** key must be a parsed key such as obtained from +** sqlite3VdbeParseRecord. +** +** If argument bSkip is non-zero, it is assumed that the caller has already +** determined that the first fields of the keys are equal. +** +** Key1 and Key2 do not have to contain the same number of fields. If all +** fields that appear in both keys are equal, then pPKey2->default_rc is +** returned. +** +** If database corruption is discovered, set pPKey2->errCode to +** SQLITE_CORRUPT and return 0. If an OOM error is encountered, +** pPKey2->errCode is set to SQLITE_NOMEM and, if it is not NULL, the +** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db). +*/ +SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( + int nKey1, const void *pKey1, /* Left key */ + UnpackedRecord *pPKey2, /* Right key */ + int bSkip /* If true, skip the first field */ +){ + u32 d1; /* Offset into aKey[] of next data element */ + int i; /* Index of next field to compare */ + u32 szHdr1; /* Size of record header in bytes */ + u32 idx1; /* Offset of first type in header */ + int rc = 0; /* Return value */ + Mem *pRhs = pPKey2->aMem; /* Next field of pPKey2 to compare */ + KeyInfo *pKeyInfo = pPKey2->pKeyInfo; + const unsigned char *aKey1 = (const unsigned char *)pKey1; + Mem mem1; + + /* If bSkip is true, then the caller has already determined that the first + ** two elements in the keys are equal. Fix the various stack variables so + ** that this routine begins comparing at the second field. */ + if( bSkip ){ + u32 s1; + idx1 = 1 + getVarint32(&aKey1[1], s1); + szHdr1 = aKey1[0]; + d1 = szHdr1 + sqlite3VdbeSerialTypeLen(s1); + i = 1; + pRhs++; + }else{ + idx1 = getVarint32(aKey1, szHdr1); + d1 = szHdr1; + if( d1>(unsigned)nKey1 ){ + pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; + return 0; /* Corruption */ + } + i = 0; + } + + VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */ + assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField + || CORRUPT_DB ); + assert( pPKey2->pKeyInfo->aSortOrder!=0 ); + assert( pPKey2->pKeyInfo->nField>0 ); + assert( idx1<=szHdr1 || CORRUPT_DB ); + do{ + u32 serial_type; + + /* RHS is an integer */ + if( pRhs->flags & MEM_Int ){ + serial_type = aKey1[idx1]; + testcase( serial_type==12 ); + if( serial_type>=12 ){ + rc = +1; + }else if( serial_type==0 ){ + rc = -1; + }else if( serial_type==7 ){ + double rhs = (double)pRhs->u.i; + sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); + if( mem1.u.rrhs ){ + rc = +1; + } + }else{ + i64 lhs = vdbeRecordDecodeInt(serial_type, &aKey1[d1]); + i64 rhs = pRhs->u.i; + if( lhsrhs ){ + rc = +1; + } + } + } + + /* RHS is real */ + else if( pRhs->flags & MEM_Real ){ + serial_type = aKey1[idx1]; + if( serial_type>=12 ){ + rc = +1; + }else if( serial_type==0 ){ + rc = -1; + }else{ + double rhs = pRhs->u.r; + double lhs; + sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); + if( serial_type==7 ){ + lhs = mem1.u.r; + }else{ + lhs = (double)mem1.u.i; + } + if( lhsrhs ){ + rc = +1; + } + } + } + + /* RHS is a string */ + else if( pRhs->flags & MEM_Str ){ + getVarint32(&aKey1[idx1], serial_type); + testcase( serial_type==12 ); + if( serial_type<12 ){ + rc = -1; + }else if( !(serial_type & 0x01) ){ + rc = +1; + }else{ + mem1.n = (serial_type - 12) / 2; + testcase( (d1+mem1.n)==(unsigned)nKey1 ); + testcase( (d1+mem1.n+1)==(unsigned)nKey1 ); + if( (d1+mem1.n) > (unsigned)nKey1 ){ + pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; + return 0; /* Corruption */ + }else if( pKeyInfo->aColl[i] ){ + mem1.enc = pKeyInfo->enc; + mem1.db = pKeyInfo->db; + mem1.flags = MEM_Str; + mem1.z = (char*)&aKey1[d1]; + rc = vdbeCompareMemString( + &mem1, pRhs, pKeyInfo->aColl[i], &pPKey2->errCode + ); + }else{ + int nCmp = MIN(mem1.n, pRhs->n); + rc = memcmp(&aKey1[d1], pRhs->z, nCmp); + if( rc==0 ) rc = mem1.n - pRhs->n; + } + } + } + + /* RHS is a blob */ + else if( pRhs->flags & MEM_Blob ){ + getVarint32(&aKey1[idx1], serial_type); + testcase( serial_type==12 ); + if( serial_type<12 || (serial_type & 0x01) ){ + rc = -1; + }else{ + int nStr = (serial_type - 12) / 2; + testcase( (d1+nStr)==(unsigned)nKey1 ); + testcase( (d1+nStr+1)==(unsigned)nKey1 ); + if( (d1+nStr) > (unsigned)nKey1 ){ + pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; + return 0; /* Corruption */ + }else{ + int nCmp = MIN(nStr, pRhs->n); + rc = memcmp(&aKey1[d1], pRhs->z, nCmp); + if( rc==0 ) rc = nStr - pRhs->n; + } + } + } + + /* RHS is null */ + else{ + serial_type = aKey1[idx1]; + rc = (serial_type!=0); + } + + if( rc!=0 ){ + if( pKeyInfo->aSortOrder[i] ){ + rc = -rc; + } + assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) ); + assert( mem1.szMalloc==0 ); /* See comment below */ + return rc; + } + + i++; + pRhs++; + d1 += sqlite3VdbeSerialTypeLen(serial_type); + idx1 += sqlite3VarintLen(serial_type); + }while( idx1<(unsigned)szHdr1 && inField && d1<=(unsigned)nKey1 ); + + /* No memory allocation is ever used on mem1. Prove this using + ** the following assert(). If the assert() fails, it indicates a + ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1). */ + assert( mem1.szMalloc==0 ); + + /* rc==0 here means that one or both of the keys ran out of fields and + ** all the fields up to that point were equal. Return the default_rc + ** value. */ + assert( CORRUPT_DB + || vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc) + || pKeyInfo->db->mallocFailed + ); + return pPKey2->default_rc; +} +SQLITE_PRIVATE int sqlite3VdbeRecordCompare( + int nKey1, const void *pKey1, /* Left key */ + UnpackedRecord *pPKey2 /* Right key */ +){ + return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0); +} + + +/* +** This function is an optimized version of sqlite3VdbeRecordCompare() +** that (a) the first field of pPKey2 is an integer, and (b) the +** size-of-header varint at the start of (pKey1/nKey1) fits in a single +** byte (i.e. is less than 128). +** +** To avoid concerns about buffer overreads, this routine is only used +** on schemas where the maximum valid header size is 63 bytes or less. +*/ +static int vdbeRecordCompareInt( + int nKey1, const void *pKey1, /* Left key */ + UnpackedRecord *pPKey2 /* Right key */ +){ + const u8 *aKey = &((const u8*)pKey1)[*(const u8*)pKey1 & 0x3F]; + int serial_type = ((const u8*)pKey1)[1]; + int res; + u32 y; + u64 x; + i64 v = pPKey2->aMem[0].u.i; + i64 lhs; + + vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo); + assert( (*(u8*)pKey1)<=0x3F || CORRUPT_DB ); + switch( serial_type ){ + case 1: { /* 1-byte signed integer */ + lhs = ONE_BYTE_INT(aKey); + testcase( lhs<0 ); + break; + } + case 2: { /* 2-byte signed integer */ + lhs = TWO_BYTE_INT(aKey); + testcase( lhs<0 ); + break; + } + case 3: { /* 3-byte signed integer */ + lhs = THREE_BYTE_INT(aKey); + testcase( lhs<0 ); + break; + } + case 4: { /* 4-byte signed integer */ + y = FOUR_BYTE_UINT(aKey); + lhs = (i64)*(int*)&y; + testcase( lhs<0 ); + break; + } + case 5: { /* 6-byte signed integer */ + lhs = FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey); + testcase( lhs<0 ); + break; + } + case 6: { /* 8-byte signed integer */ + x = FOUR_BYTE_UINT(aKey); + x = (x<<32) | FOUR_BYTE_UINT(aKey+4); + lhs = *(i64*)&x; + testcase( lhs<0 ); + break; + } + case 8: + lhs = 0; + break; + case 9: + lhs = 1; + break; + + /* This case could be removed without changing the results of running + ** this code. Including it causes gcc to generate a faster switch + ** statement (since the range of switch targets now starts at zero and + ** is contiguous) but does not cause any duplicate code to be generated + ** (as gcc is clever enough to combine the two like cases). Other + ** compilers might be similar. */ + case 0: case 7: + return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); + + default: + return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); + } + + if( v>lhs ){ + res = pPKey2->r1; + }else if( vr2; + }else if( pPKey2->nField>1 ){ + /* The first fields of the two keys are equal. Compare the trailing + ** fields. */ + res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); + }else{ + /* The first fields of the two keys are equal and there are no trailing + ** fields. Return pPKey2->default_rc in this case. */ + res = pPKey2->default_rc; + } + + assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res) ); + return res; +} + +/* +** This function is an optimized version of sqlite3VdbeRecordCompare() +** that (a) the first field of pPKey2 is a string, that (b) the first field +** uses the collation sequence BINARY and (c) that the size-of-header varint +** at the start of (pKey1/nKey1) fits in a single byte. +*/ +static int vdbeRecordCompareString( + int nKey1, const void *pKey1, /* Left key */ + UnpackedRecord *pPKey2 /* Right key */ +){ + const u8 *aKey1 = (const u8*)pKey1; + int serial_type; + int res; + + vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo); + getVarint32(&aKey1[1], serial_type); + if( serial_type<12 ){ + res = pPKey2->r1; /* (pKey1/nKey1) is a number or a null */ + }else if( !(serial_type & 0x01) ){ + res = pPKey2->r2; /* (pKey1/nKey1) is a blob */ + }else{ + int nCmp; + int nStr; + int szHdr = aKey1[0]; + + nStr = (serial_type-12) / 2; + if( (szHdr + nStr) > nKey1 ){ + pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; + return 0; /* Corruption */ + } + nCmp = MIN( pPKey2->aMem[0].n, nStr ); + res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp); + + if( res==0 ){ + res = nStr - pPKey2->aMem[0].n; + if( res==0 ){ + if( pPKey2->nField>1 ){ + res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); + }else{ + res = pPKey2->default_rc; + } + }else if( res>0 ){ + res = pPKey2->r2; + }else{ + res = pPKey2->r1; + } + }else if( res>0 ){ + res = pPKey2->r2; + }else{ + res = pPKey2->r1; + } + } + + assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res) + || CORRUPT_DB + || pPKey2->pKeyInfo->db->mallocFailed + ); + return res; +} + +/* +** Return a pointer to an sqlite3VdbeRecordCompare() compatible function +** suitable for comparing serialized records to the unpacked record passed +** as the only argument. +*/ +SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){ + /* varintRecordCompareInt() and varintRecordCompareString() both assume + ** that the size-of-header varint that occurs at the start of each record + ** fits in a single byte (i.e. is 127 or less). varintRecordCompareInt() + ** also assumes that it is safe to overread a buffer by at least the + ** maximum possible legal header size plus 8 bytes. Because there is + ** guaranteed to be at least 74 (but not 136) bytes of padding following each + ** buffer passed to varintRecordCompareInt() this makes it convenient to + ** limit the size of the header to 64 bytes in cases where the first field + ** is an integer. + ** + ** The easiest way to enforce this limit is to consider only records with + ** 13 fields or less. If the first field is an integer, the maximum legal + ** header size is (12*5 + 1 + 1) bytes. */ + if( (p->pKeyInfo->nField + p->pKeyInfo->nXField)<=13 ){ + int flags = p->aMem[0].flags; + if( p->pKeyInfo->aSortOrder[0] ){ + p->r1 = 1; + p->r2 = -1; + }else{ + p->r1 = -1; + p->r2 = 1; + } + if( (flags & MEM_Int) ){ + return vdbeRecordCompareInt; + } + testcase( flags & MEM_Real ); + testcase( flags & MEM_Null ); + testcase( flags & MEM_Blob ); + if( (flags & (MEM_Real|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){ + assert( flags & MEM_Str ); + return vdbeRecordCompareString; + } + } + + return sqlite3VdbeRecordCompare; +} + +/* +** pCur points at an index entry created using the OP_MakeRecord opcode. +** Read the rowid (the last field in the record) and store it in *rowid. +** Return SQLITE_OK if everything works, or an error code otherwise. +** +** pCur might be pointing to text obtained from a corrupt database file. +** So the content cannot be trusted. Do appropriate checks on the content. +*/ +SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){ + i64 nCellKey = 0; + int rc; + u32 szHdr; /* Size of the header */ + u32 typeRowid; /* Serial type of the rowid */ + u32 lenRowid; /* Size of the rowid */ + Mem m, v; + + /* Get the size of the index entry. Only indices entries of less + ** than 2GiB are support - anything large must be database corruption. + ** Any corruption is detected in sqlite3BtreeParseCellPtr(), though, so + ** this code can safely assume that nCellKey is 32-bits + */ + assert( sqlite3BtreeCursorIsValid(pCur) ); + VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey); + assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */ + assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey ); + + /* Read in the complete content of the index entry */ + sqlite3VdbeMemInit(&m, db, 0); + rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, 1, &m); + if( rc ){ + return rc; + } + + /* The index entry must begin with a header size */ + (void)getVarint32((u8*)m.z, szHdr); + testcase( szHdr==3 ); + testcase( szHdr==m.n ); + if( unlikely(szHdr<3 || (int)szHdr>m.n) ){ + goto idx_rowid_corruption; + } + + /* The last field of the index should be an integer - the ROWID. + ** Verify that the last entry really is an integer. */ + (void)getVarint32((u8*)&m.z[szHdr-1], typeRowid); + testcase( typeRowid==1 ); + testcase( typeRowid==2 ); + testcase( typeRowid==3 ); + testcase( typeRowid==4 ); + testcase( typeRowid==5 ); + testcase( typeRowid==6 ); + testcase( typeRowid==8 ); + testcase( typeRowid==9 ); + if( unlikely(typeRowid<1 || typeRowid>9 || typeRowid==7) ){ + goto idx_rowid_corruption; + } + lenRowid = sqlite3VdbeSerialTypeLen(typeRowid); + testcase( (u32)m.n==szHdr+lenRowid ); + if( unlikely((u32)m.npCursor; + Mem m; + + assert( sqlite3BtreeCursorIsValid(pCur) ); + VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey); + assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */ + /* nCellKey will always be between 0 and 0xffffffff because of the way + ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */ + if( nCellKey<=0 || nCellKey>0x7fffffff ){ + *res = 0; + return SQLITE_CORRUPT_BKPT; + } + sqlite3VdbeMemInit(&m, db, 0); + rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, (u32)nCellKey, 1, &m); + if( rc ){ + return rc; + } + *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked); + sqlite3VdbeMemRelease(&m); + return SQLITE_OK; +} + +/* +** This routine sets the value to be returned by subsequent calls to +** sqlite3_changes() on the database handle 'db'. +*/ +SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *db, int nChange){ + assert( sqlite3_mutex_held(db->mutex) ); + db->nChange = nChange; + db->nTotalChange += nChange; +} + +/* +** Set a flag in the vdbe to update the change counter when it is finalised +** or reset. +*/ +SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe *v){ + v->changeCntOn = 1; +} + +/* +** Mark every prepared statement associated with a database connection +** as expired. +** +** An expired statement means that recompilation of the statement is +** recommend. Statements expire when things happen that make their +** programs obsolete. Removing user-defined functions or collating +** sequences, or changing an authorization function are the types of +** things that make prepared statements obsolete. +*/ +SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3 *db){ + Vdbe *p; + for(p = db->pVdbe; p; p=p->pNext){ + p->expired = 1; + } +} + +/* +** Return the database associated with the Vdbe. +*/ +SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe *v){ + return v->db; +} + +/* +** Return a pointer to an sqlite3_value structure containing the value bound +** parameter iVar of VM v. Except, if the value is an SQL NULL, return +** 0 instead. Unless it is NULL, apply affinity aff (one of the SQLITE_AFF_* +** constants) to the value before returning it. +** +** The returned value must be freed by the caller using sqlite3ValueFree(). +*/ +SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){ + assert( iVar>0 ); + if( v ){ + Mem *pMem = &v->aVar[iVar-1]; + if( 0==(pMem->flags & MEM_Null) ){ + sqlite3_value *pRet = sqlite3ValueNew(v->db); + if( pRet ){ + sqlite3VdbeMemCopy((Mem *)pRet, pMem); + sqlite3ValueApplyAffinity(pRet, aff, SQLITE_UTF8); + } + return pRet; + } + } + return 0; +} + +/* +** Configure SQL variable iVar so that binding a new value to it signals +** to sqlite3_reoptimize() that re-preparing the statement may result +** in a better query plan. +*/ +SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){ + assert( iVar>0 ); + if( iVar>32 ){ + v->expmask = 0xffffffff; + }else{ + v->expmask |= ((u32)1 << (iVar-1)); + } +} + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored +** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored +** in memory obtained from sqlite3DbMalloc). +*/ +SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe *p, sqlite3_vtab *pVtab){ + sqlite3 *db = p->db; + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg); + sqlite3_free(pVtab->zErrMsg); + pVtab->zErrMsg = 0; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +/************** End of vdbeaux.c *********************************************/ +/************** Begin file vdbeapi.c *****************************************/ +/* +** 2004 May 26 +** +** 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 use to implement APIs that are part of the +** VDBE. +*/ + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** 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. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt *pStmt){ + Vdbe *p = (Vdbe*)pStmt; + return p==0 || p->expired; +} +#endif + +/* +** Check on a Vdbe to make sure it has not been finalized. Log +** an error and return true if it has been finalized (or is otherwise +** invalid). Return false if it is ok. +*/ +static int vdbeSafety(Vdbe *p){ + if( p->db==0 ){ + sqlite3_log(SQLITE_MISUSE, "API called with finalized prepared statement"); + return 1; + }else{ + return 0; + } +} +static int vdbeSafetyNotNull(Vdbe *p){ + if( p==0 ){ + sqlite3_log(SQLITE_MISUSE, "API called with NULL prepared statement"); + return 1; + }else{ + return vdbeSafety(p); + } +} + +/* +** The following routine destroys a virtual machine that is created by +** the sqlite3_compile() routine. The integer returned is an SQLITE_ +** success/failure code that describes the result of executing the virtual +** machine. +** +** This routine sets the error code and string returned by +** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt){ + int rc; + if( pStmt==0 ){ + /* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL + ** pointer is a harmless no-op. */ + rc = SQLITE_OK; + }else{ + Vdbe *v = (Vdbe*)pStmt; + sqlite3 *db = v->db; + if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT; + sqlite3_mutex_enter(db->mutex); + rc = sqlite3VdbeFinalize(v); + rc = sqlite3ApiExit(db, rc); + sqlite3LeaveMutexAndCloseZombie(db); + } + return rc; +} + +/* +** Terminate the current execution of an SQL statement and reset it +** back to its starting state so that it can be reused. A success code from +** the prior execution is returned. +** +** This routine sets the error code and string returned by +** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt){ + int rc; + if( pStmt==0 ){ + rc = SQLITE_OK; + }else{ + Vdbe *v = (Vdbe*)pStmt; + sqlite3_mutex_enter(v->db->mutex); + rc = sqlite3VdbeReset(v); + sqlite3VdbeRewind(v); + assert( (rc & (v->db->errMask))==rc ); + rc = sqlite3ApiExit(v->db, rc); + sqlite3_mutex_leave(v->db->mutex); + } + return rc; +} + +/* +** Set all the parameters in the compiled SQL statement to NULL. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt *pStmt){ + int i; + int rc = SQLITE_OK; + Vdbe *p = (Vdbe*)pStmt; +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex = ((Vdbe*)pStmt)->db->mutex; +#endif + sqlite3_mutex_enter(mutex); + for(i=0; inVar; i++){ + sqlite3VdbeMemRelease(&p->aVar[i]); + p->aVar[i].flags = MEM_Null; + } + if( p->isPrepareV2 && p->expmask ){ + p->expired = 1; + } + sqlite3_mutex_leave(mutex); + return rc; +} + + +/**************************** sqlite3_value_ ******************************* +** The following routines extract information from a Mem or sqlite3_value +** structure. +*/ +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value *pVal){ + Mem *p = (Mem*)pVal; + if( p->flags & (MEM_Blob|MEM_Str) ){ + sqlite3VdbeMemExpandBlob(p); + p->flags |= MEM_Blob; + return p->n ? p->z : 0; + }else{ + return sqlite3_value_text(pVal); + } +} +SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value *pVal){ + return sqlite3ValueBytes(pVal, SQLITE_UTF8); +} +SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value *pVal){ + return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE); +} +SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value *pVal){ + return sqlite3VdbeRealValue((Mem*)pVal); +} +SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value *pVal){ + return (int)sqlite3VdbeIntValue((Mem*)pVal); +} +SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value *pVal){ + return sqlite3VdbeIntValue((Mem*)pVal); +} +SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value *pVal){ + return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value* pVal){ + return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE); +} +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value *pVal){ + return sqlite3ValueText(pVal, SQLITE_UTF16BE); +} +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value *pVal){ + return sqlite3ValueText(pVal, SQLITE_UTF16LE); +} +#endif /* SQLITE_OMIT_UTF16 */ +/* EVIDENCE-OF: R-12793-43283 Every value in SQLite has one of five +** fundamental datatypes: 64-bit signed integer 64-bit IEEE floating +** point number string BLOB NULL +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value* pVal){ + static const u8 aType[] = { + SQLITE_BLOB, /* 0x00 */ + SQLITE_NULL, /* 0x01 */ + SQLITE_TEXT, /* 0x02 */ + SQLITE_NULL, /* 0x03 */ + SQLITE_INTEGER, /* 0x04 */ + SQLITE_NULL, /* 0x05 */ + SQLITE_INTEGER, /* 0x06 */ + SQLITE_NULL, /* 0x07 */ + SQLITE_FLOAT, /* 0x08 */ + SQLITE_NULL, /* 0x09 */ + SQLITE_FLOAT, /* 0x0a */ + SQLITE_NULL, /* 0x0b */ + SQLITE_INTEGER, /* 0x0c */ + SQLITE_NULL, /* 0x0d */ + SQLITE_INTEGER, /* 0x0e */ + SQLITE_NULL, /* 0x0f */ + SQLITE_BLOB, /* 0x10 */ + SQLITE_NULL, /* 0x11 */ + SQLITE_TEXT, /* 0x12 */ + SQLITE_NULL, /* 0x13 */ + SQLITE_INTEGER, /* 0x14 */ + SQLITE_NULL, /* 0x15 */ + SQLITE_INTEGER, /* 0x16 */ + SQLITE_NULL, /* 0x17 */ + SQLITE_FLOAT, /* 0x18 */ + SQLITE_NULL, /* 0x19 */ + SQLITE_FLOAT, /* 0x1a */ + SQLITE_NULL, /* 0x1b */ + SQLITE_INTEGER, /* 0x1c */ + SQLITE_NULL, /* 0x1d */ + SQLITE_INTEGER, /* 0x1e */ + SQLITE_NULL, /* 0x1f */ + }; + return aType[pVal->flags&MEM_AffMask]; +} + +/**************************** sqlite3_result_ ******************************* +** The following routines are used by user-defined functions to specify +** the function result. +** +** The setStrOrError() function calls sqlite3VdbeMemSetStr() to store the +** result as a string or blob but if the string or blob is too large, it +** then sets the error code to SQLITE_TOOBIG +** +** The invokeValueDestructor(P,X) routine invokes destructor function X() +** on value P is not going to be used and need to be destroyed. +*/ +static void setResultStrOrError( + sqlite3_context *pCtx, /* Function context */ + const char *z, /* String pointer */ + int n, /* Bytes in string, or negative */ + u8 enc, /* Encoding of z. 0 for BLOBs */ + void (*xDel)(void*) /* Destructor function */ +){ + if( sqlite3VdbeMemSetStr(pCtx->pOut, z, n, enc, xDel)==SQLITE_TOOBIG ){ + sqlite3_result_error_toobig(pCtx); + } +} +static int invokeValueDestructor( + const void *p, /* Value to destroy */ + void (*xDel)(void*), /* The destructor */ + sqlite3_context *pCtx /* Set a SQLITE_TOOBIG error if no NULL */ +){ + assert( xDel!=SQLITE_DYNAMIC ); + if( xDel==0 ){ + /* noop */ + }else if( xDel==SQLITE_TRANSIENT ){ + /* noop */ + }else{ + xDel((void*)p); + } + if( pCtx ) sqlite3_result_error_toobig(pCtx); + return SQLITE_TOOBIG; +} +SQLITE_API void SQLITE_STDCALL sqlite3_result_blob( + sqlite3_context *pCtx, + const void *z, + int n, + void (*xDel)(void *) +){ + assert( n>=0 ); + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + setResultStrOrError(pCtx, z, n, 0, xDel); +} +SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64( + sqlite3_context *pCtx, + const void *z, + sqlite3_uint64 n, + void (*xDel)(void *) +){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + assert( xDel!=SQLITE_DYNAMIC ); + if( n>0x7fffffff ){ + (void)invokeValueDestructor(z, xDel, pCtx); + }else{ + setResultStrOrError(pCtx, z, (int)n, 0, xDel); + } +} +SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context *pCtx, double rVal){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetDouble(pCtx->pOut, rVal); +} +SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + pCtx->isError = SQLITE_ERROR; + pCtx->fErrorOrAux = 1; + sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + pCtx->isError = SQLITE_ERROR; + pCtx->fErrorOrAux = 1; + sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT); +} +#endif +SQLITE_API void SQLITE_STDCALL sqlite3_result_int(sqlite3_context *pCtx, int iVal){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal); +} +SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetInt64(pCtx->pOut, iVal); +} +SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context *pCtx){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetNull(pCtx->pOut); +} +SQLITE_API void SQLITE_STDCALL sqlite3_result_text( + sqlite3_context *pCtx, + const char *z, + int n, + void (*xDel)(void *) +){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel); +} +SQLITE_API void SQLITE_STDCALL sqlite3_result_text64( + sqlite3_context *pCtx, + const char *z, + sqlite3_uint64 n, + void (*xDel)(void *), + unsigned char enc +){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + assert( xDel!=SQLITE_DYNAMIC ); + if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; + if( n>0x7fffffff ){ + (void)invokeValueDestructor(z, xDel, pCtx); + }else{ + setResultStrOrError(pCtx, z, (int)n, enc, xDel); + } +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API void SQLITE_STDCALL sqlite3_result_text16( + sqlite3_context *pCtx, + const void *z, + int n, + void (*xDel)(void *) +){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel); +} +SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be( + sqlite3_context *pCtx, + const void *z, + int n, + void (*xDel)(void *) +){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel); +} +SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le( + sqlite3_context *pCtx, + const void *z, + int n, + void (*xDel)(void *) +){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel); +} +#endif /* SQLITE_OMIT_UTF16 */ +SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemCopy(pCtx->pOut, pValue); +} +SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n); +} +SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ + pCtx->isError = errCode; + pCtx->fErrorOrAux = 1; +#ifdef SQLITE_DEBUG + if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode; +#endif + if( pCtx->pOut->flags & MEM_Null ){ + sqlite3VdbeMemSetStr(pCtx->pOut, sqlite3ErrStr(errCode), -1, + SQLITE_UTF8, SQLITE_STATIC); + } +} + +/* Force an SQLITE_TOOBIG error. */ +SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context *pCtx){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + pCtx->isError = SQLITE_TOOBIG; + pCtx->fErrorOrAux = 1; + sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1, + SQLITE_UTF8, SQLITE_STATIC); +} + +/* An SQLITE_NOMEM error. */ +SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context *pCtx){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetNull(pCtx->pOut); + pCtx->isError = SQLITE_NOMEM; + pCtx->fErrorOrAux = 1; + pCtx->pOut->db->mallocFailed = 1; +} + +/* +** This function is called after a transaction has been committed. It +** invokes callbacks registered with sqlite3_wal_hook() as required. +*/ +static int doWalCallbacks(sqlite3 *db){ + int rc = SQLITE_OK; +#ifndef SQLITE_OMIT_WAL + int i; + for(i=0; inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + int nEntry; + sqlite3BtreeEnter(pBt); + nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt)); + sqlite3BtreeLeave(pBt); + if( db->xWalCallback && nEntry>0 && rc==SQLITE_OK ){ + rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zName, nEntry); + } + } + } +#endif + return rc; +} + +/* +** Execute the statement pStmt, either until a row of data is ready, the +** statement is completely executed or an error occurs. +** +** This routine implements the bulk of the logic behind the sqlite_step() +** API. The only thing omitted is the automatic recompile if a +** schema change has occurred. That detail is handled by the +** outer sqlite3_step() wrapper procedure. +*/ +static int sqlite3Step(Vdbe *p){ + sqlite3 *db; + int rc; + + assert(p); + if( p->magic!=VDBE_MAGIC_RUN ){ + /* We used to require that sqlite3_reset() be called before retrying + ** sqlite3_step() after any error or after SQLITE_DONE. But beginning + ** with version 3.7.0, we changed this so that sqlite3_reset() would + ** be called automatically instead of throwing the SQLITE_MISUSE error. + ** This "automatic-reset" change is not technically an incompatibility, + ** since any application that receives an SQLITE_MISUSE is broken by + ** definition. + ** + ** Nevertheless, some published applications that were originally written + ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE + ** returns, and those were broken by the automatic-reset change. As a + ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the + ** legacy behavior of returning SQLITE_MISUSE for cases where the + ** previous sqlite3_step() returned something other than a SQLITE_LOCKED + ** or SQLITE_BUSY error. + */ +#ifdef SQLITE_OMIT_AUTORESET + if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){ + sqlite3_reset((sqlite3_stmt*)p); + }else{ + return SQLITE_MISUSE_BKPT; + } +#else + sqlite3_reset((sqlite3_stmt*)p); +#endif + } + + /* Check that malloc() has not failed. If it has, return early. */ + db = p->db; + if( db->mallocFailed ){ + p->rc = SQLITE_NOMEM; + return SQLITE_NOMEM; + } + + if( p->pc<=0 && p->expired ){ + p->rc = SQLITE_SCHEMA; + rc = SQLITE_ERROR; + goto end_of_step; + } + if( p->pc<0 ){ + /* If there are no other statements currently running, then + ** reset the interrupt flag. This prevents a call to sqlite3_interrupt + ** from interrupting a statement that has not yet started. + */ + if( db->nVdbeActive==0 ){ + db->u1.isInterrupted = 0; + } + + assert( db->nVdbeWrite>0 || db->autoCommit==0 + || (db->nDeferredCons==0 && db->nDeferredImmCons==0) + ); + +#ifndef SQLITE_OMIT_TRACE + if( db->xProfile && !db->init.busy ){ + sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime); + } +#endif + + db->nVdbeActive++; + if( p->readOnly==0 ) db->nVdbeWrite++; + if( p->bIsReader ) db->nVdbeRead++; + p->pc = 0; + } +#ifdef SQLITE_DEBUG + p->rcApp = SQLITE_OK; +#endif +#ifndef SQLITE_OMIT_EXPLAIN + if( p->explain ){ + rc = sqlite3VdbeList(p); + }else +#endif /* SQLITE_OMIT_EXPLAIN */ + { + db->nVdbeExec++; + rc = sqlite3VdbeExec(p); + db->nVdbeExec--; + } + +#ifndef SQLITE_OMIT_TRACE + /* Invoke the profile callback if there is one + */ + if( rc!=SQLITE_ROW && db->xProfile && !db->init.busy && p->zSql ){ + sqlite3_int64 iNow; + sqlite3OsCurrentTimeInt64(db->pVfs, &iNow); + db->xProfile(db->pProfileArg, p->zSql, (iNow - p->startTime)*1000000); + } +#endif + + if( rc==SQLITE_DONE ){ + assert( p->rc==SQLITE_OK ); + p->rc = doWalCallbacks(db); + if( p->rc!=SQLITE_OK ){ + rc = SQLITE_ERROR; + } + } + + db->errCode = rc; + if( SQLITE_NOMEM==sqlite3ApiExit(p->db, p->rc) ){ + p->rc = SQLITE_NOMEM; + } +end_of_step: + /* At this point local variable rc holds the value that should be + ** returned if this statement was compiled using the legacy + ** sqlite3_prepare() interface. According to the docs, this can only + ** be one of the values in the first assert() below. Variable p->rc + ** contains the value that would be returned if sqlite3_finalize() + ** were called on statement p. + */ + assert( rc==SQLITE_ROW || rc==SQLITE_DONE || rc==SQLITE_ERROR + || rc==SQLITE_BUSY || rc==SQLITE_MISUSE + ); + assert( (p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE) || p->rc==p->rcApp ); + if( p->isPrepareV2 && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){ + /* If this statement was prepared using sqlite3_prepare_v2(), and an + ** error has occurred, then return the error code in p->rc to the + ** caller. Set the error code in the database handle to the same value. + */ + rc = sqlite3VdbeTransferError(p); + } + return (rc&db->errMask); +} + +/* +** This is the top-level implementation of sqlite3_step(). Call +** sqlite3Step() to do most of the work. If a schema error occurs, +** call sqlite3Reprepare() and try again. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt *pStmt){ + int rc = SQLITE_OK; /* Result from sqlite3Step() */ + int rc2 = SQLITE_OK; /* Result from sqlite3Reprepare() */ + Vdbe *v = (Vdbe*)pStmt; /* the prepared statement */ + int cnt = 0; /* Counter to prevent infinite loop of reprepares */ + sqlite3 *db; /* The database connection */ + + if( vdbeSafetyNotNull(v) ){ + return SQLITE_MISUSE_BKPT; + } + db = v->db; + sqlite3_mutex_enter(db->mutex); + v->doingRerun = 0; + while( (rc = sqlite3Step(v))==SQLITE_SCHEMA + && cnt++ < SQLITE_MAX_SCHEMA_RETRY ){ + int savedPc = v->pc; + rc2 = rc = sqlite3Reprepare(v); + if( rc!=SQLITE_OK) break; + sqlite3_reset(pStmt); + if( savedPc>=0 ) v->doingRerun = 1; + assert( v->expired==0 ); + } + if( rc2!=SQLITE_OK ){ + /* This case occurs after failing to recompile an sql statement. + ** The error message from the SQL compiler has already been loaded + ** into the database handle. This block copies the error message + ** from the database handle into the statement and sets the statement + ** program counter to 0 to ensure that when the statement is + ** finalized or reset the parser error message is available via + ** sqlite3_errmsg() and sqlite3_errcode(). + */ + const char *zErr = (const char *)sqlite3_value_text(db->pErr); + sqlite3DbFree(db, v->zErrMsg); + if( !db->mallocFailed ){ + v->zErrMsg = sqlite3DbStrDup(db, zErr); + v->rc = rc2; + } else { + v->zErrMsg = 0; + v->rc = rc = SQLITE_NOMEM; + } + } + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + + +/* +** Extract the user data from a sqlite3_context structure and return a +** pointer to it. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context *p){ + assert( p && p->pFunc ); + return p->pFunc->pUserData; +} + +/* +** Extract the user data from a sqlite3_context structure and return a +** pointer to it. +** +** IMPLEMENTATION-OF: R-46798-50301 The sqlite3_context_db_handle() interface +** returns a copy of the pointer to the database connection (the 1st +** parameter) of the sqlite3_create_function() and +** sqlite3_create_function16() routines that originally registered the +** application defined function. +*/ +SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context *p){ + assert( p && p->pFunc ); + return p->pOut->db; +} + +/* +** Return the current time for a statement. If the current time +** is requested more than once within the same run of a single prepared +** statement, the exact same time is returned for each invocation regardless +** of the amount of time that elapses between invocations. In other words, +** the time returned is always the time of the first call. +*/ +SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){ + int rc; +#ifndef SQLITE_ENABLE_STAT3_OR_STAT4 + sqlite3_int64 *piTime = &p->pVdbe->iCurrentTime; + assert( p->pVdbe!=0 ); +#else + sqlite3_int64 iTime = 0; + sqlite3_int64 *piTime = p->pVdbe!=0 ? &p->pVdbe->iCurrentTime : &iTime; +#endif + if( *piTime==0 ){ + rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, piTime); + if( rc ) *piTime = 0; + } + return *piTime; +} + +/* +** The following is the implementation of an SQL function that always +** fails with an error message stating that the function is used in the +** wrong context. The sqlite3_overload_function() API might construct +** SQL function that use this routine so that the functions will exist +** for name resolution but are actually overloaded by the xFindFunction +** method of virtual tables. +*/ +SQLITE_PRIVATE void sqlite3InvalidFunction( + sqlite3_context *context, /* The function calling context */ + int NotUsed, /* Number of arguments to the function */ + sqlite3_value **NotUsed2 /* Value of each argument */ +){ + const char *zName = context->pFunc->zName; + char *zErr; + UNUSED_PARAMETER2(NotUsed, NotUsed2); + zErr = sqlite3_mprintf( + "unable to use function %s in the requested context", zName); + sqlite3_result_error(context, zErr, -1); + sqlite3_free(zErr); +} + +/* +** Create a new aggregate context for p and return a pointer to +** its pMem->z element. +*/ +static SQLITE_NOINLINE void *createAggContext(sqlite3_context *p, int nByte){ + Mem *pMem = p->pMem; + assert( (pMem->flags & MEM_Agg)==0 ); + if( nByte<=0 ){ + sqlite3VdbeMemSetNull(pMem); + pMem->z = 0; + }else{ + sqlite3VdbeMemClearAndResize(pMem, nByte); + pMem->flags = MEM_Agg; + pMem->u.pDef = p->pFunc; + if( pMem->z ){ + memset(pMem->z, 0, nByte); + } + } + return (void*)pMem->z; +} + +/* +** 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. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context *p, int nByte){ + assert( p && p->pFunc && p->pFunc->xStep ); + assert( sqlite3_mutex_held(p->pOut->db->mutex) ); + testcase( nByte<0 ); + if( (p->pMem->flags & MEM_Agg)==0 ){ + return createAggContext(p, nByte); + }else{ + return (void*)p->pMem->z; + } +} + +/* +** Return the auxiliary data pointer, if any, for the iArg'th argument to +** the user-function defined by pCtx. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ + AuxData *pAuxData; + + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); +#if SQLITE_ENABLE_STAT3_OR_STAT4 + if( pCtx->pVdbe==0 ) return 0; +#else + assert( pCtx->pVdbe!=0 ); +#endif + for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){ + if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break; + } + + return (pAuxData ? pAuxData->pAux : 0); +} + +/* +** Set the auxiliary data pointer and delete function, for the iArg'th +** argument to the user-function defined by pCtx. Any previous value is +** deleted by calling the delete function specified when it was set. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata( + sqlite3_context *pCtx, + int iArg, + void *pAux, + void (*xDelete)(void*) +){ + AuxData *pAuxData; + Vdbe *pVdbe = pCtx->pVdbe; + + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + if( iArg<0 ) goto failed; +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + if( pVdbe==0 ) goto failed; +#else + assert( pVdbe!=0 ); +#endif + + for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){ + if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break; + } + if( pAuxData==0 ){ + pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData)); + if( !pAuxData ) goto failed; + pAuxData->iOp = pCtx->iOp; + pAuxData->iArg = iArg; + pAuxData->pNext = pVdbe->pAuxData; + pVdbe->pAuxData = pAuxData; + if( pCtx->fErrorOrAux==0 ){ + pCtx->isError = 0; + pCtx->fErrorOrAux = 1; + } + }else if( pAuxData->xDelete ){ + pAuxData->xDelete(pAuxData->pAux); + } + + pAuxData->pAux = pAux; + pAuxData->xDelete = xDelete; + return; + +failed: + if( xDelete ){ + xDelete(pAux); + } +} + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** Return the number of times the Step function of an aggregate has been +** called. +** +** This function is deprecated. Do not use it for new code. It is +** provide only to avoid breaking legacy code. New aggregate function +** implementations should keep their own counts within their aggregate +** context. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context *p){ + assert( p && p->pMem && p->pFunc && p->pFunc->xStep ); + return p->pMem->n; +} +#endif + +/* +** Return the number of columns in the result set for the statement pStmt. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt){ + Vdbe *pVm = (Vdbe *)pStmt; + return pVm ? pVm->nResColumn : 0; +} + +/* +** Return the number of values available from the current row of the +** currently executing statement pStmt. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt){ + Vdbe *pVm = (Vdbe *)pStmt; + if( pVm==0 || pVm->pResultSet==0 ) return 0; + return pVm->nResColumn; +} + +/* +** Return a pointer to static memory containing an SQL NULL value. +*/ +static const Mem *columnNullValue(void){ + /* Even though the Mem structure contains an element + ** of type i64, on certain architectures (x86) with certain compiler + ** switches (-Os), gcc may align this Mem object on a 4-byte boundary + ** instead of an 8-byte one. This all works fine, except that when + ** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s + ** that a Mem structure is located on an 8-byte boundary. To prevent + ** these assert()s from failing, when building with SQLITE_DEBUG defined + ** using gcc, we force nullMem to be 8-byte aligned using the magical + ** __attribute__((aligned(8))) macro. */ + static const Mem nullMem +#if defined(SQLITE_DEBUG) && defined(__GNUC__) + __attribute__((aligned(8))) +#endif + = { + /* .u = */ {0}, + /* .flags = */ MEM_Null, + /* .enc = */ 0, + /* .n = */ 0, + /* .z = */ 0, + /* .zMalloc = */ 0, + /* .szMalloc = */ 0, + /* .iPadding1 = */ 0, + /* .db = */ 0, + /* .xDel = */ 0, +#ifdef SQLITE_DEBUG + /* .pScopyFrom = */ 0, + /* .pFiller = */ 0, +#endif + }; + return &nullMem; +} + +/* +** Check to see if column iCol of the given statement is valid. If +** it is, return a pointer to the Mem for the value of that column. +** If iCol is not valid, return a pointer to a Mem which has a value +** of NULL. +*/ +static Mem *columnMem(sqlite3_stmt *pStmt, int i){ + Vdbe *pVm; + Mem *pOut; + + pVm = (Vdbe *)pStmt; + if( pVm && pVm->pResultSet!=0 && inResColumn && i>=0 ){ + sqlite3_mutex_enter(pVm->db->mutex); + pOut = &pVm->pResultSet[i]; + }else{ + if( pVm && ALWAYS(pVm->db) ){ + sqlite3_mutex_enter(pVm->db->mutex); + sqlite3Error(pVm->db, SQLITE_RANGE); + } + pOut = (Mem*)columnNullValue(); + } + return pOut; +} + +/* +** 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. +** +** Specifically, 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() +** sqiite3_column_blob() +*/ +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. + */ + Vdbe *p = (Vdbe *)pStmt; + if( p ){ + p->rc = sqlite3ApiExit(p->db, p->rc); + sqlite3_mutex_leave(p->db->mutex); + } +} + +/**************************** sqlite3_column_ ******************************* +** The following routines are used to access elements of the current row +** in the result set. +*/ +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt *pStmt, int i){ + const void *val; + val = sqlite3_value_blob( columnMem(pStmt,i) ); + /* Even though there is no encoding conversion, value_blob() might + ** need to call malloc() to expand the result of a zeroblob() + ** expression. + */ + columnMallocFailure(pStmt); + return val; +} +SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){ + int val = sqlite3_value_bytes( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){ + int val = sqlite3_value_bytes16( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt *pStmt, int i){ + double val = sqlite3_value_double( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt *pStmt, int i){ + int val = sqlite3_value_int( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_column_int64(sqlite3_stmt *pStmt, int i){ + sqlite_int64 val = sqlite3_value_int64( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt *pStmt, int i){ + const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt *pStmt, int i){ + Mem *pOut = columnMem(pStmt, i); + if( pOut->flags&MEM_Static ){ + pOut->flags &= ~MEM_Static; + pOut->flags |= MEM_Ephem; + } + columnMallocFailure(pStmt); + return (sqlite3_value *)pOut; +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API const void *SQLITE_STDCALL 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 */ +SQLITE_API int SQLITE_STDCALL sqlite3_column_type(sqlite3_stmt *pStmt, int i){ + int iType = sqlite3_value_type( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return iType; +} + +/* +** 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; + int n; + sqlite3 *db; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pStmt==0 ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + ret = 0; + p = (Vdbe *)pStmt; + db = p->db; + assert( db!=0 ); + n = sqlite3_column_count(pStmt); + if( N=0 ){ + N += useType*n; + sqlite3_mutex_enter(db->mutex); + assert( db->mallocFailed==0 ); + 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. + */ + if( db->mallocFailed ){ + db->mallocFailed = 0; + ret = 0; + } + sqlite3_mutex_leave(db->mutex); + } + return ret; +} + +/* +** Return the name of the Nth column of the result set returned by SQL +** statement pStmt. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_name(sqlite3_stmt *pStmt, int N){ + return columnName( + pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_NAME); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt *pStmt, int N){ + return columnName( + pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_NAME); +} +#endif + +/* +** Constraint: If you have ENABLE_COLUMN_METADATA then you must +** not define OMIT_DECLTYPE. +*/ +#if defined(SQLITE_OMIT_DECLTYPE) && defined(SQLITE_ENABLE_COLUMN_METADATA) +# error "Must not define both SQLITE_OMIT_DECLTYPE \ + and SQLITE_ENABLE_COLUMN_METADATA" +#endif + +#ifndef SQLITE_OMIT_DECLTYPE +/* +** Return the column declaration type (if applicable) of the 'i'th column +** of the result set of SQL statement pStmt. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){ + return columnName( + pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DECLTYPE); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){ + return columnName( + pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DECLTYPE); +} +#endif /* SQLITE_OMIT_UTF16 */ +#endif /* SQLITE_OMIT_DECLTYPE */ + +#ifdef SQLITE_ENABLE_COLUMN_METADATA +/* +** 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 unambiguous reference to a database column. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){ + return columnName( + pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DATABASE); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){ + return columnName( + pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DATABASE); +} +#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 unambiguous reference to a database column. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){ + return columnName( + pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_TABLE); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){ + return columnName( + pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_TABLE); +} +#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 unambiguous reference to a database column. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){ + return columnName( + pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_COLUMN); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){ + return columnName( + pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_COLUMN); +} +#endif /* SQLITE_OMIT_UTF16 */ +#endif /* SQLITE_ENABLE_COLUMN_METADATA */ + + +/******************************* 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. +** +** A successful evaluation of this routine acquires the mutex on p. +** the mutex is released if any kind of error occurs. +** +** 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( vdbeSafetyNotNull(p) ){ + return SQLITE_MISUSE_BKPT; + } + sqlite3_mutex_enter(p->db->mutex); + if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){ + sqlite3Error(p->db, SQLITE_MISUSE); + sqlite3_mutex_leave(p->db->mutex); + sqlite3_log(SQLITE_MISUSE, + "bind on a busy prepared statement: [%s]", p->zSql); + return SQLITE_MISUSE_BKPT; + } + if( i<1 || i>p->nVar ){ + sqlite3Error(p->db, SQLITE_RANGE); + sqlite3_mutex_leave(p->db->mutex); + return SQLITE_RANGE; + } + i--; + pVar = &p->aVar[i]; + sqlite3VdbeMemRelease(pVar); + pVar->flags = MEM_Null; + sqlite3Error(p->db, SQLITE_OK); + + /* If the bit corresponding to this variable in Vdbe.expmask is set, then + ** binding a new value to this variable invalidates the current query plan. + ** + ** IMPLEMENTATION-OF: R-48440-37595 If the specific value bound to host + ** parameter in the WHERE clause might influence the choice of query plan + ** for a statement, then the statement will be automatically recompiled, + ** as if there had been a schema change, on the first sqlite3_step() call + ** following any change to the bindings of that parameter. + */ + if( p->isPrepareV2 && + ((i<32 && p->expmask & ((u32)1 << i)) || p->expmask==0xffffffff) + ){ + p->expired = 1; + } + return SQLITE_OK; +} + +/* +** Bind a text or BLOB value. +*/ +static int bindText( + sqlite3_stmt *pStmt, /* The statement to bind against */ + int i, /* Index of the parameter to bind */ + const void *zData, /* Pointer to the data to be bound */ + int nData, /* Number of bytes of data to be bound */ + void (*xDel)(void*), /* Destructor for the data */ + u8 encoding /* Encoding for the data */ +){ + Vdbe *p = (Vdbe *)pStmt; + Mem *pVar; + int rc; + + rc = vdbeUnbind(p, i); + if( rc==SQLITE_OK ){ + if( zData!=0 ){ + pVar = &p->aVar[i-1]; + rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); + if( rc==SQLITE_OK && encoding!=0 ){ + rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db)); + } + sqlite3Error(p->db, rc); + rc = sqlite3ApiExit(p->db, rc); + } + sqlite3_mutex_leave(p->db->mutex); + }else if( xDel!=SQLITE_STATIC && xDel!=SQLITE_TRANSIENT ){ + xDel((void*)zData); + } + return rc; +} + + +/* +** Bind a blob value to an SQL statement variable. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob( + sqlite3_stmt *pStmt, + int i, + const void *zData, + int nData, + void (*xDel)(void*) +){ + return bindText(pStmt, i, zData, nData, xDel, 0); +} +SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64( + sqlite3_stmt *pStmt, + int i, + const void *zData, + sqlite3_uint64 nData, + void (*xDel)(void*) +){ + assert( xDel!=SQLITE_DYNAMIC ); + if( nData>0x7fffffff ){ + return invokeValueDestructor(zData, xDel, 0); + }else{ + return bindText(pStmt, i, zData, (int)nData, xDel, 0); + } +} +SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ + int rc; + Vdbe *p = (Vdbe *)pStmt; + rc = vdbeUnbind(p, i); + if( rc==SQLITE_OK ){ + sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue); + sqlite3_mutex_leave(p->db->mutex); + } + return rc; +} +SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){ + return sqlite3_bind_int64(p, i, (i64)iValue); +} +SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){ + int rc; + Vdbe *p = (Vdbe *)pStmt; + rc = vdbeUnbind(p, i); + if( rc==SQLITE_OK ){ + sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue); + sqlite3_mutex_leave(p->db->mutex); + } + return rc; +} +SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ + int rc; + Vdbe *p = (Vdbe*)pStmt; + rc = vdbeUnbind(p, i); + if( rc==SQLITE_OK ){ + sqlite3_mutex_leave(p->db->mutex); + } + return rc; +} +SQLITE_API int SQLITE_STDCALL sqlite3_bind_text( + sqlite3_stmt *pStmt, + int i, + const char *zData, + int nData, + void (*xDel)(void*) +){ + return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8); +} +SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64( + sqlite3_stmt *pStmt, + int i, + const char *zData, + sqlite3_uint64 nData, + void (*xDel)(void*), + unsigned char enc +){ + assert( xDel!=SQLITE_DYNAMIC ); + if( nData>0x7fffffff ){ + return invokeValueDestructor(zData, xDel, 0); + }else{ + if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; + return bindText(pStmt, i, zData, (int)nData, xDel, enc); + } +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16( + sqlite3_stmt *pStmt, + int i, + const void *zData, + int nData, + void (*xDel)(void*) +){ + return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE); +} +#endif /* SQLITE_OMIT_UTF16 */ +SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){ + int rc; + switch( sqlite3_value_type((sqlite3_value*)pValue) ){ + case SQLITE_INTEGER: { + rc = sqlite3_bind_int64(pStmt, i, pValue->u.i); + break; + } + case SQLITE_FLOAT: { + rc = sqlite3_bind_double(pStmt, i, pValue->u.r); + break; + } + case SQLITE_BLOB: { + if( pValue->flags & MEM_Zero ){ + rc = sqlite3_bind_zeroblob(pStmt, i, pValue->u.nZero); + }else{ + rc = sqlite3_bind_blob(pStmt, i, pValue->z, pValue->n,SQLITE_TRANSIENT); + } + break; + } + case SQLITE_TEXT: { + rc = bindText(pStmt,i, pValue->z, pValue->n, SQLITE_TRANSIENT, + pValue->enc); + break; + } + default: { + rc = sqlite3_bind_null(pStmt, i); + break; + } + } + return rc; +} +SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ + int rc; + Vdbe *p = (Vdbe *)pStmt; + rc = vdbeUnbind(p, i); + if( rc==SQLITE_OK ){ + sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); + sqlite3_mutex_leave(p->db->mutex); + } + return rc; +} + +/* +** Return the number of wildcards that can be potentially bound to. +** This routine is added to support DBD::SQLite. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){ + Vdbe *p = (Vdbe*)pStmt; + return p ? p->nVar : 0; +} + +/* +** Return the name of a wildcard parameter. Return NULL if the index +** is out of range or if the wildcard is unnamed. +** +** The result is always UTF-8. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){ + Vdbe *p = (Vdbe*)pStmt; + if( p==0 || i<1 || i>p->nzVar ){ + return 0; + } + return p->azVar[i-1]; +} + +/* +** Given a wildcard parameter name, return the index of the variable +** with that name. If there is no variable with the given name, +** return 0. +*/ +SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){ + int i; + if( p==0 ){ + return 0; + } + if( zName ){ + for(i=0; inzVar; i++){ + const char *z = p->azVar[i]; + if( z && strncmp(z,zName,nName)==0 && z[nName]==0 ){ + return i+1; + } + } + } + return 0; +} +SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){ + return sqlite3VdbeParameterIndex((Vdbe*)pStmt, zName, sqlite3Strlen30(zName)); +} + +/* +** Transfer all bindings from the first statement over to the second. +*/ +SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){ + Vdbe *pFrom = (Vdbe*)pFromStmt; + Vdbe *pTo = (Vdbe*)pToStmt; + int i; + assert( pTo->db==pFrom->db ); + assert( pTo->nVar==pFrom->nVar ); + sqlite3_mutex_enter(pTo->db->mutex); + for(i=0; inVar; i++){ + sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]); + } + sqlite3_mutex_leave(pTo->db->mutex); + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** Deprecated external interface. Internal/core SQLite code +** should call sqlite3TransferBindings. +** +** It is misuse to call this routine with statements from different +** database connections. But as this is a deprecated interface, we +** will not bother to check for that condition. +** +** If the two statements contain a different number of bindings, then +** an SQLITE_ERROR is returned. Nothing else can go wrong, so otherwise +** SQLITE_OK is returned. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){ + Vdbe *pFrom = (Vdbe*)pFromStmt; + Vdbe *pTo = (Vdbe*)pToStmt; + if( pFrom->nVar!=pTo->nVar ){ + return SQLITE_ERROR; + } + if( pTo->isPrepareV2 && pTo->expmask ){ + pTo->expired = 1; + } + if( pFrom->isPrepareV2 && pFrom->expmask ){ + pFrom->expired = 1; + } + return sqlite3TransferBindings(pFromStmt, pToStmt); +} +#endif + +/* +** 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. +*/ +SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt *pStmt){ + return pStmt ? ((Vdbe*)pStmt)->db : 0; +} + +/* +** Return true if the prepared statement is guaranteed to not modify the +** database. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt){ + return pStmt ? ((Vdbe*)pStmt)->readOnly : 1; +} + +/* +** Return true if the prepared statement is in need of being reset. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt *pStmt){ + Vdbe *v = (Vdbe*)pStmt; + return v!=0 && v->pc>=0 && v->magic==VDBE_MAGIC_RUN; +} + +/* +** Return a pointer to the next prepared statement after pStmt associated +** with database connection pDb. If pStmt is NULL, return the first +** prepared statement for the database connection. Return NULL if there +** are no more. +*/ +SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){ + sqlite3_stmt *pNext; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(pDb) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(pDb->mutex); + if( pStmt==0 ){ + pNext = (sqlite3_stmt*)pDb->pVdbe; + }else{ + pNext = (sqlite3_stmt*)((Vdbe*)pStmt)->pNext; + } + sqlite3_mutex_leave(pDb->mutex); + return pNext; +} + +/* +** Return the value of a status counter for a prepared statement +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ + Vdbe *pVdbe = (Vdbe*)pStmt; + u32 v; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !pStmt ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + v = pVdbe->aCounter[op]; + if( resetFlag ) pVdbe->aCounter[op] = 0; + return (int)v; +} + +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS +/* +** Return status data for a single loop within query pStmt. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_stmt_scanstatus( + sqlite3_stmt *pStmt, /* Prepared statement being queried */ + int idx, /* Index of loop to report on */ + int iScanStatusOp, /* Which metric to return */ + void *pOut /* OUT: Write the answer here */ +){ + Vdbe *p = (Vdbe*)pStmt; + ScanStatus *pScan; + if( idx<0 || idx>=p->nScan ) return 1; + pScan = &p->aScan[idx]; + switch( iScanStatusOp ){ + case SQLITE_SCANSTAT_NLOOP: { + *(sqlite3_int64*)pOut = p->anExec[pScan->addrLoop]; + break; + } + case SQLITE_SCANSTAT_NVISIT: { + *(sqlite3_int64*)pOut = p->anExec[pScan->addrVisit]; + break; + } + case SQLITE_SCANSTAT_EST: { + double r = 1.0; + LogEst x = pScan->nEst; + while( x<100 ){ + x += 10; + r *= 0.5; + } + *(double*)pOut = r*sqlite3LogEstToInt(x); + break; + } + case SQLITE_SCANSTAT_NAME: { + *(const char**)pOut = pScan->zName; + break; + } + case SQLITE_SCANSTAT_EXPLAIN: { + if( pScan->addrExplain ){ + *(const char**)pOut = p->aOp[ pScan->addrExplain ].p4.z; + }else{ + *(const char**)pOut = 0; + } + break; + } + case SQLITE_SCANSTAT_SELECTID: { + if( pScan->addrExplain ){ + *(int*)pOut = p->aOp[ pScan->addrExplain ].p1; + }else{ + *(int*)pOut = -1; + } + break; + } + default: { + return 1; + } + } + return 0; +} + +/* +** Zero all counters associated with the sqlite3_stmt_scanstatus() data. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){ + Vdbe *p = (Vdbe*)pStmt; + memset(p->anExec, 0, p->nOp * sizeof(i64)); +} +#endif /* SQLITE_ENABLE_STMT_SCANSTATUS */ + +/************** End of vdbeapi.c *********************************************/ +/************** Begin file vdbetrace.c ***************************************/ +/* +** 2009 November 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 code used to insert the values of host parameters +** (aka "wildcards") into the SQL text output by sqlite3_trace(). +** +** The Vdbe parse-tree explainer is also found here. +*/ + +#ifndef SQLITE_OMIT_TRACE + +/* +** zSql is a zero-terminated string of UTF-8 SQL text. Return the number of +** bytes in this text up to but excluding the first character in +** a host parameter. If the text contains no host parameters, return +** the total number of bytes in the text. +*/ +static int findNextHostParameter(const char *zSql, int *pnToken){ + int tokenType; + int nTotal = 0; + int n; + + *pnToken = 0; + while( zSql[0] ){ + n = sqlite3GetToken((u8*)zSql, &tokenType); + assert( n>0 && tokenType!=TK_ILLEGAL ); + if( tokenType==TK_VARIABLE ){ + *pnToken = n; + break; + } + nTotal += n; + zSql += n; + } + return nTotal; +} + +/* +** This function returns a pointer to a nul-terminated string in memory +** obtained from sqlite3DbMalloc(). If sqlite3.nVdbeExec is 1, then the +** string contains a copy of zRawSql but with host parameters expanded to +** their current bindings. Or, if sqlite3.nVdbeExec is greater than 1, +** then the returned string holds a copy of zRawSql with "-- " prepended +** to each line of text. +** +** If the SQLITE_TRACE_SIZE_LIMIT macro is defined to an integer, then +** then long strings and blobs are truncated to that many bytes. This +** can be used to prevent unreasonably large trace strings when dealing +** with large (multi-megabyte) strings and blobs. +** +** The calling function is responsible for making sure the memory returned +** is eventually freed. +** +** ALGORITHM: Scan the input string looking for host parameters in any of +** these forms: ?, ?N, $A, @A, :A. Take care to avoid text within +** string literals, quoted identifier names, and comments. For text forms, +** the host parameter index is found by scanning the prepared +** statement for the corresponding OP_Variable opcode. Once the host +** parameter index is known, locate the value in p->aVar[]. Then render +** the value as a literal in place of the host parameter name. +*/ +SQLITE_PRIVATE char *sqlite3VdbeExpandSql( + Vdbe *p, /* The prepared statement being evaluated */ + const char *zRawSql /* Raw text of the SQL statement */ +){ + sqlite3 *db; /* The database connection */ + int idx = 0; /* Index of a host parameter */ + int nextIndex = 1; /* Index of next ? host parameter */ + int n; /* Length of a token prefix */ + int nToken; /* Length of the parameter token */ + int i; /* Loop counter */ + Mem *pVar; /* Value of a host parameter */ + StrAccum out; /* Accumulate the output here */ + char zBase[100]; /* Initial working space */ + + db = p->db; + sqlite3StrAccumInit(&out, db, zBase, sizeof(zBase), + db->aLimit[SQLITE_LIMIT_LENGTH]); + if( db->nVdbeExec>1 ){ + while( *zRawSql ){ + const char *zStart = zRawSql; + while( *(zRawSql++)!='\n' && *zRawSql ); + sqlite3StrAccumAppend(&out, "-- ", 3); + assert( (zRawSql - zStart) > 0 ); + sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart)); + } + }else if( p->nVar==0 ){ + sqlite3StrAccumAppend(&out, zRawSql, sqlite3Strlen30(zRawSql)); + }else{ + while( zRawSql[0] ){ + n = findNextHostParameter(zRawSql, &nToken); + assert( n>0 ); + sqlite3StrAccumAppend(&out, zRawSql, n); + zRawSql += n; + assert( zRawSql[0] || nToken==0 ); + if( nToken==0 ) break; + if( zRawSql[0]=='?' ){ + if( nToken>1 ){ + assert( sqlite3Isdigit(zRawSql[1]) ); + sqlite3GetInt32(&zRawSql[1], &idx); + }else{ + idx = nextIndex; + } + }else{ + assert( zRawSql[0]==':' || zRawSql[0]=='$' || + zRawSql[0]=='@' || zRawSql[0]=='#' ); + testcase( zRawSql[0]==':' ); + testcase( zRawSql[0]=='$' ); + testcase( zRawSql[0]=='@' ); + testcase( zRawSql[0]=='#' ); + idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken); + assert( idx>0 ); + } + zRawSql += nToken; + nextIndex = idx + 1; + assert( idx>0 && idx<=p->nVar ); + pVar = &p->aVar[idx-1]; + if( pVar->flags & MEM_Null ){ + sqlite3StrAccumAppend(&out, "NULL", 4); + }else if( pVar->flags & MEM_Int ){ + sqlite3XPrintf(&out, 0, "%lld", pVar->u.i); + }else if( pVar->flags & MEM_Real ){ + sqlite3XPrintf(&out, 0, "%!.15g", pVar->u.r); + }else if( pVar->flags & MEM_Str ){ + int nOut; /* Number of bytes of the string text to include in output */ +#ifndef SQLITE_OMIT_UTF16 + u8 enc = ENC(db); + Mem utf8; + if( enc!=SQLITE_UTF8 ){ + memset(&utf8, 0, sizeof(utf8)); + utf8.db = db; + sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC); + sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8); + pVar = &utf8; + } +#endif + nOut = pVar->n; +#ifdef SQLITE_TRACE_SIZE_LIMIT + if( nOut>SQLITE_TRACE_SIZE_LIMIT ){ + nOut = SQLITE_TRACE_SIZE_LIMIT; + while( nOutn && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; } + } +#endif + sqlite3XPrintf(&out, 0, "'%.*q'", nOut, pVar->z); +#ifdef SQLITE_TRACE_SIZE_LIMIT + if( nOutn ){ + sqlite3XPrintf(&out, 0, "/*+%d bytes*/", pVar->n-nOut); + } +#endif +#ifndef SQLITE_OMIT_UTF16 + if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8); +#endif + }else if( pVar->flags & MEM_Zero ){ + sqlite3XPrintf(&out, 0, "zeroblob(%d)", pVar->u.nZero); + }else{ + int nOut; /* Number of bytes of the blob to include in output */ + assert( pVar->flags & MEM_Blob ); + sqlite3StrAccumAppend(&out, "x'", 2); + nOut = pVar->n; +#ifdef SQLITE_TRACE_SIZE_LIMIT + if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT; +#endif + for(i=0; iz[i]&0xff); + } + sqlite3StrAccumAppend(&out, "'", 1); +#ifdef SQLITE_TRACE_SIZE_LIMIT + if( nOutn ){ + sqlite3XPrintf(&out, 0, "/*+%d bytes*/", pVar->n-nOut); + } +#endif + } + } + } + return sqlite3StrAccumFinish(&out); +} + +#endif /* #ifndef SQLITE_OMIT_TRACE */ + +/************** End of vdbetrace.c *******************************************/ +/************** Begin file vdbe.c ********************************************/ +/* +** 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. +** +************************************************************************* +** The code in this file implements the function that runs the +** bytecode of a prepared statement. +** +** 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. +*/ + +/* +** Invoke this macro on memory cells just prior to changing the +** value of the cell. This macro verifies that shallow copies are +** not misused. A shallow copy of a string or blob just copies a +** pointer to the string or blob, not the content. If the original +** is changed while the copy is still in use, the string or blob might +** be changed out from under the copy. This macro verifies that nothing +** like that ever happens. +*/ +#ifdef SQLITE_DEBUG +# define memAboutToChange(P,M) sqlite3VdbeMemAboutToChange(P,M) +#else +# define memAboutToChange(P,M) +#endif + +/* +** The following global variable is incremented every time a cursor +** moves, either by the OP_SeekXX, OP_Next, or OP_Prev opcodes. The test +** procedures use this information to make sure that indices are +** working correctly. This variable has no function other than to +** help verify the correct operation of the library. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_search_count = 0; +#endif + +/* +** When this global variable is positive, it gets decremented once before +** each instruction in the VDBE. When it reaches zero, the u1.isInterrupted +** field of the sqlite3 structure is set in order to simulate an interrupt. +** +** This facility is used for testing purposes only. It does not function +** in an ordinary build. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_interrupt_count = 0; +#endif + +/* +** The next global variable is incremented each type the OP_Sort opcode +** is executed. The test procedures use this information to make sure that +** sorting is occurring or not occurring at appropriate times. This variable +** has no function other than to help verify the correct operation of the +** library. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_sort_count = 0; +#endif + +/* +** The next global variable records the size of the largest MEM_Blob +** or MEM_Str that has been used by a VDBE opcode. The test procedures +** use this information to make sure that the zero-blob functionality +** is working correctly. This variable has no function other than to +** help verify the correct operation of the library. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_max_blobsize = 0; +static void updateMaxBlobsize(Mem *p){ + if( (p->flags & (MEM_Str|MEM_Blob))!=0 && p->n>sqlite3_max_blobsize ){ + sqlite3_max_blobsize = p->n; + } +} +#endif + +/* +** The next global variable is incremented each time the OP_Found opcode +** is executed. This is used to test whether or not the foreign key +** operation implemented using OP_FkIsZero is working. This variable +** has no function other than to help verify the correct operation of the +** library. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_found_count = 0; +#endif + +/* +** Test a register to see if it exceeds the current maximum blob size. +** If it does, record the new maximum blob size. +*/ +#if defined(SQLITE_TEST) && !defined(SQLITE_OMIT_BUILTIN_TEST) +# define UPDATE_MAX_BLOBSIZE(P) updateMaxBlobsize(P) +#else +# define UPDATE_MAX_BLOBSIZE(P) +#endif + +/* +** Invoke the VDBE coverage callback, if that callback is defined. This +** feature is used for test suite validation only and does not appear an +** production builds. +** +** M is an integer, 2 or 3, that indices how many different ways the +** branch can go. It is usually 2. "I" is the direction the branch +** goes. 0 means falls through. 1 means branch is taken. 2 means the +** second alternative branch is taken. +** +** iSrcLine is the source code line (from the __LINE__ macro) that +** generated the VDBE instruction. This instrumentation assumes that all +** source code is in a single file (the amalgamation). Special values 1 +** and 2 for the iSrcLine parameter mean that this particular branch is +** always taken or never taken, respectively. +*/ +#if !defined(SQLITE_VDBE_COVERAGE) +# define VdbeBranchTaken(I,M) +#else +# define VdbeBranchTaken(I,M) vdbeTakeBranch(pOp->iSrcLine,I,M) + static void vdbeTakeBranch(int iSrcLine, u8 I, u8 M){ + if( iSrcLine<=2 && ALWAYS(iSrcLine>0) ){ + M = iSrcLine; + /* Assert the truth of VdbeCoverageAlwaysTaken() and + ** VdbeCoverageNeverTaken() */ + assert( (M & I)==I ); + }else{ + if( sqlite3GlobalConfig.xVdbeBranch==0 ) return; /*NO_TEST*/ + sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg, + iSrcLine,I,M); + } + } +#endif + +/* +** Convert the given register into a string if it isn't one +** already. Return non-zero if a malloc() fails. +*/ +#define Stringify(P, enc) \ + if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc,0)) \ + { goto no_mem; } + +/* +** 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 register +** does not control the string, it might be deleted without the register +** knowing it. +** +** This routine converts an ephemeral string into a dynamically allocated +** string that the register itself controls. In other words, it +** converts an MEM_Ephem string into a string with P.z==P.zMalloc. +*/ +#define Deephemeralize(P) \ + if( ((P)->flags&MEM_Ephem)!=0 \ + && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;} + +/* Return true if the cursor was opened using the OP_OpenSorter opcode. */ +#define isSorter(x) ((x)->pSorter!=0) + +/* +** Allocate VdbeCursor number iCur. Return a pointer to it. Return NULL +** if we run out of memory. +*/ +static VdbeCursor *allocateCursor( + Vdbe *p, /* The virtual machine */ + int iCur, /* Index of the new VdbeCursor */ + int nField, /* Number of fields in the table or index */ + int iDb, /* Database the cursor belongs to, or -1 */ + int isBtreeCursor /* True for B-Tree. False for pseudo-table or vtab */ +){ + /* Find the memory cell that will be used to store the blob of memory + ** required for this VdbeCursor structure. It is convenient to use a + ** vdbe memory cell to manage the memory allocation required for a + ** VdbeCursor structure for the following reasons: + ** + ** * Sometimes cursor numbers are used for a couple of different + ** purposes in a vdbe program. The different uses might require + ** different sized allocations. Memory cells provide growable + ** allocations. + ** + ** * When using ENABLE_MEMORY_MANAGEMENT, memory cell buffers can + ** be freed lazily via the sqlite3_release_memory() API. This + ** minimizes the number of malloc calls made by the system. + ** + ** Memory cells for cursors are allocated at the top of the address + ** space. Memory cell (p->nMem) corresponds to cursor 0. Space for + ** cursor 1 is managed by memory cell (p->nMem-1), etc. + */ + Mem *pMem = &p->aMem[p->nMem-iCur]; + + int nByte; + VdbeCursor *pCx = 0; + nByte = + ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + + (isBtreeCursor?sqlite3BtreeCursorSize():0); + + assert( iCurnCursor ); + if( p->apCsr[iCur] ){ + sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); + p->apCsr[iCur] = 0; + } + if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){ + p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z; + memset(pCx, 0, sizeof(VdbeCursor)); + pCx->iDb = iDb; + pCx->nField = nField; + pCx->aOffset = &pCx->aType[nField]; + if( isBtreeCursor ){ + pCx->pCursor = (BtCursor*) + &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField]; + sqlite3BtreeCursorZero(pCx->pCursor); + } + } + return pCx; +} + +/* +** Try to convert a value into a numeric representation if we can +** do so without loss of information. In other words, if the string +** looks like a number, convert it into a number. If it does not +** look like a number, leave it alone. +** +** If the bTryForInt flag is true, then extra effort is made to give +** an integer representation. Strings that look like floating point +** values but which have no fractional component (example: '48.00') +** will have a MEM_Int representation when bTryForInt is true. +** +** If bTryForInt is false, then if the input string contains a decimal +** point or exponential notation, the result is only MEM_Real, even +** if there is an exact integer representation of the quantity. +*/ +static void applyNumericAffinity(Mem *pRec, int bTryForInt){ + double rValue; + i64 iValue; + u8 enc = pRec->enc; + assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real))==MEM_Str ); + if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; + if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ + pRec->u.i = iValue; + pRec->flags |= MEM_Int; + }else{ + pRec->u.r = rValue; + pRec->flags |= MEM_Real; + if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec); + } +} + +/* +** 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, /* The value to apply affinity to */ + char affinity, /* The affinity to be applied */ + u8 enc /* Use this text encoding */ +){ + if( affinity>=SQLITE_AFF_NUMERIC ){ + assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL + || affinity==SQLITE_AFF_NUMERIC ); + if( (pRec->flags & MEM_Int)==0 ){ + if( (pRec->flags & MEM_Real)==0 ){ + if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1); + }else{ + sqlite3VdbeIntegerAffinity(pRec); + } + } + }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, 1); + } + } +} + +/* +** Try to convert the type of a function argument or a result column +** into a numeric representation. Use either INTEGER or REAL whichever +** is appropriate. But only do the conversion if it is possible without +** loss of information and return the revised type of the argument. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value *pVal){ + int eType = sqlite3_value_type(pVal); + if( eType==SQLITE_TEXT ){ + Mem *pMem = (Mem*)pVal; + applyNumericAffinity(pMem, 0); + eType = sqlite3_value_type(pVal); + } + return eType; +} + +/* +** Exported version of applyAffinity(). This one works on sqlite3_value*, +** not the internal Mem* type. +*/ +SQLITE_PRIVATE void sqlite3ValueApplyAffinity( + sqlite3_value *pVal, + u8 affinity, + u8 enc +){ + applyAffinity((Mem *)pVal, affinity, enc); +} + +/* +** pMem currently only holds a string type (or maybe a BLOB that we can +** interpret as a string if we want to). Compute its corresponding +** numeric type, if has one. Set the pMem->u.r and pMem->u.i fields +** accordingly. +*/ +static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ + assert( (pMem->flags & (MEM_Int|MEM_Real))==0 ); + assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ); + if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){ + return 0; + } + if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==SQLITE_OK ){ + return MEM_Int; + } + return MEM_Real; +} + +/* +** Return the numeric type for pMem, either MEM_Int or MEM_Real or both or +** none. +** +** Unlike applyNumericAffinity(), this routine does not modify pMem->flags. +** But it does set pMem->u.r and pMem->u.i appropriately. +*/ +static u16 numericType(Mem *pMem){ + if( pMem->flags & (MEM_Int|MEM_Real) ){ + return pMem->flags & (MEM_Int|MEM_Real); + } + if( pMem->flags & (MEM_Str|MEM_Blob) ){ + return computeNumericType(pMem); + } + return 0; +} + +#ifdef SQLITE_DEBUG +/* +** Write a nice string representation of the contents of cell pMem +** into buffer zBuf, length nBuf. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){ + char *zCsr = zBuf; + int f = pMem->flags; + + static const char *const encnames[] = {"(X)", "(8)", "(16LE)", "(16BE)"}; + + if( f&MEM_Blob ){ + int i; + char c; + if( f & MEM_Dyn ){ + c = 'z'; + assert( (f & (MEM_Static|MEM_Ephem))==0 ); + }else if( f & MEM_Static ){ + c = 't'; + assert( (f & (MEM_Dyn|MEM_Ephem))==0 ); + }else if( f & MEM_Ephem ){ + c = 'e'; + assert( (f & (MEM_Static|MEM_Dyn))==0 ); + }else{ + c = 's'; + } + + sqlite3_snprintf(100, zCsr, "%c", c); + zCsr += sqlite3Strlen30(zCsr); + sqlite3_snprintf(100, zCsr, "%d[", pMem->n); + zCsr += sqlite3Strlen30(zCsr); + for(i=0; i<16 && in; i++){ + sqlite3_snprintf(100, zCsr, "%02X", ((int)pMem->z[i] & 0xFF)); + zCsr += sqlite3Strlen30(zCsr); + } + for(i=0; i<16 && in; i++){ + char z = pMem->z[i]; + if( z<32 || z>126 ) *zCsr++ = '.'; + else *zCsr++ = z; + } + + sqlite3_snprintf(100, zCsr, "]%s", encnames[pMem->enc]); + zCsr += sqlite3Strlen30(zCsr); + if( f & MEM_Zero ){ + sqlite3_snprintf(100, zCsr,"+%dz",pMem->u.nZero); + zCsr += sqlite3Strlen30(zCsr); + } + *zCsr = '\0'; + }else if( f & MEM_Str ){ + int j, k; + zBuf[0] = ' '; + if( f & MEM_Dyn ){ + zBuf[1] = 'z'; + assert( (f & (MEM_Static|MEM_Ephem))==0 ); + }else if( f & MEM_Static ){ + zBuf[1] = 't'; + assert( (f & (MEM_Dyn|MEM_Ephem))==0 ); + }else if( f & MEM_Ephem ){ + zBuf[1] = 'e'; + assert( (f & (MEM_Static|MEM_Dyn))==0 ); + }else{ + zBuf[1] = 's'; + } + k = 2; + sqlite3_snprintf(100, &zBuf[k], "%d", pMem->n); + k += sqlite3Strlen30(&zBuf[k]); + zBuf[k++] = '['; + for(j=0; j<15 && jn; j++){ + u8 c = pMem->z[j]; + if( c>=0x20 && c<0x7f ){ + zBuf[k++] = c; + }else{ + zBuf[k++] = '.'; + } + } + zBuf[k++] = ']'; + sqlite3_snprintf(100,&zBuf[k], encnames[pMem->enc]); + k += sqlite3Strlen30(&zBuf[k]); + zBuf[k++] = 0; + } +} +#endif + +#ifdef SQLITE_DEBUG +/* +** Print the value of a register for tracing purposes: +*/ +static void memTracePrint(Mem *p){ + if( p->flags & MEM_Undefined ){ + printf(" undefined"); + }else if( p->flags & MEM_Null ){ + printf(" NULL"); + }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){ + printf(" si:%lld", p->u.i); + }else if( p->flags & MEM_Int ){ + printf(" i:%lld", p->u.i); +#ifndef SQLITE_OMIT_FLOATING_POINT + }else if( p->flags & MEM_Real ){ + printf(" r:%g", p->u.r); +#endif + }else if( p->flags & MEM_RowSet ){ + printf(" (rowset)"); + }else{ + char zBuf[200]; + sqlite3VdbeMemPrettyPrint(p, zBuf); + printf(" %s", zBuf); + } +} +static void registerTrace(int iReg, Mem *p){ + printf("REG[%d] = ", iReg); + memTracePrint(p); + printf("\n"); +} +#endif + +#ifdef SQLITE_DEBUG +# define REGISTER_TRACE(R,M) if(db->flags&SQLITE_VdbeTrace)registerTrace(R,M) +#else +# define REGISTER_TRACE(R,M) +#endif + + +#ifdef VDBE_PROFILE + +/* +** hwtime.h contains inline assembler code for implementing +** high-performance timing routines. +*/ +/************** Include hwtime.h in the middle of vdbe.c *********************/ +/************** Begin file hwtime.h ******************************************/ +/* +** 2008 May 27 +** +** 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 inline asm code for retrieving "high-performance" +** counters for x86 class CPUs. +*/ +#ifndef _HWTIME_H_ +#define _HWTIME_H_ + +/* +** The following routine only works on pentium-class (or newer) processors. +** It uses the RDTSC opcode to read the cycle count value out of the +** processor and returns that value. This can be used for high-res +** profiling. +*/ +#if (defined(__GNUC__) || defined(_MSC_VER)) && \ + (defined(i386) || defined(__i386__) || defined(_M_IX86)) + + #if defined(__GNUC__) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned int lo, hi; + __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); + return (sqlite_uint64)hi << 32 | lo; + } + + #elif defined(_MSC_VER) + + __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ + __asm { + rdtsc + ret ; return value at EDX:EAX + } + } + + #endif + +#elif (defined(__GNUC__) && defined(__x86_64__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned long val; + __asm__ __volatile__ ("rdtsc" : "=A" (val)); + return val; + } + +#elif (defined(__GNUC__) && defined(__ppc__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned long long retval; + unsigned long junk; + __asm__ __volatile__ ("\n\ + 1: mftbu %1\n\ + mftb %L0\n\ + mftbu %0\n\ + cmpw %0,%1\n\ + bne 1b" + : "=r" (retval), "=r" (junk)); + return retval; + } + +#else + + #error Need implementation of sqlite3Hwtime() for your platform. + + /* + ** To compile without implementing sqlite3Hwtime() for your platform, + ** you can remove the above #error and use the following + ** stub function. You will lose timing support for many + ** of the debugging and testing utilities, but it should at + ** least compile and run. + */ +SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } + +#endif + +#endif /* !defined(_HWTIME_H_) */ + +/************** End of hwtime.h **********************************************/ +/************** Continuing where we left off in vdbe.c ***********************/ + +#endif + +#ifndef NDEBUG +/* +** This function is only called from within an assert() expression. It +** checks that the sqlite3.nTransaction variable is correctly set to +** the number of non-transaction savepoints currently in the +** linked list starting at sqlite3.pSavepoint. +** +** Usage: +** +** assert( checkSavepointCount(db) ); +*/ +static int checkSavepointCount(sqlite3 *db){ + int n = 0; + Savepoint *p; + for(p=db->pSavepoint; p; p=p->pNext) n++; + assert( n==(db->nSavepoint + db->isTransactionSavepoint) ); + return 1; +} +#endif + +/* +** Return the register of pOp->p2 after first preparing it to be +** overwritten with an integer value. +*/ +static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){ + Mem *pOut; + assert( pOp->p2>0 ); + assert( pOp->p2<=(p->nMem-p->nCursor) ); + pOut = &p->aMem[pOp->p2]; + memAboutToChange(p, pOut); + if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut); + pOut->flags = MEM_Int; + return pOut; +} + + +/* +** Execute as much of a VDBE program as we can. +** This is the core of sqlite3_step(). +*/ +SQLITE_PRIVATE int sqlite3VdbeExec( + Vdbe *p /* The VDBE */ +){ + Op *aOp = p->aOp; /* Copy of p->aOp */ + Op *pOp = aOp; /* Current operation */ +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) + Op *pOrigOp; /* Value of pOp at the top of the loop */ +#endif + int rc = SQLITE_OK; /* Value to return */ + sqlite3 *db = p->db; /* The database */ + u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */ + u8 encoding = ENC(db); /* The database encoding */ + int iCompare = 0; /* Result of last OP_Compare operation */ + unsigned nVmStep = 0; /* Number of virtual machine steps */ +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + unsigned nProgressLimit = 0;/* Invoke xProgress() when nVmStep reaches this */ +#endif + Mem *aMem = p->aMem; /* Copy of p->aMem */ + Mem *pIn1 = 0; /* 1st input operand */ + Mem *pIn2 = 0; /* 2nd input operand */ + Mem *pIn3 = 0; /* 3rd input operand */ + Mem *pOut = 0; /* Output operand */ + int *aPermute = 0; /* Permutation of columns for OP_Compare */ + i64 lastRowid = db->lastRowid; /* Saved value of the last insert ROWID */ +#ifdef VDBE_PROFILE + u64 start; /* CPU clock count at start of opcode */ +#endif + /*** INSERT STACK UNION HERE ***/ + + assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ + sqlite3VdbeEnter(p); + 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 ); + assert( p->bIsReader || p->readOnly!=0 ); + p->rc = SQLITE_OK; + p->iCurrentTime = 0; + assert( p->explain==0 ); + p->pResultSet = 0; + db->busyHandler.nBusy = 0; + if( db->u1.isInterrupted ) goto abort_due_to_interrupt; + sqlite3VdbeIOTraceSql(p); +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + if( db->xProgress ){ + assert( 0 < db->nProgressOps ); + nProgressLimit = (unsigned)p->aCounter[SQLITE_STMTSTATUS_VM_STEP]; + if( nProgressLimit==0 ){ + nProgressLimit = db->nProgressOps; + }else{ + nProgressLimit %= (unsigned)db->nProgressOps; + } + } +#endif +#ifdef SQLITE_DEBUG + sqlite3BeginBenignMalloc(); + if( p->pc==0 + && (p->db->flags & (SQLITE_VdbeListing|SQLITE_VdbeEQP|SQLITE_VdbeTrace))!=0 + ){ + int i; + int once = 1; + sqlite3VdbePrintSql(p); + if( p->db->flags & SQLITE_VdbeListing ){ + printf("VDBE Program Listing:\n"); + for(i=0; inOp; i++){ + sqlite3VdbePrintOp(stdout, i, &aOp[i]); + } + } + if( p->db->flags & SQLITE_VdbeEQP ){ + for(i=0; inOp; i++){ + if( aOp[i].opcode==OP_Explain ){ + if( once ) printf("VDBE Query Plan:\n"); + printf("%s\n", aOp[i].p4.z); + once = 0; + } + } + } + if( p->db->flags & SQLITE_VdbeTrace ) printf("VDBE Trace:\n"); + } + sqlite3EndBenignMalloc(); +#endif + for(pOp=&aOp[p->pc]; rc==SQLITE_OK; pOp++){ + assert( pOp>=aOp && pOp<&aOp[p->nOp]); + if( db->mallocFailed ) goto no_mem; +#ifdef VDBE_PROFILE + start = sqlite3Hwtime(); +#endif + nVmStep++; +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + if( p->anExec ) p->anExec[(int)(pOp-aOp)]++; +#endif + + /* Only allow tracing if SQLITE_DEBUG is defined. + */ +#ifdef SQLITE_DEBUG + if( db->flags & SQLITE_VdbeTrace ){ + sqlite3VdbePrintOp(stdout, (int)(pOp - aOp), pOp); + } +#endif + + + /* Check to see if we need to simulate an interrupt. This only happens + ** if we have a special test build. + */ +#ifdef SQLITE_TEST + if( sqlite3_interrupt_count>0 ){ + sqlite3_interrupt_count--; + if( sqlite3_interrupt_count==0 ){ + sqlite3_interrupt(db); + } + } +#endif + + /* Sanity checking on other operands */ +#ifdef SQLITE_DEBUG + assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] ); + if( (pOp->opflags & OPFLG_IN1)!=0 ){ + assert( pOp->p1>0 ); + assert( pOp->p1<=(p->nMem-p->nCursor) ); + assert( memIsValid(&aMem[pOp->p1]) ); + assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) ); + REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]); + } + if( (pOp->opflags & OPFLG_IN2)!=0 ){ + assert( pOp->p2>0 ); + assert( pOp->p2<=(p->nMem-p->nCursor) ); + assert( memIsValid(&aMem[pOp->p2]) ); + assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) ); + REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]); + } + if( (pOp->opflags & OPFLG_IN3)!=0 ){ + assert( pOp->p3>0 ); + assert( pOp->p3<=(p->nMem-p->nCursor) ); + assert( memIsValid(&aMem[pOp->p3]) ); + assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) ); + REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]); + } + if( (pOp->opflags & OPFLG_OUT2)!=0 ){ + assert( pOp->p2>0 ); + assert( pOp->p2<=(p->nMem-p->nCursor) ); + memAboutToChange(p, &aMem[pOp->p2]); + } + if( (pOp->opflags & OPFLG_OUT3)!=0 ){ + assert( pOp->p3>0 ); + assert( pOp->p3<=(p->nMem-p->nCursor) ); + memAboutToChange(p, &aMem[pOp->p3]); + } +#endif +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) + pOrigOp = pOp; +#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. +** +** Other keywords in the comment that follows each case are used to +** construct the OPFLG_INITIALIZER value that initializes opcodeProperty[]. +** Keywords include: in1, in2, in3, out2, out3. See +** the mkopcodeh.awk script for additional information. +** +** 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. +** +** The P1 parameter is not actually used by this opcode. However, it +** is sometimes set to 1 instead of 0 as a hint to the command-line shell +** that this Goto is the bottom of a loop and that the lines from P2 down +** to the current line should be indented for EXPLAIN output. +*/ +case OP_Goto: { /* jump */ +jump_to_p2_and_check_for_interrupt: + pOp = &aOp[pOp->p2 - 1]; + + /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev, + ** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon + ** completion. Check to see if sqlite3_interrupt() has been called + ** or if the progress callback needs to be invoked. + ** + ** This code uses unstructured "goto" statements and does not look clean. + ** But that is not due to sloppy coding habits. The code is written this + ** way for performance, to avoid having to run the interrupt and progress + ** checks on every opcode. This helps sqlite3_step() to run about 1.5% + ** faster according to "valgrind --tool=cachegrind" */ +check_for_interrupt: + if( db->u1.isInterrupted ) goto abort_due_to_interrupt; +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + /* Call the progress callback if it is configured and the required number + ** of VDBE ops have been executed (either since this invocation of + ** sqlite3VdbeExec() or since last time the progress callback was called). + ** If the progress callback returns non-zero, exit the virtual machine with + ** a return code SQLITE_ABORT. + */ + if( db->xProgress!=0 && nVmStep>=nProgressLimit ){ + assert( db->nProgressOps!=0 ); + nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps); + if( db->xProgress(db->pProgressArg) ){ + rc = SQLITE_INTERRUPT; + goto vdbe_error_halt; + } + } +#endif + + break; +} + +/* Opcode: Gosub P1 P2 * * * +** +** Write the current address onto register P1 +** and then jump to address P2. +*/ +case OP_Gosub: { /* jump */ + assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); + pIn1 = &aMem[pOp->p1]; + assert( VdbeMemDynamic(pIn1)==0 ); + memAboutToChange(p, pIn1); + pIn1->flags = MEM_Int; + pIn1->u.i = (int)(pOp-aOp); + REGISTER_TRACE(pOp->p1, pIn1); + + /* Most jump operations do a goto to this spot in order to update + ** the pOp pointer. */ +jump_to_p2: + pOp = &aOp[pOp->p2 - 1]; + break; +} + +/* Opcode: Return P1 * * * * +** +** Jump to the next instruction after the address in register P1. After +** the jump, register P1 becomes undefined. +*/ +case OP_Return: { /* in1 */ + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags==MEM_Int ); + pOp = &aOp[pIn1->u.i]; + pIn1->flags = MEM_Undefined; + break; +} + +/* Opcode: InitCoroutine P1 P2 P3 * * +** +** Set up register P1 so that it will Yield to the coroutine +** located at address P3. +** +** If P2!=0 then the coroutine implementation immediately follows +** this opcode. So jump over the coroutine implementation to +** address P2. +** +** See also: EndCoroutine +*/ +case OP_InitCoroutine: { /* jump */ + assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); + assert( pOp->p2>=0 && pOp->p2nOp ); + assert( pOp->p3>=0 && pOp->p3nOp ); + pOut = &aMem[pOp->p1]; + assert( !VdbeMemDynamic(pOut) ); + pOut->u.i = pOp->p3 - 1; + pOut->flags = MEM_Int; + if( pOp->p2 ) goto jump_to_p2; + break; +} + +/* Opcode: EndCoroutine P1 * * * * +** +** The instruction at the address in register P1 is a Yield. +** Jump to the P2 parameter of that Yield. +** After the jump, register P1 becomes undefined. +** +** See also: InitCoroutine +*/ +case OP_EndCoroutine: { /* in1 */ + VdbeOp *pCaller; + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags==MEM_Int ); + assert( pIn1->u.i>=0 && pIn1->u.inOp ); + pCaller = &aOp[pIn1->u.i]; + assert( pCaller->opcode==OP_Yield ); + assert( pCaller->p2>=0 && pCaller->p2nOp ); + pOp = &aOp[pCaller->p2 - 1]; + pIn1->flags = MEM_Undefined; + break; +} + +/* Opcode: Yield P1 P2 * * * +** +** Swap the program counter with the value in register P1. This +** has the effect of yielding to a coroutine. +** +** If the coroutine that is launched by this instruction ends with +** Yield or Return then continue to the next instruction. But if +** the coroutine launched by this instruction ends with +** EndCoroutine, then jump to P2 rather than continuing with the +** next instruction. +** +** See also: InitCoroutine +*/ +case OP_Yield: { /* in1, jump */ + int pcDest; + pIn1 = &aMem[pOp->p1]; + assert( VdbeMemDynamic(pIn1)==0 ); + pIn1->flags = MEM_Int; + pcDest = (int)pIn1->u.i; + pIn1->u.i = (int)(pOp - aOp); + REGISTER_TRACE(pOp->p1, pIn1); + pOp = &aOp[pcDest]; + break; +} + +/* Opcode: HaltIfNull P1 P2 P3 P4 P5 +** Synopsis: if r[P3]=null halt +** +** Check the value in register P3. If it is NULL then Halt using +** parameter P1, P2, and P4 as if this were a Halt instruction. If the +** value in register P3 is not NULL, then this routine is a no-op. +** The P5 parameter should be 1. +*/ +case OP_HaltIfNull: { /* in3 */ + pIn3 = &aMem[pOp->p3]; + if( (pIn3->flags & MEM_Null)==0 ) break; + /* Fall through into OP_Halt */ +} + +/* Opcode: Halt P1 P2 * P4 P5 +** +** Exit immediately. All open cursors, 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 P4 is not null then it is an error message string. +** +** P5 is a value between 0 and 4, inclusive, that modifies the P4 string. +** +** 0: (no change) +** 1: NOT NULL contraint failed: P4 +** 2: UNIQUE constraint failed: P4 +** 3: CHECK constraint failed: P4 +** 4: FOREIGN KEY constraint failed: P4 +** +** If P5 is not zero and P4 is NULL, then everything after the ":" is +** omitted. +** +** 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: { + const char *zType; + const char *zLogFmt; + VdbeFrame *pFrame; + int pcx; + + pcx = (int)(pOp - aOp); + if( pOp->p1==SQLITE_OK && p->pFrame ){ + /* Halt the sub-program. Return control to the parent frame. */ + pFrame = p->pFrame; + p->pFrame = pFrame->pParent; + p->nFrame--; + sqlite3VdbeSetChanges(db, p->nChange); + pcx = sqlite3VdbeFrameRestore(pFrame); + lastRowid = db->lastRowid; + if( pOp->p2==OE_Ignore ){ + /* Instruction pcx is the OP_Program that invoked the sub-program + ** currently being halted. If the p2 instruction of this OP_Halt + ** instruction is set to OE_Ignore, then the sub-program is throwing + ** an IGNORE exception. In this case jump to the address specified + ** as the p2 of the calling OP_Program. */ + pcx = p->aOp[pcx].p2-1; + } + aOp = p->aOp; + aMem = p->aMem; + pOp = &aOp[pcx]; + break; + } + p->rc = pOp->p1; + p->errorAction = (u8)pOp->p2; + p->pc = pcx; + if( p->rc ){ + if( pOp->p5 ){ + static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK", + "FOREIGN KEY" }; + assert( pOp->p5>=1 && pOp->p5<=4 ); + testcase( pOp->p5==1 ); + testcase( pOp->p5==2 ); + testcase( pOp->p5==3 ); + testcase( pOp->p5==4 ); + zType = azType[pOp->p5-1]; + }else{ + zType = 0; + } + assert( zType!=0 || pOp->p4.z!=0 ); + zLogFmt = "abort at %d in [%s]: %s"; + if( zType && pOp->p4.z ){ + sqlite3SetString(&p->zErrMsg, db, "%s constraint failed: %s", + zType, pOp->p4.z); + }else if( pOp->p4.z ){ + sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z); + }else{ + sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", zType); + } + sqlite3_log(pOp->p1, zLogFmt, pcx, p->zSql, p->zErrMsg); + } + rc = sqlite3VdbeHalt(p); + assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR ); + if( rc==SQLITE_BUSY ){ + p->rc = rc = SQLITE_BUSY; + }else{ + assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ); + assert( rc==SQLITE_OK || db->nDeferredCons>0 || db->nDeferredImmCons>0 ); + rc = p->rc ? SQLITE_ERROR : SQLITE_DONE; + } + goto vdbe_return; +} + +/* Opcode: Integer P1 P2 * * * +** Synopsis: r[P2]=P1 +** +** The 32-bit integer value P1 is written into register P2. +*/ +case OP_Integer: { /* out2 */ + pOut = out2Prerelease(p, pOp); + pOut->u.i = pOp->p1; + break; +} + +/* Opcode: Int64 * P2 * P4 * +** Synopsis: r[P2]=P4 +** +** P4 is a pointer to a 64-bit integer value. +** Write that value into register P2. +*/ +case OP_Int64: { /* out2 */ + pOut = out2Prerelease(p, pOp); + assert( pOp->p4.pI64!=0 ); + pOut->u.i = *pOp->p4.pI64; + break; +} + +#ifndef SQLITE_OMIT_FLOATING_POINT +/* Opcode: Real * P2 * P4 * +** Synopsis: r[P2]=P4 +** +** P4 is a pointer to a 64-bit floating point value. +** Write that value into register P2. +*/ +case OP_Real: { /* same as TK_FLOAT, out2 */ + pOut = out2Prerelease(p, pOp); + pOut->flags = MEM_Real; + assert( !sqlite3IsNaN(*pOp->p4.pReal) ); + pOut->u.r = *pOp->p4.pReal; + break; +} +#endif + +/* Opcode: String8 * P2 * P4 * +** Synopsis: r[P2]='P4' +** +** P4 points to a nul terminated UTF-8 string. This opcode is transformed +** into a String opcode before it is executed for the first time. During +** this transformation, the length of string P4 is computed and stored +** as the P1 parameter. +*/ +case OP_String8: { /* same as TK_STRING, out2 */ + assert( pOp->p4.z!=0 ); + pOut = out2Prerelease(p, pOp); + pOp->opcode = OP_String; + pOp->p1 = sqlite3Strlen30(pOp->p4.z); + +#ifndef SQLITE_OMIT_UTF16 + if( encoding!=SQLITE_UTF8 ){ + rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); + if( rc==SQLITE_TOOBIG ) goto too_big; + if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem; + assert( pOut->szMalloc>0 && pOut->zMalloc==pOut->z ); + assert( VdbeMemDynamic(pOut)==0 ); + pOut->szMalloc = 0; + pOut->flags |= MEM_Static; + if( pOp->p4type==P4_DYNAMIC ){ + sqlite3DbFree(db, pOp->p4.z); + } + pOp->p4type = P4_DYNAMIC; + pOp->p4.z = pOut->z; + pOp->p1 = pOut->n; + } +#endif + if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + goto too_big; + } + /* Fall through to the next case, OP_String */ +} + +/* Opcode: String P1 P2 P3 P4 P5 +** Synopsis: r[P2]='P4' (len=P1) +** +** The string value P4 of length P1 (bytes) is stored in register P2. +** +** If P5!=0 and the content of register P3 is greater than zero, then +** the datatype of the register P2 is converted to BLOB. The content is +** the same sequence of bytes, it is merely interpreted as a BLOB instead +** of a string, as if it had been CAST. +*/ +case OP_String: { /* out2 */ + assert( pOp->p4.z!=0 ); + pOut = out2Prerelease(p, pOp); + pOut->flags = MEM_Str|MEM_Static|MEM_Term; + pOut->z = pOp->p4.z; + pOut->n = pOp->p1; + pOut->enc = encoding; + UPDATE_MAX_BLOBSIZE(pOut); + if( pOp->p5 ){ + assert( pOp->p3>0 ); + assert( pOp->p3<=(p->nMem-p->nCursor) ); + pIn3 = &aMem[pOp->p3]; + assert( pIn3->flags & MEM_Int ); + if( pIn3->u.i ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term; + } + break; +} + +/* Opcode: Null P1 P2 P3 * * +** Synopsis: r[P2..P3]=NULL +** +** Write a NULL into registers P2. If P3 greater than P2, then also write +** NULL into register P3 and every register in between P2 and P3. If P3 +** is less than P2 (typically P3 is zero) then only register P2 is +** set to NULL. +** +** If the P1 value is non-zero, then also set the MEM_Cleared flag so that +** NULL values will not compare equal even if SQLITE_NULLEQ is set on +** OP_Ne or OP_Eq. +*/ +case OP_Null: { /* out2 */ + int cnt; + u16 nullFlag; + pOut = out2Prerelease(p, pOp); + cnt = pOp->p3-pOp->p2; + assert( pOp->p3<=(p->nMem-p->nCursor) ); + pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; + while( cnt>0 ){ + pOut++; + memAboutToChange(p, pOut); + sqlite3VdbeMemSetNull(pOut); + pOut->flags = nullFlag; + cnt--; + } + break; +} + +/* Opcode: SoftNull P1 * * * * +** Synopsis: r[P1]=NULL +** +** Set register P1 to have the value NULL as seen by the OP_MakeRecord +** instruction, but do not free any string or blob memory associated with +** the register, so that if the value was a string or blob that was +** previously copied using OP_SCopy, the copies will continue to be valid. +*/ +case OP_SoftNull: { + assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); + pOut = &aMem[pOp->p1]; + pOut->flags = (pOut->flags|MEM_Null)&~MEM_Undefined; + break; +} + +/* Opcode: Blob P1 P2 * P4 * +** Synopsis: r[P2]=P4 (len=P1) +** +** P4 points to a blob of data P1 bytes long. Store this +** blob in register P2. +*/ +case OP_Blob: { /* out2 */ + assert( pOp->p1 <= SQLITE_MAX_LENGTH ); + pOut = out2Prerelease(p, pOp); + sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0); + pOut->enc = encoding; + UPDATE_MAX_BLOBSIZE(pOut); + break; +} + +/* Opcode: Variable P1 P2 * P4 * +** Synopsis: r[P2]=parameter(P1,P4) +** +** Transfer the values of bound parameter P1 into register P2 +** +** If the parameter is named, then its name appears in P4. +** The P4 value is used by sqlite3_bind_parameter_name(). +*/ +case OP_Variable: { /* out2 */ + Mem *pVar; /* Value being transferred */ + + assert( pOp->p1>0 && pOp->p1<=p->nVar ); + assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] ); + pVar = &p->aVar[pOp->p1 - 1]; + if( sqlite3VdbeMemTooBig(pVar) ){ + goto too_big; + } + pOut = out2Prerelease(p, pOp); + sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static); + UPDATE_MAX_BLOBSIZE(pOut); + break; +} + +/* Opcode: Move P1 P2 P3 * * +** Synopsis: r[P2@P3]=r[P1@P3] +** +** Move the P3 values in register P1..P1+P3-1 over into +** registers P2..P2+P3-1. Registers P1..P1+P3-1 are +** left holding a NULL. It is an error for register ranges +** P1..P1+P3-1 and P2..P2+P3-1 to overlap. It is an error +** for P3 to be less than 1. +*/ +case OP_Move: { + int n; /* Number of registers left to copy */ + int p1; /* Register to copy from */ + int p2; /* Register to copy to */ + + n = pOp->p3; + p1 = pOp->p1; + p2 = pOp->p2; + assert( n>0 && p1>0 && p2>0 ); + assert( p1+n<=p2 || p2+n<=p1 ); + + pIn1 = &aMem[p1]; + pOut = &aMem[p2]; + do{ + assert( pOut<=&aMem[(p->nMem-p->nCursor)] ); + assert( pIn1<=&aMem[(p->nMem-p->nCursor)] ); + assert( memIsValid(pIn1) ); + memAboutToChange(p, pOut); + sqlite3VdbeMemMove(pOut, pIn1); +#ifdef SQLITE_DEBUG + if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrompScopyFrom += pOp->p2 - p1; + } +#endif + Deephemeralize(pOut); + REGISTER_TRACE(p2++, pOut); + pIn1++; + pOut++; + }while( --n ); + break; +} + +/* Opcode: Copy P1 P2 P3 * * +** Synopsis: r[P2@P3+1]=r[P1@P3+1] +** +** Make a copy of registers P1..P1+P3 into registers P2..P2+P3. +** +** This instruction makes a deep copy of the value. A duplicate +** is made of any string or blob constant. See also OP_SCopy. +*/ +case OP_Copy: { + int n; + + n = pOp->p3; + pIn1 = &aMem[pOp->p1]; + pOut = &aMem[pOp->p2]; + assert( pOut!=pIn1 ); + while( 1 ){ + sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); + Deephemeralize(pOut); +#ifdef SQLITE_DEBUG + pOut->pScopyFrom = 0; +#endif + REGISTER_TRACE(pOp->p2+pOp->p3-n, pOut); + if( (n--)==0 ) break; + pOut++; + pIn1++; + } + break; +} + +/* Opcode: SCopy P1 P2 * * * +** Synopsis: r[P2]=r[P1] +** +** Make a shallow copy of register P1 into register P2. +** +** This instruction makes a shallow copy of the value. If the value +** is a string or blob, then the copy is only a pointer to the +** original and hence if the original changes so will the copy. +** Worse, if the original is deallocated, the copy becomes invalid. +** Thus the program must guarantee that the original will not change +** during the lifetime of the copy. Use OP_Copy to make a complete +** copy. +*/ +case OP_SCopy: { /* out2 */ + pIn1 = &aMem[pOp->p1]; + pOut = &aMem[pOp->p2]; + assert( pOut!=pIn1 ); + sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); +#ifdef SQLITE_DEBUG + if( pOut->pScopyFrom==0 ) pOut->pScopyFrom = pIn1; +#endif + break; +} + +/* Opcode: ResultRow P1 P2 * * * +** Synopsis: output=r[P1@P2] +** +** The registers P1 through P1+P2-1 contain a single row of +** results. 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 r(P1)..r(P1+P2-1) values as +** the result row. +*/ +case OP_ResultRow: { + Mem *pMem; + int i; + assert( p->nResColumn==pOp->p2 ); + assert( pOp->p1>0 ); + assert( pOp->p1+pOp->p2<=(p->nMem-p->nCursor)+1 ); + +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + /* Run the progress counter just before returning. + */ + if( db->xProgress!=0 + && nVmStep>=nProgressLimit + && db->xProgress(db->pProgressArg)!=0 + ){ + rc = SQLITE_INTERRUPT; + goto vdbe_error_halt; + } +#endif + + /* If this statement has violated immediate foreign key constraints, do + ** not return the number of rows modified. And do not RELEASE the statement + ** transaction. It needs to be rolled back. */ + if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){ + assert( db->flags&SQLITE_CountRows ); + assert( p->usesStmtJournal ); + break; + } + + /* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then + ** DML statements invoke this opcode to return the number of rows + ** modified to the user. This is the only way that a VM that + ** opens a statement transaction may invoke this opcode. + ** + ** In case this is such a statement, close any statement transaction + ** opened by this VM before returning control to the user. This is to + ** ensure that statement-transactions are always nested, not overlapping. + ** If the open statement-transaction is not closed here, then the user + ** may step another VM that opens its own statement transaction. This + ** may lead to overlapping statement transactions. + ** + ** The statement transaction is never a top-level transaction. Hence + ** the RELEASE call below can never fail. + */ + assert( p->iStatement==0 || db->flags&SQLITE_CountRows ); + rc = sqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE); + if( NEVER(rc!=SQLITE_OK) ){ + break; + } + + /* 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 de-ephemeralized as + ** a side effect. + */ + pMem = p->pResultSet = &aMem[pOp->p1]; + for(i=0; ip2; i++){ + assert( memIsValid(&pMem[i]) ); + Deephemeralize(&pMem[i]); + assert( (pMem[i].flags & MEM_Ephem)==0 + || (pMem[i].flags & (MEM_Str|MEM_Blob))==0 ); + sqlite3VdbeMemNulTerminate(&pMem[i]); + REGISTER_TRACE(pOp->p1+i, &pMem[i]); + } + if( db->mallocFailed ) goto no_mem; + + /* Return SQLITE_ROW + */ + p->pc = (int)(pOp - aOp) + 1; + rc = SQLITE_ROW; + goto vdbe_return; +} + +/* Opcode: Concat P1 P2 P3 * * +** Synopsis: r[P3]=r[P2]+r[P1] +** +** Add the text in register P1 onto the end of the text in +** register P2 and store the result in register P3. +** If either the P1 or P2 text are NULL then store NULL in P3. +** +** P3 = P2 || P1 +** +** It is illegal for P1 and P3 to be the same register. Sometimes, +** if P3 is the same register as P2, the implementation is able +** to avoid a memcpy(). +*/ +case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ + i64 nByte; + + pIn1 = &aMem[pOp->p1]; + pIn2 = &aMem[pOp->p2]; + pOut = &aMem[pOp->p3]; + assert( pIn1!=pOut ); + if( (pIn1->flags | pIn2->flags) & MEM_Null ){ + sqlite3VdbeMemSetNull(pOut); + break; + } + if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem; + Stringify(pIn1, encoding); + Stringify(pIn2, encoding); + nByte = pIn1->n + pIn2->n; + if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + goto too_big; + } + if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){ + goto no_mem; + } + MemSetTypeFlag(pOut, MEM_Str); + if( pOut!=pIn2 ){ + memcpy(pOut->z, pIn2->z, pIn2->n); + } + memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n); + pOut->z[nByte]=0; + pOut->z[nByte+1] = 0; + pOut->flags |= MEM_Term; + pOut->n = (int)nByte; + pOut->enc = encoding; + UPDATE_MAX_BLOBSIZE(pOut); + break; +} + +/* Opcode: Add P1 P2 P3 * * +** Synopsis: r[P3]=r[P1]+r[P2] +** +** Add the value in register P1 to the value in register P2 +** and store the result in register P3. +** If either input is NULL, the result is NULL. +*/ +/* Opcode: Multiply P1 P2 P3 * * +** Synopsis: r[P3]=r[P1]*r[P2] +** +** +** Multiply the value in register P1 by the value in register P2 +** and store the result in register P3. +** If either input is NULL, the result is NULL. +*/ +/* Opcode: Subtract P1 P2 P3 * * +** Synopsis: r[P3]=r[P2]-r[P1] +** +** Subtract the value in register P1 from the value in register P2 +** and store the result in register P3. +** If either input is NULL, the result is NULL. +*/ +/* Opcode: Divide P1 P2 P3 * * +** Synopsis: r[P3]=r[P2]/r[P1] +** +** Divide the value in register P1 by the value in register P2 +** and store the result in register P3 (P3=P2/P1). If the value in +** register P1 is zero, then the result is NULL. If either input is +** NULL, the result is NULL. +*/ +/* Opcode: Remainder P1 P2 P3 * * +** Synopsis: r[P3]=r[P2]%r[P1] +** +** Compute the remainder after integer register P2 is divided by +** register P1 and store the result in register P3. +** If the value in register P1 is zero the result is NULL. +** If either operand is NULL, the result is NULL. +*/ +case OP_Add: /* same as TK_PLUS, in1, in2, out3 */ +case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */ +case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */ +case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */ +case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ + char bIntint; /* Started out as two integer operands */ + u16 flags; /* Combined MEM_* flags from both inputs */ + u16 type1; /* Numeric type of left operand */ + u16 type2; /* Numeric type of right operand */ + i64 iA; /* Integer value of left operand */ + i64 iB; /* Integer value of right operand */ + double rA; /* Real value of left operand */ + double rB; /* Real value of right operand */ + + pIn1 = &aMem[pOp->p1]; + type1 = numericType(pIn1); + pIn2 = &aMem[pOp->p2]; + type2 = numericType(pIn2); + pOut = &aMem[pOp->p3]; + flags = pIn1->flags | pIn2->flags; + if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null; + if( (type1 & type2 & MEM_Int)!=0 ){ + iA = pIn1->u.i; + iB = pIn2->u.i; + bIntint = 1; + switch( pOp->opcode ){ + case OP_Add: if( sqlite3AddInt64(&iB,iA) ) goto fp_math; break; + case OP_Subtract: if( sqlite3SubInt64(&iB,iA) ) goto fp_math; break; + case OP_Multiply: if( sqlite3MulInt64(&iB,iA) ) goto fp_math; break; + case OP_Divide: { + if( iA==0 ) goto arithmetic_result_is_null; + if( iA==-1 && iB==SMALLEST_INT64 ) goto fp_math; + iB /= iA; + break; + } + default: { + if( iA==0 ) goto arithmetic_result_is_null; + if( iA==-1 ) iA = 1; + iB %= iA; + break; + } + } + pOut->u.i = iB; + MemSetTypeFlag(pOut, MEM_Int); + }else{ + bIntint = 0; +fp_math: + rA = sqlite3VdbeRealValue(pIn1); + rB = sqlite3VdbeRealValue(pIn2); + switch( pOp->opcode ){ + case OP_Add: rB += rA; break; + case OP_Subtract: rB -= rA; break; + case OP_Multiply: rB *= rA; break; + case OP_Divide: { + /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ + if( rA==(double)0 ) goto arithmetic_result_is_null; + rB /= rA; + break; + } + default: { + iA = (i64)rA; + iB = (i64)rB; + if( iA==0 ) goto arithmetic_result_is_null; + if( iA==-1 ) iA = 1; + rB = (double)(iB % iA); + break; + } + } +#ifdef SQLITE_OMIT_FLOATING_POINT + pOut->u.i = rB; + MemSetTypeFlag(pOut, MEM_Int); +#else + if( sqlite3IsNaN(rB) ){ + goto arithmetic_result_is_null; + } + pOut->u.r = rB; + MemSetTypeFlag(pOut, MEM_Real); + if( ((type1|type2)&MEM_Real)==0 && !bIntint ){ + sqlite3VdbeIntegerAffinity(pOut); + } +#endif + } + break; + +arithmetic_result_is_null: + sqlite3VdbeMemSetNull(pOut); + break; +} + +/* Opcode: CollSeq P1 * * P4 +** +** P4 is a pointer to a CollSeq struct. If the next call to a user function +** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will +** be returned. This is used by the built-in min(), max() and nullif() +** functions. +** +** If P1 is not zero, then it is a register that a subsequent min() or +** max() aggregate will set to 1 if the current row is not the minimum or +** maximum. The P1 register is initialized to 0 by this instruction. +** +** The interface used by the implementation of the aforementioned functions +** to retrieve the collation sequence set by this opcode is not available +** publicly. Only built-in functions have access to this feature. +*/ +case OP_CollSeq: { + assert( pOp->p4type==P4_COLLSEQ ); + if( pOp->p1 ){ + sqlite3VdbeMemSetInt64(&aMem[pOp->p1], 0); + } + break; +} + +/* Opcode: Function P1 P2 P3 P4 P5 +** Synopsis: r[P3]=func(r[P2@P5]) +** +** Invoke a user function (P4 is a pointer to a Function structure that +** defines the function) with P5 arguments taken from register P2 and +** successors. The result of the function is stored in register P3. +** Register P3 must not be one of the function inputs. +** +** 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; + + n = pOp->p5; + apVal = p->apArg; + assert( apVal || n==0 ); + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); + ctx.pOut = &aMem[pOp->p3]; + memAboutToChange(p, ctx.pOut); + + assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) ); + assert( pOp->p3p2 || pOp->p3>=pOp->p2+n ); + pArg = &aMem[pOp->p2]; + for(i=0; ip2+i, pArg); + } + + assert( pOp->p4type==P4_FUNCDEF ); + ctx.pFunc = pOp->p4.pFunc; + ctx.iOp = (int)(pOp - aOp); + ctx.pVdbe = p; + MemSetTypeFlag(ctx.pOut, MEM_Null); + ctx.fErrorOrAux = 0; + db->lastRowid = lastRowid; + (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */ + lastRowid = db->lastRowid; /* Remember rowid changes made by xFunc */ + + /* If the function returned an error, throw an exception */ + if( ctx.fErrorOrAux ){ + if( ctx.isError ){ + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut)); + rc = ctx.isError; + } + sqlite3VdbeDeleteAuxData(p, (int)(pOp - aOp), pOp->p1); + } + + /* Copy the result of the function into register P3 */ + sqlite3VdbeChangeEncoding(ctx.pOut, encoding); + if( sqlite3VdbeMemTooBig(ctx.pOut) ){ + goto too_big; + } + + REGISTER_TRACE(pOp->p3, ctx.pOut); + UPDATE_MAX_BLOBSIZE(ctx.pOut); + break; +} + +/* Opcode: BitAnd P1 P2 P3 * * +** Synopsis: r[P3]=r[P1]&r[P2] +** +** Take the bit-wise AND of the values in register P1 and P2 and +** store the result in register P3. +** If either input is NULL, the result is NULL. +*/ +/* Opcode: BitOr P1 P2 P3 * * +** Synopsis: r[P3]=r[P1]|r[P2] +** +** Take the bit-wise OR of the values in register P1 and P2 and +** store the result in register P3. +** If either input is NULL, the result is NULL. +*/ +/* Opcode: ShiftLeft P1 P2 P3 * * +** Synopsis: r[P3]=r[P2]<>r[P1] +** +** Shift the integer value in register P2 to the right by the +** number of bits specified by the integer in register P1. +** Store the result in register P3. +** If either input is NULL, the result is NULL. +*/ +case OP_BitAnd: /* same as TK_BITAND, in1, in2, out3 */ +case OP_BitOr: /* same as TK_BITOR, in1, in2, out3 */ +case OP_ShiftLeft: /* same as TK_LSHIFT, in1, in2, out3 */ +case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */ + i64 iA; + u64 uA; + i64 iB; + u8 op; + + pIn1 = &aMem[pOp->p1]; + pIn2 = &aMem[pOp->p2]; + pOut = &aMem[pOp->p3]; + if( (pIn1->flags | pIn2->flags) & MEM_Null ){ + sqlite3VdbeMemSetNull(pOut); + break; + } + iA = sqlite3VdbeIntValue(pIn2); + iB = sqlite3VdbeIntValue(pIn1); + op = pOp->opcode; + if( op==OP_BitAnd ){ + iA &= iB; + }else if( op==OP_BitOr ){ + iA |= iB; + }else if( iB!=0 ){ + assert( op==OP_ShiftRight || op==OP_ShiftLeft ); + + /* If shifting by a negative amount, shift in the other direction */ + if( iB<0 ){ + assert( OP_ShiftRight==OP_ShiftLeft+1 ); + op = 2*OP_ShiftLeft + 1 - op; + iB = iB>(-64) ? -iB : 64; + } + + if( iB>=64 ){ + iA = (iA>=0 || op==OP_ShiftLeft) ? 0 : -1; + }else{ + memcpy(&uA, &iA, sizeof(uA)); + if( op==OP_ShiftLeft ){ + uA <<= iB; + }else{ + uA >>= iB; + /* Sign-extend on a right shift of a negative number */ + if( iA<0 ) uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-iB); + } + memcpy(&iA, &uA, sizeof(iA)); + } + } + pOut->u.i = iA; + MemSetTypeFlag(pOut, MEM_Int); + break; +} + +/* Opcode: AddImm P1 P2 * * * +** Synopsis: r[P1]=r[P1]+P2 +** +** Add the constant P2 to the value in register P1. +** The result is always an integer. +** +** To force any register to be an integer, just add 0. +*/ +case OP_AddImm: { /* in1 */ + pIn1 = &aMem[pOp->p1]; + memAboutToChange(p, pIn1); + sqlite3VdbeMemIntegerify(pIn1); + pIn1->u.i += pOp->p2; + break; +} + +/* Opcode: MustBeInt P1 P2 * * * +** +** Force the value in register P1 to be an integer. If the value +** in P1 is not an integer and cannot be converted into an integer +** without data loss, then jump immediately to P2, or if P2==0 +** raise an SQLITE_MISMATCH exception. +*/ +case OP_MustBeInt: { /* jump, in1 */ + pIn1 = &aMem[pOp->p1]; + if( (pIn1->flags & MEM_Int)==0 ){ + applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding); + VdbeBranchTaken((pIn1->flags&MEM_Int)==0, 2); + if( (pIn1->flags & MEM_Int)==0 ){ + if( pOp->p2==0 ){ + rc = SQLITE_MISMATCH; + goto abort_due_to_error; + }else{ + goto jump_to_p2; + } + } + } + MemSetTypeFlag(pIn1, MEM_Int); + break; +} + +#ifndef SQLITE_OMIT_FLOATING_POINT +/* Opcode: RealAffinity P1 * * * * +** +** If register P1 holds 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: { /* in1 */ + pIn1 = &aMem[pOp->p1]; + if( pIn1->flags & MEM_Int ){ + sqlite3VdbeMemRealify(pIn1); + } + break; +} +#endif + +#ifndef SQLITE_OMIT_CAST +/* Opcode: Cast P1 P2 * * * +** Synopsis: affinity(r[P1]) +** +** Force the value in register P1 to be the type defined by P2. +** +**
      +**
    • TEXT +**
    • BLOB +**
    • NUMERIC +**
    • INTEGER +**
    • REAL +**
    +** +** A NULL value is not changed by this routine. It remains NULL. +*/ +case OP_Cast: { /* in1 */ + assert( pOp->p2>=SQLITE_AFF_NONE && pOp->p2<=SQLITE_AFF_REAL ); + testcase( pOp->p2==SQLITE_AFF_TEXT ); + testcase( pOp->p2==SQLITE_AFF_NONE ); + testcase( pOp->p2==SQLITE_AFF_NUMERIC ); + testcase( pOp->p2==SQLITE_AFF_INTEGER ); + testcase( pOp->p2==SQLITE_AFF_REAL ); + pIn1 = &aMem[pOp->p1]; + memAboutToChange(p, pIn1); + rc = ExpandBlob(pIn1); + sqlite3VdbeMemCast(pIn1, pOp->p2, encoding); + UPDATE_MAX_BLOBSIZE(pIn1); + break; +} +#endif /* SQLITE_OMIT_CAST */ + +/* Opcode: Lt P1 P2 P3 P4 P5 +** Synopsis: if r[P1]r[P3] goto P2 +** +** This works just like the Lt opcode except that the jump is taken if +** the content of register P3 is greater than the content of +** register P1. See the Lt opcode for additional information. +*/ +/* Opcode: Ge P1 P2 P3 P4 P5 +** Synopsis: if r[P1]>=r[P3] goto P2 +** +** This works just like the Lt opcode except that the jump is taken if +** the content of register P3 is greater than or equal to the content of +** register P1. See the Lt opcode for additional information. +*/ +case OP_Eq: /* same as TK_EQ, jump, in1, in3 */ +case OP_Ne: /* same as TK_NE, jump, in1, in3 */ +case OP_Lt: /* same as TK_LT, jump, in1, in3 */ +case OP_Le: /* same as TK_LE, jump, in1, in3 */ +case OP_Gt: /* same as TK_GT, jump, in1, in3 */ +case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ + int res; /* Result of the comparison of pIn1 against pIn3 */ + char affinity; /* Affinity to use for comparison */ + u16 flags1; /* Copy of initial value of pIn1->flags */ + u16 flags3; /* Copy of initial value of pIn3->flags */ + + pIn1 = &aMem[pOp->p1]; + pIn3 = &aMem[pOp->p3]; + flags1 = pIn1->flags; + flags3 = pIn3->flags; + if( (flags1 | flags3)&MEM_Null ){ + /* One or both operands are NULL */ + if( pOp->p5 & SQLITE_NULLEQ ){ + /* If SQLITE_NULLEQ is set (which will only happen if the operator is + ** OP_Eq or OP_Ne) then take the jump or not depending on whether + ** or not both operands are null. + */ + assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne ); + assert( (flags1 & MEM_Cleared)==0 ); + assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 ); + if( (flags1&MEM_Null)!=0 + && (flags3&MEM_Null)!=0 + && (flags3&MEM_Cleared)==0 + ){ + res = 0; /* Results are equal */ + }else{ + res = 1; /* Results are not equal */ + } + }else{ + /* SQLITE_NULLEQ is clear and at least one operand is NULL, + ** then the result is always NULL. + ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. + */ + if( pOp->p5 & SQLITE_STOREP2 ){ + pOut = &aMem[pOp->p2]; + MemSetTypeFlag(pOut, MEM_Null); + REGISTER_TRACE(pOp->p2, pOut); + }else{ + VdbeBranchTaken(2,3); + if( pOp->p5 & SQLITE_JUMPIFNULL ){ + goto jump_to_p2; + } + } + break; + } + }else{ + /* Neither operand is NULL. Do a comparison. */ + affinity = pOp->p5 & SQLITE_AFF_MASK; + if( affinity>=SQLITE_AFF_NUMERIC ){ + if( (pIn1->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ + applyNumericAffinity(pIn1,0); + } + if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ + applyNumericAffinity(pIn3,0); + } + }else if( affinity==SQLITE_AFF_TEXT ){ + if( (pIn1->flags & MEM_Str)==0 && (pIn1->flags & (MEM_Int|MEM_Real))!=0 ){ + testcase( pIn1->flags & MEM_Int ); + testcase( pIn1->flags & MEM_Real ); + sqlite3VdbeMemStringify(pIn1, encoding, 1); + testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) ); + flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); + } + if( (pIn3->flags & MEM_Str)==0 && (pIn3->flags & (MEM_Int|MEM_Real))!=0 ){ + testcase( pIn3->flags & MEM_Int ); + testcase( pIn3->flags & MEM_Real ); + sqlite3VdbeMemStringify(pIn3, encoding, 1); + testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn) ); + flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask); + } + } + assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 ); + if( pIn1->flags & MEM_Zero ){ + sqlite3VdbeMemExpandBlob(pIn1); + flags1 &= ~MEM_Zero; + } + if( pIn3->flags & MEM_Zero ){ + sqlite3VdbeMemExpandBlob(pIn3); + flags3 &= ~MEM_Zero; + } + if( db->mallocFailed ) goto no_mem; + res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); + } + switch( pOp->opcode ){ + case OP_Eq: res = res==0; break; + case OP_Ne: res = res!=0; break; + case OP_Lt: res = res<0; break; + case OP_Le: res = res<=0; break; + case OP_Gt: res = res>0; break; + default: res = res>=0; break; + } + + /* Undo any changes made by applyAffinity() to the input registers. */ + assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) ); + pIn1->flags = flags1; + assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) ); + pIn3->flags = flags3; + + if( pOp->p5 & SQLITE_STOREP2 ){ + pOut = &aMem[pOp->p2]; + memAboutToChange(p, pOut); + MemSetTypeFlag(pOut, MEM_Int); + pOut->u.i = res; + REGISTER_TRACE(pOp->p2, pOut); + }else{ + VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3); + if( res ){ + goto jump_to_p2; + } + } + break; +} + +/* Opcode: Permutation * * * P4 * +** +** Set the permutation used by the OP_Compare operator to be the array +** of integers in P4. +** +** The permutation is only valid until the next OP_Compare that has +** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should +** occur immediately prior to the OP_Compare. +*/ +case OP_Permutation: { + assert( pOp->p4type==P4_INTARRAY ); + assert( pOp->p4.ai ); + aPermute = pOp->p4.ai; + break; +} + +/* Opcode: Compare P1 P2 P3 P4 P5 +** Synopsis: r[P1@P3] <-> r[P2@P3] +** +** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this +** vector "A") and in reg(P2)..reg(P2+P3-1) ("B"). Save the result of +** the comparison for use by the next OP_Jump instruct. +** +** If P5 has the OPFLAG_PERMUTE bit set, then the order of comparison is +** determined by the most recent OP_Permutation operator. If the +** OPFLAG_PERMUTE bit is clear, then register are compared in sequential +** order. +** +** P4 is a KeyInfo structure that defines collating sequences and sort +** orders for the comparison. The permutation applies to registers +** only. The KeyInfo elements are used sequentially. +** +** The comparison is a sort comparison, so NULLs compare equal, +** NULLs are less than numbers, numbers are less than strings, +** and strings are less than blobs. +*/ +case OP_Compare: { + int n; + int i; + int p1; + int p2; + const KeyInfo *pKeyInfo; + int idx; + CollSeq *pColl; /* Collating sequence to use on this term */ + int bRev; /* True for DESCENDING sort order */ + + if( (pOp->p5 & OPFLAG_PERMUTE)==0 ) aPermute = 0; + n = pOp->p3; + pKeyInfo = pOp->p4.pKeyInfo; + assert( n>0 ); + assert( pKeyInfo!=0 ); + p1 = pOp->p1; + p2 = pOp->p2; +#if SQLITE_DEBUG + if( aPermute ){ + int k, mx = 0; + for(k=0; kmx ) mx = aPermute[k]; + assert( p1>0 && p1+mx<=(p->nMem-p->nCursor)+1 ); + assert( p2>0 && p2+mx<=(p->nMem-p->nCursor)+1 ); + }else{ + assert( p1>0 && p1+n<=(p->nMem-p->nCursor)+1 ); + assert( p2>0 && p2+n<=(p->nMem-p->nCursor)+1 ); + } +#endif /* SQLITE_DEBUG */ + for(i=0; inField ); + pColl = pKeyInfo->aColl[i]; + bRev = pKeyInfo->aSortOrder[i]; + iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl); + if( iCompare ){ + if( bRev ) iCompare = -iCompare; + break; + } + } + aPermute = 0; + break; +} + +/* Opcode: Jump P1 P2 P3 * * +** +** Jump to the instruction at address P1, P2, or P3 depending on whether +** in the most recent OP_Compare instruction the P1 vector was less than +** equal to, or greater than the P2 vector, respectively. +*/ +case OP_Jump: { /* jump */ + if( iCompare<0 ){ + VdbeBranchTaken(0,3); pOp = &aOp[pOp->p1 - 1]; + }else if( iCompare==0 ){ + VdbeBranchTaken(1,3); pOp = &aOp[pOp->p2 - 1]; + }else{ + VdbeBranchTaken(2,3); pOp = &aOp[pOp->p3 - 1]; + } + break; +} + +/* Opcode: And P1 P2 P3 * * +** Synopsis: r[P3]=(r[P1] && r[P2]) +** +** Take the logical AND of the values in registers P1 and P2 and +** write the result into register P3. +** +** If either P1 or P2 is 0 (false) then the result is 0 even if +** the other input is NULL. A NULL and true or two NULLs give +** a NULL output. +*/ +/* Opcode: Or P1 P2 P3 * * +** Synopsis: r[P3]=(r[P1] || r[P2]) +** +** Take the logical OR of the values in register P1 and P2 and +** store the answer in register P3. +** +** If either P1 or P2 is nonzero (true) then the result is 1 (true) +** even if the other input is NULL. A NULL and false or two NULLs +** give a NULL output. +*/ +case OP_And: /* same as TK_AND, in1, in2, out3 */ +case OP_Or: { /* same as TK_OR, in1, in2, out3 */ + int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ + int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ + + pIn1 = &aMem[pOp->p1]; + if( pIn1->flags & MEM_Null ){ + v1 = 2; + }else{ + v1 = sqlite3VdbeIntValue(pIn1)!=0; + } + pIn2 = &aMem[pOp->p2]; + if( pIn2->flags & MEM_Null ){ + v2 = 2; + }else{ + v2 = sqlite3VdbeIntValue(pIn2)!=0; + } + if( pOp->opcode==OP_And ){ + static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 }; + v1 = and_logic[v1*3+v2]; + }else{ + static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 }; + v1 = or_logic[v1*3+v2]; + } + pOut = &aMem[pOp->p3]; + if( v1==2 ){ + MemSetTypeFlag(pOut, MEM_Null); + }else{ + pOut->u.i = v1; + MemSetTypeFlag(pOut, MEM_Int); + } + break; +} + +/* Opcode: Not P1 P2 * * * +** Synopsis: r[P2]= !r[P1] +** +** Interpret the value in register P1 as a boolean value. Store the +** boolean complement in register P2. If the value in register P1 is +** NULL, then a NULL is stored in P2. +*/ +case OP_Not: { /* same as TK_NOT, in1, out2 */ + pIn1 = &aMem[pOp->p1]; + pOut = &aMem[pOp->p2]; + sqlite3VdbeMemSetNull(pOut); + if( (pIn1->flags & MEM_Null)==0 ){ + pOut->flags = MEM_Int; + pOut->u.i = !sqlite3VdbeIntValue(pIn1); + } + break; +} + +/* Opcode: BitNot P1 P2 * * * +** Synopsis: r[P1]= ~r[P1] +** +** Interpret the content of register P1 as an integer. Store the +** ones-complement of the P1 value into register P2. If P1 holds +** a NULL then store a NULL in P2. +*/ +case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ + pIn1 = &aMem[pOp->p1]; + pOut = &aMem[pOp->p2]; + sqlite3VdbeMemSetNull(pOut); + if( (pIn1->flags & MEM_Null)==0 ){ + pOut->flags = MEM_Int; + pOut->u.i = ~sqlite3VdbeIntValue(pIn1); + } + break; +} + +/* Opcode: Once P1 P2 * * * +** +** Check the "once" flag number P1. If it is set, jump to instruction P2. +** Otherwise, set the flag and fall through to the next instruction. +** In other words, this opcode causes all following opcodes up through P2 +** (but not including P2) to run just once and to be skipped on subsequent +** times through the loop. +** +** All "once" flags are initially cleared whenever a prepared statement +** first begins to run. +*/ +case OP_Once: { /* jump */ + assert( pOp->p1nOnceFlag ); + VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2); + if( p->aOnceFlag[pOp->p1] ){ + goto jump_to_p2; + }else{ + p->aOnceFlag[pOp->p1] = 1; + } + break; +} + +/* Opcode: If P1 P2 P3 * * +** +** Jump to P2 if the value in register P1 is true. The value +** is considered true if it is numeric and non-zero. If the value +** in P1 is NULL then take the jump if and only if P3 is non-zero. +*/ +/* Opcode: IfNot P1 P2 P3 * * +** +** Jump to P2 if the value in register P1 is False. The value +** is considered false if it has a numeric value of zero. If the value +** in P1 is NULL then take the jump if and only if P3 is non-zero. +*/ +case OP_If: /* jump, in1 */ +case OP_IfNot: { /* jump, in1 */ + int c; + pIn1 = &aMem[pOp->p1]; + if( pIn1->flags & MEM_Null ){ + c = pOp->p3; + }else{ +#ifdef SQLITE_OMIT_FLOATING_POINT + c = sqlite3VdbeIntValue(pIn1)!=0; +#else + c = sqlite3VdbeRealValue(pIn1)!=0.0; +#endif + if( pOp->opcode==OP_IfNot ) c = !c; + } + VdbeBranchTaken(c!=0, 2); + if( c ){ + goto jump_to_p2; + } + break; +} + +/* Opcode: IsNull P1 P2 * * * +** Synopsis: if r[P1]==NULL goto P2 +** +** Jump to P2 if the value in register P1 is NULL. +*/ +case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */ + pIn1 = &aMem[pOp->p1]; + VdbeBranchTaken( (pIn1->flags & MEM_Null)!=0, 2); + if( (pIn1->flags & MEM_Null)!=0 ){ + goto jump_to_p2; + } + break; +} + +/* Opcode: NotNull P1 P2 * * * +** Synopsis: if r[P1]!=NULL goto P2 +** +** Jump to P2 if the value in register P1 is not NULL. +*/ +case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */ + pIn1 = &aMem[pOp->p1]; + VdbeBranchTaken( (pIn1->flags & MEM_Null)==0, 2); + if( (pIn1->flags & MEM_Null)==0 ){ + goto jump_to_p2; + } + break; +} + +/* Opcode: Column P1 P2 P3 P4 P5 +** Synopsis: r[P3]=PX +** +** 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.) Extract the P2-th column +** from this record. If there are less that (P2+1) +** values in the record, extract a NULL. +** +** The value extracted is stored in register P3. +** +** If the column contains fewer than P2 fields, then extract a NULL. Or, +** if the P4 argument is a P4_MEM use the value of the P4 argument as +** the result. +** +** If the OPFLAG_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor, +** then the cache of the cursor is reset prior to extracting the column. +** The first OP_Column against a pseudo-table after the value of the content +** register has changed should have this bit set. +** +** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 when +** the result is guaranteed to only be used as the argument of a length() +** or typeof() function, respectively. The loading of large blobs can be +** skipped for length() and all content loading can be skipped for typeof(). +*/ +case OP_Column: { + i64 payloadSize64; /* Number of bytes in the record */ + int p2; /* column number to retrieve */ + VdbeCursor *pC; /* The VDBE cursor */ + BtCursor *pCrsr; /* The BTree cursor */ + u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */ + int len; /* The length of the serialized data for the column */ + int i; /* Loop counter */ + Mem *pDest; /* Where to write the extracted value */ + Mem sMem; /* For storing the record being decoded */ + const u8 *zData; /* Part of the record being decoded */ + const u8 *zHdr; /* Next unparsed byte of the header */ + const u8 *zEndHdr; /* Pointer to first byte after the header */ + u32 offset; /* Offset into the data */ + u32 szField; /* Number of bytes in the content of a field */ + u32 avail; /* Number of bytes of available data */ + u32 t; /* A type code from the record header */ + u16 fx; /* pDest->flags value */ + Mem *pReg; /* PseudoTable input register */ + + p2 = pOp->p2; + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); + pDest = &aMem[pOp->p3]; + memAboutToChange(p, pDest); + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( p2nField ); + aOffset = pC->aOffset; +#ifndef SQLITE_OMIT_VIRTUALTABLE + assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */ +#endif + pCrsr = pC->pCursor; + assert( pCrsr!=0 || pC->pseudoTableReg>0 ); /* pCrsr NULL on PseudoTables */ + assert( pCrsr!=0 || pC->nullRow ); /* pC->nullRow on PseudoTables */ + + /* If the cursor cache is stale, bring it up-to-date */ + rc = sqlite3VdbeCursorMoveto(pC); + if( rc ) goto abort_due_to_error; + if( pC->cacheStatus!=p->cacheCtr ){ + if( pC->nullRow ){ + if( pCrsr==0 ){ + assert( pC->pseudoTableReg>0 ); + pReg = &aMem[pC->pseudoTableReg]; + assert( pReg->flags & MEM_Blob ); + assert( memIsValid(pReg) ); + pC->payloadSize = pC->szRow = avail = pReg->n; + pC->aRow = (u8*)pReg->z; + }else{ + sqlite3VdbeMemSetNull(pDest); + goto op_column_out; + } + }else{ + assert( pCrsr ); + if( pC->isTable==0 ){ + assert( sqlite3BtreeCursorIsValid(pCrsr) ); + VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &payloadSize64); + assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ + /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the + ** payload size, so it is impossible for payloadSize64 to be + ** larger than 32 bits. */ + assert( (payloadSize64 & SQLITE_MAX_U32)==(u64)payloadSize64 ); + pC->aRow = sqlite3BtreeKeyFetch(pCrsr, &avail); + pC->payloadSize = (u32)payloadSize64; + }else{ + assert( sqlite3BtreeCursorIsValid(pCrsr) ); + VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &pC->payloadSize); + assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ + pC->aRow = sqlite3BtreeDataFetch(pCrsr, &avail); + } + assert( avail<=65536 ); /* Maximum page size is 64KiB */ + if( pC->payloadSize <= (u32)avail ){ + pC->szRow = pC->payloadSize; + }else{ + pC->szRow = avail; + } + if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ + goto too_big; + } + } + pC->cacheStatus = p->cacheCtr; + pC->iHdrOffset = getVarint32(pC->aRow, offset); + pC->nHdrParsed = 0; + aOffset[0] = offset; + + /* Make sure a corrupt database has not given us an oversize header. + ** Do this now to avoid an oversize memory allocation. + ** + ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte + ** types use so much data space that there can only be 4096 and 32 of + ** them, respectively. So the maximum header length results from a + ** 3-byte type for each of the maximum of 32768 columns plus three + ** extra bytes for the header length itself. 32768*3 + 3 = 98307. + */ + if( offset > 98307 || offset > pC->payloadSize ){ + rc = SQLITE_CORRUPT_BKPT; + goto op_column_error; + } + + if( availaRow does not have to hold the entire row, but it does at least + ** need to cover the header of the record. If pC->aRow does not contain + ** the complete header, then set it to zero, forcing the header to be + ** dynamically allocated. */ + pC->aRow = 0; + pC->szRow = 0; + } + + /* The following goto is an optimization. It can be omitted and + ** everything will still work. But OP_Column is measurably faster + ** by skipping the subsequent conditional, which is always true. + */ + assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */ + goto op_column_read_header; + } + + /* Make sure at least the first p2+1 entries of the header have been + ** parsed and valid information is in aOffset[] and pC->aType[]. + */ + if( pC->nHdrParsed<=p2 ){ + /* If there is more header available for parsing in the record, try + ** to extract additional fields up through the p2+1-th field + */ + op_column_read_header: + if( pC->iHdrOffsetaRow==0 ){ + memset(&sMem, 0, sizeof(sMem)); + rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0], + !pC->isTable, &sMem); + if( rc!=SQLITE_OK ){ + goto op_column_error; + } + zData = (u8*)sMem.z; + }else{ + zData = pC->aRow; + } + + /* Fill in pC->aType[i] and aOffset[i] values through the p2-th field. */ + i = pC->nHdrParsed; + offset = aOffset[i]; + zHdr = zData + pC->iHdrOffset; + zEndHdr = zData + aOffset[0]; + assert( i<=p2 && zHdraType[i] = t; + szField = sqlite3VdbeSerialTypeLen(t); + offset += szField; + if( offsetnHdrParsed = i; + pC->iHdrOffset = (u32)(zHdr - zData); + if( pC->aRow==0 ){ + sqlite3VdbeMemRelease(&sMem); + sMem.flags = MEM_Null; + } + + /* The record is corrupt if any of the following are true: + ** (1) the bytes of the header extend past the declared header size + ** (zHdr>zEndHdr) + ** (2) the entire header was used but not all data was used + ** (zHdr==zEndHdr && offset!=pC->payloadSize) + ** (3) the end of the data extends beyond the end of the record. + ** (offset > pC->payloadSize) + */ + if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset!=pC->payloadSize)) + || (offset > pC->payloadSize) + ){ + rc = SQLITE_CORRUPT_BKPT; + goto op_column_error; + } + } + + /* If after trying to extract new entries from the header, nHdrParsed is + ** still not up to p2, that means that the record has fewer than p2 + ** columns. So the result will be either the default value or a NULL. + */ + if( pC->nHdrParsed<=p2 ){ + if( pOp->p4type==P4_MEM ){ + sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static); + }else{ + sqlite3VdbeMemSetNull(pDest); + } + goto op_column_out; + } + } + + /* Extract the content for the p2+1-th column. Control can only + ** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are + ** all valid. + */ + assert( p2nHdrParsed ); + assert( rc==SQLITE_OK ); + assert( sqlite3VdbeCheckMemInvariants(pDest) ); + if( VdbeMemDynamic(pDest) ) sqlite3VdbeMemSetNull(pDest); + t = pC->aType[p2]; + if( pC->szRow>=aOffset[p2+1] ){ + /* This is the common case where the desired content fits on the original + ** page - where the content is not on an overflow page */ + sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], t, pDest); + }else{ + /* This branch happens only when content is on overflow pages */ + if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0 + && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0)) + || (len = sqlite3VdbeSerialTypeLen(t))==0 + ){ + /* Content is irrelevant for + ** 1. the typeof() function, + ** 2. the length(X) function if X is a blob, and + ** 3. if the content length is zero. + ** So we might as well use bogus content rather than reading + ** content from disk. NULL will work for the value for strings + ** and blobs and whatever is in the payloadSize64 variable + ** will work for everything else. */ + sqlite3VdbeSerialGet(t<=13 ? (u8*)&payloadSize64 : 0, t, pDest); + }else{ + rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, !pC->isTable, + pDest); + if( rc!=SQLITE_OK ){ + goto op_column_error; + } + sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest); + pDest->flags &= ~MEM_Ephem; + } + } + pDest->enc = encoding; + +op_column_out: + /* If the column value is an ephemeral string, go ahead and persist + ** that string in case the cursor moves before the column value is + ** used. The following code does the equivalent of Deephemeralize() + ** but does it faster. */ + if( (pDest->flags & MEM_Ephem)!=0 && pDest->z ){ + fx = pDest->flags & (MEM_Str|MEM_Blob); + assert( fx!=0 ); + zData = (const u8*)pDest->z; + len = pDest->n; + if( sqlite3VdbeMemClearAndResize(pDest, len+2) ) goto no_mem; + memcpy(pDest->z, zData, len); + pDest->z[len] = 0; + pDest->z[len+1] = 0; + pDest->flags = fx|MEM_Term; + } +op_column_error: + UPDATE_MAX_BLOBSIZE(pDest); + REGISTER_TRACE(pOp->p3, pDest); + break; +} + +/* Opcode: Affinity P1 P2 * P4 * +** Synopsis: affinity(r[P1@P2]) +** +** Apply affinities to a range of P2 registers starting with P1. +** +** P4 is a string that is P2 characters long. The nth character of the +** string indicates the column affinity that should be used for the nth +** memory cell in the range. +*/ +case OP_Affinity: { + const char *zAffinity; /* The affinity to be applied */ + char cAff; /* A single character of affinity */ + + zAffinity = pOp->p4.z; + assert( zAffinity!=0 ); + assert( zAffinity[pOp->p2]==0 ); + pIn1 = &aMem[pOp->p1]; + while( (cAff = *(zAffinity++))!=0 ){ + assert( pIn1 <= &p->aMem[(p->nMem-p->nCursor)] ); + assert( memIsValid(pIn1) ); + applyAffinity(pIn1, cAff, encoding); + pIn1++; + } + break; +} + +/* Opcode: MakeRecord P1 P2 P3 P4 * +** Synopsis: r[P3]=mkrec(r[P1@P2]) +** +** Convert P2 registers beginning with P1 into the [record format] +** use as a data record in a database table or as a key +** in an index. The OP_Column opcode can decode the record later. +** +** P4 may be a string that is P2 characters long. The nth character of the +** string indicates the column affinity that should be used for the nth +** field of the index key. +** +** The mapping from character to affinity is given by the SQLITE_AFF_ +** macros defined in sqliteInt.h. +** +** If P4 is NULL then all index fields have the affinity NONE. +*/ +case OP_MakeRecord: { + u8 *zNewRecord; /* A buffer to hold the data for the new record */ + Mem *pRec; /* The new record */ + u64 nData; /* Number of bytes of data space */ + int nHdr; /* Number of bytes of header space */ + i64 nByte; /* Data space required for this record */ + i64 nZero; /* Number of zero bytes at the end of the record */ + int nVarint; /* Number of bytes in a varint */ + u32 serial_type; /* Type field */ + Mem *pData0; /* First field to be combined into the record */ + Mem *pLast; /* Last field of the record */ + int nField; /* Number of fields in the record */ + char *zAffinity; /* The affinity string for the record */ + int file_format; /* File format to use for encoding */ + int i; /* Space used in zNewRecord[] header */ + int j; /* Space used in zNewRecord[] content */ + int len; /* Length of a field */ + + /* 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 | + ** ------------------------------------------------------------------------ + ** + ** Data(0) is taken from register P1. Data(1) comes from register P1+1 + ** and so forth. + ** + ** Each type field is a varint representing the serial type of the + ** corresponding data element (see sqlite3VdbeSerialType()). The + ** hdr-size field is also a varint which is the offset from the beginning + ** of the record to data0. + */ + nData = 0; /* Number of bytes of data space */ + nHdr = 0; /* Number of bytes of header space */ + nZero = 0; /* Number of zero bytes at the end of the record */ + nField = pOp->p1; + zAffinity = pOp->p4.z; + assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem-p->nCursor)+1 ); + pData0 = &aMem[nField]; + nField = pOp->p2; + pLast = &pData0[nField-1]; + file_format = p->minWriteFileFormat; + + /* Identify the output register */ + assert( pOp->p3p1 || pOp->p3>=pOp->p1+pOp->p2 ); + pOut = &aMem[pOp->p3]; + memAboutToChange(p, pOut); + + /* Apply the requested affinity to all inputs + */ + assert( pData0<=pLast ); + if( zAffinity ){ + pRec = pData0; + do{ + applyAffinity(pRec++, *(zAffinity++), encoding); + assert( zAffinity[0]==0 || pRec<=pLast ); + }while( zAffinity[0] ); + } + + /* Loop through the elements that will make up the record to figure + ** out how much space is required for the new record. + */ + pRec = pLast; + do{ + assert( memIsValid(pRec) ); + pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format); + len = sqlite3VdbeSerialTypeLen(serial_type); + if( pRec->flags & MEM_Zero ){ + if( nData ){ + sqlite3VdbeMemExpandBlob(pRec); + }else{ + nZero += pRec->u.nZero; + len -= pRec->u.nZero; + } + } + nData += len; + testcase( serial_type==127 ); + testcase( serial_type==128 ); + nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type); + }while( (--pRec)>=pData0 ); + + /* EVIDENCE-OF: R-22564-11647 The header begins with a single varint + ** which determines the total number of bytes in the header. The varint + ** value is the size of the header in bytes including the size varint + ** itself. */ + testcase( nHdr==126 ); + testcase( nHdr==127 ); + if( nHdr<=126 ){ + /* The common case */ + nHdr += 1; + }else{ + /* Rare case of a really large header */ + nVarint = sqlite3VarintLen(nHdr); + nHdr += nVarint; + if( nVarintdb->aLimit[SQLITE_LIMIT_LENGTH] ){ + goto too_big; + } + + /* Make sure the output register has a buffer large enough to store + ** the new record. The output register (pOp->p3) is not allowed to + ** be one of the input registers (because the following call to + ** sqlite3VdbeMemClearAndResize() could clobber the value before it is used). + */ + if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){ + goto no_mem; + } + zNewRecord = (u8 *)pOut->z; + + /* Write the record */ + i = putVarint32(zNewRecord, nHdr); + j = nHdr; + assert( pData0<=pLast ); + pRec = pData0; + do{ + serial_type = pRec->uTemp; + /* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more + ** additional varints, one per column. */ + i += putVarint32(&zNewRecord[i], serial_type); /* serial type */ + /* EVIDENCE-OF: R-64536-51728 The values for each column in the record + ** immediately follow the header. */ + j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */ + }while( (++pRec)<=pLast ); + assert( i==nHdr ); + assert( j==nByte ); + + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); + pOut->n = (int)nByte; + pOut->flags = MEM_Blob; + if( nZero ){ + pOut->u.nZero = nZero; + pOut->flags |= MEM_Zero; + } + pOut->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */ + REGISTER_TRACE(pOp->p3, pOut); + UPDATE_MAX_BLOBSIZE(pOut); + break; +} + +/* Opcode: Count P1 P2 * * * +** Synopsis: r[P2]=count() +** +** Store the number of entries (an integer value) in the table or index +** opened by cursor P1 in register P2 +*/ +#ifndef SQLITE_OMIT_BTREECOUNT +case OP_Count: { /* out2 */ + i64 nEntry; + BtCursor *pCrsr; + + pCrsr = p->apCsr[pOp->p1]->pCursor; + assert( pCrsr ); + nEntry = 0; /* Not needed. Only used to silence a warning. */ + rc = sqlite3BtreeCount(pCrsr, &nEntry); + pOut = out2Prerelease(p, pOp); + pOut->u.i = nEntry; + break; +} +#endif + +/* Opcode: Savepoint P1 * * P4 * +** +** Open, release or rollback the savepoint named by parameter P4, depending +** on the value of P1. To open a new savepoint, P1==0. To release (commit) an +** existing savepoint, P1==1, or to rollback an existing savepoint P1==2. +*/ +case OP_Savepoint: { + int p1; /* Value of P1 operand */ + char *zName; /* Name of savepoint */ + int nName; + Savepoint *pNew; + Savepoint *pSavepoint; + Savepoint *pTmp; + int iSavepoint; + int ii; + + p1 = pOp->p1; + zName = pOp->p4.z; + + /* Assert that the p1 parameter is valid. Also that if there is no open + ** transaction, then there cannot be any savepoints. + */ + assert( db->pSavepoint==0 || db->autoCommit==0 ); + assert( p1==SAVEPOINT_BEGIN||p1==SAVEPOINT_RELEASE||p1==SAVEPOINT_ROLLBACK ); + assert( db->pSavepoint || db->isTransactionSavepoint==0 ); + assert( checkSavepointCount(db) ); + assert( p->bIsReader ); + + if( p1==SAVEPOINT_BEGIN ){ + if( db->nVdbeWrite>0 ){ + /* A new savepoint cannot be created if there are active write + ** statements (i.e. open read/write incremental blob handles). + */ + sqlite3SetString(&p->zErrMsg, db, "cannot open savepoint - " + "SQL statements in progress"); + rc = SQLITE_BUSY; + }else{ + nName = sqlite3Strlen30(zName); + +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* This call is Ok even if this savepoint is actually a transaction + ** savepoint (and therefore should not prompt xSavepoint()) callbacks. + ** If this is a transaction savepoint being opened, it is guaranteed + ** that the db->aVTrans[] array is empty. */ + assert( db->autoCommit==0 || db->nVTrans==0 ); + rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, + db->nStatement+db->nSavepoint); + if( rc!=SQLITE_OK ) goto abort_due_to_error; +#endif + + /* Create a new savepoint structure. */ + pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+nName+1); + if( pNew ){ + pNew->zName = (char *)&pNew[1]; + memcpy(pNew->zName, zName, nName+1); + + /* If there is no open transaction, then mark this as a special + ** "transaction savepoint". */ + if( db->autoCommit ){ + db->autoCommit = 0; + db->isTransactionSavepoint = 1; + }else{ + db->nSavepoint++; + } + + /* Link the new savepoint into the database handle's list. */ + pNew->pNext = db->pSavepoint; + db->pSavepoint = pNew; + pNew->nDeferredCons = db->nDeferredCons; + pNew->nDeferredImmCons = db->nDeferredImmCons; + } + } + }else{ + iSavepoint = 0; + + /* Find the named savepoint. If there is no such savepoint, then an + ** an error is returned to the user. */ + for( + pSavepoint = db->pSavepoint; + pSavepoint && sqlite3StrICmp(pSavepoint->zName, zName); + pSavepoint = pSavepoint->pNext + ){ + iSavepoint++; + } + if( !pSavepoint ){ + sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", zName); + rc = SQLITE_ERROR; + }else if( db->nVdbeWrite>0 && p1==SAVEPOINT_RELEASE ){ + /* It is not possible to release (commit) a savepoint if there are + ** active write statements. + */ + sqlite3SetString(&p->zErrMsg, db, + "cannot release savepoint - SQL statements in progress" + ); + rc = SQLITE_BUSY; + }else{ + + /* Determine whether or not this is a transaction savepoint. If so, + ** and this is a RELEASE command, then the current transaction + ** is committed. + */ + int isTransaction = pSavepoint->pNext==0 && db->isTransactionSavepoint; + if( isTransaction && p1==SAVEPOINT_RELEASE ){ + if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ + goto vdbe_return; + } + db->autoCommit = 1; + if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ + p->pc = (int)(pOp - aOp); + db->autoCommit = 0; + p->rc = rc = SQLITE_BUSY; + goto vdbe_return; + } + db->isTransactionSavepoint = 0; + rc = p->rc; + }else{ + int isSchemaChange; + iSavepoint = db->nSavepoint - iSavepoint - 1; + if( p1==SAVEPOINT_ROLLBACK ){ + isSchemaChange = (db->flags & SQLITE_InternChanges)!=0; + for(ii=0; iinDb; ii++){ + rc = sqlite3BtreeTripAllCursors(db->aDb[ii].pBt, + SQLITE_ABORT_ROLLBACK, + isSchemaChange==0); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + } + }else{ + isSchemaChange = 0; + } + for(ii=0; iinDb; ii++){ + rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint); + if( rc!=SQLITE_OK ){ + goto abort_due_to_error; + } + } + if( isSchemaChange ){ + sqlite3ExpirePreparedStatements(db); + sqlite3ResetAllSchemasOfConnection(db); + db->flags = (db->flags | SQLITE_InternChanges); + } + } + + /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all + ** savepoints nested inside of the savepoint being operated on. */ + while( db->pSavepoint!=pSavepoint ){ + pTmp = db->pSavepoint; + db->pSavepoint = pTmp->pNext; + sqlite3DbFree(db, pTmp); + db->nSavepoint--; + } + + /* If it is a RELEASE, then destroy the savepoint being operated on + ** too. If it is a ROLLBACK TO, then set the number of deferred + ** constraint violations present in the database to the value stored + ** when the savepoint was created. */ + if( p1==SAVEPOINT_RELEASE ){ + assert( pSavepoint==db->pSavepoint ); + db->pSavepoint = pSavepoint->pNext; + sqlite3DbFree(db, pSavepoint); + if( !isTransaction ){ + db->nSavepoint--; + } + }else{ + db->nDeferredCons = pSavepoint->nDeferredCons; + db->nDeferredImmCons = pSavepoint->nDeferredImmCons; + } + + if( !isTransaction || p1==SAVEPOINT_ROLLBACK ){ + rc = sqlite3VtabSavepoint(db, p1, iSavepoint); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + } + } + } + + 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 a ROLLBACK fails. A COMMIT fails if +** there are active writing VMs or active VMs that use shared cache. +** +** This instruction causes the VM to halt. +*/ +case OP_AutoCommit: { + int desiredAutoCommit; + int iRollback; + int turnOnAC; + + desiredAutoCommit = pOp->p1; + iRollback = pOp->p2; + turnOnAC = desiredAutoCommit && !db->autoCommit; + assert( desiredAutoCommit==1 || desiredAutoCommit==0 ); + assert( desiredAutoCommit==1 || iRollback==0 ); + assert( db->nVdbeActive>0 ); /* At least this one VM is active */ + assert( p->bIsReader ); + +#if 0 + if( turnOnAC && iRollback && db->nVdbeActive>1 ){ + /* If this instruction implements a ROLLBACK and other VMs are + ** still running, and a transaction is active, return an error indicating + ** that the other VMs must complete first. + */ + sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - " + "SQL statements in progress"); + rc = SQLITE_BUSY; + }else +#endif + if( turnOnAC && !iRollback && db->nVdbeWrite>0 ){ + /* If this instruction implements a COMMIT and other VMs are writing + ** return an error indicating that the other VMs must complete first. + */ + sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - " + "SQL statements in progress"); + rc = SQLITE_BUSY; + }else if( desiredAutoCommit!=db->autoCommit ){ + if( iRollback ){ + assert( desiredAutoCommit==1 ); + sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); + db->autoCommit = 1; + }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ + goto vdbe_return; + }else{ + db->autoCommit = (u8)desiredAutoCommit; + if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ + p->pc = (int)(pOp - aOp); + db->autoCommit = (u8)(1-desiredAutoCommit); + p->rc = rc = SQLITE_BUSY; + goto vdbe_return; + } + } + assert( db->nStatement==0 ); + sqlite3CloseSavepoints(db); + if( p->rc==SQLITE_OK ){ + rc = SQLITE_DONE; + }else{ + rc = SQLITE_ERROR; + } + goto vdbe_return; + }else{ + sqlite3SetString(&p->zErrMsg, db, + (!desiredAutoCommit)?"cannot start a transaction within a transaction":( + (iRollback)?"cannot rollback - no transaction is active": + "cannot commit - no transaction is active")); + + rc = SQLITE_ERROR; + } + break; +} + +/* Opcode: Transaction P1 P2 P3 P4 P5 +** +** Begin a transaction on database P1 if a transaction is not already +** active. +** If P2 is non-zero, then a write-transaction is started, or if a +** read-transaction is already active, it is upgraded to a write-transaction. +** If P2 is zero, then a read-transaction is started. +** +** P1 is the index of the database file on which the transaction is +** started. Index 0 is the main database file and index 1 is the +** file used for temporary tables. Indices of 2 or more are used for +** attached databases. +** +** If a write-transaction is started and the Vdbe.usesStmtJournal flag is +** true (this flag is set if the Vdbe may modify more than one row and may +** throw an ABORT exception), a statement transaction may also be opened. +** More specifically, a statement transaction is opened iff the database +** connection is currently not in autocommit mode, or if there are other +** active statements. A statement transaction allows the changes made by this +** VDBE to be rolled back after an error without having to roll back the +** entire transaction. If no error is encountered, the statement transaction +** will automatically commit when the VDBE halts. +** +** If P5!=0 then this opcode also checks the schema cookie against P3 +** and the schema generation counter against P4. +** The cookie changes its value whenever the database schema changes. +** This operation is used to detect when that the cookie has changed +** and that the current process needs to reread the schema. If the schema +** cookie in P3 differs from the schema cookie in the database header or +** if the schema generation counter in P4 differs from the current +** generation counter, then an SQLITE_SCHEMA error is raised and execution +** halts. The sqlite3_step() wrapper function might then reprepare the +** statement and rerun it from the beginning. +*/ +case OP_Transaction: { + Btree *pBt; + int iMeta; + int iGen; + + assert( p->bIsReader ); + assert( p->readOnly==0 || pOp->p2==0 ); + assert( pOp->p1>=0 && pOp->p1nDb ); + assert( DbMaskTest(p->btreeMask, pOp->p1) ); + if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){ + rc = SQLITE_READONLY; + goto abort_due_to_error; + } + pBt = db->aDb[pOp->p1].pBt; + + if( pBt ){ + rc = sqlite3BtreeBeginTrans(pBt, pOp->p2); + if( rc==SQLITE_BUSY ){ + p->pc = (int)(pOp - aOp); + p->rc = rc = SQLITE_BUSY; + goto vdbe_return; + } + if( rc!=SQLITE_OK ){ + goto abort_due_to_error; + } + + if( pOp->p2 && p->usesStmtJournal + && (db->autoCommit==0 || db->nVdbeRead>1) + ){ + assert( sqlite3BtreeIsInTrans(pBt) ); + if( p->iStatement==0 ){ + assert( db->nStatement>=0 && db->nSavepoint>=0 ); + db->nStatement++; + p->iStatement = db->nSavepoint + db->nStatement; + } + + rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement-1); + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeBeginStmt(pBt, p->iStatement); + } + + /* Store the current value of the database handles deferred constraint + ** counter. If the statement transaction needs to be rolled back, + ** the value of this counter needs to be restored too. */ + p->nStmtDefCons = db->nDeferredCons; + p->nStmtDefImmCons = db->nDeferredImmCons; + } + + /* Gather the schema version number for checking: + ** IMPLEMENTATION-OF: R-32195-19465 The schema version is used by SQLite + ** each time a query is executed to ensure that the internal cache of the + ** schema used when compiling the SQL query matches the schema of the + ** database against which the compiled query is actually executed. + */ + sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta); + iGen = db->aDb[pOp->p1].pSchema->iGeneration; + }else{ + iGen = iMeta = 0; + } + assert( pOp->p5==0 || pOp->p4type==P4_INT32 ); + if( pOp->p5 && (iMeta!=pOp->p3 || iGen!=pOp->p4.i) ){ + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); + /* If the schema-cookie from the database file matches the cookie + ** stored with the in-memory representation of the schema, do + ** not reload the schema from the database file. + ** + ** If virtual-tables are in use, this is not just an optimization. + ** Often, v-tables store their data in other SQLite tables, which + ** are queried from within xNext() and other v-table methods using + ** prepared queries. If such a query is out-of-date, we do not want to + ** discard the database schema, as the user code implementing the + ** v-table would have to be ready for the sqlite3_vtab structure itself + ** to be invalidated whenever sqlite3_step() is called from within + ** a v-table method. + */ + if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){ + sqlite3ResetOneSchema(db, pOp->p1); + } + p->expired = 1; + rc = SQLITE_SCHEMA; + } + break; +} + +/* Opcode: ReadCookie P1 P2 P3 * * +** +** Read cookie number P3 from database P1 and write it into register P2. +** P3==1 is the schema version. P3==2 is the database format. +** P3==3 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. +** +** There must be a read-lock on the database (either a transaction +** must be started or there must be an open cursor) before +** executing this instruction. +*/ +case OP_ReadCookie: { /* out2 */ + int iMeta; + int iDb; + int iCookie; + + assert( p->bIsReader ); + iDb = pOp->p1; + iCookie = pOp->p3; + assert( pOp->p3=0 && iDbnDb ); + assert( db->aDb[iDb].pBt!=0 ); + assert( DbMaskTest(p->btreeMask, iDb) ); + + sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta); + pOut = out2Prerelease(p, pOp); + pOut->u.i = iMeta; + break; +} + +/* Opcode: SetCookie P1 P2 P3 * * +** +** Write the content of register P3 (interpreted as an integer) +** into cookie number P2 of database P1. P2==1 is the schema version. +** P2==2 is the database format. P2==3 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: { /* in3 */ + Db *pDb; + assert( pOp->p2p1>=0 && pOp->p1nDb ); + assert( DbMaskTest(p->btreeMask, pOp->p1) ); + assert( p->readOnly==0 ); + pDb = &db->aDb[pOp->p1]; + assert( pDb->pBt!=0 ); + assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); + pIn3 = &aMem[pOp->p3]; + sqlite3VdbeMemIntegerify(pIn3); + /* See note about index shifting on OP_ReadCookie */ + rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, (int)pIn3->u.i); + if( pOp->p2==BTREE_SCHEMA_VERSION ){ + /* When the schema cookie changes, record the new cookie internally */ + pDb->pSchema->schema_cookie = (int)pIn3->u.i; + db->flags |= SQLITE_InternChanges; + }else if( pOp->p2==BTREE_FILE_FORMAT ){ + /* Record changes in the file format */ + pDb->pSchema->file_format = (u8)pIn3->u.i; + } + if( pOp->p1==1 ){ + /* Invalidate all prepared statements whenever the TEMP database + ** schema is changed. Ticket #1644 */ + sqlite3ExpirePreparedStatements(db); + p->expired = 0; + } + break; +} + +/* Opcode: OpenRead P1 P2 P3 P4 P5 +** Synopsis: root=P2 iDb=P3 +** +** Open a read-only cursor for the database table whose root page is +** P2 in a database file. The database file is determined by P3. +** P3==0 means the main database, P3==1 means the database used for +** temporary tables, and P3>1 means used the corresponding attached +** database. Give the new cursor an identifier of P1. The P1 +** values need not be contiguous but all P1 values should be small integers. +** It is an error for P1 to be negative. +** +** If P5!=0 then use the content of register P2 as the root page, not +** the value of P2 itself. +** +** There will be a read lock on the database whenever there is an +** open cursor. If the database was unlocked prior to this instruction +** then a read lock is acquired as part of this instruction. A read +** lock allows other processes to read the database but prohibits +** any other process from modifying the database. The read lock is +** released when all cursors are closed. If this instruction attempts +** to get a read lock but fails, the script terminates with an +** SQLITE_BUSY error code. +** +** The P4 value may be either an integer (P4_INT32) or a pointer to +** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo +** structure, then said structure defines the content and collating +** sequence of the index being opened. Otherwise, if P4 is an integer +** value, it is set to the number of columns in the table. +** +** See also: OpenWrite, ReopenIdx +*/ +/* Opcode: ReopenIdx P1 P2 P3 P4 P5 +** Synopsis: root=P2 iDb=P3 +** +** The ReopenIdx opcode works exactly like ReadOpen except that it first +** checks to see if the cursor on P1 is already open with a root page +** number of P2 and if it is this opcode becomes a no-op. In other words, +** if the cursor is already open, do not reopen it. +** +** The ReopenIdx opcode may only be used with P5==0 and with P4 being +** a P4_KEYINFO object. Furthermore, the P3 value must be the same as +** every other ReopenIdx or OpenRead for the same cursor number. +** +** See the OpenRead opcode documentation for additional information. +*/ +/* Opcode: OpenWrite P1 P2 P3 P4 P5 +** Synopsis: root=P2 iDb=P3 +** +** Open a read/write cursor named P1 on the table or index whose root +** page is P2. Or if P5!=0 use the content of register P2 to find the +** root page. +** +** The P4 value may be either an integer (P4_INT32) or a pointer to +** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo +** structure, then said structure defines the content and collating +** sequence of the index being opened. Otherwise, if P4 is an integer +** value, it is set to the number of columns in the table, or to the +** largest index of any column of the table that is actually used. +** +** 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_ReopenIdx: { + int nField; + KeyInfo *pKeyInfo; + int p2; + int iDb; + int wrFlag; + Btree *pX; + VdbeCursor *pCur; + Db *pDb; + + assert( pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ ); + assert( pOp->p4type==P4_KEYINFO ); + pCur = p->apCsr[pOp->p1]; + if( pCur && pCur->pgnoRoot==(u32)pOp->p2 ){ + assert( pCur->iDb==pOp->p3 ); /* Guaranteed by the code generator */ + goto open_cursor_set_hints; + } + /* If the cursor is not currently open or is open on a different + ** index, then fall through into OP_OpenRead to force a reopen */ +case OP_OpenRead: +case OP_OpenWrite: + + assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR|OPFLAG_SEEKEQ))==pOp->p5 ); + assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ ); + assert( p->bIsReader ); + assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx + || p->readOnly==0 ); + + if( p->expired ){ + rc = SQLITE_ABORT_ROLLBACK; + break; + } + + nField = 0; + pKeyInfo = 0; + p2 = pOp->p2; + iDb = pOp->p3; + assert( iDb>=0 && iDbnDb ); + assert( DbMaskTest(p->btreeMask, iDb) ); + pDb = &db->aDb[iDb]; + pX = pDb->pBt; + assert( pX!=0 ); + if( pOp->opcode==OP_OpenWrite ){ + wrFlag = 1; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + if( pDb->pSchema->file_format < p->minWriteFileFormat ){ + p->minWriteFileFormat = pDb->pSchema->file_format; + } + }else{ + wrFlag = 0; + } + if( pOp->p5 & OPFLAG_P2ISREG ){ + assert( p2>0 ); + assert( p2<=(p->nMem-p->nCursor) ); + pIn2 = &aMem[p2]; + assert( memIsValid(pIn2) ); + assert( (pIn2->flags & MEM_Int)!=0 ); + sqlite3VdbeMemIntegerify(pIn2); + p2 = (int)pIn2->u.i; + /* The p2 value always comes from a prior OP_CreateTable opcode and + ** that opcode will always set the p2 value to 2 or more or else fail. + ** If there were a failure, the prepared statement would have halted + ** before reaching this instruction. */ + if( NEVER(p2<2) ) { + rc = SQLITE_CORRUPT_BKPT; + goto abort_due_to_error; + } + } + if( pOp->p4type==P4_KEYINFO ){ + pKeyInfo = pOp->p4.pKeyInfo; + assert( pKeyInfo->enc==ENC(db) ); + assert( pKeyInfo->db==db ); + nField = pKeyInfo->nField+pKeyInfo->nXField; + }else if( pOp->p4type==P4_INT32 ){ + nField = pOp->p4.i; + } + assert( pOp->p1>=0 ); + assert( nField>=0 ); + testcase( nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */ + pCur = allocateCursor(p, pOp->p1, nField, iDb, 1); + if( pCur==0 ) goto no_mem; + pCur->nullRow = 1; + pCur->isOrdered = 1; + pCur->pgnoRoot = p2; + rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor); + pCur->pKeyInfo = pKeyInfo; + /* Set the VdbeCursor.isTable variable. Previous versions of + ** SQLite used to check if the root-page flags were sane at this point + ** and report database corruption if they were not, but this check has + ** since moved into the btree layer. */ + pCur->isTable = pOp->p4type!=P4_KEYINFO; + +open_cursor_set_hints: + assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); + assert( OPFLAG_SEEKEQ==BTREE_SEEK_EQ ); + sqlite3BtreeCursorHints(pCur->pCursor, + (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ))); + break; +} + +/* Opcode: OpenEphemeral P1 P2 * P4 P5 +** Synopsis: nColumn=P2 +** +** Open a new cursor P1 to a transient table. +** The cursor is always opened read/write even if +** the main database is read-only. The ephemeral +** table is deleted automatically when the cursor is closed. +** +** P2 is the number of columns in the ephemeral table. +** The cursor points to a BTree table if P4==0 and to a BTree index +** if P4 is not 0. If P4 is not NULL, it points to a KeyInfo structure +** that defines the format of keys in the index. +** +** The P5 parameter can be a mask of the BTREE_* flags defined +** in btree.h. These flags control aspects of the operation of +** the btree. The BTREE_OMIT_JOURNAL and BTREE_SINGLE flags are +** added automatically. +*/ +/* Opcode: OpenAutoindex P1 P2 * P4 * +** Synopsis: nColumn=P2 +** +** This opcode works the same as OP_OpenEphemeral. It has a +** different name to distinguish its use. Tables created using +** by this opcode will be used for automatically created transient +** indices in joins. +*/ +case OP_OpenAutoindex: +case OP_OpenEphemeral: { + VdbeCursor *pCx; + KeyInfo *pKeyInfo; + + static const int vfsFlags = + SQLITE_OPEN_READWRITE | + SQLITE_OPEN_CREATE | + SQLITE_OPEN_EXCLUSIVE | + SQLITE_OPEN_DELETEONCLOSE | + SQLITE_OPEN_TRANSIENT_DB; + assert( pOp->p1>=0 ); + assert( pOp->p2>=0 ); + pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); + if( pCx==0 ) goto no_mem; + pCx->nullRow = 1; + pCx->isEphemeral = 1; + rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBt, + BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeBeginTrans(pCx->pBt, 1); + } + if( rc==SQLITE_OK ){ + /* If a transient index is required, create it by calling + ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before + ** opening it. If a transient table is required, just use the + ** automatically created table with root-page 1 (an BLOB_INTKEY table). + */ + if( (pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ + int pgno; + assert( pOp->p4type==P4_KEYINFO ); + rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5); + if( rc==SQLITE_OK ){ + assert( pgno==MASTER_ROOT+1 ); + assert( pKeyInfo->db==db ); + assert( pKeyInfo->enc==ENC(db) ); + pCx->pKeyInfo = pKeyInfo; + rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, pKeyInfo, pCx->pCursor); + } + pCx->isTable = 0; + }else{ + rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, pCx->pCursor); + pCx->isTable = 1; + } + } + pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); + break; +} + +/* Opcode: SorterOpen P1 P2 P3 P4 * +** +** This opcode works like OP_OpenEphemeral except that it opens +** a transient index that is specifically designed to sort large +** tables using an external merge-sort algorithm. +** +** If argument P3 is non-zero, then it indicates that the sorter may +** assume that a stable sort considering the first P3 fields of each +** key is sufficient to produce the required results. +*/ +case OP_SorterOpen: { + VdbeCursor *pCx; + + assert( pOp->p1>=0 ); + assert( pOp->p2>=0 ); + pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); + if( pCx==0 ) goto no_mem; + pCx->pKeyInfo = pOp->p4.pKeyInfo; + assert( pCx->pKeyInfo->db==db ); + assert( pCx->pKeyInfo->enc==ENC(db) ); + rc = sqlite3VdbeSorterInit(db, pOp->p3, pCx); + break; +} + +/* Opcode: SequenceTest P1 P2 * * * +** Synopsis: if( cursor[P1].ctr++ ) pc = P2 +** +** P1 is a sorter cursor. If the sequence counter is currently zero, jump +** to P2. Regardless of whether or not the jump is taken, increment the +** the sequence value. +*/ +case OP_SequenceTest: { + VdbeCursor *pC; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC->pSorter ); + if( (pC->seqCount++)==0 ){ + goto jump_to_p2; + } + break; +} + +/* Opcode: OpenPseudo P1 P2 P3 * * +** Synopsis: P3 columns in r[P2] +** +** Open a new cursor that points to a fake table that contains a single +** row of data. The content of that one row is the content of memory +** register P2. In other words, cursor P1 becomes an alias for the +** MEM_Blob content contained in register P2. +** +** A pseudo-table created by this opcode is used to hold a single +** row output from the sorter so that the row can be decomposed into +** individual columns using the OP_Column opcode. The OP_Column opcode +** is the only cursor opcode that works with a pseudo-table. +** +** P3 is the number of fields in the records that will be stored by +** the pseudo-table. +*/ +case OP_OpenPseudo: { + VdbeCursor *pCx; + + assert( pOp->p1>=0 ); + assert( pOp->p3>=0 ); + pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0); + if( pCx==0 ) goto no_mem; + pCx->nullRow = 1; + pCx->pseudoTableReg = pOp->p2; + pCx->isTable = 1; + assert( pOp->p5==0 ); + break; +} + +/* 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: { + assert( pOp->p1>=0 && pOp->p1nCursor ); + sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]); + p->apCsr[pOp->p1] = 0; + break; +} + +/* Opcode: SeekGE P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), +** use the value in register P3 as the key. If cursor P1 refers +** to an SQL index, then P3 is the first in an array of P4 registers +** that are used as an unpacked index key. +** +** Reposition cursor P1 so that it points to the smallest entry that +** is greater than or equal to the key value. If there are no records +** greater than or equal to the key and P2 is not zero, then jump to P2. +** +** This opcode leaves the cursor configured to move in forward order, +** from the beginning toward the end. In other words, the cursor is +** configured to use Next, not Prev. +** +** See also: Found, NotFound, SeekLt, SeekGt, SeekLe +*/ +/* Opcode: SeekGT P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), +** use the value in register P3 as a key. If cursor P1 refers +** to an SQL index, then P3 is the first in an array of P4 registers +** that are used as an unpacked index key. +** +** Reposition cursor P1 so that it points to the smallest entry that +** is greater than the key value. If there are no records greater than +** the key and P2 is not zero, then jump to P2. +** +** This opcode leaves the cursor configured to move in forward order, +** from the beginning toward the end. In other words, the cursor is +** configured to use Next, not Prev. +** +** See also: Found, NotFound, SeekLt, SeekGe, SeekLe +*/ +/* Opcode: SeekLT P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), +** use the value in register P3 as a key. If cursor P1 refers +** to an SQL index, then P3 is the first in an array of P4 registers +** that are used as an unpacked index key. +** +** Reposition cursor P1 so that it points to the largest entry that +** is less than the key value. If there are no records less than +** the key and P2 is not zero, then jump to P2. +** +** This opcode leaves the cursor configured to move in reverse order, +** from the end toward the beginning. In other words, the cursor is +** configured to use Prev, not Next. +** +** See also: Found, NotFound, SeekGt, SeekGe, SeekLe +*/ +/* Opcode: SeekLE P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), +** use the value in register P3 as a key. If cursor P1 refers +** to an SQL index, then P3 is the first in an array of P4 registers +** that are used as an unpacked index key. +** +** Reposition cursor P1 so that it points to the largest entry that +** is less than or equal to the key value. If there are no records +** less than or equal to the key and P2 is not zero, then jump to P2. +** +** This opcode leaves the cursor configured to move in reverse order, +** from the end toward the beginning. In other words, the cursor is +** configured to use Prev, not Next. +** +** See also: Found, NotFound, SeekGt, SeekGe, SeekLt +*/ +case OP_SeekLT: /* jump, in3 */ +case OP_SeekLE: /* jump, in3 */ +case OP_SeekGE: /* jump, in3 */ +case OP_SeekGT: { /* jump, in3 */ + int res; + int oc; + VdbeCursor *pC; + UnpackedRecord r; + int nField; + i64 iKey; /* The rowid we are to seek to */ + + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p2!=0 ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->pseudoTableReg==0 ); + assert( OP_SeekLE == OP_SeekLT+1 ); + assert( OP_SeekGE == OP_SeekLT+2 ); + assert( OP_SeekGT == OP_SeekLT+3 ); + assert( pC->isOrdered ); + assert( pC->pCursor!=0 ); + oc = pOp->opcode; + pC->nullRow = 0; +#ifdef SQLITE_DEBUG + pC->seekOp = pOp->opcode; +#endif + + /* For a cursor with the BTREE_SEEK_EQ hint, only the OP_SeekGE and + ** OP_SeekLE opcodes are allowed, and these must be immediately followed + ** by an OP_IdxGT or OP_IdxLT opcode, respectively, with the same key. + */ +#ifdef SQLITE_DEBUG + if( sqlite3BtreeCursorHasHint(pC->pCursor, BTREE_SEEK_EQ) ){ + assert( pOp->opcode==OP_SeekGE || pOp->opcode==OP_SeekLE ); + assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT ); + assert( pOp[1].p1==pOp[0].p1 ); + assert( pOp[1].p2==pOp[0].p2 ); + assert( pOp[1].p3==pOp[0].p3 ); + assert( pOp[1].p4.i==pOp[0].p4.i ); + } +#endif + + if( pC->isTable ){ + /* The input value in P3 might be of any type: integer, real, string, + ** blob, or NULL. But it needs to be an integer before we can do + ** the seek, so convert it. */ + pIn3 = &aMem[pOp->p3]; + if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ + applyNumericAffinity(pIn3, 0); + } + iKey = sqlite3VdbeIntValue(pIn3); + + /* If the P3 value could not be converted into an integer without + ** loss of information, then special processing is required... */ + if( (pIn3->flags & MEM_Int)==0 ){ + if( (pIn3->flags & MEM_Real)==0 ){ + /* If the P3 value cannot be converted into any kind of a number, + ** then the seek is not possible, so jump to P2 */ + VdbeBranchTaken(1,2); goto jump_to_p2; + break; + } + + /* If the approximation iKey is larger than the actual real search + ** term, substitute >= for > and < for <=. e.g. if the search term + ** is 4.9 and the integer approximation 5: + ** + ** (x > 4.9) -> (x >= 5) + ** (x <= 4.9) -> (x < 5) + */ + if( pIn3->u.r<(double)iKey ){ + assert( OP_SeekGE==(OP_SeekGT-1) ); + assert( OP_SeekLT==(OP_SeekLE-1) ); + assert( (OP_SeekLE & 0x0001)==(OP_SeekGT & 0x0001) ); + if( (oc & 0x0001)==(OP_SeekGT & 0x0001) ) oc--; + } + + /* If the approximation iKey is smaller than the actual real search + ** term, substitute <= for < and > for >=. */ + else if( pIn3->u.r>(double)iKey ){ + assert( OP_SeekLE==(OP_SeekLT+1) ); + assert( OP_SeekGT==(OP_SeekGE+1) ); + assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) ); + if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++; + } + } + rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res); + pC->movetoTarget = iKey; /* Used by OP_Delete */ + if( rc!=SQLITE_OK ){ + goto abort_due_to_error; + } + }else{ + nField = pOp->p4.i; + assert( pOp->p4type==P4_INT32 ); + assert( nField>0 ); + r.pKeyInfo = pC->pKeyInfo; + r.nField = (u16)nField; + + /* The next line of code computes as follows, only faster: + ** if( oc==OP_SeekGT || oc==OP_SeekLE ){ + ** r.default_rc = -1; + ** }else{ + ** r.default_rc = +1; + ** } + */ + r.default_rc = ((1 & (oc - OP_SeekLT)) ? -1 : +1); + assert( oc!=OP_SeekGT || r.default_rc==-1 ); + assert( oc!=OP_SeekLE || r.default_rc==-1 ); + assert( oc!=OP_SeekGE || r.default_rc==+1 ); + assert( oc!=OP_SeekLT || r.default_rc==+1 ); + + r.aMem = &aMem[pOp->p3]; +#ifdef SQLITE_DEBUG + { int i; for(i=0; ipCursor, &r, 0, 0, &res); + if( rc!=SQLITE_OK ){ + goto abort_due_to_error; + } + } + pC->deferredMoveto = 0; + pC->cacheStatus = CACHE_STALE; +#ifdef SQLITE_TEST + sqlite3_search_count++; +#endif + if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT ); + if( res<0 || (res==0 && oc==OP_SeekGT) ){ + res = 0; + rc = sqlite3BtreeNext(pC->pCursor, &res); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + }else{ + res = 0; + } + }else{ + assert( oc==OP_SeekLT || oc==OP_SeekLE ); + if( res>0 || (res==0 && oc==OP_SeekLT) ){ + res = 0; + rc = sqlite3BtreePrevious(pC->pCursor, &res); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + }else{ + /* res might be negative because the table is empty. Check to + ** see if this is the case. + */ + res = sqlite3BtreeEof(pC->pCursor); + } + } + assert( pOp->p2>0 ); + VdbeBranchTaken(res!=0,2); + if( res ){ + goto jump_to_p2; + } + break; +} + +/* Opcode: Seek P1 P2 * * * +** Synopsis: intkey=r[P2] +** +** P1 is an open table cursor and P2 is a rowid integer. Arrange +** for P1 to move so that it points to the rowid given by P2. +** +** This is actually a deferred seek. Nothing actually happens until +** the cursor is used to read a record. That way, if no reads +** occur, no unnecessary I/O happens. +*/ +case OP_Seek: { /* in2 */ + VdbeCursor *pC; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->pCursor!=0 ); + assert( pC->isTable ); + pC->nullRow = 0; + pIn2 = &aMem[pOp->p2]; + pC->movetoTarget = sqlite3VdbeIntValue(pIn2); + pC->deferredMoveto = 1; + break; +} + + +/* Opcode: Found P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** If P4==0 then register P3 holds a blob constructed by MakeRecord. If +** P4>0 then register P3 is the first of P4 registers that form an unpacked +** record. +** +** Cursor P1 is on an index btree. If the record identified by P3 and P4 +** is a prefix of any entry in P1 then a jump is made to P2 and +** P1 is left pointing at the matching entry. +** +** This operation leaves the cursor in a state where it can be +** advanced in the forward direction. The Next instruction will work, +** but not the Prev instruction. +** +** See also: NotFound, NoConflict, NotExists. SeekGe +*/ +/* Opcode: NotFound P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** If P4==0 then register P3 holds a blob constructed by MakeRecord. If +** P4>0 then register P3 is the first of P4 registers that form an unpacked +** record. +** +** Cursor P1 is on an index btree. If the record identified by P3 and P4 +** is not the prefix of any entry in P1 then a jump is made to P2. If P1 +** does contain an entry whose prefix matches the P3/P4 record then control +** falls through to the next instruction and P1 is left pointing at the +** matching entry. +** +** This operation leaves the cursor in a state where it cannot be +** advanced in either direction. In other words, the Next and Prev +** opcodes do not work after this operation. +** +** See also: Found, NotExists, NoConflict +*/ +/* Opcode: NoConflict P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** If P4==0 then register P3 holds a blob constructed by MakeRecord. If +** P4>0 then register P3 is the first of P4 registers that form an unpacked +** record. +** +** Cursor P1 is on an index btree. If the record identified by P3 and P4 +** contains any NULL value, jump immediately to P2. If all terms of the +** record are not-NULL then a check is done to determine if any row in the +** P1 index btree has a matching key prefix. If there are no matches, jump +** immediately to P2. If there is a match, fall through and leave the P1 +** cursor pointing to the matching row. +** +** This opcode is similar to OP_NotFound with the exceptions that the +** branch is always taken if any part of the search key input is NULL. +** +** This operation leaves the cursor in a state where it cannot be +** advanced in either direction. In other words, the Next and Prev +** opcodes do not work after this operation. +** +** See also: NotFound, Found, NotExists +*/ +case OP_NoConflict: /* jump, in3 */ +case OP_NotFound: /* jump, in3 */ +case OP_Found: { /* jump, in3 */ + int alreadyExists; + int takeJump; + int ii; + VdbeCursor *pC; + int res; + char *pFree; + UnpackedRecord *pIdxKey; + UnpackedRecord r; + char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*4 + 7]; + +#ifdef SQLITE_TEST + if( pOp->opcode!=OP_NoConflict ) sqlite3_found_count++; +#endif + + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p4type==P4_INT32 ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); +#ifdef SQLITE_DEBUG + pC->seekOp = pOp->opcode; +#endif + pIn3 = &aMem[pOp->p3]; + assert( pC->pCursor!=0 ); + assert( pC->isTable==0 ); + pFree = 0; + if( pOp->p4.i>0 ){ + r.pKeyInfo = pC->pKeyInfo; + r.nField = (u16)pOp->p4.i; + r.aMem = pIn3; + for(ii=0; iip3+ii, &r.aMem[ii]); +#endif + } + pIdxKey = &r; + }else{ + pIdxKey = sqlite3VdbeAllocUnpackedRecord( + pC->pKeyInfo, aTempRec, sizeof(aTempRec), &pFree + ); + if( pIdxKey==0 ) goto no_mem; + assert( pIn3->flags & MEM_Blob ); + ExpandBlob(pIn3); + sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey); + } + pIdxKey->default_rc = 0; + takeJump = 0; + if( pOp->opcode==OP_NoConflict ){ + /* For the OP_NoConflict opcode, take the jump if any of the + ** input fields are NULL, since any key with a NULL will not + ** conflict */ + for(ii=0; iinField; ii++){ + if( pIdxKey->aMem[ii].flags & MEM_Null ){ + takeJump = 1; + break; + } + } + } + rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, pIdxKey, 0, 0, &res); + sqlite3DbFree(db, pFree); + if( rc!=SQLITE_OK ){ + break; + } + pC->seekResult = res; + alreadyExists = (res==0); + pC->nullRow = 1-alreadyExists; + pC->deferredMoveto = 0; + pC->cacheStatus = CACHE_STALE; + if( pOp->opcode==OP_Found ){ + VdbeBranchTaken(alreadyExists!=0,2); + if( alreadyExists ) goto jump_to_p2; + }else{ + VdbeBranchTaken(takeJump||alreadyExists==0,2); + if( takeJump || !alreadyExists ) goto jump_to_p2; + } + break; +} + +/* Opcode: NotExists P1 P2 P3 * * +** Synopsis: intkey=r[P3] +** +** P1 is the index of a cursor open on an SQL table btree (with integer +** keys). P3 is an integer rowid. If P1 does not contain a record with +** rowid P3 then jump immediately to P2. If P1 does contain a record +** with rowid P3 then leave the cursor pointing at that record and fall +** through to the next instruction. +** +** The OP_NotFound opcode performs the same operation on index btrees +** (with arbitrary multi-value keys). +** +** This opcode leaves the cursor in a state where it cannot be advanced +** in either direction. In other words, the Next and Prev opcodes will +** not work following this opcode. +** +** See also: Found, NotFound, NoConflict +*/ +case OP_NotExists: { /* jump, in3 */ + VdbeCursor *pC; + BtCursor *pCrsr; + int res; + u64 iKey; + + pIn3 = &aMem[pOp->p3]; + assert( pIn3->flags & MEM_Int ); + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); +#ifdef SQLITE_DEBUG + pC->seekOp = 0; +#endif + assert( pC->isTable ); + assert( pC->pseudoTableReg==0 ); + pCrsr = pC->pCursor; + assert( pCrsr!=0 ); + res = 0; + iKey = pIn3->u.i; + rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res); + pC->movetoTarget = iKey; /* Used by OP_Delete */ + pC->nullRow = 0; + pC->cacheStatus = CACHE_STALE; + pC->deferredMoveto = 0; + VdbeBranchTaken(res!=0,2); + pC->seekResult = res; + if( res!=0 ) goto jump_to_p2; + break; +} + +/* Opcode: Sequence P1 P2 * * * +** Synopsis: r[P2]=cursor[P1].ctr++ +** +** Find the next available sequence number for cursor P1. +** Write the sequence number into register P2. +** The sequence number on the cursor is incremented after this +** instruction. +*/ +case OP_Sequence: { /* out2 */ + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( p->apCsr[pOp->p1]!=0 ); + pOut = out2Prerelease(p, pOp); + pOut->u.i = p->apCsr[pOp->p1]->seqCount++; + break; +} + + +/* Opcode: NewRowid P1 P2 P3 * * +** Synopsis: r[P2]=rowid +** +** 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 written +** written to register P2. +** +** If P3>0 then P3 is a register in the root frame of this VDBE 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, +** an SQLITE_FULL error is generated. The P3 register is updated with the ' +** generated record number. This P3 mechanism is used to help implement the +** AUTOINCREMENT feature. +*/ +case OP_NewRowid: { /* out2 */ + i64 v; /* The new rowid */ + VdbeCursor *pC; /* Cursor of table to get the new rowid */ + int res; /* Result of an sqlite3BtreeLast() */ + int cnt; /* Counter to limit the number of searches */ + Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ + VdbeFrame *pFrame; /* Root frame of VDBE */ + + v = 0; + res = 0; + pOut = out2Prerelease(p, pOp); + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + if( NEVER(pC->pCursor==0) ){ + /* The zero initialization above is all that is needed */ + }else{ + /* The next rowid or record number (different terms for the same + ** thing) is obtained in a two-step algorithm. + ** + ** First we attempt to find the largest existing rowid and add one + ** to that. But if the largest existing rowid is already the maximum + ** positive integer, we have to fall through to the second + ** probabilistic algorithm + ** + ** The second algorithm is to select a rowid at random and see if + ** it already exists in the table. If it does not exist, we have + ** succeeded. If the random rowid does exist, we select a new one + ** and try again, up to 100 times. + */ + assert( pC->isTable ); + +#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 (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff ) +#endif + + if( !pC->useRandomRowid ){ + rc = sqlite3BtreeLast(pC->pCursor, &res); + if( rc!=SQLITE_OK ){ + goto abort_due_to_error; + } + if( res ){ + v = 1; /* IMP: R-61914-48074 */ + }else{ + assert( sqlite3BtreeCursorIsValid(pC->pCursor) ); + rc = sqlite3BtreeKeySize(pC->pCursor, &v); + assert( rc==SQLITE_OK ); /* Cannot fail following BtreeLast() */ + if( v>=MAX_ROWID ){ + pC->useRandomRowid = 1; + }else{ + v++; /* IMP: R-29538-34987 */ + } + } + } + +#ifndef SQLITE_OMIT_AUTOINCREMENT + if( pOp->p3 ){ + /* Assert that P3 is a valid memory cell. */ + assert( pOp->p3>0 ); + if( p->pFrame ){ + for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); + /* Assert that P3 is a valid memory cell. */ + assert( pOp->p3<=pFrame->nMem ); + pMem = &pFrame->aMem[pOp->p3]; + }else{ + /* Assert that P3 is a valid memory cell. */ + assert( pOp->p3<=(p->nMem-p->nCursor) ); + pMem = &aMem[pOp->p3]; + memAboutToChange(p, pMem); + } + assert( memIsValid(pMem) ); + + REGISTER_TRACE(pOp->p3, pMem); + sqlite3VdbeMemIntegerify(pMem); + assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ + if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){ + rc = SQLITE_FULL; /* IMP: R-12275-61338 */ + goto abort_due_to_error; + } + if( vu.i+1 ){ + v = pMem->u.i + 1; + } + pMem->u.i = v; + } +#endif + if( pC->useRandomRowid ){ + /* IMPLEMENTATION-OF: R-07677-41881 If the largest ROWID is equal to the + ** largest possible integer (9223372036854775807) then the database + ** engine starts picking positive candidate ROWIDs at random until + ** it finds one that is not previously used. */ + assert( pOp->p3==0 ); /* We cannot be in random rowid mode if this is + ** an AUTOINCREMENT table. */ + cnt = 0; + do{ + sqlite3_randomness(sizeof(v), &v); + v &= (MAX_ROWID>>1); v++; /* Ensure that v is greater than zero */ + }while( ((rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)v, + 0, &res))==SQLITE_OK) + && (res==0) + && (++cnt<100)); + if( rc==SQLITE_OK && res==0 ){ + rc = SQLITE_FULL; /* IMP: R-38219-53002 */ + goto abort_due_to_error; + } + assert( v>0 ); /* EV: R-40812-03570 */ + } + pC->deferredMoveto = 0; + pC->cacheStatus = CACHE_STALE; + } + pOut->u.i = v; + break; +} + +/* Opcode: Insert P1 P2 P3 P4 P5 +** Synopsis: intkey=r[P3] data=r[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 MEM_Blob stored in register +** number P2. The key is stored in register P3. The key must +** be a MEM_Int. +** +** If the OPFLAG_NCHANGE flag of P5 is set, then the row change count is +** incremented (otherwise not). If the OPFLAG_LASTROWID flag of P5 is set, +** then rowid is stored for subsequent return by the +** sqlite3_last_insert_rowid() function (otherwise it is unmodified). +** +** If the OPFLAG_USESEEKRESULT flag of P5 is set and if the result of +** the last seek operation (OP_NotExists) was a success, then this +** operation will not attempt to find the appropriate row before doing +** the insert but will instead overwrite the row that the cursor is +** currently pointing to. Presumably, the prior OP_NotExists opcode +** has already positioned the cursor correctly. This is an optimization +** that boosts performance by avoiding redundant seeks. +** +** If the OPFLAG_ISUPDATE flag is set, then this opcode is part of an +** UPDATE operation. Otherwise (if the flag is clear) then this opcode +** is part of an INSERT operation. The difference is only important to +** the update hook. +** +** Parameter P4 may point to a string containing the table-name, or +** may be NULL. If it is not NULL, then the update-hook +** (sqlite3.xUpdateCallback) is invoked following a successful insert. +** +** (WARNING/TODO: If P1 is a pseudo-cursor and P2 is dynamically +** allocated, then ownership of P2 is transferred to the pseudo-cursor +** and register P2 becomes ephemeral. If the cursor is changed, the +** value of register P2 will then change. Make sure this does not +** cause any problems.) +** +** This instruction only works on tables. The equivalent instruction +** for indices is OP_IdxInsert. +*/ +/* Opcode: InsertInt P1 P2 P3 P4 P5 +** Synopsis: intkey=P3 data=r[P2] +** +** This works exactly like OP_Insert except that the key is the +** integer value P3, not the value of the integer stored in register P3. +*/ +case OP_Insert: +case OP_InsertInt: { + Mem *pData; /* MEM cell holding data for the record to be inserted */ + Mem *pKey; /* MEM cell holding key for the record */ + i64 iKey; /* The integer ROWID or key for the record to be inserted */ + VdbeCursor *pC; /* Cursor to table into which insert is written */ + int nZero; /* Number of zero-bytes to append */ + int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ + const char *zDb; /* database name - used by the update hook */ + const char *zTbl; /* Table name - used by the opdate hook */ + int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ + + pData = &aMem[pOp->p2]; + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( memIsValid(pData) ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->pCursor!=0 ); + assert( pC->pseudoTableReg==0 ); + assert( pC->isTable ); + REGISTER_TRACE(pOp->p2, pData); + + if( pOp->opcode==OP_Insert ){ + pKey = &aMem[pOp->p3]; + assert( pKey->flags & MEM_Int ); + assert( memIsValid(pKey) ); + REGISTER_TRACE(pOp->p3, pKey); + iKey = pKey->u.i; + }else{ + assert( pOp->opcode==OP_InsertInt ); + iKey = pOp->p3; + } + + if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; + if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = iKey; + if( pData->flags & MEM_Null ){ + pData->z = 0; + pData->n = 0; + }else{ + assert( pData->flags & (MEM_Blob|MEM_Str) ); + } + seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0); + if( pData->flags & MEM_Zero ){ + nZero = pData->u.nZero; + }else{ + nZero = 0; + } + rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey, + pData->z, pData->n, nZero, + (pOp->p5 & OPFLAG_APPEND)!=0, seekResult + ); + pC->deferredMoveto = 0; + pC->cacheStatus = CACHE_STALE; + + /* Invoke the update-hook if required. */ + if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ + zDb = db->aDb[pC->iDb].zName; + zTbl = pOp->p4.z; + op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); + assert( pC->isTable ); + db->xUpdateCallback(db->pUpdateArg, op, zDb, zTbl, iKey); + assert( pC->iDb>=0 ); + } + break; +} + +/* Opcode: Delete P1 P2 * P4 * +** +** 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 a Next loop. +** +** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is +** incremented (otherwise not). +** +** P1 must not be pseudo-table. It has to be a real table with +** multiple rows. +** +** If P4 is not NULL, then it is the name of the table that P1 is +** pointing to. The update hook will be invoked, if it exists. +** If P4 is not NULL then the P1 cursor must have been positioned +** using OP_NotFound prior to invoking this opcode. +*/ +case OP_Delete: { + VdbeCursor *pC; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ + assert( pC->deferredMoveto==0 ); + +#ifdef SQLITE_DEBUG + /* The seek operation that positioned the cursor prior to OP_Delete will + ** have also set the pC->movetoTarget field to the rowid of the row that + ** is being deleted */ + if( pOp->p4.z && pC->isTable ){ + i64 iKey = 0; + sqlite3BtreeKeySize(pC->pCursor, &iKey); + assert( pC->movetoTarget==iKey ); + } +#endif + + rc = sqlite3BtreeDelete(pC->pCursor); + pC->cacheStatus = CACHE_STALE; + + /* Invoke the update-hook if required. */ + if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && pC->isTable ){ + db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, + db->aDb[pC->iDb].zName, pOp->p4.z, pC->movetoTarget); + assert( pC->iDb>=0 ); + } + if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++; + break; +} +/* Opcode: ResetCount * * * * * +** +** The value of the change counter is copied to the database handle +** change counter (returned by subsequent calls to sqlite3_changes()). +** Then the VMs internal change counter resets to 0. +** This is used by trigger programs. +*/ +case OP_ResetCount: { + sqlite3VdbeSetChanges(db, p->nChange); + p->nChange = 0; + break; +} + +/* Opcode: SorterCompare P1 P2 P3 P4 +** Synopsis: if key(P1)!=trim(r[P3],P4) goto P2 +** +** P1 is a sorter cursor. This instruction compares a prefix of the +** record blob in register P3 against a prefix of the entry that +** the sorter cursor currently points to. Only the first P4 fields +** of r[P3] and the sorter record are compared. +** +** If either P3 or the sorter contains a NULL in one of their significant +** fields (not counting the P4 fields at the end which are ignored) then +** the comparison is assumed to be equal. +** +** Fall through to next instruction if the two records compare equal to +** each other. Jump to P2 if they are different. +*/ +case OP_SorterCompare: { + VdbeCursor *pC; + int res; + int nKeyCol; + + pC = p->apCsr[pOp->p1]; + assert( isSorter(pC) ); + assert( pOp->p4type==P4_INT32 ); + pIn3 = &aMem[pOp->p3]; + nKeyCol = pOp->p4.i; + res = 0; + rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res); + VdbeBranchTaken(res!=0,2); + if( res ) goto jump_to_p2; + break; +}; + +/* Opcode: SorterData P1 P2 P3 * * +** Synopsis: r[P2]=data +** +** Write into register P2 the current sorter data for sorter cursor P1. +** Then clear the column header cache on cursor P3. +** +** This opcode is normally use to move a record out of the sorter and into +** a register that is the source for a pseudo-table cursor created using +** OpenPseudo. That pseudo-table cursor is the one that is identified by +** parameter P3. Clearing the P3 column cache as part of this opcode saves +** us from having to issue a separate NullRow instruction to clear that cache. +*/ +case OP_SorterData: { + VdbeCursor *pC; + + pOut = &aMem[pOp->p2]; + pC = p->apCsr[pOp->p1]; + assert( isSorter(pC) ); + rc = sqlite3VdbeSorterRowkey(pC, pOut); + assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) ); + assert( pOp->p1>=0 && pOp->p1nCursor ); + p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE; + break; +} + +/* Opcode: RowData P1 P2 * * * +** Synopsis: r[P2]=data +** +** Write into register P2 the complete row data for cursor P1. +** There is no interpretation of the data. +** It is just copied onto the P2 register exactly as +** it is found in the database file. +** +** If the P1 cursor must be pointing to a valid row (not a NULL row) +** of a real table, not a pseudo-table. +*/ +/* Opcode: RowKey P1 P2 * * * +** Synopsis: r[P2]=key +** +** Write into register P2 the complete row key for cursor P1. +** There is no interpretation of the data. +** The key is copied onto the P2 register exactly as +** it is found in the database file. +** +** If the P1 cursor must be pointing to a valid row (not a NULL row) +** of a real table, not a pseudo-table. +*/ +case OP_RowKey: +case OP_RowData: { + VdbeCursor *pC; + BtCursor *pCrsr; + u32 n; + i64 n64; + + pOut = &aMem[pOp->p2]; + memAboutToChange(p, pOut); + + /* Note that RowKey and RowData are really exactly the same instruction */ + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( isSorter(pC)==0 ); + assert( pC->isTable || pOp->opcode!=OP_RowData ); + assert( pC->isTable==0 || pOp->opcode==OP_RowData ); + assert( pC!=0 ); + assert( pC->nullRow==0 ); + assert( pC->pseudoTableReg==0 ); + assert( pC->pCursor!=0 ); + pCrsr = pC->pCursor; + + /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or + ** OP_Rewind/Op_Next with no intervening instructions that might invalidate + ** the cursor. If this where not the case, on of the following assert()s + ** would fail. Should this ever change (because of changes in the code + ** generator) then the fix would be to insert a call to + ** sqlite3VdbeCursorMoveto(). + */ + assert( pC->deferredMoveto==0 ); + assert( sqlite3BtreeCursorIsValid(pCrsr) ); +#if 0 /* Not required due to the previous to assert() statements */ + rc = sqlite3VdbeCursorMoveto(pC); + if( rc!=SQLITE_OK ) goto abort_due_to_error; +#endif + + if( pC->isTable==0 ){ + assert( !pC->isTable ); + VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64); + assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ + if( n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + goto too_big; + } + n = (u32)n64; + }else{ + VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &n); + assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ + if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ + goto too_big; + } + } + testcase( n==0 ); + if( sqlite3VdbeMemClearAndResize(pOut, MAX(n,32)) ){ + goto no_mem; + } + pOut->n = n; + MemSetTypeFlag(pOut, MEM_Blob); + if( pC->isTable==0 ){ + rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z); + }else{ + rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z); + } + pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ + UPDATE_MAX_BLOBSIZE(pOut); + REGISTER_TRACE(pOp->p2, pOut); + break; +} + +/* Opcode: Rowid P1 P2 * * * +** Synopsis: r[P2]=rowid +** +** Store in register P2 an integer which is the key of the table entry that +** P1 is currently point to. +** +** P1 can be either an ordinary table or a virtual table. There used to +** be a separate OP_VRowid opcode for use with virtual tables, but this +** one opcode now works for both table types. +*/ +case OP_Rowid: { /* out2 */ + VdbeCursor *pC; + i64 v; + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; + + pOut = out2Prerelease(p, pOp); + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->pseudoTableReg==0 || pC->nullRow ); + if( pC->nullRow ){ + pOut->flags = MEM_Null; + break; + }else if( pC->deferredMoveto ){ + v = pC->movetoTarget; +#ifndef SQLITE_OMIT_VIRTUALTABLE + }else if( pC->pVtabCursor ){ + pVtab = pC->pVtabCursor->pVtab; + pModule = pVtab->pModule; + assert( pModule->xRowid ); + rc = pModule->xRowid(pC->pVtabCursor, &v); + sqlite3VtabImportErrmsg(p, pVtab); +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + }else{ + assert( pC->pCursor!=0 ); + rc = sqlite3VdbeCursorRestore(pC); + if( rc ) goto abort_due_to_error; + if( pC->nullRow ){ + pOut->flags = MEM_Null; + break; + } + rc = sqlite3BtreeKeySize(pC->pCursor, &v); + assert( rc==SQLITE_OK ); /* Always so because of CursorRestore() above */ + } + pOut->u.i = v; + 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 +** write a NULL. +*/ +case OP_NullRow: { + VdbeCursor *pC; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + pC->nullRow = 1; + pC->cacheStatus = CACHE_STALE; + if( pC->pCursor ){ + sqlite3BtreeClearCursor(pC->pCursor); + } + break; +} + +/* Opcode: Last P1 P2 P3 * * +** +** The next use of the Rowid or Column or Prev 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. +** +** This opcode leaves the cursor configured to move in reverse order, +** from the end toward the beginning. In other words, the cursor is +** configured to use Prev, not Next. +*/ +case OP_Last: { /* jump */ + VdbeCursor *pC; + BtCursor *pCrsr; + int res; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + pCrsr = pC->pCursor; + res = 0; + assert( pCrsr!=0 ); + rc = sqlite3BtreeLast(pCrsr, &res); + pC->nullRow = (u8)res; + pC->deferredMoveto = 0; + pC->cacheStatus = CACHE_STALE; + pC->seekResult = pOp->p3; +#ifdef SQLITE_DEBUG + pC->seekOp = OP_Last; +#endif + if( pOp->p2>0 ){ + VdbeBranchTaken(res!=0,2); + if( res ) goto jump_to_p2; + } + 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_SorterSort: /* jump */ +case OP_Sort: { /* jump */ +#ifdef SQLITE_TEST + sqlite3_sort_count++; + sqlite3_search_count--; +#endif + p->aCounter[SQLITE_STMTSTATUS_SORT]++; + /* 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, jump immediately to P2. +** If the table or index is not empty, fall through to the following +** instruction. +** +** This opcode leaves the cursor configured to move in forward order, +** from the beginning toward the end. In other words, the cursor is +** configured to use Next, not Prev. +*/ +case OP_Rewind: { /* jump */ + VdbeCursor *pC; + BtCursor *pCrsr; + int res; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) ); + res = 1; +#ifdef SQLITE_DEBUG + pC->seekOp = OP_Rewind; +#endif + if( isSorter(pC) ){ + rc = sqlite3VdbeSorterRewind(pC, &res); + }else{ + pCrsr = pC->pCursor; + assert( pCrsr ); + rc = sqlite3BtreeFirst(pCrsr, &res); + pC->deferredMoveto = 0; + pC->cacheStatus = CACHE_STALE; + } + pC->nullRow = (u8)res; + assert( pOp->p2>0 && pOp->p2nOp ); + VdbeBranchTaken(res!=0,2); + if( res ) goto jump_to_p2; + break; +} + +/* Opcode: Next P1 P2 P3 P4 P5 +** +** Advance cursor P1 so that it points to the next key/data pair in its +** table or index. If there are no more key/value pairs then fall through +** to the following instruction. But if the cursor advance was successful, +** jump immediately to P2. +** +** The Next opcode is only valid following an SeekGT, SeekGE, or +** OP_Rewind opcode used to position the cursor. Next is not allowed +** to follow SeekLT, SeekLE, or OP_Last. +** +** The P1 cursor must be for a real table, not a pseudo-table. P1 must have +** been opened prior to this opcode or the program will segfault. +** +** The P3 value is a hint to the btree implementation. If P3==1, that +** means P1 is an SQL index and that this instruction could have been +** omitted if that index had been unique. P3 is usually 0. P3 is +** always either 0 or 1. +** +** P4 is always of type P4_ADVANCE. The function pointer points to +** sqlite3BtreeNext(). +** +** If P5 is positive and the jump is taken, then event counter +** number P5-1 in the prepared statement is incremented. +** +** See also: Prev, NextIfOpen +*/ +/* Opcode: NextIfOpen P1 P2 P3 P4 P5 +** +** This opcode works just like Next except that if cursor P1 is not +** open it behaves a no-op. +*/ +/* Opcode: Prev P1 P2 P3 P4 P5 +** +** 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. +** +** +** The Prev opcode is only valid following an SeekLT, SeekLE, or +** OP_Last opcode used to position the cursor. Prev is not allowed +** to follow SeekGT, SeekGE, or OP_Rewind. +** +** The P1 cursor must be for a real table, not a pseudo-table. If P1 is +** not open then the behavior is undefined. +** +** The P3 value is a hint to the btree implementation. If P3==1, that +** means P1 is an SQL index and that this instruction could have been +** omitted if that index had been unique. P3 is usually 0. P3 is +** always either 0 or 1. +** +** P4 is always of type P4_ADVANCE. The function pointer points to +** sqlite3BtreePrevious(). +** +** If P5 is positive and the jump is taken, then event counter +** number P5-1 in the prepared statement is incremented. +*/ +/* Opcode: PrevIfOpen P1 P2 P3 P4 P5 +** +** This opcode works just like Prev except that if cursor P1 is not +** open it behaves a no-op. +*/ +case OP_SorterNext: { /* jump */ + VdbeCursor *pC; + int res; + + pC = p->apCsr[pOp->p1]; + assert( isSorter(pC) ); + res = 0; + rc = sqlite3VdbeSorterNext(db, pC, &res); + goto next_tail; +case OP_PrevIfOpen: /* jump */ +case OP_NextIfOpen: /* jump */ + if( p->apCsr[pOp->p1]==0 ) break; + /* Fall through */ +case OP_Prev: /* jump */ +case OP_Next: /* jump */ + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p5aCounter) ); + pC = p->apCsr[pOp->p1]; + res = pOp->p3; + assert( pC!=0 ); + assert( pC->deferredMoveto==0 ); + assert( pC->pCursor ); + assert( res==0 || (res==1 && pC->isTable==0) ); + testcase( res==1 ); + assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); + assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); + assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext ); + assert( pOp->opcode!=OP_PrevIfOpen || pOp->p4.xAdvance==sqlite3BtreePrevious); + + /* The Next opcode is only used after SeekGT, SeekGE, and Rewind. + ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */ + assert( pOp->opcode!=OP_Next || pOp->opcode!=OP_NextIfOpen + || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE + || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found); + assert( pOp->opcode!=OP_Prev || pOp->opcode!=OP_PrevIfOpen + || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE + || pC->seekOp==OP_Last ); + + rc = pOp->p4.xAdvance(pC->pCursor, &res); +next_tail: + pC->cacheStatus = CACHE_STALE; + VdbeBranchTaken(res==0,2); + if( res==0 ){ + pC->nullRow = 0; + p->aCounter[pOp->p5]++; +#ifdef SQLITE_TEST + sqlite3_search_count++; +#endif + goto jump_to_p2_and_check_for_interrupt; + }else{ + pC->nullRow = 1; + } + goto check_for_interrupt; +} + +/* Opcode: IdxInsert P1 P2 P3 * P5 +** Synopsis: key=r[P2] +** +** Register P2 holds an SQL index key made using the +** MakeRecord instructions. This opcode writes that key +** into the index P1. Data for the entry is nil. +** +** P3 is a flag that provides a hint to the b-tree layer that this +** insert is likely to be an append. +** +** If P5 has the OPFLAG_NCHANGE bit set, then the change counter is +** incremented by this instruction. If the OPFLAG_NCHANGE bit is clear, +** then the change counter is unchanged. +** +** If P5 has the OPFLAG_USESEEKRESULT bit set, then the cursor must have +** just done a seek to the spot where the new entry is to be inserted. +** This flag avoids doing an extra seek. +** +** This instruction only works for indices. The equivalent instruction +** for tables is OP_Insert. +*/ +case OP_SorterInsert: /* in2 */ +case OP_IdxInsert: { /* in2 */ + VdbeCursor *pC; + BtCursor *pCrsr; + int nKey; + const char *zKey; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( isSorter(pC)==(pOp->opcode==OP_SorterInsert) ); + pIn2 = &aMem[pOp->p2]; + assert( pIn2->flags & MEM_Blob ); + pCrsr = pC->pCursor; + if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; + assert( pCrsr!=0 ); + assert( pC->isTable==0 ); + rc = ExpandBlob(pIn2); + if( rc==SQLITE_OK ){ + if( isSorter(pC) ){ + rc = sqlite3VdbeSorterWrite(pC, pIn2); + }else{ + nKey = pIn2->n; + zKey = pIn2->z; + rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0, 0, pOp->p3, + ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) + ); + assert( pC->deferredMoveto==0 ); + pC->cacheStatus = CACHE_STALE; + } + } + break; +} + +/* Opcode: IdxDelete P1 P2 P3 * * +** Synopsis: key=r[P2@P3] +** +** The content of P3 registers starting at register P2 form +** an unpacked index key. This opcode removes that entry from the +** index opened by cursor P1. +*/ +case OP_IdxDelete: { + VdbeCursor *pC; + BtCursor *pCrsr; + int res; + UnpackedRecord r; + + assert( pOp->p3>0 ); + assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem-p->nCursor)+1 ); + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + pCrsr = pC->pCursor; + assert( pCrsr!=0 ); + assert( pOp->p5==0 ); + r.pKeyInfo = pC->pKeyInfo; + r.nField = (u16)pOp->p3; + r.default_rc = 0; + r.aMem = &aMem[pOp->p2]; +#ifdef SQLITE_DEBUG + { int i; for(i=0; ideferredMoveto==0 ); + pC->cacheStatus = CACHE_STALE; + break; +} + +/* Opcode: IdxRowid P1 P2 * * * +** Synopsis: r[P2]=rowid +** +** Write into register P2 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, MakeRecord. +*/ +case OP_IdxRowid: { /* out2 */ + BtCursor *pCrsr; + VdbeCursor *pC; + i64 rowid; + + pOut = out2Prerelease(p, pOp); + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + pCrsr = pC->pCursor; + assert( pCrsr!=0 ); + pOut->flags = MEM_Null; + assert( pC->isTable==0 ); + assert( pC->deferredMoveto==0 ); + + /* sqlite3VbeCursorRestore() can only fail if the record has been deleted + ** out from under the cursor. That will never happend for an IdxRowid + ** opcode, hence the NEVER() arround the check of the return value. + */ + rc = sqlite3VdbeCursorRestore(pC); + if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; + + if( !pC->nullRow ){ + rowid = 0; /* Not needed. Only used to silence a warning. */ + rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid); + if( rc!=SQLITE_OK ){ + goto abort_due_to_error; + } + pOut->u.i = rowid; + pOut->flags = MEM_Int; + } + break; +} + +/* Opcode: IdxGE P1 P2 P3 P4 P5 +** Synopsis: key=r[P3@P4] +** +** The P4 register values beginning with P3 form an unpacked index +** key that omits the PRIMARY KEY. Compare this key value against the index +** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID +** fields at the end. +** +** If the P1 index entry is greater than or equal to the key value +** then jump to P2. Otherwise fall through to the next instruction. +*/ +/* Opcode: IdxGT P1 P2 P3 P4 P5 +** Synopsis: key=r[P3@P4] +** +** The P4 register values beginning with P3 form an unpacked index +** key that omits the PRIMARY KEY. Compare this key value against the index +** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID +** fields at the end. +** +** If the P1 index entry is greater than the key value +** then jump to P2. Otherwise fall through to the next instruction. +*/ +/* Opcode: IdxLT P1 P2 P3 P4 P5 +** Synopsis: key=r[P3@P4] +** +** The P4 register values beginning with P3 form an unpacked index +** key that omits the PRIMARY KEY or ROWID. Compare this key value against +** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or +** ROWID on the P1 index. +** +** If the P1 index entry is less than the key value then jump to P2. +** Otherwise fall through to the next instruction. +*/ +/* Opcode: IdxLE P1 P2 P3 P4 P5 +** Synopsis: key=r[P3@P4] +** +** The P4 register values beginning with P3 form an unpacked index +** key that omits the PRIMARY KEY or ROWID. Compare this key value against +** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or +** ROWID on the P1 index. +** +** If the P1 index entry is less than or equal to the key value then jump +** to P2. Otherwise fall through to the next instruction. +*/ +case OP_IdxLE: /* jump */ +case OP_IdxGT: /* jump */ +case OP_IdxLT: /* jump */ +case OP_IdxGE: { /* jump */ + VdbeCursor *pC; + int res; + UnpackedRecord r; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->isOrdered ); + assert( pC->pCursor!=0); + assert( pC->deferredMoveto==0 ); + assert( pOp->p5==0 || pOp->p5==1 ); + assert( pOp->p4type==P4_INT32 ); + r.pKeyInfo = pC->pKeyInfo; + r.nField = (u16)pOp->p4.i; + if( pOp->opcodeopcode==OP_IdxLE || pOp->opcode==OP_IdxGT ); + r.default_rc = -1; + }else{ + assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxLT ); + r.default_rc = 0; + } + r.aMem = &aMem[pOp->p3]; +#ifdef SQLITE_DEBUG + { int i; for(i=0; iopcode&1)==(OP_IdxLT&1) ){ + assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxLT ); + res = -res; + }else{ + assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxGT ); + res++; + } + VdbeBranchTaken(res>0,2); + if( res>0 ) goto jump_to_p2; + break; +} + +/* Opcode: Destroy P1 P2 P3 * * +** +** Delete an entire database table or index whose root page in the database +** file is given by P1. +** +** The table being destroyed is in the main database file if P3==0. If +** P3==1 then the table to be clear is in the auxiliary database file +** that is used to store tables create using CREATE TEMPORARY TABLE. +** +** If AUTOVACUUM is enabled then it is possible that another root page +** might be moved into the newly deleted root page in order to keep all +** root pages contiguous at the beginning of the database. The former +** value of the root page that moved - its value before the move occurred - +** is stored in register P2. If no page +** movement was required (because the table being dropped was already +** the last one in the database) then a zero is stored in register P2. +** If AUTOVACUUM is disabled then a zero is stored in register P2. +** +** See also: Clear +*/ +case OP_Destroy: { /* out2 */ + int iMoved; + int iDb; + + assert( p->readOnly==0 ); + pOut = out2Prerelease(p, pOp); + pOut->flags = MEM_Null; + if( db->nVdbeRead > db->nVDestroy+1 ){ + rc = SQLITE_LOCKED; + p->errorAction = OE_Abort; + }else{ + iDb = pOp->p3; + assert( DbMaskTest(p->btreeMask, iDb) ); + iMoved = 0; /* Not needed. Only to silence a warning. */ + rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved); + pOut->flags = MEM_Int; + pOut->u.i = iMoved; +#ifndef SQLITE_OMIT_AUTOVACUUM + if( rc==SQLITE_OK && iMoved!=0 ){ + sqlite3RootPageMoved(db, iDb, iMoved, pOp->p1); + /* All OP_Destroy operations occur on the same btree */ + assert( resetSchemaOnFault==0 || resetSchemaOnFault==iDb+1 ); + resetSchemaOnFault = iDb+1; + } +#endif + } + break; +} + +/* Opcode: Clear P1 P2 P3 +** +** Delete all contents of the database table or index whose root page +** in the database file is given by P1. But, unlike Destroy, do not +** remove the table or index from the database file. +** +** 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. +** +** If the P3 value is non-zero, then the table referred to must be an +** intkey table (an SQL table, not an index). In this case the row change +** count is incremented by the number of rows in the table being cleared. +** If P3 is greater than zero, then the value stored in register P3 is +** also incremented by the number of rows in the table being cleared. +** +** See also: Destroy +*/ +case OP_Clear: { + int nChange; + + nChange = 0; + assert( p->readOnly==0 ); + assert( DbMaskTest(p->btreeMask, pOp->p2) ); + rc = sqlite3BtreeClearTable( + db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0) + ); + if( pOp->p3 ){ + p->nChange += nChange; + if( pOp->p3>0 ){ + assert( memIsValid(&aMem[pOp->p3]) ); + memAboutToChange(p, &aMem[pOp->p3]); + aMem[pOp->p3].u.i += nChange; + } + } + break; +} + +/* Opcode: ResetSorter P1 * * * * +** +** Delete all contents from the ephemeral table or sorter +** that is open on cursor P1. +** +** This opcode only works for cursors used for sorting and +** opened with OP_OpenEphemeral or OP_SorterOpen. +*/ +case OP_ResetSorter: { + VdbeCursor *pC; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + if( pC->pSorter ){ + sqlite3VdbeSorterReset(db, pC->pSorter); + }else{ + assert( pC->isEphemeral ); + rc = sqlite3BtreeClearTableOfCursor(pC->pCursor); + } + break; +} + +/* Opcode: CreateTable P1 P2 * * * +** Synopsis: r[P2]=root iDb=P1 +** +** Allocate a new table in the main database file if P1==0 or in the +** auxiliary database file if P1==1 or in an attached database if +** P1>1. Write the root page number of the new table into +** register P2 +** +** The difference between a table and an index is this: A table must +** have a 4-byte integer key and can have arbitrary data. An index +** has an arbitrary key but no data. +** +** See also: CreateIndex +*/ +/* Opcode: CreateIndex P1 P2 * * * +** Synopsis: r[P2]=root iDb=P1 +** +** Allocate a new index in the main database file if P1==0 or in the +** auxiliary database file if P1==1 or in an attached database if +** P1>1. Write the root page number of the new table into +** register P2. +** +** See documentation on OP_CreateTable for additional information. +*/ +case OP_CreateIndex: /* out2 */ +case OP_CreateTable: { /* out2 */ + int pgno; + int flags; + Db *pDb; + + pOut = out2Prerelease(p, pOp); + pgno = 0; + assert( pOp->p1>=0 && pOp->p1nDb ); + assert( DbMaskTest(p->btreeMask, pOp->p1) ); + assert( p->readOnly==0 ); + pDb = &db->aDb[pOp->p1]; + assert( pDb->pBt!=0 ); + if( pOp->opcode==OP_CreateTable ){ + /* flags = BTREE_INTKEY; */ + flags = BTREE_INTKEY; + }else{ + flags = BTREE_BLOBKEY; + } + rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags); + pOut->u.i = pgno; + break; +} + +/* Opcode: ParseSchema P1 * * P4 * +** +** Read and parse all entries from the SQLITE_MASTER table of database P1 +** that match the WHERE clause P4. +** +** This opcode invokes the parser to create a new virtual machine, +** then runs the new virtual machine. It is thus a re-entrant opcode. +*/ +case OP_ParseSchema: { + int iDb; + const char *zMaster; + char *zSql; + InitData initData; + + /* Any prepared statement that invokes this opcode will hold mutexes + ** on every btree. This is a prerequisite for invoking + ** sqlite3InitCallback(). + */ +#ifdef SQLITE_DEBUG + for(iDb=0; iDbnDb; iDb++){ + assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); + } +#endif + + iDb = pOp->p1; + assert( iDb>=0 && iDbnDb ); + assert( DbHasProperty(db, iDb, DB_SchemaLoaded) ); + /* Used to be a conditional */ { + zMaster = SCHEMA_TABLE(iDb); + initData.db = db; + initData.iDb = pOp->p1; + initData.pzErrMsg = &p->zErrMsg; + zSql = sqlite3MPrintf(db, + "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid", + db->aDb[iDb].zName, zMaster, pOp->p4.z); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + assert( db->init.busy==0 ); + db->init.busy = 1; + initData.rc = SQLITE_OK; + assert( !db->mallocFailed ); + rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); + if( rc==SQLITE_OK ) rc = initData.rc; + sqlite3DbFree(db, zSql); + db->init.busy = 0; + } + } + if( rc ) sqlite3ResetAllSchemasOfConnection(db); + if( rc==SQLITE_NOMEM ){ + goto no_mem; + } + break; +} + +#if !defined(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: { + assert( pOp->p1>=0 && pOp->p1nDb ); + rc = sqlite3AnalysisLoad(db, pOp->p1); + break; +} +#endif /* !defined(SQLITE_OMIT_ANALYZE) */ + +/* Opcode: DropTable P1 * * P4 * +** +** Remove the internal (in-memory) data structures that describe +** the table named P4 in database P1. This is called after a table +** is dropped from disk (using the Destroy opcode) in order to keep +** the internal representation of the +** schema consistent with what is on disk. +*/ +case OP_DropTable: { + sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.z); + break; +} + +/* Opcode: DropIndex P1 * * P4 * +** +** Remove the internal (in-memory) data structures that describe +** the index named P4 in database P1. This is called after an index +** is dropped from disk (using the Destroy opcode) +** in order to keep the internal representation of the +** schema consistent with what is on disk. +*/ +case OP_DropIndex: { + sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.z); + break; +} + +/* Opcode: DropTrigger P1 * * P4 * +** +** Remove the internal (in-memory) data structures that describe +** the trigger named P4 in database P1. This is called after a trigger +** is dropped from disk (using the Destroy opcode) in order to keep +** the internal representation of the +** schema consistent with what is on disk. +*/ +case OP_DropTrigger: { + sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.z); + break; +} + + +#ifndef SQLITE_OMIT_INTEGRITY_CHECK +/* Opcode: IntegrityCk P1 P2 P3 * P5 +** +** Do an analysis of the currently open database. Store in +** register P1 the text of an error message describing any problems. +** If no problems are found, store a NULL in register P1. +** +** The register P3 contains the maximum number of allowed errors. +** At most reg(P3) errors will be reported. +** In other words, the analysis stops as soon as reg(P1) errors are +** seen. Reg(P1) is updated with the number of errors remaining. +** +** The root page numbers of all tables in the database are integer +** stored in reg(P1), reg(P1+1), reg(P1+2), .... There are P2 tables +** total. +** +** If P5 is not zero, the check is done on the auxiliary database +** file, not the main database file. +** +** This opcode is used to implement the integrity_check pragma. +*/ +case OP_IntegrityCk: { + int nRoot; /* Number of tables to check. (Number of root pages.) */ + int *aRoot; /* Array of rootpage numbers for tables to be checked */ + int j; /* Loop counter */ + int nErr; /* Number of errors reported */ + char *z; /* Text of the error report */ + Mem *pnErr; /* Register keeping track of errors remaining */ + + assert( p->bIsReader ); + nRoot = pOp->p2; + assert( nRoot>0 ); + aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(nRoot+1) ); + if( aRoot==0 ) goto no_mem; + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); + pnErr = &aMem[pOp->p3]; + assert( (pnErr->flags & MEM_Int)!=0 ); + assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 ); + pIn1 = &aMem[pOp->p1]; + for(j=0; jp5nDb ); + assert( DbMaskTest(p->btreeMask, pOp->p5) ); + z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot, + (int)pnErr->u.i, &nErr); + sqlite3DbFree(db, aRoot); + pnErr->u.i -= nErr; + sqlite3VdbeMemSetNull(pIn1); + if( nErr==0 ){ + assert( z==0 ); + }else if( z==0 ){ + goto no_mem; + }else{ + sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free); + } + UPDATE_MAX_BLOBSIZE(pIn1); + sqlite3VdbeChangeEncoding(pIn1, encoding); + break; +} +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +/* Opcode: RowSetAdd P1 P2 * * * +** Synopsis: rowset(P1)=r[P2] +** +** Insert the integer value held by register P2 into a boolean index +** held in register P1. +** +** An assertion fails if P2 is not an integer. +*/ +case OP_RowSetAdd: { /* in1, in2 */ + pIn1 = &aMem[pOp->p1]; + pIn2 = &aMem[pOp->p2]; + assert( (pIn2->flags & MEM_Int)!=0 ); + if( (pIn1->flags & MEM_RowSet)==0 ){ + sqlite3VdbeMemSetRowSet(pIn1); + if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem; + } + sqlite3RowSetInsert(pIn1->u.pRowSet, pIn2->u.i); + break; +} + +/* Opcode: RowSetRead P1 P2 P3 * * +** Synopsis: r[P3]=rowset(P1) +** +** Extract the smallest value from boolean index P1 and put that value into +** register P3. Or, if boolean index P1 is initially empty, leave P3 +** unchanged and jump to instruction P2. +*/ +case OP_RowSetRead: { /* jump, in1, out3 */ + i64 val; + + pIn1 = &aMem[pOp->p1]; + if( (pIn1->flags & MEM_RowSet)==0 + || sqlite3RowSetNext(pIn1->u.pRowSet, &val)==0 + ){ + /* The boolean index is empty */ + sqlite3VdbeMemSetNull(pIn1); + VdbeBranchTaken(1,2); + goto jump_to_p2_and_check_for_interrupt; + }else{ + /* A value was pulled from the index */ + VdbeBranchTaken(0,2); + sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val); + } + goto check_for_interrupt; +} + +/* Opcode: RowSetTest P1 P2 P3 P4 +** Synopsis: if r[P3] in rowset(P1) goto P2 +** +** Register P3 is assumed to hold a 64-bit integer value. If register P1 +** contains a RowSet object and that RowSet object contains +** the value held in P3, jump to register P2. Otherwise, insert the +** integer in P3 into the RowSet and continue on to the +** next opcode. +** +** The RowSet object is optimized for the case where successive sets +** of integers, where each set contains no duplicates. Each set +** of values is identified by a unique P4 value. The first set +** must have P4==0, the final set P4=-1. P4 must be either -1 or +** non-negative. For non-negative values of P4 only the lower 4 +** bits are significant. +** +** This allows optimizations: (a) when P4==0 there is no need to test +** the rowset object for P3, as it is guaranteed not to contain it, +** (b) when P4==-1 there is no need to insert the value, as it will +** never be tested for, and (c) when a value that is part of set X is +** inserted, there is no need to search to see if the same value was +** previously inserted as part of set X (only if it was previously +** inserted as part of some other set). +*/ +case OP_RowSetTest: { /* jump, in1, in3 */ + int iSet; + int exists; + + pIn1 = &aMem[pOp->p1]; + pIn3 = &aMem[pOp->p3]; + iSet = pOp->p4.i; + assert( pIn3->flags&MEM_Int ); + + /* If there is anything other than a rowset object in memory cell P1, + ** delete it now and initialize P1 with an empty rowset + */ + if( (pIn1->flags & MEM_RowSet)==0 ){ + sqlite3VdbeMemSetRowSet(pIn1); + if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem; + } + + assert( pOp->p4type==P4_INT32 ); + assert( iSet==-1 || iSet>=0 ); + if( iSet ){ + exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i); + VdbeBranchTaken(exists!=0,2); + if( exists ) goto jump_to_p2; + } + if( iSet>=0 ){ + sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i); + } + break; +} + + +#ifndef SQLITE_OMIT_TRIGGER + +/* Opcode: Program P1 P2 P3 P4 P5 +** +** Execute the trigger program passed as P4 (type P4_SUBPROGRAM). +** +** P1 contains the address of the memory cell that contains the first memory +** cell in an array of values used as arguments to the sub-program. P2 +** contains the address to jump to if the sub-program throws an IGNORE +** exception using the RAISE() function. Register P3 contains the address +** of a memory cell in this (the parent) VM that is used to allocate the +** memory required by the sub-vdbe at runtime. +** +** P4 is a pointer to the VM containing the trigger program. +** +** If P5 is non-zero, then recursive program invocation is enabled. +*/ +case OP_Program: { /* jump */ + int nMem; /* Number of memory registers for sub-program */ + int nByte; /* Bytes of runtime space required for sub-program */ + Mem *pRt; /* Register to allocate runtime space */ + Mem *pMem; /* Used to iterate through memory cells */ + Mem *pEnd; /* Last memory cell in new array */ + VdbeFrame *pFrame; /* New vdbe frame to execute in */ + SubProgram *pProgram; /* Sub-program to execute */ + void *t; /* Token identifying trigger */ + + pProgram = pOp->p4.pProgram; + pRt = &aMem[pOp->p3]; + assert( pProgram->nOp>0 ); + + /* If the p5 flag is clear, then recursive invocation of triggers is + ** disabled for backwards compatibility (p5 is set if this sub-program + ** is really a trigger, not a foreign key action, and the flag set + ** and cleared by the "PRAGMA recursive_triggers" command is clear). + ** + ** It is recursive invocation of triggers, at the SQL level, that is + ** disabled. In some cases a single trigger may generate more than one + ** SubProgram (if the trigger may be executed with more than one different + ** ON CONFLICT algorithm). SubProgram structures associated with a + ** single trigger all have the same value for the SubProgram.token + ** variable. */ + if( pOp->p5 ){ + t = pProgram->token; + for(pFrame=p->pFrame; pFrame && pFrame->token!=t; pFrame=pFrame->pParent); + if( pFrame ) break; + } + + if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){ + rc = SQLITE_ERROR; + sqlite3SetString(&p->zErrMsg, db, "too many levels of trigger recursion"); + break; + } + + /* Register pRt is used to store the memory required to save the state + ** of the current program, and the memory required at runtime to execute + ** the trigger program. If this trigger has been fired before, then pRt + ** is already allocated. Otherwise, it must be initialized. */ + if( (pRt->flags&MEM_Frame)==0 ){ + /* SubProgram.nMem is set to the number of memory cells used by the + ** program stored in SubProgram.aOp. As well as these, one memory + ** cell is required for each cursor used by the program. Set local + ** variable nMem (and later, VdbeFrame.nChildMem) to this value. + */ + nMem = pProgram->nMem + pProgram->nCsr; + nByte = ROUND8(sizeof(VdbeFrame)) + + nMem * sizeof(Mem) + + pProgram->nCsr * sizeof(VdbeCursor *) + + pProgram->nOnce * sizeof(u8); + pFrame = sqlite3DbMallocZero(db, nByte); + if( !pFrame ){ + goto no_mem; + } + sqlite3VdbeMemRelease(pRt); + pRt->flags = MEM_Frame; + pRt->u.pFrame = pFrame; + + pFrame->v = p; + pFrame->nChildMem = nMem; + pFrame->nChildCsr = pProgram->nCsr; + pFrame->pc = (int)(pOp - aOp); + pFrame->aMem = p->aMem; + pFrame->nMem = p->nMem; + pFrame->apCsr = p->apCsr; + pFrame->nCursor = p->nCursor; + pFrame->aOp = p->aOp; + pFrame->nOp = p->nOp; + pFrame->token = pProgram->token; + pFrame->aOnceFlag = p->aOnceFlag; + pFrame->nOnceFlag = p->nOnceFlag; +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + pFrame->anExec = p->anExec; +#endif + + pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem]; + for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){ + pMem->flags = MEM_Undefined; + pMem->db = db; + } + }else{ + pFrame = pRt->u.pFrame; + assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem ); + assert( pProgram->nCsr==pFrame->nChildCsr ); + assert( (int)(pOp - aOp)==pFrame->pc ); + } + + p->nFrame++; + pFrame->pParent = p->pFrame; + pFrame->lastRowid = lastRowid; + pFrame->nChange = p->nChange; + pFrame->nDbChange = p->db->nChange; + p->nChange = 0; + p->pFrame = pFrame; + p->aMem = aMem = &VdbeFrameMem(pFrame)[-1]; + p->nMem = pFrame->nChildMem; + p->nCursor = (u16)pFrame->nChildCsr; + p->apCsr = (VdbeCursor **)&aMem[p->nMem+1]; + p->aOp = aOp = pProgram->aOp; + p->nOp = pProgram->nOp; + p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor]; + p->nOnceFlag = pProgram->nOnce; +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + p->anExec = 0; +#endif + pOp = &aOp[-1]; + memset(p->aOnceFlag, 0, p->nOnceFlag); + + break; +} + +/* Opcode: Param P1 P2 * * * +** +** This opcode is only ever present in sub-programs called via the +** OP_Program instruction. Copy a value currently stored in a memory +** cell of the calling (parent) frame to cell P2 in the current frames +** address space. This is used by trigger programs to access the new.* +** and old.* values. +** +** The address of the cell in the parent frame is determined by adding +** the value of the P1 argument to the value of the P1 argument to the +** calling OP_Program instruction. +*/ +case OP_Param: { /* out2 */ + VdbeFrame *pFrame; + Mem *pIn; + pOut = out2Prerelease(p, pOp); + pFrame = p->pFrame; + pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1]; + sqlite3VdbeMemShallowCopy(pOut, pIn, MEM_Ephem); + break; +} + +#endif /* #ifndef SQLITE_OMIT_TRIGGER */ + +#ifndef SQLITE_OMIT_FOREIGN_KEY +/* Opcode: FkCounter P1 P2 * * * +** Synopsis: fkctr[P1]+=P2 +** +** Increment a "constraint counter" by P2 (P2 may be negative or positive). +** If P1 is non-zero, the database constraint counter is incremented +** (deferred foreign key constraints). Otherwise, if P1 is zero, the +** statement counter is incremented (immediate foreign key constraints). +*/ +case OP_FkCounter: { + if( db->flags & SQLITE_DeferFKs ){ + db->nDeferredImmCons += pOp->p2; + }else if( pOp->p1 ){ + db->nDeferredCons += pOp->p2; + }else{ + p->nFkConstraint += pOp->p2; + } + break; +} + +/* Opcode: FkIfZero P1 P2 * * * +** Synopsis: if fkctr[P1]==0 goto P2 +** +** This opcode tests if a foreign key constraint-counter is currently zero. +** If so, jump to instruction P2. Otherwise, fall through to the next +** instruction. +** +** If P1 is non-zero, then the jump is taken if the database constraint-counter +** is zero (the one that counts deferred constraint violations). If P1 is +** zero, the jump is taken if the statement constraint-counter is zero +** (immediate foreign key constraint violations). +*/ +case OP_FkIfZero: { /* jump */ + if( pOp->p1 ){ + VdbeBranchTaken(db->nDeferredCons==0 && db->nDeferredImmCons==0, 2); + if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) goto jump_to_p2; + }else{ + VdbeBranchTaken(p->nFkConstraint==0 && db->nDeferredImmCons==0, 2); + if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) goto jump_to_p2; + } + break; +} +#endif /* #ifndef SQLITE_OMIT_FOREIGN_KEY */ + +#ifndef SQLITE_OMIT_AUTOINCREMENT +/* Opcode: MemMax P1 P2 * * * +** Synopsis: r[P1]=max(r[P1],r[P2]) +** +** P1 is a register in the root frame of this VM (the root frame is +** different from the current frame if this instruction is being executed +** within a sub-program). Set the value of register P1 to the maximum of +** its current value and the value in register P2. +** +** This instruction throws an error if the memory cell is not initially +** an integer. +*/ +case OP_MemMax: { /* in2 */ + VdbeFrame *pFrame; + if( p->pFrame ){ + for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); + pIn1 = &pFrame->aMem[pOp->p1]; + }else{ + pIn1 = &aMem[pOp->p1]; + } + assert( memIsValid(pIn1) ); + sqlite3VdbeMemIntegerify(pIn1); + pIn2 = &aMem[pOp->p2]; + sqlite3VdbeMemIntegerify(pIn2); + if( pIn1->u.iu.i){ + pIn1->u.i = pIn2->u.i; + } + break; +} +#endif /* SQLITE_OMIT_AUTOINCREMENT */ + +/* Opcode: IfPos P1 P2 * * * +** Synopsis: if r[P1]>0 goto P2 +** +** Register P1 must contain an integer. +** If the value of register P1 is 1 or greater, jump to P2 and +** add the literal value P3 to register P1. +** +** If the initial value of register P1 is less than 1, then the +** value is unchanged and control passes through to the next instruction. +*/ +case OP_IfPos: { /* jump, in1 */ + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags&MEM_Int ); + VdbeBranchTaken( pIn1->u.i>0, 2); + if( pIn1->u.i>0 ) goto jump_to_p2; + break; +} + +/* Opcode: IfNeg P1 P2 P3 * * +** Synopsis: r[P1]+=P3, if r[P1]<0 goto P2 +** +** Register P1 must contain an integer. Add literal P3 to the value in +** register P1 then if the value of register P1 is less than zero, jump to P2. +*/ +case OP_IfNeg: { /* jump, in1 */ + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags&MEM_Int ); + pIn1->u.i += pOp->p3; + VdbeBranchTaken(pIn1->u.i<0, 2); + if( pIn1->u.i<0 ) goto jump_to_p2; + break; +} + +/* Opcode: IfNotZero P1 P2 P3 * * +** Synopsis: if r[P1]!=0 then r[P1]+=P3, goto P2 +** +** Register P1 must contain an integer. If the content of register P1 is +** initially nonzero, then add P3 to P1 and jump to P2. If register P1 is +** initially zero, leave it unchanged and fall through. +*/ +case OP_IfNotZero: { /* jump, in1 */ + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags&MEM_Int ); + VdbeBranchTaken(pIn1->u.i<0, 2); + if( pIn1->u.i ){ + pIn1->u.i += pOp->p3; + goto jump_to_p2; + } + break; +} + +/* Opcode: DecrJumpZero P1 P2 * * * +** Synopsis: if (--r[P1])==0 goto P2 +** +** Register P1 must hold an integer. Decrement the value in register P1 +** then jump to P2 if the new value is exactly zero. +*/ +case OP_DecrJumpZero: { /* jump, in1 */ + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags&MEM_Int ); + pIn1->u.i--; + VdbeBranchTaken(pIn1->u.i==0, 2); + if( pIn1->u.i==0 ) goto jump_to_p2; + break; +} + + +/* Opcode: JumpZeroIncr P1 P2 * * * +** Synopsis: if (r[P1]++)==0 ) goto P2 +** +** The register P1 must contain an integer. If register P1 is initially +** zero, then jump to P2. Increment register P1 regardless of whether or +** not the jump is taken. +*/ +case OP_JumpZeroIncr: { /* jump, in1 */ + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags&MEM_Int ); + VdbeBranchTaken(pIn1->u.i==0, 2); + if( (pIn1->u.i++)==0 ) goto jump_to_p2; + break; +} + +/* Opcode: AggStep * P2 P3 P4 P5 +** Synopsis: accum=r[P3] step(r[P2@P5]) +** +** Execute the step function for an aggregate. The +** function has P5 arguments. P4 is a pointer to the FuncDef +** structure that specifies the function. Use register +** P3 as the accumulator. +** +** The P5 arguments are taken from register P2 and its +** successors. +*/ +case OP_AggStep: { + int n; + int i; + Mem *pMem; + Mem *pRec; + Mem t; + sqlite3_context ctx; + sqlite3_value **apVal; + + n = pOp->p5; + assert( n>=0 ); + pRec = &aMem[pOp->p2]; + apVal = p->apArg; + assert( apVal || n==0 ); + for(i=0; ip4.pFunc; + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); + ctx.pMem = pMem = &aMem[pOp->p3]; + pMem->n++; + sqlite3VdbeMemInit(&t, db, MEM_Null); + ctx.pOut = &t; + ctx.isError = 0; + ctx.pVdbe = p; + ctx.iOp = (int)(pOp - aOp); + ctx.skipFlag = 0; + (ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */ + if( ctx.isError ){ + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&t)); + rc = ctx.isError; + } + if( ctx.skipFlag ){ + assert( pOp[-1].opcode==OP_CollSeq ); + i = pOp[-1].p1; + if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1); + } + sqlite3VdbeMemRelease(&t); + break; +} + +/* Opcode: AggFinal P1 P2 * P4 * +** Synopsis: accum=r[P1] N=P2 +** +** 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 +** P4 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 +** P4 argument is only needed for the degenerate case where +** the step function was not previously called. +*/ +case OP_AggFinal: { + Mem *pMem; + assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); + pMem = &aMem[pOp->p1]; + assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); + rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); + if( rc ){ + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(pMem)); + } + sqlite3VdbeChangeEncoding(pMem, encoding); + UPDATE_MAX_BLOBSIZE(pMem); + if( sqlite3VdbeMemTooBig(pMem) ){ + goto too_big; + } + break; +} + +#ifndef SQLITE_OMIT_WAL +/* Opcode: Checkpoint P1 P2 P3 * * +** +** Checkpoint database P1. This is a no-op if P1 is not currently in +** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL, +** RESTART, or TRUNCATE. Write 1 or 0 into mem[P3] if the checkpoint returns +** SQLITE_BUSY or not, respectively. Write the number of pages in the +** WAL after the checkpoint into mem[P3+1] and the number of pages +** in the WAL that have been checkpointed after the checkpoint +** completes into mem[P3+2]. However on an error, mem[P3+1] and +** mem[P3+2] are initialized to -1. +*/ +case OP_Checkpoint: { + int i; /* Loop counter */ + int aRes[3]; /* Results */ + Mem *pMem; /* Write results here */ + + assert( p->readOnly==0 ); + aRes[0] = 0; + aRes[1] = aRes[2] = -1; + assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE + || pOp->p2==SQLITE_CHECKPOINT_FULL + || pOp->p2==SQLITE_CHECKPOINT_RESTART + || pOp->p2==SQLITE_CHECKPOINT_TRUNCATE + ); + rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]); + if( rc==SQLITE_BUSY ){ + rc = SQLITE_OK; + aRes[0] = 1; + } + for(i=0, pMem = &aMem[pOp->p3]; i<3; i++, pMem++){ + sqlite3VdbeMemSetInt64(pMem, (i64)aRes[i]); + } + break; +}; +#endif + +#ifndef SQLITE_OMIT_PRAGMA +/* Opcode: JournalMode P1 P2 P3 * * +** +** Change the journal mode of database P1 to P3. P3 must be one of the +** PAGER_JOURNALMODE_XXX values. If changing between the various rollback +** modes (delete, truncate, persist, off and memory), this is a simple +** operation. No IO is required. +** +** If changing into or out of WAL mode the procedure is more complicated. +** +** Write a string containing the final journal-mode to register P2. +*/ +case OP_JournalMode: { /* out2 */ + Btree *pBt; /* Btree to change journal mode of */ + Pager *pPager; /* Pager associated with pBt */ + int eNew; /* New journal mode */ + int eOld; /* The old journal mode */ +#ifndef SQLITE_OMIT_WAL + const char *zFilename; /* Name of database file for pPager */ +#endif + + pOut = out2Prerelease(p, pOp); + eNew = pOp->p3; + assert( eNew==PAGER_JOURNALMODE_DELETE + || eNew==PAGER_JOURNALMODE_TRUNCATE + || eNew==PAGER_JOURNALMODE_PERSIST + || eNew==PAGER_JOURNALMODE_OFF + || eNew==PAGER_JOURNALMODE_MEMORY + || eNew==PAGER_JOURNALMODE_WAL + || eNew==PAGER_JOURNALMODE_QUERY + ); + assert( pOp->p1>=0 && pOp->p1nDb ); + assert( p->readOnly==0 ); + + pBt = db->aDb[pOp->p1].pBt; + pPager = sqlite3BtreePager(pBt); + eOld = sqlite3PagerGetJournalMode(pPager); + if( eNew==PAGER_JOURNALMODE_QUERY ) eNew = eOld; + if( !sqlite3PagerOkToChangeJournalMode(pPager) ) eNew = eOld; + +#ifndef SQLITE_OMIT_WAL + zFilename = sqlite3PagerFilename(pPager, 1); + + /* Do not allow a transition to journal_mode=WAL for a database + ** in temporary storage or if the VFS does not support shared memory + */ + if( eNew==PAGER_JOURNALMODE_WAL + && (sqlite3Strlen30(zFilename)==0 /* Temp file */ + || !sqlite3PagerWalSupported(pPager)) /* No shared-memory support */ + ){ + eNew = eOld; + } + + if( (eNew!=eOld) + && (eOld==PAGER_JOURNALMODE_WAL || eNew==PAGER_JOURNALMODE_WAL) + ){ + if( !db->autoCommit || db->nVdbeRead>1 ){ + rc = SQLITE_ERROR; + sqlite3SetString(&p->zErrMsg, db, + "cannot change %s wal mode from within a transaction", + (eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of") + ); + break; + }else{ + + if( eOld==PAGER_JOURNALMODE_WAL ){ + /* If leaving WAL mode, close the log file. If successful, the call + ** to PagerCloseWal() checkpoints and deletes the write-ahead-log + ** file. An EXCLUSIVE lock may still be held on the database file + ** after a successful return. + */ + rc = sqlite3PagerCloseWal(pPager); + if( rc==SQLITE_OK ){ + sqlite3PagerSetJournalMode(pPager, eNew); + } + }else if( eOld==PAGER_JOURNALMODE_MEMORY ){ + /* Cannot transition directly from MEMORY to WAL. Use mode OFF + ** as an intermediate */ + sqlite3PagerSetJournalMode(pPager, PAGER_JOURNALMODE_OFF); + } + + /* Open a transaction on the database file. Regardless of the journal + ** mode, this transaction always uses a rollback journal. + */ + assert( sqlite3BtreeIsInTrans(pBt)==0 ); + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeSetVersion(pBt, (eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); + } + } + } +#endif /* ifndef SQLITE_OMIT_WAL */ + + if( rc ){ + eNew = eOld; + } + eNew = sqlite3PagerSetJournalMode(pPager, eNew); + + pOut->flags = MEM_Str|MEM_Static|MEM_Term; + pOut->z = (char *)sqlite3JournalModename(eNew); + pOut->n = sqlite3Strlen30(pOut->z); + pOut->enc = SQLITE_UTF8; + sqlite3VdbeChangeEncoding(pOut, encoding); + break; +}; +#endif /* SQLITE_OMIT_PRAGMA */ + +#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) +/* 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: { + assert( p->readOnly==0 ); + rc = sqlite3RunVacuum(&p->zErrMsg, db); + break; +} +#endif + +#if !defined(SQLITE_OMIT_AUTOVACUUM) +/* Opcode: IncrVacuum P1 P2 * * * +** +** Perform a single step of the incremental vacuum procedure on +** the P1 database. If the vacuum has finished, jump to instruction +** P2. Otherwise, fall through to the next instruction. +*/ +case OP_IncrVacuum: { /* jump */ + Btree *pBt; + + assert( pOp->p1>=0 && pOp->p1nDb ); + assert( DbMaskTest(p->btreeMask, pOp->p1) ); + assert( p->readOnly==0 ); + pBt = db->aDb[pOp->p1].pBt; + rc = sqlite3BtreeIncrVacuum(pBt); + VdbeBranchTaken(rc==SQLITE_DONE,2); + if( rc==SQLITE_DONE ){ + rc = SQLITE_OK; + goto jump_to_p2; + } + break; +} +#endif + +/* Opcode: Expire P1 * * * * +** +** Cause precompiled statements to expire. When an expired statement +** is executed using sqlite3_step() it will either automatically +** reprepare itself (if it was originally created using sqlite3_prepare_v2()) +** or it will fail with SQLITE_SCHEMA. +** +** If P1 is 0, then all SQL statements become expired. If P1 is non-zero, +** then only the currently executing statement is expired. +*/ +case OP_Expire: { + if( !pOp->p1 ){ + sqlite3ExpirePreparedStatements(db); + }else{ + p->expired = 1; + } + break; +} + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* Opcode: TableLock P1 P2 P3 P4 * +** Synopsis: iDb=P1 root=P2 write=P3 +** +** Obtain a lock on a particular table. This instruction is only used when +** the shared-cache feature is enabled. +** +** P1 is the index of the database in sqlite3.aDb[] of the database +** on which the lock is acquired. A readlock is obtained if P3==0 or +** a write lock if P3==1. +** +** P2 contains the root-page of the table to lock. +** +** P4 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: { + u8 isWriteLock = (u8)pOp->p3; + if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){ + int p1 = pOp->p1; + assert( p1>=0 && p1nDb ); + assert( DbMaskTest(p->btreeMask, p1) ); + assert( isWriteLock==0 || isWriteLock==1 ); + rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock); + if( (rc&0xFF)==SQLITE_LOCKED ){ + const char *z = pOp->p4.z; + sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z); + } + } + break; +} +#endif /* SQLITE_OMIT_SHARED_CACHE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VBegin * * * P4 * +** +** P4 may be a pointer to an sqlite3_vtab structure. If so, call the +** xBegin method for that table. +** +** Also, whether or not P4 is set, check that this is not being called from +** within a callback to a virtual table xSync() method. If it is, the error +** code will be set to SQLITE_LOCKED. +*/ +case OP_VBegin: { + VTable *pVTab; + pVTab = pOp->p4.pVtab; + rc = sqlite3VtabBegin(db, pVTab); + if( pVTab ) sqlite3VtabImportErrmsg(p, pVTab->pVtab); + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VCreate P1 P2 * * * +** +** P2 is a register that holds the name of a virtual table in database +** P1. Call the xCreate method for that table. +*/ +case OP_VCreate: { + Mem sMem; /* For storing the record being decoded */ + const char *zTab; /* Name of the virtual table */ + + memset(&sMem, 0, sizeof(sMem)); + sMem.db = db; + /* Because P2 is always a static string, it is impossible for the + ** sqlite3VdbeMemCopy() to fail */ + assert( (aMem[pOp->p2].flags & MEM_Str)!=0 ); + assert( (aMem[pOp->p2].flags & MEM_Static)!=0 ); + rc = sqlite3VdbeMemCopy(&sMem, &aMem[pOp->p2]); + assert( rc==SQLITE_OK ); + zTab = (const char*)sqlite3_value_text(&sMem); + assert( zTab || db->mallocFailed ); + if( zTab ){ + rc = sqlite3VtabCallCreate(db, pOp->p1, zTab, &p->zErrMsg); + } + sqlite3VdbeMemRelease(&sMem); + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VDestroy P1 * * P4 * +** +** P4 is the name of a virtual table in database P1. Call the xDestroy method +** of that table. +*/ +case OP_VDestroy: { + db->nVDestroy++; + rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z); + db->nVDestroy--; + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VOpen P1 * * P4 * +** +** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. +** P1 is a cursor number. This opcode opens a cursor to the virtual +** table and stores that cursor in P1. +*/ +case OP_VOpen: { + VdbeCursor *pCur; + sqlite3_vtab_cursor *pVtabCursor; + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; + + assert( p->bIsReader ); + pCur = 0; + pVtabCursor = 0; + pVtab = pOp->p4.pVtab->pVtab; + if( pVtab==0 || NEVER(pVtab->pModule==0) ){ + rc = SQLITE_LOCKED; + break; + } + pModule = pVtab->pModule; + rc = pModule->xOpen(pVtab, &pVtabCursor); + sqlite3VtabImportErrmsg(p, pVtab); + if( SQLITE_OK==rc ){ + /* Initialize sqlite3_vtab_cursor base class */ + pVtabCursor->pVtab = pVtab; + + /* Initialize vdbe cursor object */ + pCur = allocateCursor(p, pOp->p1, 0, -1, 0); + if( pCur ){ + pCur->pVtabCursor = pVtabCursor; + pVtab->nRef++; + }else{ + assert( db->mallocFailed ); + pModule->xClose(pVtabCursor); + goto no_mem; + } + } + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VFilter P1 P2 P3 P4 * +** Synopsis: iplan=r[P3] zplan='P4' +** +** P1 is a cursor opened using VOpen. P2 is an address to jump to if +** the filtered result set is empty. +** +** P4 is either NULL or a string that was generated by the xBestIndex +** method of the module. The interpretation of the P4 string is left +** to the module implementation. +** +** This opcode invokes the xFilter method on the virtual table specified +** by P1. The integer query plan parameter to xFilter is stored in register +** P3. Register P3+1 stores the argc parameter to be passed to the +** xFilter method. Registers P3+2..P3+1+argc are the argc +** additional parameters which are passed to +** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter. +** +** A jump is made to P2 if the result set after filtering would be empty. +*/ +case OP_VFilter: { /* jump */ + int nArg; + int iQuery; + const sqlite3_module *pModule; + Mem *pQuery; + Mem *pArgc; + sqlite3_vtab_cursor *pVtabCursor; + sqlite3_vtab *pVtab; + VdbeCursor *pCur; + int res; + int i; + Mem **apArg; + + pQuery = &aMem[pOp->p3]; + pArgc = &pQuery[1]; + pCur = p->apCsr[pOp->p1]; + assert( memIsValid(pQuery) ); + REGISTER_TRACE(pOp->p3, pQuery); + assert( pCur->pVtabCursor ); + pVtabCursor = pCur->pVtabCursor; + pVtab = pVtabCursor->pVtab; + pModule = pVtab->pModule; + + /* Grab the index number and argc parameters */ + assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int ); + nArg = (int)pArgc->u.i; + iQuery = (int)pQuery->u.i; + + /* Invoke the xFilter method */ + res = 0; + apArg = p->apArg; + for(i = 0; ixFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg); + sqlite3VtabImportErrmsg(p, pVtab); + if( rc==SQLITE_OK ){ + res = pModule->xEof(pVtabCursor); + } + pCur->nullRow = 0; + VdbeBranchTaken(res!=0,2); + if( res ) goto jump_to_p2; + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VColumn P1 P2 P3 * * +** Synopsis: r[P3]=vcolumn(P2) +** +** Store the value of the P2-th column of +** the row of the virtual-table that the +** P1 cursor is pointing to into register P3. +*/ +case OP_VColumn: { + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; + Mem *pDest; + sqlite3_context sContext; + + VdbeCursor *pCur = p->apCsr[pOp->p1]; + assert( pCur->pVtabCursor ); + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); + pDest = &aMem[pOp->p3]; + memAboutToChange(p, pDest); + if( pCur->nullRow ){ + sqlite3VdbeMemSetNull(pDest); + break; + } + pVtab = pCur->pVtabCursor->pVtab; + pModule = pVtab->pModule; + assert( pModule->xColumn ); + memset(&sContext, 0, sizeof(sContext)); + sContext.pOut = pDest; + MemSetTypeFlag(pDest, MEM_Null); + rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2); + sqlite3VtabImportErrmsg(p, pVtab); + if( sContext.isError ){ + rc = sContext.isError; + } + sqlite3VdbeChangeEncoding(pDest, encoding); + REGISTER_TRACE(pOp->p3, pDest); + UPDATE_MAX_BLOBSIZE(pDest); + + if( sqlite3VdbeMemTooBig(pDest) ){ + goto too_big; + } + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VNext P1 P2 * * * +** +** Advance virtual table P1 to the next row in its result set and +** jump to instruction P2. Or, if the virtual table has reached +** the end of its result set, then fall through to the next instruction. +*/ +case OP_VNext: { /* jump */ + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; + int res; + VdbeCursor *pCur; + + res = 0; + pCur = p->apCsr[pOp->p1]; + assert( pCur->pVtabCursor ); + if( pCur->nullRow ){ + break; + } + pVtab = pCur->pVtabCursor->pVtab; + pModule = pVtab->pModule; + assert( pModule->xNext ); + + /* Invoke the xNext() method of the module. There is no way for the + ** underlying implementation to return an error if one occurs during + ** xNext(). Instead, if an error occurs, true is returned (indicating that + ** data is available) and the error code returned when xColumn or + ** some other method is next invoked on the save virtual table cursor. + */ + rc = pModule->xNext(pCur->pVtabCursor); + sqlite3VtabImportErrmsg(p, pVtab); + if( rc==SQLITE_OK ){ + res = pModule->xEof(pCur->pVtabCursor); + } + VdbeBranchTaken(!res,2); + if( !res ){ + /* If there is data, jump to P2 */ + goto jump_to_p2_and_check_for_interrupt; + } + goto check_for_interrupt; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VRename P1 * * P4 * +** +** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. +** This opcode invokes the corresponding xRename method. The value +** in register P1 is passed as the zName argument to the xRename method. +*/ +case OP_VRename: { + sqlite3_vtab *pVtab; + Mem *pName; + + pVtab = pOp->p4.pVtab->pVtab; + pName = &aMem[pOp->p1]; + assert( pVtab->pModule->xRename ); + assert( memIsValid(pName) ); + assert( p->readOnly==0 ); + REGISTER_TRACE(pOp->p1, pName); + assert( pName->flags & MEM_Str ); + testcase( pName->enc==SQLITE_UTF8 ); + testcase( pName->enc==SQLITE_UTF16BE ); + testcase( pName->enc==SQLITE_UTF16LE ); + rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8); + if( rc==SQLITE_OK ){ + rc = pVtab->pModule->xRename(pVtab, pName->z); + sqlite3VtabImportErrmsg(p, pVtab); + p->expired = 0; + } + break; +} +#endif + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VUpdate P1 P2 P3 P4 P5 +** Synopsis: data=r[P3@P2] +** +** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. +** This opcode invokes the corresponding xUpdate method. P2 values +** are contiguous memory cells starting at P3 to pass to the xUpdate +** invocation. The value in register (P3+P2-1) corresponds to the +** p2th element of the argv array passed to xUpdate. +** +** The xUpdate method will do a DELETE or an INSERT or both. +** The argv[0] element (which corresponds to memory cell P3) +** is the rowid of a row to delete. If argv[0] is NULL then no +** deletion occurs. The argv[1] element is the rowid of the new +** row. This can be NULL to have the virtual table select the new +** rowid for itself. The subsequent elements in the array are +** the values of columns in the new row. +** +** If P2==1 then no insert is performed. argv[0] is the rowid of +** a row to delete. +** +** P1 is a boolean flag. If it is set to true and the xUpdate call +** is successful, then the value returned by sqlite3_last_insert_rowid() +** is set to the value of the rowid for the row just inserted. +** +** P5 is the error actions (OE_Replace, OE_Fail, OE_Ignore, etc) to +** apply in the case of a constraint failure on an insert or update. +*/ +case OP_VUpdate: { + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; + int nArg; + int i; + sqlite_int64 rowid; + Mem **apArg; + Mem *pX; + + assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback + || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace + ); + assert( p->readOnly==0 ); + pVtab = pOp->p4.pVtab->pVtab; + if( pVtab==0 || NEVER(pVtab->pModule==0) ){ + rc = SQLITE_LOCKED; + break; + } + pModule = pVtab->pModule; + nArg = pOp->p2; + assert( pOp->p4type==P4_VTAB ); + if( ALWAYS(pModule->xUpdate) ){ + u8 vtabOnConflict = db->vtabOnConflict; + apArg = p->apArg; + pX = &aMem[pOp->p3]; + for(i=0; ivtabOnConflict = pOp->p5; + rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid); + db->vtabOnConflict = vtabOnConflict; + sqlite3VtabImportErrmsg(p, pVtab); + if( rc==SQLITE_OK && pOp->p1 ){ + assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) ); + db->lastRowid = lastRowid = rowid; + } + if( (rc&0xff)==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){ + if( pOp->p5==OE_Ignore ){ + rc = SQLITE_OK; + }else{ + p->errorAction = ((pOp->p5==OE_Replace) ? OE_Abort : pOp->p5); + } + }else{ + p->nChange++; + } + } + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +/* Opcode: Pagecount P1 P2 * * * +** +** Write the current number of pages in database P1 to memory cell P2. +*/ +case OP_Pagecount: { /* out2 */ + pOut = out2Prerelease(p, pOp); + pOut->u.i = sqlite3BtreeLastPage(db->aDb[pOp->p1].pBt); + break; +} +#endif + + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +/* Opcode: MaxPgcnt P1 P2 P3 * * +** +** Try to set the maximum page count for database P1 to the value in P3. +** Do not let the maximum page count fall below the current page count and +** do not change the maximum page count value if P3==0. +** +** Store the maximum page count after the change in register P2. +*/ +case OP_MaxPgcnt: { /* out2 */ + unsigned int newMax; + Btree *pBt; + + pOut = out2Prerelease(p, pOp); + pBt = db->aDb[pOp->p1].pBt; + newMax = 0; + if( pOp->p3 ){ + newMax = sqlite3BtreeLastPage(pBt); + if( newMax < (unsigned)pOp->p3 ) newMax = (unsigned)pOp->p3; + } + pOut->u.i = sqlite3BtreeMaxPageCount(pBt, newMax); + break; +} +#endif + + +/* Opcode: Init * P2 * P4 * +** Synopsis: Start at P2 +** +** Programs contain a single instance of this opcode as the very first +** opcode. +** +** If tracing is enabled (by the sqlite3_trace()) interface, then +** the UTF-8 string contained in P4 is emitted on the trace callback. +** Or if P4 is blank, use the string returned by sqlite3_sql(). +** +** If P2 is not zero, jump to instruction P2. +*/ +case OP_Init: { /* jump */ + char *zTrace; + char *z; + +#ifndef SQLITE_OMIT_TRACE + if( db->xTrace + && !p->doingRerun + && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 + ){ + z = sqlite3VdbeExpandSql(p, zTrace); + db->xTrace(db->pTraceArg, z); + sqlite3DbFree(db, z); + } +#ifdef SQLITE_USE_FCNTL_TRACE + zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); + if( zTrace ){ + int i; + for(i=0; inDb; i++){ + if( DbMaskTest(p->btreeMask, i)==0 ) continue; + sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace); + } + } +#endif /* SQLITE_USE_FCNTL_TRACE */ +#ifdef SQLITE_DEBUG + if( (db->flags & SQLITE_SqlTrace)!=0 + && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 + ){ + sqlite3DebugPrintf("SQL-trace: %s\n", zTrace); + } +#endif /* SQLITE_DEBUG */ +#endif /* SQLITE_OMIT_TRACE */ + if( pOp->p2 ) goto jump_to_p2; + 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. +*/ +default: { /* This is really OP_Noop and OP_Explain */ + assert( pOp->opcode==OP_Noop || pOp->opcode==OP_Explain ); + 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 + { + u64 endTime = sqlite3Hwtime(); + if( endTime>start ) pOrigOp->cycles += endTime - start; + pOrigOp->cnt++; + } +#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 + assert( pOp>=&aOp[-1] && pOp<&aOp[p->nOp-1] ); + +#ifdef SQLITE_DEBUG + if( db->flags & SQLITE_VdbeTrace ){ + if( rc!=0 ) printf("rc=%d\n",rc); + if( pOrigOp->opflags & (OPFLG_OUT2) ){ + registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]); + } + if( pOrigOp->opflags & OPFLG_OUT3 ){ + registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]); + } + } +#endif /* SQLITE_DEBUG */ +#endif /* NDEBUG */ + } /* The end of the for(;;) loop the loops through opcodes */ + + /* If we reach this point, it means that execution is finished with + ** an error of some kind. + */ +vdbe_error_halt: + assert( rc ); + p->rc = rc; + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(rc, "statement aborts at %d: [%s] %s", + (int)(pOp - aOp), p->zSql, p->zErrMsg); + sqlite3VdbeHalt(p); + if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1; + rc = SQLITE_ERROR; + if( resetSchemaOnFault>0 ){ + sqlite3ResetOneSchema(db, resetSchemaOnFault-1); + } + + /* This is the only way out of this procedure. We have to + ** release the mutexes on btrees that were acquired at the + ** top. */ +vdbe_return: + db->lastRowid = lastRowid; + testcase( nVmStep>0 ); + p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep; + sqlite3VdbeLeave(p); + return rc; + + /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH + ** is encountered. + */ +too_big: + sqlite3SetString(&p->zErrMsg, db, "string or blob too big"); + rc = SQLITE_TOOBIG; + goto vdbe_error_halt; + + /* Jump to here if a malloc() fails. + */ +no_mem: + db->mallocFailed = 1; + sqlite3SetString(&p->zErrMsg, db, "out of memory"); + rc = SQLITE_NOMEM; + goto vdbe_error_halt; + + /* Jump to here for any other kind of fatal error. The "rc" variable + ** should hold the error number. + */ +abort_due_to_error: + assert( p->zErrMsg==0 ); + if( db->mallocFailed ) rc = SQLITE_NOMEM; + if( rc!=SQLITE_IOERR_NOMEM ){ + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(rc)); + } + goto vdbe_error_halt; + + /* Jump to here if the sqlite3_interrupt() API sets the interrupt + ** flag. + */ +abort_due_to_interrupt: + assert( db->u1.isInterrupted ); + rc = SQLITE_INTERRUPT; + p->rc = rc; + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(rc)); + goto vdbe_error_halt; +} + + +/************** End of vdbe.c ************************************************/ +/************** Begin file vdbeblob.c ****************************************/ +/* +** 2007 May 1 +** +** 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 incremental BLOB I/O. +*/ + + +#ifndef SQLITE_OMIT_INCRBLOB + +/* +** Valid sqlite3_blob* handles point to Incrblob structures. +*/ +typedef struct Incrblob Incrblob; +struct Incrblob { + int flags; /* Copy of "flags" passed to sqlite3_blob_open() */ + int nByte; /* Size of open blob, in bytes */ + int iOffset; /* Byte offset of blob in cursor data */ + int iCol; /* Table column this handle is open on */ + BtCursor *pCsr; /* Cursor pointing at blob row */ + sqlite3_stmt *pStmt; /* Statement holding cursor open */ + sqlite3 *db; /* The associated database */ +}; + + +/* +** This function is used by both blob_open() and blob_reopen(). It seeks +** the b-tree cursor associated with blob handle p to point to row iRow. +** If successful, SQLITE_OK is returned and subsequent calls to +** sqlite3_blob_read() or sqlite3_blob_write() access the specified row. +** +** If an error occurs, or if the specified row does not exist or does not +** contain a value of type TEXT or BLOB in the column nominated when the +** blob handle was opened, then an error code is returned and *pzErr may +** be set to point to a buffer containing an error message. It is the +** responsibility of the caller to free the error message buffer using +** sqlite3DbFree(). +** +** If an error does occur, then the b-tree cursor is closed. All subsequent +** calls to sqlite3_blob_read(), blob_write() or blob_reopen() will +** immediately return SQLITE_ABORT. +*/ +static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ + int rc; /* Error code */ + char *zErr = 0; /* Error message */ + Vdbe *v = (Vdbe *)p->pStmt; + + /* Set the value of the SQL statements only variable to integer iRow. + ** This is done directly instead of using sqlite3_bind_int64() to avoid + ** triggering asserts related to mutexes. + */ + assert( v->aVar[0].flags&MEM_Int ); + v->aVar[0].u.i = iRow; + + rc = sqlite3_step(p->pStmt); + if( rc==SQLITE_ROW ){ + VdbeCursor *pC = v->apCsr[0]; + u32 type = pC->aType[p->iCol]; + if( type<12 ){ + zErr = sqlite3MPrintf(p->db, "cannot open value of type %s", + type==0?"null": type==7?"real": "integer" + ); + rc = SQLITE_ERROR; + sqlite3_finalize(p->pStmt); + p->pStmt = 0; + }else{ + p->iOffset = pC->aType[p->iCol + pC->nField]; + p->nByte = sqlite3VdbeSerialTypeLen(type); + p->pCsr = pC->pCursor; + sqlite3BtreeIncrblobCursor(p->pCsr); + } + } + + if( rc==SQLITE_ROW ){ + rc = SQLITE_OK; + }else if( p->pStmt ){ + rc = sqlite3_finalize(p->pStmt); + p->pStmt = 0; + if( rc==SQLITE_OK ){ + zErr = sqlite3MPrintf(p->db, "no such rowid: %lld", iRow); + rc = SQLITE_ERROR; + }else{ + zErr = sqlite3MPrintf(p->db, "%s", sqlite3_errmsg(p->db)); + } + } + + assert( rc!=SQLITE_OK || zErr==0 ); + assert( rc!=SQLITE_ROW && rc!=SQLITE_DONE ); + + *pzErr = zErr; + return rc; +} + +/* +** Open a blob handle. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_blob_open( + sqlite3* db, /* The database connection */ + const char *zDb, /* The attached database containing the blob */ + const char *zTable, /* The table containing the blob */ + const char *zColumn, /* The column containing the blob */ + sqlite_int64 iRow, /* The row containing the glob */ + int flags, /* True -> read/write access, false -> read-only */ + sqlite3_blob **ppBlob /* Handle for accessing the blob returned here */ +){ + int nAttempt = 0; + int iCol; /* Index of zColumn in row-record */ + + /* This VDBE program seeks a btree cursor to the identified + ** db/table/row entry. The reason for using a vdbe program instead + ** of writing code to use the b-tree layer directly is that the + ** vdbe program will take advantage of the various transaction, + ** locking and error handling infrastructure built into the vdbe. + ** + ** After seeking the cursor, the vdbe executes an OP_ResultRow. + ** Code external to the Vdbe then "borrows" the b-tree cursor and + ** uses it to implement the blob_read(), blob_write() and + ** blob_bytes() functions. + ** + ** The sqlite3_blob_close() function finalizes the vdbe program, + ** which closes the b-tree cursor and (possibly) commits the + ** transaction. + */ + static const int iLn = VDBE_OFFSET_LINENO(4); + static const VdbeOpList openBlob[] = { + /* {OP_Transaction, 0, 0, 0}, // 0: Inserted separately */ + {OP_TableLock, 0, 0, 0}, /* 1: Acquire a read or write lock */ + /* One of the following two instructions is replaced by an OP_Noop. */ + {OP_OpenRead, 0, 0, 0}, /* 2: Open cursor 0 for reading */ + {OP_OpenWrite, 0, 0, 0}, /* 3: Open cursor 0 for read/write */ + {OP_Variable, 1, 1, 1}, /* 4: Push the rowid to the stack */ + {OP_NotExists, 0, 10, 1}, /* 5: Seek the cursor */ + {OP_Column, 0, 0, 1}, /* 6 */ + {OP_ResultRow, 1, 0, 0}, /* 7 */ + {OP_Goto, 0, 4, 0}, /* 8 */ + {OP_Close, 0, 0, 0}, /* 9 */ + {OP_Halt, 0, 0, 0}, /* 10 */ + }; + + int rc = SQLITE_OK; + char *zErr = 0; + Table *pTab; + Parse *pParse = 0; + Incrblob *pBlob = 0; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( ppBlob==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + *ppBlob = 0; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zTable==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + flags = !!flags; /* flags = (flags ? 1 : 0); */ + + sqlite3_mutex_enter(db->mutex); + + pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob)); + if( !pBlob ) goto blob_open_out; + pParse = sqlite3StackAllocRaw(db, sizeof(*pParse)); + if( !pParse ) goto blob_open_out; + + do { + memset(pParse, 0, sizeof(Parse)); + pParse->db = db; + sqlite3DbFree(db, zErr); + zErr = 0; + + sqlite3BtreeEnterAll(db); + pTab = sqlite3LocateTable(pParse, 0, zTable, zDb); + if( pTab && IsVirtual(pTab) ){ + pTab = 0; + sqlite3ErrorMsg(pParse, "cannot open virtual table: %s", zTable); + } + if( pTab && !HasRowid(pTab) ){ + pTab = 0; + sqlite3ErrorMsg(pParse, "cannot open table without rowid: %s", zTable); + } +#ifndef SQLITE_OMIT_VIEW + if( pTab && pTab->pSelect ){ + pTab = 0; + sqlite3ErrorMsg(pParse, "cannot open view: %s", zTable); + } +#endif + if( !pTab ){ + if( pParse->zErrMsg ){ + sqlite3DbFree(db, zErr); + zErr = pParse->zErrMsg; + pParse->zErrMsg = 0; + } + rc = SQLITE_ERROR; + sqlite3BtreeLeaveAll(db); + goto blob_open_out; + } + + /* Now search pTab for the exact column. */ + for(iCol=0; iColnCol; iCol++) { + if( sqlite3StrICmp(pTab->aCol[iCol].zName, zColumn)==0 ){ + break; + } + } + if( iCol==pTab->nCol ){ + sqlite3DbFree(db, zErr); + zErr = sqlite3MPrintf(db, "no such column: \"%s\"", zColumn); + rc = SQLITE_ERROR; + sqlite3BtreeLeaveAll(db); + goto blob_open_out; + } + + /* If the value is being opened for writing, check that the + ** column is not indexed, and that it is not part of a foreign key. + ** It is against the rules to open a column to which either of these + ** descriptions applies for writing. */ + if( flags ){ + const char *zFault = 0; + Index *pIdx; +#ifndef SQLITE_OMIT_FOREIGN_KEY + if( db->flags&SQLITE_ForeignKeys ){ + /* Check that the column is not part of an FK child key definition. It + ** is not necessary to check if it is part of a parent key, as parent + ** key columns must be indexed. The check below will pick up this + ** case. */ + FKey *pFKey; + for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){ + int j; + for(j=0; jnCol; j++){ + if( pFKey->aCol[j].iFrom==iCol ){ + zFault = "foreign key"; + } + } + } + } +#endif + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int j; + for(j=0; jnKeyCol; j++){ + if( pIdx->aiColumn[j]==iCol ){ + zFault = "indexed"; + } + } + } + if( zFault ){ + sqlite3DbFree(db, zErr); + zErr = sqlite3MPrintf(db, "cannot open %s column for writing", zFault); + rc = SQLITE_ERROR; + sqlite3BtreeLeaveAll(db); + goto blob_open_out; + } + } + + pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(pParse); + assert( pBlob->pStmt || db->mallocFailed ); + if( pBlob->pStmt ){ + Vdbe *v = (Vdbe *)pBlob->pStmt; + int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + + + sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, flags, + pTab->pSchema->schema_cookie, + pTab->pSchema->iGeneration); + sqlite3VdbeChangeP5(v, 1); + sqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn); + + /* Make sure a mutex is held on the table to be accessed */ + sqlite3VdbeUsesBtree(v, iDb); + + /* Configure the OP_TableLock instruction */ +#ifdef SQLITE_OMIT_SHARED_CACHE + sqlite3VdbeChangeToNoop(v, 1); +#else + sqlite3VdbeChangeP1(v, 1, iDb); + sqlite3VdbeChangeP2(v, 1, pTab->tnum); + sqlite3VdbeChangeP3(v, 1, flags); + sqlite3VdbeChangeP4(v, 1, pTab->zName, P4_TRANSIENT); +#endif + + /* Remove either the OP_OpenWrite or OpenRead. Set the P2 + ** parameter of the other to pTab->tnum. */ + sqlite3VdbeChangeToNoop(v, 3 - flags); + sqlite3VdbeChangeP2(v, 2 + flags, pTab->tnum); + sqlite3VdbeChangeP3(v, 2 + flags, iDb); + + /* Configure the number of columns. Configure the cursor to + ** think that the table has one more column than it really + ** does. An OP_Column to retrieve this imaginary column will + ** always return an SQL NULL. This is useful because it means + ** we can invoke OP_Column to fill in the vdbe cursors type + ** and offset cache without causing any IO. + */ + sqlite3VdbeChangeP4(v, 2+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32); + sqlite3VdbeChangeP2(v, 6, pTab->nCol); + if( !db->mallocFailed ){ + pParse->nVar = 1; + pParse->nMem = 1; + pParse->nTab = 1; + sqlite3VdbeMakeReady(v, pParse); + } + } + + pBlob->flags = flags; + pBlob->iCol = iCol; + pBlob->db = db; + sqlite3BtreeLeaveAll(db); + if( db->mallocFailed ){ + goto blob_open_out; + } + sqlite3_bind_int64(pBlob->pStmt, 1, iRow); + rc = blobSeekToRow(pBlob, iRow, &zErr); + } while( (++nAttempt)mallocFailed==0 ){ + *ppBlob = (sqlite3_blob *)pBlob; + }else{ + if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt); + sqlite3DbFree(db, pBlob); + } + sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr); + sqlite3DbFree(db, zErr); + sqlite3ParserReset(pParse); + sqlite3StackFree(db, pParse); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Close a blob handle that was previously created using +** sqlite3_blob_open(). +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *pBlob){ + Incrblob *p = (Incrblob *)pBlob; + int rc; + sqlite3 *db; + + if( p ){ + db = p->db; + sqlite3_mutex_enter(db->mutex); + rc = sqlite3_finalize(p->pStmt); + sqlite3DbFree(db, p); + sqlite3_mutex_leave(db->mutex); + }else{ + rc = SQLITE_OK; + } + return rc; +} + +/* +** Perform a read or write operation on a blob +*/ +static int blobReadWrite( + sqlite3_blob *pBlob, + void *z, + int n, + int iOffset, + int (*xCall)(BtCursor*, u32, u32, void*) +){ + int rc; + Incrblob *p = (Incrblob *)pBlob; + Vdbe *v; + sqlite3 *db; + + if( p==0 ) return SQLITE_MISUSE_BKPT; + db = p->db; + sqlite3_mutex_enter(db->mutex); + v = (Vdbe*)p->pStmt; + + if( n<0 || iOffset<0 || ((sqlite3_int64)iOffset+n)>p->nByte ){ + /* Request is out of range. Return a transient error. */ + rc = SQLITE_ERROR; + }else if( v==0 ){ + /* If there is no statement handle, then the blob-handle has + ** already been invalidated. Return SQLITE_ABORT in this case. + */ + rc = SQLITE_ABORT; + }else{ + /* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is + ** returned, clean-up the statement handle. + */ + assert( db == v->db ); + sqlite3BtreeEnterCursor(p->pCsr); + rc = xCall(p->pCsr, iOffset+p->iOffset, n, z); + sqlite3BtreeLeaveCursor(p->pCsr); + if( rc==SQLITE_ABORT ){ + sqlite3VdbeFinalize(v); + p->pStmt = 0; + }else{ + v->rc = rc; + } + } + sqlite3Error(db, rc); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Read data from a blob handle. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){ + return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreeData); +} + +/* +** Write data to a blob handle. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){ + return blobReadWrite(pBlob, (void *)z, n, iOffset, sqlite3BtreePutData); +} + +/* +** Query a blob handle for the size of the data. +** +** The Incrblob.nByte field is fixed for the lifetime of the Incrblob +** so no mutex is required for access. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *pBlob){ + Incrblob *p = (Incrblob *)pBlob; + return (p && p->pStmt) ? p->nByte : 0; +} + +/* +** Move an existing blob handle to point to a different row of the same +** database table. +** +** If an error occurs, or if the specified row does not exist or does not +** contain a blob or text value, then an error code is returned and the +** database handle error code and message set. If this happens, then all +** subsequent calls to sqlite3_blob_xxx() functions (except blob_close()) +** immediately return SQLITE_ABORT. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){ + int rc; + Incrblob *p = (Incrblob *)pBlob; + sqlite3 *db; + + if( p==0 ) return SQLITE_MISUSE_BKPT; + db = p->db; + sqlite3_mutex_enter(db->mutex); + + if( p->pStmt==0 ){ + /* If there is no statement handle, then the blob-handle has + ** already been invalidated. Return SQLITE_ABORT in this case. + */ + rc = SQLITE_ABORT; + }else{ + char *zErr; + rc = blobSeekToRow(p, iRow, &zErr); + if( rc!=SQLITE_OK ){ + sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr); + sqlite3DbFree(db, zErr); + } + assert( rc!=SQLITE_SCHEMA ); + } + + rc = sqlite3ApiExit(db, rc); + assert( rc==SQLITE_OK || p->pStmt==0 ); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +#endif /* #ifndef SQLITE_OMIT_INCRBLOB */ + +/************** End of vdbeblob.c ********************************************/ +/************** Begin file vdbesort.c ****************************************/ +/* +** 2011-07-09 +** +** 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 for the VdbeSorter object, used in concert with +** a VdbeCursor to sort large numbers of keys for CREATE INDEX statements +** or by SELECT statements with ORDER BY clauses that cannot be satisfied +** using indexes and without LIMIT clauses. +** +** The VdbeSorter object implements a multi-threaded external merge sort +** algorithm that is efficient even if the number of elements being sorted +** exceeds the available memory. +** +** Here is the (internal, non-API) interface between this module and the +** rest of the SQLite system: +** +** sqlite3VdbeSorterInit() Create a new VdbeSorter object. +** +** sqlite3VdbeSorterWrite() Add a single new row to the VdbeSorter +** object. The row is a binary blob in the +** OP_MakeRecord format that contains both +** the ORDER BY key columns and result columns +** in the case of a SELECT w/ ORDER BY, or +** the complete record for an index entry +** in the case of a CREATE INDEX. +** +** sqlite3VdbeSorterRewind() Sort all content previously added. +** Position the read cursor on the +** first sorted element. +** +** sqlite3VdbeSorterNext() Advance the read cursor to the next sorted +** element. +** +** sqlite3VdbeSorterRowkey() Return the complete binary blob for the +** row currently under the read cursor. +** +** sqlite3VdbeSorterCompare() Compare the binary blob for the row +** currently under the read cursor against +** another binary blob X and report if +** X is strictly less than the read cursor. +** Used to enforce uniqueness in a +** CREATE UNIQUE INDEX statement. +** +** sqlite3VdbeSorterClose() Close the VdbeSorter object and reclaim +** all resources. +** +** sqlite3VdbeSorterReset() Refurbish the VdbeSorter for reuse. This +** is like Close() followed by Init() only +** much faster. +** +** The interfaces above must be called in a particular order. Write() can +** only occur in between Init()/Reset() and Rewind(). Next(), Rowkey(), and +** Compare() can only occur in between Rewind() and Close()/Reset(). i.e. +** +** Init() +** for each record: Write() +** Rewind() +** Rowkey()/Compare() +** Next() +** Close() +** +** Algorithm: +** +** Records passed to the sorter via calls to Write() are initially held +** unsorted in main memory. Assuming the amount of memory used never exceeds +** a threshold, when Rewind() is called the set of records is sorted using +** an in-memory merge sort. In this case, no temporary files are required +** and subsequent calls to Rowkey(), Next() and Compare() read records +** directly from main memory. +** +** If the amount of space used to store records in main memory exceeds the +** threshold, then the set of records currently in memory are sorted and +** written to a temporary file in "Packed Memory Array" (PMA) format. +** A PMA created at this point is known as a "level-0 PMA". Higher levels +** of PMAs may be created by merging existing PMAs together - for example +** merging two or more level-0 PMAs together creates a level-1 PMA. +** +** The threshold for the amount of main memory to use before flushing +** records to a PMA is roughly the same as the limit configured for the +** page-cache of the main database. Specifically, the threshold is set to +** the value returned by "PRAGMA main.page_size" multipled by +** that returned by "PRAGMA main.cache_size", in bytes. +** +** If the sorter is running in single-threaded mode, then all PMAs generated +** are appended to a single temporary file. Or, if the sorter is running in +** multi-threaded mode then up to (N+1) temporary files may be opened, where +** N is the configured number of worker threads. In this case, instead of +** sorting the records and writing the PMA to a temporary file itself, the +** calling thread usually launches a worker thread to do so. Except, if +** there are already N worker threads running, the main thread does the work +** itself. +** +** The sorter is running in multi-threaded mode if (a) the library was built +** with pre-processor symbol SQLITE_MAX_WORKER_THREADS set to a value greater +** than zero, and (b) worker threads have been enabled at runtime by calling +** "PRAGMA threads=N" with some value of N greater than 0. +** +** When Rewind() is called, any data remaining in memory is flushed to a +** final PMA. So at this point the data is stored in some number of sorted +** PMAs within temporary files on disk. +** +** If there are fewer than SORTER_MAX_MERGE_COUNT PMAs in total and the +** sorter is running in single-threaded mode, then these PMAs are merged +** incrementally as keys are retreived from the sorter by the VDBE. The +** MergeEngine object, described in further detail below, performs this +** merge. +** +** Or, if running in multi-threaded mode, then a background thread is +** launched to merge the existing PMAs. Once the background thread has +** merged T bytes of data into a single sorted PMA, the main thread +** begins reading keys from that PMA while the background thread proceeds +** with merging the next T bytes of data. And so on. +** +** Parameter T is set to half the value of the memory threshold used +** by Write() above to determine when to create a new PMA. +** +** If there are more than SORTER_MAX_MERGE_COUNT PMAs in total when +** Rewind() is called, then a hierarchy of incremental-merges is used. +** First, T bytes of data from the first SORTER_MAX_MERGE_COUNT PMAs on +** disk are merged together. Then T bytes of data from the second set, and +** so on, such that no operation ever merges more than SORTER_MAX_MERGE_COUNT +** PMAs at a time. This done is to improve locality. +** +** If running in multi-threaded mode and there are more than +** SORTER_MAX_MERGE_COUNT PMAs on disk when Rewind() is called, then more +** than one background thread may be created. Specifically, there may be +** one background thread for each temporary file on disk, and one background +** thread to merge the output of each of the others to a single PMA for +** the main thread to read from. +*/ + +/* +** If SQLITE_DEBUG_SORTER_THREADS is defined, this module outputs various +** messages to stderr that may be helpful in understanding the performance +** characteristics of the sorter in multi-threaded mode. +*/ +#if 0 +# define SQLITE_DEBUG_SORTER_THREADS 1 +#endif + +/* +** Hard-coded maximum amount of data to accumulate in memory before flushing +** to a level 0 PMA. The purpose of this limit is to prevent various integer +** overflows. 512MiB. +*/ +#define SQLITE_MAX_PMASZ (1<<29) + +/* +** Private objects used by the sorter +*/ +typedef struct MergeEngine MergeEngine; /* Merge PMAs together */ +typedef struct PmaReader PmaReader; /* Incrementally read one PMA */ +typedef struct PmaWriter PmaWriter; /* Incrementally write one PMA */ +typedef struct SorterRecord SorterRecord; /* A record being sorted */ +typedef struct SortSubtask SortSubtask; /* A sub-task in the sort process */ +typedef struct SorterFile SorterFile; /* Temporary file object wrapper */ +typedef struct SorterList SorterList; /* In-memory list of records */ +typedef struct IncrMerger IncrMerger; /* Read & merge multiple PMAs */ + +/* +** A container for a temp file handle and the current amount of data +** stored in the file. +*/ +struct SorterFile { + sqlite3_file *pFd; /* File handle */ + i64 iEof; /* Bytes of data stored in pFd */ +}; + +/* +** An in-memory list of objects to be sorted. +** +** If aMemory==0 then each object is allocated separately and the objects +** are connected using SorterRecord.u.pNext. If aMemory!=0 then all objects +** are stored in the aMemory[] bulk memory, one right after the other, and +** are connected using SorterRecord.u.iNext. +*/ +struct SorterList { + SorterRecord *pList; /* Linked list of records */ + u8 *aMemory; /* If non-NULL, bulk memory to hold pList */ + int szPMA; /* Size of pList as PMA in bytes */ +}; + +/* +** The MergeEngine object is used to combine two or more smaller PMAs into +** one big PMA using a merge operation. Separate PMAs all need to be +** combined into one big PMA in order to be able to step through the sorted +** records in order. +** +** The aReadr[] array contains a PmaReader object for each of the PMAs being +** merged. An aReadr[] object either points to a valid key or else is at EOF. +** ("EOF" means "End Of File". When aReadr[] is at EOF there is no more data.) +** For the purposes of the paragraphs below, we assume that the array is +** actually N elements in size, where N is the smallest power of 2 greater +** to or equal to the number of PMAs being merged. The extra aReadr[] elements +** are treated as if they are empty (always at EOF). +** +** The aTree[] array is also N elements in size. The value of N is stored in +** the MergeEngine.nTree variable. +** +** The final (N/2) elements of aTree[] contain the results of comparing +** pairs of PMA keys together. Element i contains the result of +** comparing aReadr[2*i-N] and aReadr[2*i-N+1]. Whichever key is smaller, the +** aTree element is set to the index of it. +** +** For the purposes of this comparison, EOF is considered greater than any +** other key value. If the keys are equal (only possible with two EOF +** values), it doesn't matter which index is stored. +** +** The (N/4) elements of aTree[] that precede the final (N/2) described +** above contains the index of the smallest of each block of 4 PmaReaders +** And so on. So that aTree[1] contains the index of the PmaReader that +** currently points to the smallest key value. aTree[0] is unused. +** +** Example: +** +** aReadr[0] -> Banana +** aReadr[1] -> Feijoa +** aReadr[2] -> Elderberry +** aReadr[3] -> Currant +** aReadr[4] -> Grapefruit +** aReadr[5] -> Apple +** aReadr[6] -> Durian +** aReadr[7] -> EOF +** +** aTree[] = { X, 5 0, 5 0, 3, 5, 6 } +** +** The current element is "Apple" (the value of the key indicated by +** PmaReader 5). When the Next() operation is invoked, PmaReader 5 will +** be advanced to the next key in its segment. Say the next key is +** "Eggplant": +** +** aReadr[5] -> Eggplant +** +** The contents of aTree[] are updated first by comparing the new PmaReader +** 5 key to the current key of PmaReader 4 (still "Grapefruit"). The PmaReader +** 5 value is still smaller, so aTree[6] is set to 5. And so on up the tree. +** The value of PmaReader 6 - "Durian" - is now smaller than that of PmaReader +** 5, so aTree[3] is set to 6. Key 0 is smaller than key 6 (Bananafile2. And instead of using a +** background thread to prepare data for the PmaReader, with a single +** threaded IncrMerger the allocate part of pTask->file2 is "refilled" with +** keys from pMerger by the calling thread whenever the PmaReader runs out +** of data. +*/ +struct IncrMerger { + SortSubtask *pTask; /* Task that owns this merger */ + MergeEngine *pMerger; /* Merge engine thread reads data from */ + i64 iStartOff; /* Offset to start writing file at */ + int mxSz; /* Maximum bytes of data to store */ + int bEof; /* Set to true when merge is finished */ + int bUseThread; /* True to use a bg thread for this object */ + SorterFile aFile[2]; /* aFile[0] for reading, [1] for writing */ +}; + +/* +** An instance of this object is used for writing a PMA. +** +** The PMA is written one record at a time. Each record is of an arbitrary +** size. But I/O is more efficient if it occurs in page-sized blocks where +** each block is aligned on a page boundary. This object caches writes to +** the PMA so that aligned, page-size blocks are written. +*/ +struct PmaWriter { + int eFWErr; /* Non-zero if in an error state */ + u8 *aBuffer; /* Pointer to write buffer */ + int nBuffer; /* Size of write buffer in bytes */ + int iBufStart; /* First byte of buffer to write */ + int iBufEnd; /* Last byte of buffer to write */ + i64 iWriteOff; /* Offset of start of buffer in file */ + sqlite3_file *pFd; /* File handle to write to */ +}; + +/* +** This object is the header on a single record while that record is being +** held in memory and prior to being written out as part of a PMA. +** +** How the linked list is connected depends on how memory is being managed +** by this module. If using a separate allocation for each in-memory record +** (VdbeSorter.list.aMemory==0), then the list is always connected using the +** SorterRecord.u.pNext pointers. +** +** Or, if using the single large allocation method (VdbeSorter.list.aMemory!=0), +** then while records are being accumulated the list is linked using the +** SorterRecord.u.iNext offset. This is because the aMemory[] array may +** be sqlite3Realloc()ed while records are being accumulated. Once the VM +** has finished passing records to the sorter, or when the in-memory buffer +** is full, the list is sorted. As part of the sorting process, it is +** converted to use the SorterRecord.u.pNext pointers. See function +** vdbeSorterSort() for details. +*/ +struct SorterRecord { + int nVal; /* Size of the record in bytes */ + union { + SorterRecord *pNext; /* Pointer to next record in list */ + int iNext; /* Offset within aMemory of next record */ + } u; + /* The data for the record immediately follows this header */ +}; + +/* Return a pointer to the buffer containing the record data for SorterRecord +** object p. Should be used as if: +** +** void *SRVAL(SorterRecord *p) { return (void*)&p[1]; } +*/ +#define SRVAL(p) ((void*)((SorterRecord*)(p) + 1)) + + +/* Maximum number of PMAs that a single MergeEngine can merge */ +#define SORTER_MAX_MERGE_COUNT 16 + +static int vdbeIncrSwap(IncrMerger*); +static void vdbeIncrFree(IncrMerger *); + +/* +** Free all memory belonging to the PmaReader object passed as the +** argument. All structure fields are set to zero before returning. +*/ +static void vdbePmaReaderClear(PmaReader *pReadr){ + sqlite3_free(pReadr->aAlloc); + sqlite3_free(pReadr->aBuffer); + if( pReadr->aMap ) sqlite3OsUnfetch(pReadr->pFd, 0, pReadr->aMap); + vdbeIncrFree(pReadr->pIncr); + memset(pReadr, 0, sizeof(PmaReader)); +} + +/* +** Read the next nByte bytes of data from the PMA p. +** If successful, set *ppOut to point to a buffer containing the data +** and return SQLITE_OK. Otherwise, if an error occurs, return an SQLite +** error code. +** +** The buffer returned in *ppOut is only valid until the +** next call to this function. +*/ +static int vdbePmaReadBlob( + PmaReader *p, /* PmaReader from which to take the blob */ + int nByte, /* Bytes of data to read */ + u8 **ppOut /* OUT: Pointer to buffer containing data */ +){ + int iBuf; /* Offset within buffer to read from */ + int nAvail; /* Bytes of data available in buffer */ + + if( p->aMap ){ + *ppOut = &p->aMap[p->iReadOff]; + p->iReadOff += nByte; + return SQLITE_OK; + } + + assert( p->aBuffer ); + + /* If there is no more data to be read from the buffer, read the next + ** p->nBuffer bytes of data from the file into it. Or, if there are less + ** than p->nBuffer bytes remaining in the PMA, read all remaining data. */ + iBuf = p->iReadOff % p->nBuffer; + if( iBuf==0 ){ + int nRead; /* Bytes to read from disk */ + int rc; /* sqlite3OsRead() return code */ + + /* Determine how many bytes of data to read. */ + if( (p->iEof - p->iReadOff) > (i64)p->nBuffer ){ + nRead = p->nBuffer; + }else{ + nRead = (int)(p->iEof - p->iReadOff); + } + assert( nRead>0 ); + + /* Readr data from the file. Return early if an error occurs. */ + rc = sqlite3OsRead(p->pFd, p->aBuffer, nRead, p->iReadOff); + assert( rc!=SQLITE_IOERR_SHORT_READ ); + if( rc!=SQLITE_OK ) return rc; + } + nAvail = p->nBuffer - iBuf; + + if( nByte<=nAvail ){ + /* The requested data is available in the in-memory buffer. In this + ** case there is no need to make a copy of the data, just return a + ** pointer into the buffer to the caller. */ + *ppOut = &p->aBuffer[iBuf]; + p->iReadOff += nByte; + }else{ + /* The requested data is not all available in the in-memory buffer. + ** In this case, allocate space at p->aAlloc[] to copy the requested + ** range into. Then return a copy of pointer p->aAlloc to the caller. */ + int nRem; /* Bytes remaining to copy */ + + /* Extend the p->aAlloc[] allocation if required. */ + if( p->nAllocnAlloc*2); + while( nByte>nNew ) nNew = nNew*2; + aNew = sqlite3Realloc(p->aAlloc, nNew); + if( !aNew ) return SQLITE_NOMEM; + p->nAlloc = nNew; + p->aAlloc = aNew; + } + + /* Copy as much data as is available in the buffer into the start of + ** p->aAlloc[]. */ + memcpy(p->aAlloc, &p->aBuffer[iBuf], nAvail); + p->iReadOff += nAvail; + nRem = nByte - nAvail; + + /* The following loop copies up to p->nBuffer bytes per iteration into + ** the p->aAlloc[] buffer. */ + while( nRem>0 ){ + int rc; /* vdbePmaReadBlob() return code */ + int nCopy; /* Number of bytes to copy */ + u8 *aNext; /* Pointer to buffer to copy data from */ + + nCopy = nRem; + if( nRem>p->nBuffer ) nCopy = p->nBuffer; + rc = vdbePmaReadBlob(p, nCopy, &aNext); + if( rc!=SQLITE_OK ) return rc; + assert( aNext!=p->aAlloc ); + memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy); + nRem -= nCopy; + } + + *ppOut = p->aAlloc; + } + + return SQLITE_OK; +} + +/* +** Read a varint from the stream of data accessed by p. Set *pnOut to +** the value read. +*/ +static int vdbePmaReadVarint(PmaReader *p, u64 *pnOut){ + int iBuf; + + if( p->aMap ){ + p->iReadOff += sqlite3GetVarint(&p->aMap[p->iReadOff], pnOut); + }else{ + iBuf = p->iReadOff % p->nBuffer; + if( iBuf && (p->nBuffer-iBuf)>=9 ){ + p->iReadOff += sqlite3GetVarint(&p->aBuffer[iBuf], pnOut); + }else{ + u8 aVarint[16], *a; + int i = 0, rc; + do{ + rc = vdbePmaReadBlob(p, 1, &a); + if( rc ) return rc; + aVarint[(i++)&0xf] = a[0]; + }while( (a[0]&0x80)!=0 ); + sqlite3GetVarint(aVarint, pnOut); + } + } + + return SQLITE_OK; +} + +/* +** Attempt to memory map file pFile. If successful, set *pp to point to the +** new mapping and return SQLITE_OK. If the mapping is not attempted +** (because the file is too large or the VFS layer is configured not to use +** mmap), return SQLITE_OK and set *pp to NULL. +** +** Or, if an error occurs, return an SQLite error code. The final value of +** *pp is undefined in this case. +*/ +static int vdbeSorterMapFile(SortSubtask *pTask, SorterFile *pFile, u8 **pp){ + int rc = SQLITE_OK; + if( pFile->iEof<=(i64)(pTask->pSorter->db->nMaxSorterMmap) ){ + sqlite3_file *pFd = pFile->pFd; + if( pFd->pMethods->iVersion>=3 ){ + rc = sqlite3OsFetch(pFd, 0, (int)pFile->iEof, (void**)pp); + testcase( rc!=SQLITE_OK ); + } + } + return rc; +} + +/* +** Attach PmaReader pReadr to file pFile (if it is not already attached to +** that file) and seek it to offset iOff within the file. Return SQLITE_OK +** if successful, or an SQLite error code if an error occurs. +*/ +static int vdbePmaReaderSeek( + SortSubtask *pTask, /* Task context */ + PmaReader *pReadr, /* Reader whose cursor is to be moved */ + SorterFile *pFile, /* Sorter file to read from */ + i64 iOff /* Offset in pFile */ +){ + int rc = SQLITE_OK; + + assert( pReadr->pIncr==0 || pReadr->pIncr->bEof==0 ); + + if( sqlite3FaultSim(201) ) return SQLITE_IOERR_READ; + if( pReadr->aMap ){ + sqlite3OsUnfetch(pReadr->pFd, 0, pReadr->aMap); + pReadr->aMap = 0; + } + pReadr->iReadOff = iOff; + pReadr->iEof = pFile->iEof; + pReadr->pFd = pFile->pFd; + + rc = vdbeSorterMapFile(pTask, pFile, &pReadr->aMap); + if( rc==SQLITE_OK && pReadr->aMap==0 ){ + int pgsz = pTask->pSorter->pgsz; + int iBuf = pReadr->iReadOff % pgsz; + if( pReadr->aBuffer==0 ){ + pReadr->aBuffer = (u8*)sqlite3Malloc(pgsz); + if( pReadr->aBuffer==0 ) rc = SQLITE_NOMEM; + pReadr->nBuffer = pgsz; + } + if( rc==SQLITE_OK && iBuf ){ + int nRead = pgsz - iBuf; + if( (pReadr->iReadOff + nRead) > pReadr->iEof ){ + nRead = (int)(pReadr->iEof - pReadr->iReadOff); + } + rc = sqlite3OsRead( + pReadr->pFd, &pReadr->aBuffer[iBuf], nRead, pReadr->iReadOff + ); + testcase( rc!=SQLITE_OK ); + } + } + + return rc; +} + +/* +** Advance PmaReader pReadr to the next key in its PMA. Return SQLITE_OK if +** no error occurs, or an SQLite error code if one does. +*/ +static int vdbePmaReaderNext(PmaReader *pReadr){ + int rc = SQLITE_OK; /* Return Code */ + u64 nRec = 0; /* Size of record in bytes */ + + + if( pReadr->iReadOff>=pReadr->iEof ){ + IncrMerger *pIncr = pReadr->pIncr; + int bEof = 1; + if( pIncr ){ + rc = vdbeIncrSwap(pIncr); + if( rc==SQLITE_OK && pIncr->bEof==0 ){ + rc = vdbePmaReaderSeek( + pIncr->pTask, pReadr, &pIncr->aFile[0], pIncr->iStartOff + ); + bEof = 0; + } + } + + if( bEof ){ + /* This is an EOF condition */ + vdbePmaReaderClear(pReadr); + testcase( rc!=SQLITE_OK ); + return rc; + } + } + + if( rc==SQLITE_OK ){ + rc = vdbePmaReadVarint(pReadr, &nRec); + } + if( rc==SQLITE_OK ){ + pReadr->nKey = (int)nRec; + rc = vdbePmaReadBlob(pReadr, (int)nRec, &pReadr->aKey); + testcase( rc!=SQLITE_OK ); + } + + return rc; +} + +/* +** Initialize PmaReader pReadr to scan through the PMA stored in file pFile +** starting at offset iStart and ending at offset iEof-1. This function +** leaves the PmaReader pointing to the first key in the PMA (or EOF if the +** PMA is empty). +** +** If the pnByte parameter is NULL, then it is assumed that the file +** contains a single PMA, and that that PMA omits the initial length varint. +*/ +static int vdbePmaReaderInit( + SortSubtask *pTask, /* Task context */ + SorterFile *pFile, /* Sorter file to read from */ + i64 iStart, /* Start offset in pFile */ + PmaReader *pReadr, /* PmaReader to populate */ + i64 *pnByte /* IN/OUT: Increment this value by PMA size */ +){ + int rc; + + assert( pFile->iEof>iStart ); + assert( pReadr->aAlloc==0 && pReadr->nAlloc==0 ); + assert( pReadr->aBuffer==0 ); + assert( pReadr->aMap==0 ); + + rc = vdbePmaReaderSeek(pTask, pReadr, pFile, iStart); + if( rc==SQLITE_OK ){ + u64 nByte; /* Size of PMA in bytes */ + rc = vdbePmaReadVarint(pReadr, &nByte); + pReadr->iEof = pReadr->iReadOff + nByte; + *pnByte += nByte; + } + + if( rc==SQLITE_OK ){ + rc = vdbePmaReaderNext(pReadr); + } + return rc; +} + +/* +** A version of vdbeSorterCompare() that assumes that it has already been +** determined that the first field of key1 is equal to the first field of +** key2. +*/ +static int vdbeSorterCompareTail( + SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ + int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ + const void *pKey1, int nKey1, /* Left side of comparison */ + const void *pKey2, int nKey2 /* Right side of comparison */ +){ + UnpackedRecord *r2 = pTask->pUnpacked; + if( *pbKey2Cached==0 ){ + sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); + *pbKey2Cached = 1; + } + return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, r2, 1); +} + +/* +** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2, +** size nKey2 bytes). Use (pTask->pKeyInfo) for the collation sequences +** used by the comparison. Return the result of the comparison. +** +** If IN/OUT parameter *pbKey2Cached is true when this function is called, +** it is assumed that (pTask->pUnpacked) contains the unpacked version +** of key2. If it is false, (pTask->pUnpacked) is populated with the unpacked +** version of key2 and *pbKey2Cached set to true before returning. +** +** If an OOM error is encountered, (pTask->pUnpacked->error_rc) is set +** to SQLITE_NOMEM. +*/ +static int vdbeSorterCompare( + SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ + int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ + const void *pKey1, int nKey1, /* Left side of comparison */ + const void *pKey2, int nKey2 /* Right side of comparison */ +){ + UnpackedRecord *r2 = pTask->pUnpacked; + if( !*pbKey2Cached ){ + sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); + *pbKey2Cached = 1; + } + return sqlite3VdbeRecordCompare(nKey1, pKey1, r2); +} + +/* +** A specially optimized version of vdbeSorterCompare() that assumes that +** the first field of each key is a TEXT value and that the collation +** sequence to compare them with is BINARY. +*/ +static int vdbeSorterCompareText( + SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ + int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ + const void *pKey1, int nKey1, /* Left side of comparison */ + const void *pKey2, int nKey2 /* Right side of comparison */ +){ + const u8 * const p1 = (const u8 * const)pKey1; + const u8 * const p2 = (const u8 * const)pKey2; + const u8 * const v1 = &p1[ p1[0] ]; /* Pointer to value 1 */ + const u8 * const v2 = &p2[ p2[0] ]; /* Pointer to value 2 */ + + int n1; + int n2; + int res; + + getVarint32(&p1[1], n1); n1 = (n1 - 13) / 2; + getVarint32(&p2[1], n2); n2 = (n2 - 13) / 2; + res = memcmp(v1, v2, MIN(n1, n2)); + if( res==0 ){ + res = n1 - n2; + } + + if( res==0 ){ + if( pTask->pSorter->pKeyInfo->nField>1 ){ + res = vdbeSorterCompareTail( + pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 + ); + } + }else{ + if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){ + res = res * -1; + } + } + + return res; +} + +/* +** A specially optimized version of vdbeSorterCompare() that assumes that +** the first field of each key is an INTEGER value. +*/ +static int vdbeSorterCompareInt( + SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ + int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ + const void *pKey1, int nKey1, /* Left side of comparison */ + const void *pKey2, int nKey2 /* Right side of comparison */ +){ + const u8 * const p1 = (const u8 * const)pKey1; + const u8 * const p2 = (const u8 * const)pKey2; + const int s1 = p1[1]; /* Left hand serial type */ + const int s2 = p2[1]; /* Right hand serial type */ + const u8 * const v1 = &p1[ p1[0] ]; /* Pointer to value 1 */ + const u8 * const v2 = &p2[ p2[0] ]; /* Pointer to value 2 */ + int res; /* Return value */ + + assert( (s1>0 && s1<7) || s1==8 || s1==9 ); + assert( (s2>0 && s2<7) || s2==8 || s2==9 ); + + if( s1>7 && s2>7 ){ + res = s1 - s2; + }else{ + if( s1==s2 ){ + if( (*v1 ^ *v2) & 0x80 ){ + /* The two values have different signs */ + res = (*v1 & 0x80) ? -1 : +1; + }else{ + /* The two values have the same sign. Compare using memcmp(). */ + static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8 }; + int i; + res = 0; + for(i=0; i7 ){ + res = +1; + }else if( s1>7 ){ + res = -1; + }else{ + res = s1 - s2; + } + assert( res!=0 ); + + if( res>0 ){ + if( *v1 & 0x80 ) res = -1; + }else{ + if( *v2 & 0x80 ) res = +1; + } + } + } + + if( res==0 ){ + if( pTask->pSorter->pKeyInfo->nField>1 ){ + res = vdbeSorterCompareTail( + pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 + ); + } + }else if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){ + res = res * -1; + } + + return res; +} + +/* +** Initialize the temporary index cursor just opened as a sorter cursor. +** +** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nField) +** to determine the number of fields that should be compared from the +** records being sorted. However, if the value passed as argument nField +** is non-zero and the sorter is able to guarantee a stable sort, nField +** is used instead. This is used when sorting records for a CREATE INDEX +** statement. In this case, keys are always delivered to the sorter in +** order of the primary key, which happens to be make up the final part +** of the records being sorted. So if the sort is stable, there is never +** any reason to compare PK fields and they can be ignored for a small +** performance boost. +** +** The sorter can guarantee a stable sort when running in single-threaded +** mode, but not in multi-threaded mode. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterInit( + sqlite3 *db, /* Database connection (for malloc()) */ + int nField, /* Number of key fields in each record */ + VdbeCursor *pCsr /* Cursor that holds the new sorter */ +){ + int pgsz; /* Page size of main database */ + int i; /* Used to iterate through aTask[] */ + int mxCache; /* Cache size */ + VdbeSorter *pSorter; /* The new sorter */ + KeyInfo *pKeyInfo; /* Copy of pCsr->pKeyInfo with db==0 */ + int szKeyInfo; /* Size of pCsr->pKeyInfo in bytes */ + int sz; /* Size of pSorter in bytes */ + int rc = SQLITE_OK; +#if SQLITE_MAX_WORKER_THREADS==0 +# define nWorker 0 +#else + int nWorker; +#endif + + /* Initialize the upper limit on the number of worker threads */ +#if SQLITE_MAX_WORKER_THREADS>0 + if( sqlite3TempInMemory(db) || sqlite3GlobalConfig.bCoreMutex==0 ){ + nWorker = 0; + }else{ + nWorker = db->aLimit[SQLITE_LIMIT_WORKER_THREADS]; + } +#endif + + /* Do not allow the total number of threads (main thread + all workers) + ** to exceed the maximum merge count */ +#if SQLITE_MAX_WORKER_THREADS>=SORTER_MAX_MERGE_COUNT + if( nWorker>=SORTER_MAX_MERGE_COUNT ){ + nWorker = SORTER_MAX_MERGE_COUNT-1; + } +#endif + + assert( pCsr->pKeyInfo && pCsr->pBt==0 ); + szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nField-1)*sizeof(CollSeq*); + sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask); + + pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); + pCsr->pSorter = pSorter; + if( pSorter==0 ){ + rc = SQLITE_NOMEM; + }else{ + pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz); + memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo); + pKeyInfo->db = 0; + if( nField && nWorker==0 ){ + pKeyInfo->nXField += (pKeyInfo->nField - nField); + pKeyInfo->nField = nField; + } + pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt); + pSorter->nTask = nWorker + 1; + pSorter->iPrev = nWorker-1; + pSorter->bUseThreads = (pSorter->nTask>1); + pSorter->db = db; + for(i=0; inTask; i++){ + SortSubtask *pTask = &pSorter->aTask[i]; + pTask->pSorter = pSorter; + } + + if( !sqlite3TempInMemory(db) ){ + u32 szPma = sqlite3GlobalConfig.szPma; + pSorter->mnPmaSize = szPma * pgsz; + mxCache = db->aDb[0].pSchema->cache_size; + if( mxCache<(int)szPma ) mxCache = (int)szPma; + pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_PMASZ); + + /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of + ** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary + ** large heap allocations. + */ + if( sqlite3GlobalConfig.pScratch==0 ){ + assert( pSorter->iMemory==0 ); + pSorter->nMemory = pgsz; + pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz); + if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM; + } + } + + if( (pKeyInfo->nField+pKeyInfo->nXField)<13 + && (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl) + ){ + pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT; + } + } + + return rc; +} +#undef nWorker /* Defined at the top of this function */ + +/* +** Free the list of sorted records starting at pRecord. +*/ +static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){ + SorterRecord *p; + SorterRecord *pNext; + for(p=pRecord; p; p=pNext){ + pNext = p->u.pNext; + sqlite3DbFree(db, p); + } +} + +/* +** Free all resources owned by the object indicated by argument pTask. All +** fields of *pTask are zeroed before returning. +*/ +static void vdbeSortSubtaskCleanup(sqlite3 *db, SortSubtask *pTask){ + sqlite3DbFree(db, pTask->pUnpacked); +#if SQLITE_MAX_WORKER_THREADS>0 + /* pTask->list.aMemory can only be non-zero if it was handed memory + ** from the main thread. That only occurs SQLITE_MAX_WORKER_THREADS>0 */ + if( pTask->list.aMemory ){ + sqlite3_free(pTask->list.aMemory); + }else +#endif + { + assert( pTask->list.aMemory==0 ); + vdbeSorterRecordFree(0, pTask->list.pList); + } + if( pTask->file.pFd ){ + sqlite3OsCloseFree(pTask->file.pFd); + } + if( pTask->file2.pFd ){ + sqlite3OsCloseFree(pTask->file2.pFd); + } + memset(pTask, 0, sizeof(SortSubtask)); +} + +#ifdef SQLITE_DEBUG_SORTER_THREADS +static void vdbeSorterWorkDebug(SortSubtask *pTask, const char *zEvent){ + i64 t; + int iTask = (pTask - pTask->pSorter->aTask); + sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); + fprintf(stderr, "%lld:%d %s\n", t, iTask, zEvent); +} +static void vdbeSorterRewindDebug(const char *zEvent){ + i64 t; + sqlite3OsCurrentTimeInt64(sqlite3_vfs_find(0), &t); + fprintf(stderr, "%lld:X %s\n", t, zEvent); +} +static void vdbeSorterPopulateDebug( + SortSubtask *pTask, + const char *zEvent +){ + i64 t; + int iTask = (pTask - pTask->pSorter->aTask); + sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); + fprintf(stderr, "%lld:bg%d %s\n", t, iTask, zEvent); +} +static void vdbeSorterBlockDebug( + SortSubtask *pTask, + int bBlocked, + const char *zEvent +){ + if( bBlocked ){ + i64 t; + sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); + fprintf(stderr, "%lld:main %s\n", t, zEvent); + } +} +#else +# define vdbeSorterWorkDebug(x,y) +# define vdbeSorterRewindDebug(y) +# define vdbeSorterPopulateDebug(x,y) +# define vdbeSorterBlockDebug(x,y,z) +#endif + +#if SQLITE_MAX_WORKER_THREADS>0 +/* +** Join thread pTask->thread. +*/ +static int vdbeSorterJoinThread(SortSubtask *pTask){ + int rc = SQLITE_OK; + if( pTask->pThread ){ +#ifdef SQLITE_DEBUG_SORTER_THREADS + int bDone = pTask->bDone; +#endif + void *pRet = SQLITE_INT_TO_PTR(SQLITE_ERROR); + vdbeSorterBlockDebug(pTask, !bDone, "enter"); + (void)sqlite3ThreadJoin(pTask->pThread, &pRet); + vdbeSorterBlockDebug(pTask, !bDone, "exit"); + rc = SQLITE_PTR_TO_INT(pRet); + assert( pTask->bDone==1 ); + pTask->bDone = 0; + pTask->pThread = 0; + } + return rc; +} + +/* +** Launch a background thread to run xTask(pIn). +*/ +static int vdbeSorterCreateThread( + SortSubtask *pTask, /* Thread will use this task object */ + void *(*xTask)(void*), /* Routine to run in a separate thread */ + void *pIn /* Argument passed into xTask() */ +){ + assert( pTask->pThread==0 && pTask->bDone==0 ); + return sqlite3ThreadCreate(&pTask->pThread, xTask, pIn); +} + +/* +** Join all outstanding threads launched by SorterWrite() to create +** level-0 PMAs. +*/ +static int vdbeSorterJoinAll(VdbeSorter *pSorter, int rcin){ + int rc = rcin; + int i; + + /* This function is always called by the main user thread. + ** + ** If this function is being called after SorterRewind() has been called, + ** it is possible that thread pSorter->aTask[pSorter->nTask-1].pThread + ** is currently attempt to join one of the other threads. To avoid a race + ** condition where this thread also attempts to join the same object, join + ** thread pSorter->aTask[pSorter->nTask-1].pThread first. */ + for(i=pSorter->nTask-1; i>=0; i--){ + SortSubtask *pTask = &pSorter->aTask[i]; + int rc2 = vdbeSorterJoinThread(pTask); + if( rc==SQLITE_OK ) rc = rc2; + } + return rc; +} +#else +# define vdbeSorterJoinAll(x,rcin) (rcin) +# define vdbeSorterJoinThread(pTask) SQLITE_OK +#endif + +/* +** Allocate a new MergeEngine object capable of handling up to +** nReader PmaReader inputs. +** +** nReader is automatically rounded up to the next power of two. +** nReader may not exceed SORTER_MAX_MERGE_COUNT even after rounding up. +*/ +static MergeEngine *vdbeMergeEngineNew(int nReader){ + int N = 2; /* Smallest power of two >= nReader */ + int nByte; /* Total bytes of space to allocate */ + MergeEngine *pNew; /* Pointer to allocated object to return */ + + assert( nReader<=SORTER_MAX_MERGE_COUNT ); + + while( NnTree = N; + pNew->pTask = 0; + pNew->aReadr = (PmaReader*)&pNew[1]; + pNew->aTree = (int*)&pNew->aReadr[N]; + } + return pNew; +} + +/* +** Free the MergeEngine object passed as the only argument. +*/ +static void vdbeMergeEngineFree(MergeEngine *pMerger){ + int i; + if( pMerger ){ + for(i=0; inTree; i++){ + vdbePmaReaderClear(&pMerger->aReadr[i]); + } + } + sqlite3_free(pMerger); +} + +/* +** Free all resources associated with the IncrMerger object indicated by +** the first argument. +*/ +static void vdbeIncrFree(IncrMerger *pIncr){ + if( pIncr ){ +#if SQLITE_MAX_WORKER_THREADS>0 + if( pIncr->bUseThread ){ + vdbeSorterJoinThread(pIncr->pTask); + if( pIncr->aFile[0].pFd ) sqlite3OsCloseFree(pIncr->aFile[0].pFd); + if( pIncr->aFile[1].pFd ) sqlite3OsCloseFree(pIncr->aFile[1].pFd); + } +#endif + vdbeMergeEngineFree(pIncr->pMerger); + sqlite3_free(pIncr); + } +} + +/* +** Reset a sorting cursor back to its original empty state. +*/ +SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *db, VdbeSorter *pSorter){ + int i; + (void)vdbeSorterJoinAll(pSorter, SQLITE_OK); + assert( pSorter->bUseThreads || pSorter->pReader==0 ); +#if SQLITE_MAX_WORKER_THREADS>0 + if( pSorter->pReader ){ + vdbePmaReaderClear(pSorter->pReader); + sqlite3DbFree(db, pSorter->pReader); + pSorter->pReader = 0; + } +#endif + vdbeMergeEngineFree(pSorter->pMerger); + pSorter->pMerger = 0; + for(i=0; inTask; i++){ + SortSubtask *pTask = &pSorter->aTask[i]; + vdbeSortSubtaskCleanup(db, pTask); + pTask->pSorter = pSorter; + } + if( pSorter->list.aMemory==0 ){ + vdbeSorterRecordFree(0, pSorter->list.pList); + } + pSorter->list.pList = 0; + pSorter->list.szPMA = 0; + pSorter->bUsePMA = 0; + pSorter->iMemory = 0; + pSorter->mxKeysize = 0; + sqlite3DbFree(db, pSorter->pUnpacked); + pSorter->pUnpacked = 0; +} + +/* +** Free any cursor components allocated by sqlite3VdbeSorterXXX routines. +*/ +SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){ + VdbeSorter *pSorter = pCsr->pSorter; + if( pSorter ){ + sqlite3VdbeSorterReset(db, pSorter); + sqlite3_free(pSorter->list.aMemory); + sqlite3DbFree(db, pSorter); + pCsr->pSorter = 0; + } +} + +#if SQLITE_MAX_MMAP_SIZE>0 +/* +** The first argument is a file-handle open on a temporary file. The file +** is guaranteed to be nByte bytes or smaller in size. This function +** attempts to extend the file to nByte bytes in size and to ensure that +** the VFS has memory mapped it. +** +** Whether or not the file does end up memory mapped of course depends on +** the specific VFS implementation. +*/ +static void vdbeSorterExtendFile(sqlite3 *db, sqlite3_file *pFd, i64 nByte){ + if( nByte<=(i64)(db->nMaxSorterMmap) && pFd->pMethods->iVersion>=3 ){ + void *p = 0; + int chunksize = 4*1024; + sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_CHUNK_SIZE, &chunksize); + sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_SIZE_HINT, &nByte); + sqlite3OsFetch(pFd, 0, (int)nByte, &p); + sqlite3OsUnfetch(pFd, 0, p); + } +} +#else +# define vdbeSorterExtendFile(x,y,z) +#endif + +/* +** Allocate space for a file-handle and open a temporary file. If successful, +** set *ppFd to point to the malloc'd file-handle and return SQLITE_OK. +** Otherwise, set *ppFd to 0 and return an SQLite error code. +*/ +static int vdbeSorterOpenTempFile( + sqlite3 *db, /* Database handle doing sort */ + i64 nExtend, /* Attempt to extend file to this size */ + sqlite3_file **ppFd +){ + int rc; + if( sqlite3FaultSim(202) ) return SQLITE_IOERR_ACCESS; + rc = sqlite3OsOpenMalloc(db->pVfs, 0, ppFd, + SQLITE_OPEN_TEMP_JOURNAL | + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | + SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE, &rc + ); + if( rc==SQLITE_OK ){ + i64 max = SQLITE_MAX_MMAP_SIZE; + sqlite3OsFileControlHint(*ppFd, SQLITE_FCNTL_MMAP_SIZE, (void*)&max); + if( nExtend>0 ){ + vdbeSorterExtendFile(db, *ppFd, nExtend); + } + } + return rc; +} + +/* +** If it has not already been allocated, allocate the UnpackedRecord +** structure at pTask->pUnpacked. Return SQLITE_OK if successful (or +** if no allocation was required), or SQLITE_NOMEM otherwise. +*/ +static int vdbeSortAllocUnpacked(SortSubtask *pTask){ + if( pTask->pUnpacked==0 ){ + char *pFree; + pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord( + pTask->pSorter->pKeyInfo, 0, 0, &pFree + ); + assert( pTask->pUnpacked==(UnpackedRecord*)pFree ); + if( pFree==0 ) return SQLITE_NOMEM; + pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nField; + pTask->pUnpacked->errCode = 0; + } + return SQLITE_OK; +} + + +/* +** Merge the two sorted lists p1 and p2 into a single list. +** Set *ppOut to the head of the new list. +*/ +static void vdbeSorterMerge( + SortSubtask *pTask, /* Calling thread context */ + SorterRecord *p1, /* First list to merge */ + SorterRecord *p2, /* Second list to merge */ + SorterRecord **ppOut /* OUT: Head of merged list */ +){ + SorterRecord *pFinal = 0; + SorterRecord **pp = &pFinal; + int bCached = 0; + + while( p1 && p2 ){ + int res; + res = pTask->xCompare( + pTask, &bCached, SRVAL(p1), p1->nVal, SRVAL(p2), p2->nVal + ); + + if( res<=0 ){ + *pp = p1; + pp = &p1->u.pNext; + p1 = p1->u.pNext; + }else{ + *pp = p2; + pp = &p2->u.pNext; + p2 = p2->u.pNext; + bCached = 0; + } + } + *pp = p1 ? p1 : p2; + *ppOut = pFinal; +} + +/* +** Return the SorterCompare function to compare values collected by the +** sorter object passed as the only argument. +*/ +static SorterCompare vdbeSorterGetCompare(VdbeSorter *p){ + if( p->typeMask==SORTER_TYPE_INTEGER ){ + return vdbeSorterCompareInt; + }else if( p->typeMask==SORTER_TYPE_TEXT ){ + return vdbeSorterCompareText; + } + return vdbeSorterCompare; +} + +/* +** Sort the linked list of records headed at pTask->pList. Return +** SQLITE_OK if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if +** an error occurs. +*/ +static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){ + int i; + SorterRecord **aSlot; + SorterRecord *p; + int rc; + + rc = vdbeSortAllocUnpacked(pTask); + if( rc!=SQLITE_OK ) return rc; + + p = pList->pList; + pTask->xCompare = vdbeSorterGetCompare(pTask->pSorter); + + aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *)); + if( !aSlot ){ + return SQLITE_NOMEM; + } + + while( p ){ + SorterRecord *pNext; + if( pList->aMemory ){ + if( (u8*)p==pList->aMemory ){ + pNext = 0; + }else{ + assert( p->u.iNextaMemory) ); + pNext = (SorterRecord*)&pList->aMemory[p->u.iNext]; + } + }else{ + pNext = p->u.pNext; + } + + p->u.pNext = 0; + for(i=0; aSlot[i]; i++){ + vdbeSorterMerge(pTask, p, aSlot[i], &p); + aSlot[i] = 0; + } + aSlot[i] = p; + p = pNext; + } + + p = 0; + for(i=0; i<64; i++){ + vdbeSorterMerge(pTask, p, aSlot[i], &p); + } + pList->pList = p; + + sqlite3_free(aSlot); + assert( pTask->pUnpacked->errCode==SQLITE_OK + || pTask->pUnpacked->errCode==SQLITE_NOMEM + ); + return pTask->pUnpacked->errCode; +} + +/* +** Initialize a PMA-writer object. +*/ +static void vdbePmaWriterInit( + sqlite3_file *pFd, /* File handle to write to */ + PmaWriter *p, /* Object to populate */ + int nBuf, /* Buffer size */ + i64 iStart /* Offset of pFd to begin writing at */ +){ + memset(p, 0, sizeof(PmaWriter)); + p->aBuffer = (u8*)sqlite3Malloc(nBuf); + if( !p->aBuffer ){ + p->eFWErr = SQLITE_NOMEM; + }else{ + p->iBufEnd = p->iBufStart = (iStart % nBuf); + p->iWriteOff = iStart - p->iBufStart; + p->nBuffer = nBuf; + p->pFd = pFd; + } +} + +/* +** Write nData bytes of data to the PMA. Return SQLITE_OK +** if successful, or an SQLite error code if an error occurs. +*/ +static void vdbePmaWriteBlob(PmaWriter *p, u8 *pData, int nData){ + int nRem = nData; + while( nRem>0 && p->eFWErr==0 ){ + int nCopy = nRem; + if( nCopy>(p->nBuffer - p->iBufEnd) ){ + nCopy = p->nBuffer - p->iBufEnd; + } + + memcpy(&p->aBuffer[p->iBufEnd], &pData[nData-nRem], nCopy); + p->iBufEnd += nCopy; + if( p->iBufEnd==p->nBuffer ){ + p->eFWErr = sqlite3OsWrite(p->pFd, + &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, + p->iWriteOff + p->iBufStart + ); + p->iBufStart = p->iBufEnd = 0; + p->iWriteOff += p->nBuffer; + } + assert( p->iBufEndnBuffer ); + + nRem -= nCopy; + } +} + +/* +** Flush any buffered data to disk and clean up the PMA-writer object. +** The results of using the PMA-writer after this call are undefined. +** Return SQLITE_OK if flushing the buffered data succeeds or is not +** required. Otherwise, return an SQLite error code. +** +** Before returning, set *piEof to the offset immediately following the +** last byte written to the file. +*/ +static int vdbePmaWriterFinish(PmaWriter *p, i64 *piEof){ + int rc; + if( p->eFWErr==0 && ALWAYS(p->aBuffer) && p->iBufEnd>p->iBufStart ){ + p->eFWErr = sqlite3OsWrite(p->pFd, + &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, + p->iWriteOff + p->iBufStart + ); + } + *piEof = (p->iWriteOff + p->iBufEnd); + sqlite3_free(p->aBuffer); + rc = p->eFWErr; + memset(p, 0, sizeof(PmaWriter)); + return rc; +} + +/* +** Write value iVal encoded as a varint to the PMA. Return +** SQLITE_OK if successful, or an SQLite error code if an error occurs. +*/ +static void vdbePmaWriteVarint(PmaWriter *p, u64 iVal){ + int nByte; + u8 aByte[10]; + nByte = sqlite3PutVarint(aByte, iVal); + vdbePmaWriteBlob(p, aByte, nByte); +} + +/* +** Write the current contents of in-memory linked-list pList to a level-0 +** PMA in the temp file belonging to sub-task pTask. Return SQLITE_OK if +** successful, or an SQLite error code otherwise. +** +** The format of a PMA is: +** +** * A varint. This varint contains the total number of bytes of content +** in the PMA (not including the varint itself). +** +** * One or more records packed end-to-end in order of ascending keys. +** Each record consists of a varint followed by a blob of data (the +** key). The varint is the number of bytes in the blob of data. +*/ +static int vdbeSorterListToPMA(SortSubtask *pTask, SorterList *pList){ + sqlite3 *db = pTask->pSorter->db; + int rc = SQLITE_OK; /* Return code */ + PmaWriter writer; /* Object used to write to the file */ + +#ifdef SQLITE_DEBUG + /* Set iSz to the expected size of file pTask->file after writing the PMA. + ** This is used by an assert() statement at the end of this function. */ + i64 iSz = pList->szPMA + sqlite3VarintLen(pList->szPMA) + pTask->file.iEof; +#endif + + vdbeSorterWorkDebug(pTask, "enter"); + memset(&writer, 0, sizeof(PmaWriter)); + assert( pList->szPMA>0 ); + + /* If the first temporary PMA file has not been opened, open it now. */ + if( pTask->file.pFd==0 ){ + rc = vdbeSorterOpenTempFile(db, 0, &pTask->file.pFd); + assert( rc!=SQLITE_OK || pTask->file.pFd ); + assert( pTask->file.iEof==0 ); + assert( pTask->nPMA==0 ); + } + + /* Try to get the file to memory map */ + if( rc==SQLITE_OK ){ + vdbeSorterExtendFile(db, pTask->file.pFd, pTask->file.iEof+pList->szPMA+9); + } + + /* Sort the list */ + if( rc==SQLITE_OK ){ + rc = vdbeSorterSort(pTask, pList); + } + + if( rc==SQLITE_OK ){ + SorterRecord *p; + SorterRecord *pNext = 0; + + vdbePmaWriterInit(pTask->file.pFd, &writer, pTask->pSorter->pgsz, + pTask->file.iEof); + pTask->nPMA++; + vdbePmaWriteVarint(&writer, pList->szPMA); + for(p=pList->pList; p; p=pNext){ + pNext = p->u.pNext; + vdbePmaWriteVarint(&writer, p->nVal); + vdbePmaWriteBlob(&writer, SRVAL(p), p->nVal); + if( pList->aMemory==0 ) sqlite3_free(p); + } + pList->pList = p; + rc = vdbePmaWriterFinish(&writer, &pTask->file.iEof); + } + + vdbeSorterWorkDebug(pTask, "exit"); + assert( rc!=SQLITE_OK || pList->pList==0 ); + assert( rc!=SQLITE_OK || pTask->file.iEof==iSz ); + return rc; +} + +/* +** Advance the MergeEngine to its next entry. +** Set *pbEof to true there is no next entry because +** the MergeEngine has reached the end of all its inputs. +** +** Return SQLITE_OK if successful or an error code if an error occurs. +*/ +static int vdbeMergeEngineStep( + MergeEngine *pMerger, /* The merge engine to advance to the next row */ + int *pbEof /* Set TRUE at EOF. Set false for more content */ +){ + int rc; + int iPrev = pMerger->aTree[1];/* Index of PmaReader to advance */ + SortSubtask *pTask = pMerger->pTask; + + /* Advance the current PmaReader */ + rc = vdbePmaReaderNext(&pMerger->aReadr[iPrev]); + + /* Update contents of aTree[] */ + if( rc==SQLITE_OK ){ + int i; /* Index of aTree[] to recalculate */ + PmaReader *pReadr1; /* First PmaReader to compare */ + PmaReader *pReadr2; /* Second PmaReader to compare */ + int bCached = 0; + + /* Find the first two PmaReaders to compare. The one that was just + ** advanced (iPrev) and the one next to it in the array. */ + pReadr1 = &pMerger->aReadr[(iPrev & 0xFFFE)]; + pReadr2 = &pMerger->aReadr[(iPrev | 0x0001)]; + + for(i=(pMerger->nTree+iPrev)/2; i>0; i=i/2){ + /* Compare pReadr1 and pReadr2. Store the result in variable iRes. */ + int iRes; + if( pReadr1->pFd==0 ){ + iRes = +1; + }else if( pReadr2->pFd==0 ){ + iRes = -1; + }else{ + iRes = pTask->xCompare(pTask, &bCached, + pReadr1->aKey, pReadr1->nKey, pReadr2->aKey, pReadr2->nKey + ); + } + + /* If pReadr1 contained the smaller value, set aTree[i] to its index. + ** Then set pReadr2 to the next PmaReader to compare to pReadr1. In this + ** case there is no cache of pReadr2 in pTask->pUnpacked, so set + ** pKey2 to point to the record belonging to pReadr2. + ** + ** Alternatively, if pReadr2 contains the smaller of the two values, + ** set aTree[i] to its index and update pReadr1. If vdbeSorterCompare() + ** was actually called above, then pTask->pUnpacked now contains + ** a value equivalent to pReadr2. So set pKey2 to NULL to prevent + ** vdbeSorterCompare() from decoding pReadr2 again. + ** + ** If the two values were equal, then the value from the oldest + ** PMA should be considered smaller. The VdbeSorter.aReadr[] array + ** is sorted from oldest to newest, so pReadr1 contains older values + ** than pReadr2 iff (pReadr1aTree[i] = (int)(pReadr1 - pMerger->aReadr); + pReadr2 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ]; + bCached = 0; + }else{ + if( pReadr1->pFd ) bCached = 0; + pMerger->aTree[i] = (int)(pReadr2 - pMerger->aReadr); + pReadr1 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ]; + } + } + *pbEof = (pMerger->aReadr[pMerger->aTree[1]].pFd==0); + } + + return (rc==SQLITE_OK ? pTask->pUnpacked->errCode : rc); +} + +#if SQLITE_MAX_WORKER_THREADS>0 +/* +** The main routine for background threads that write level-0 PMAs. +*/ +static void *vdbeSorterFlushThread(void *pCtx){ + SortSubtask *pTask = (SortSubtask*)pCtx; + int rc; /* Return code */ + assert( pTask->bDone==0 ); + rc = vdbeSorterListToPMA(pTask, &pTask->list); + pTask->bDone = 1; + return SQLITE_INT_TO_PTR(rc); +} +#endif /* SQLITE_MAX_WORKER_THREADS>0 */ + +/* +** Flush the current contents of VdbeSorter.list to a new PMA, possibly +** using a background thread. +*/ +static int vdbeSorterFlushPMA(VdbeSorter *pSorter){ +#if SQLITE_MAX_WORKER_THREADS==0 + pSorter->bUsePMA = 1; + return vdbeSorterListToPMA(&pSorter->aTask[0], &pSorter->list); +#else + int rc = SQLITE_OK; + int i; + SortSubtask *pTask = 0; /* Thread context used to create new PMA */ + int nWorker = (pSorter->nTask-1); + + /* Set the flag to indicate that at least one PMA has been written. + ** Or will be, anyhow. */ + pSorter->bUsePMA = 1; + + /* Select a sub-task to sort and flush the current list of in-memory + ** records to disk. If the sorter is running in multi-threaded mode, + ** round-robin between the first (pSorter->nTask-1) tasks. Except, if + ** the background thread from a sub-tasks previous turn is still running, + ** skip it. If the first (pSorter->nTask-1) sub-tasks are all still busy, + ** fall back to using the final sub-task. The first (pSorter->nTask-1) + ** sub-tasks are prefered as they use background threads - the final + ** sub-task uses the main thread. */ + for(i=0; iiPrev + i + 1) % nWorker; + pTask = &pSorter->aTask[iTest]; + if( pTask->bDone ){ + rc = vdbeSorterJoinThread(pTask); + } + if( rc!=SQLITE_OK || pTask->pThread==0 ) break; + } + + if( rc==SQLITE_OK ){ + if( i==nWorker ){ + /* Use the foreground thread for this operation */ + rc = vdbeSorterListToPMA(&pSorter->aTask[nWorker], &pSorter->list); + }else{ + /* Launch a background thread for this operation */ + u8 *aMem = pTask->list.aMemory; + void *pCtx = (void*)pTask; + + assert( pTask->pThread==0 && pTask->bDone==0 ); + assert( pTask->list.pList==0 ); + assert( pTask->list.aMemory==0 || pSorter->list.aMemory!=0 ); + + pSorter->iPrev = (u8)(pTask - pSorter->aTask); + pTask->list = pSorter->list; + pSorter->list.pList = 0; + pSorter->list.szPMA = 0; + if( aMem ){ + pSorter->list.aMemory = aMem; + pSorter->nMemory = sqlite3MallocSize(aMem); + }else if( pSorter->list.aMemory ){ + pSorter->list.aMemory = sqlite3Malloc(pSorter->nMemory); + if( !pSorter->list.aMemory ) return SQLITE_NOMEM; + } + + rc = vdbeSorterCreateThread(pTask, vdbeSorterFlushThread, pCtx); + } + } + + return rc; +#endif /* SQLITE_MAX_WORKER_THREADS!=0 */ +} + +/* +** Add a record to the sorter. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterWrite( + const VdbeCursor *pCsr, /* Sorter cursor */ + Mem *pVal /* Memory cell containing record */ +){ + VdbeSorter *pSorter = pCsr->pSorter; + int rc = SQLITE_OK; /* Return Code */ + SorterRecord *pNew; /* New list element */ + + int bFlush; /* True to flush contents of memory to PMA */ + int nReq; /* Bytes of memory required */ + int nPMA; /* Bytes of PMA space required */ + int t; /* serial type of first record field */ + + getVarint32((const u8*)&pVal->z[1], t); + if( t>0 && t<10 && t!=7 ){ + pSorter->typeMask &= SORTER_TYPE_INTEGER; + }else if( t>10 && (t & 0x01) ){ + pSorter->typeMask &= SORTER_TYPE_TEXT; + }else{ + pSorter->typeMask = 0; + } + + assert( pSorter ); + + /* Figure out whether or not the current contents of memory should be + ** flushed to a PMA before continuing. If so, do so. + ** + ** If using the single large allocation mode (pSorter->aMemory!=0), then + ** flush the contents of memory to a new PMA if (a) at least one value is + ** already in memory and (b) the new value will not fit in memory. + ** + ** Or, if using separate allocations for each record, flush the contents + ** of memory to a PMA if either of the following are true: + ** + ** * The total memory allocated for the in-memory list is greater + ** than (page-size * cache-size), or + ** + ** * The total memory allocated for the in-memory list is greater + ** than (page-size * 10) and sqlite3HeapNearlyFull() returns true. + */ + nReq = pVal->n + sizeof(SorterRecord); + nPMA = pVal->n + sqlite3VarintLen(pVal->n); + if( pSorter->mxPmaSize ){ + if( pSorter->list.aMemory ){ + bFlush = pSorter->iMemory && (pSorter->iMemory+nReq) > pSorter->mxPmaSize; + }else{ + bFlush = ( + (pSorter->list.szPMA > pSorter->mxPmaSize) + || (pSorter->list.szPMA > pSorter->mnPmaSize && sqlite3HeapNearlyFull()) + ); + } + if( bFlush ){ + rc = vdbeSorterFlushPMA(pSorter); + pSorter->list.szPMA = 0; + pSorter->iMemory = 0; + assert( rc!=SQLITE_OK || pSorter->list.pList==0 ); + } + } + + pSorter->list.szPMA += nPMA; + if( nPMA>pSorter->mxKeysize ){ + pSorter->mxKeysize = nPMA; + } + + if( pSorter->list.aMemory ){ + int nMin = pSorter->iMemory + nReq; + + if( nMin>pSorter->nMemory ){ + u8 *aNew; + int nNew = pSorter->nMemory * 2; + while( nNew < nMin ) nNew = nNew*2; + if( nNew > pSorter->mxPmaSize ) nNew = pSorter->mxPmaSize; + if( nNew < nMin ) nNew = nMin; + + aNew = sqlite3Realloc(pSorter->list.aMemory, nNew); + if( !aNew ) return SQLITE_NOMEM; + pSorter->list.pList = (SorterRecord*)( + aNew + ((u8*)pSorter->list.pList - pSorter->list.aMemory) + ); + pSorter->list.aMemory = aNew; + pSorter->nMemory = nNew; + } + + pNew = (SorterRecord*)&pSorter->list.aMemory[pSorter->iMemory]; + pSorter->iMemory += ROUND8(nReq); + pNew->u.iNext = (int)((u8*)(pSorter->list.pList) - pSorter->list.aMemory); + }else{ + pNew = (SorterRecord *)sqlite3Malloc(nReq); + if( pNew==0 ){ + return SQLITE_NOMEM; + } + pNew->u.pNext = pSorter->list.pList; + } + + memcpy(SRVAL(pNew), pVal->z, pVal->n); + pNew->nVal = pVal->n; + pSorter->list.pList = pNew; + + return rc; +} + +/* +** Read keys from pIncr->pMerger and populate pIncr->aFile[1]. The format +** of the data stored in aFile[1] is the same as that used by regular PMAs, +** except that the number-of-bytes varint is omitted from the start. +*/ +static int vdbeIncrPopulate(IncrMerger *pIncr){ + int rc = SQLITE_OK; + int rc2; + i64 iStart = pIncr->iStartOff; + SorterFile *pOut = &pIncr->aFile[1]; + SortSubtask *pTask = pIncr->pTask; + MergeEngine *pMerger = pIncr->pMerger; + PmaWriter writer; + assert( pIncr->bEof==0 ); + + vdbeSorterPopulateDebug(pTask, "enter"); + + vdbePmaWriterInit(pOut->pFd, &writer, pTask->pSorter->pgsz, iStart); + while( rc==SQLITE_OK ){ + int dummy; + PmaReader *pReader = &pMerger->aReadr[ pMerger->aTree[1] ]; + int nKey = pReader->nKey; + i64 iEof = writer.iWriteOff + writer.iBufEnd; + + /* Check if the output file is full or if the input has been exhausted. + ** In either case exit the loop. */ + if( pReader->pFd==0 ) break; + if( (iEof + nKey + sqlite3VarintLen(nKey))>(iStart + pIncr->mxSz) ) break; + + /* Write the next key to the output. */ + vdbePmaWriteVarint(&writer, nKey); + vdbePmaWriteBlob(&writer, pReader->aKey, nKey); + assert( pIncr->pMerger->pTask==pTask ); + rc = vdbeMergeEngineStep(pIncr->pMerger, &dummy); + } + + rc2 = vdbePmaWriterFinish(&writer, &pOut->iEof); + if( rc==SQLITE_OK ) rc = rc2; + vdbeSorterPopulateDebug(pTask, "exit"); + return rc; +} + +#if SQLITE_MAX_WORKER_THREADS>0 +/* +** The main routine for background threads that populate aFile[1] of +** multi-threaded IncrMerger objects. +*/ +static void *vdbeIncrPopulateThread(void *pCtx){ + IncrMerger *pIncr = (IncrMerger*)pCtx; + void *pRet = SQLITE_INT_TO_PTR( vdbeIncrPopulate(pIncr) ); + pIncr->pTask->bDone = 1; + return pRet; +} + +/* +** Launch a background thread to populate aFile[1] of pIncr. +*/ +static int vdbeIncrBgPopulate(IncrMerger *pIncr){ + void *p = (void*)pIncr; + assert( pIncr->bUseThread ); + return vdbeSorterCreateThread(pIncr->pTask, vdbeIncrPopulateThread, p); +} +#endif + +/* +** This function is called when the PmaReader corresponding to pIncr has +** finished reading the contents of aFile[0]. Its purpose is to "refill" +** aFile[0] such that the PmaReader should start rereading it from the +** beginning. +** +** For single-threaded objects, this is accomplished by literally reading +** keys from pIncr->pMerger and repopulating aFile[0]. +** +** For multi-threaded objects, all that is required is to wait until the +** background thread is finished (if it is not already) and then swap +** aFile[0] and aFile[1] in place. If the contents of pMerger have not +** been exhausted, this function also launches a new background thread +** to populate the new aFile[1]. +** +** SQLITE_OK is returned on success, or an SQLite error code otherwise. +*/ +static int vdbeIncrSwap(IncrMerger *pIncr){ + int rc = SQLITE_OK; + +#if SQLITE_MAX_WORKER_THREADS>0 + if( pIncr->bUseThread ){ + rc = vdbeSorterJoinThread(pIncr->pTask); + + if( rc==SQLITE_OK ){ + SorterFile f0 = pIncr->aFile[0]; + pIncr->aFile[0] = pIncr->aFile[1]; + pIncr->aFile[1] = f0; + } + + if( rc==SQLITE_OK ){ + if( pIncr->aFile[0].iEof==pIncr->iStartOff ){ + pIncr->bEof = 1; + }else{ + rc = vdbeIncrBgPopulate(pIncr); + } + } + }else +#endif + { + rc = vdbeIncrPopulate(pIncr); + pIncr->aFile[0] = pIncr->aFile[1]; + if( pIncr->aFile[0].iEof==pIncr->iStartOff ){ + pIncr->bEof = 1; + } + } + + return rc; +} + +/* +** Allocate and return a new IncrMerger object to read data from pMerger. +** +** If an OOM condition is encountered, return NULL. In this case free the +** pMerger argument before returning. +*/ +static int vdbeIncrMergerNew( + SortSubtask *pTask, /* The thread that will be using the new IncrMerger */ + MergeEngine *pMerger, /* The MergeEngine that the IncrMerger will control */ + IncrMerger **ppOut /* Write the new IncrMerger here */ +){ + int rc = SQLITE_OK; + IncrMerger *pIncr = *ppOut = (IncrMerger*) + (sqlite3FaultSim(100) ? 0 : sqlite3MallocZero(sizeof(*pIncr))); + if( pIncr ){ + pIncr->pMerger = pMerger; + pIncr->pTask = pTask; + pIncr->mxSz = MAX(pTask->pSorter->mxKeysize+9,pTask->pSorter->mxPmaSize/2); + pTask->file2.iEof += pIncr->mxSz; + }else{ + vdbeMergeEngineFree(pMerger); + rc = SQLITE_NOMEM; + } + return rc; +} + +#if SQLITE_MAX_WORKER_THREADS>0 +/* +** Set the "use-threads" flag on object pIncr. +*/ +static void vdbeIncrMergerSetThreads(IncrMerger *pIncr){ + pIncr->bUseThread = 1; + pIncr->pTask->file2.iEof -= pIncr->mxSz; +} +#endif /* SQLITE_MAX_WORKER_THREADS>0 */ + + + +/* +** Recompute pMerger->aTree[iOut] by comparing the next keys on the +** two PmaReaders that feed that entry. Neither of the PmaReaders +** are advanced. This routine merely does the comparison. +*/ +static void vdbeMergeEngineCompare( + MergeEngine *pMerger, /* Merge engine containing PmaReaders to compare */ + int iOut /* Store the result in pMerger->aTree[iOut] */ +){ + int i1; + int i2; + int iRes; + PmaReader *p1; + PmaReader *p2; + + assert( iOutnTree && iOut>0 ); + + if( iOut>=(pMerger->nTree/2) ){ + i1 = (iOut - pMerger->nTree/2) * 2; + i2 = i1 + 1; + }else{ + i1 = pMerger->aTree[iOut*2]; + i2 = pMerger->aTree[iOut*2+1]; + } + + p1 = &pMerger->aReadr[i1]; + p2 = &pMerger->aReadr[i2]; + + if( p1->pFd==0 ){ + iRes = i2; + }else if( p2->pFd==0 ){ + iRes = i1; + }else{ + SortSubtask *pTask = pMerger->pTask; + int bCached = 0; + int res; + assert( pTask->pUnpacked!=0 ); /* from vdbeSortSubtaskMain() */ + res = pTask->xCompare( + pTask, &bCached, p1->aKey, p1->nKey, p2->aKey, p2->nKey + ); + if( res<=0 ){ + iRes = i1; + }else{ + iRes = i2; + } + } + + pMerger->aTree[iOut] = iRes; +} + +/* +** Allowed values for the eMode parameter to vdbeMergeEngineInit() +** and vdbePmaReaderIncrMergeInit(). +** +** Only INCRINIT_NORMAL is valid in single-threaded builds (when +** SQLITE_MAX_WORKER_THREADS==0). The other values are only used +** when there exists one or more separate worker threads. +*/ +#define INCRINIT_NORMAL 0 +#define INCRINIT_TASK 1 +#define INCRINIT_ROOT 2 + +/* +** Forward reference required as the vdbeIncrMergeInit() and +** vdbePmaReaderIncrInit() routines are called mutually recursively when +** building a merge tree. +*/ +static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode); + +/* +** Initialize the MergeEngine object passed as the second argument. Once this +** function returns, the first key of merged data may be read from the +** MergeEngine object in the usual fashion. +** +** If argument eMode is INCRINIT_ROOT, then it is assumed that any IncrMerge +** objects attached to the PmaReader objects that the merger reads from have +** already been populated, but that they have not yet populated aFile[0] and +** set the PmaReader objects up to read from it. In this case all that is +** required is to call vdbePmaReaderNext() on each PmaReader to point it at +** its first key. +** +** Otherwise, if eMode is any value other than INCRINIT_ROOT, then use +** vdbePmaReaderIncrMergeInit() to initialize each PmaReader that feeds data +** to pMerger. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +static int vdbeMergeEngineInit( + SortSubtask *pTask, /* Thread that will run pMerger */ + MergeEngine *pMerger, /* MergeEngine to initialize */ + int eMode /* One of the INCRINIT_XXX constants */ +){ + int rc = SQLITE_OK; /* Return code */ + int i; /* For looping over PmaReader objects */ + int nTree = pMerger->nTree; + + /* eMode is always INCRINIT_NORMAL in single-threaded mode */ + assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL ); + + /* Verify that the MergeEngine is assigned to a single thread */ + assert( pMerger->pTask==0 ); + pMerger->pTask = pTask; + + for(i=0; i0 && eMode==INCRINIT_ROOT ){ + /* PmaReaders should be normally initialized in order, as if they are + ** reading from the same temp file this makes for more linear file IO. + ** However, in the INCRINIT_ROOT case, if PmaReader aReadr[nTask-1] is + ** in use it will block the vdbePmaReaderNext() call while it uses + ** the main thread to fill its buffer. So calling PmaReaderNext() + ** on this PmaReader before any of the multi-threaded PmaReaders takes + ** better advantage of multi-processor hardware. */ + rc = vdbePmaReaderNext(&pMerger->aReadr[nTree-i-1]); + }else{ + rc = vdbePmaReaderIncrInit(&pMerger->aReadr[i], INCRINIT_NORMAL); + } + if( rc!=SQLITE_OK ) return rc; + } + + for(i=pMerger->nTree-1; i>0; i--){ + vdbeMergeEngineCompare(pMerger, i); + } + return pTask->pUnpacked->errCode; +} + +/* +** The PmaReader passed as the first argument is guaranteed to be an +** incremental-reader (pReadr->pIncr!=0). This function serves to open +** and/or initialize the temp file related fields of the IncrMerge +** object at (pReadr->pIncr). +** +** If argument eMode is set to INCRINIT_NORMAL, then all PmaReaders +** in the sub-tree headed by pReadr are also initialized. Data is then +** loaded into the buffers belonging to pReadr and it is set to point to +** the first key in its range. +** +** If argument eMode is set to INCRINIT_TASK, then pReadr is guaranteed +** to be a multi-threaded PmaReader and this function is being called in a +** background thread. In this case all PmaReaders in the sub-tree are +** initialized as for INCRINIT_NORMAL and the aFile[1] buffer belonging to +** pReadr is populated. However, pReadr itself is not set up to point +** to its first key. A call to vdbePmaReaderNext() is still required to do +** that. +** +** The reason this function does not call vdbePmaReaderNext() immediately +** in the INCRINIT_TASK case is that vdbePmaReaderNext() assumes that it has +** to block on thread (pTask->thread) before accessing aFile[1]. But, since +** this entire function is being run by thread (pTask->thread), that will +** lead to the current background thread attempting to join itself. +** +** Finally, if argument eMode is set to INCRINIT_ROOT, it may be assumed +** that pReadr->pIncr is a multi-threaded IncrMerge objects, and that all +** child-trees have already been initialized using IncrInit(INCRINIT_TASK). +** In this case vdbePmaReaderNext() is called on all child PmaReaders and +** the current PmaReader set to point to the first key in its range. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){ + int rc = SQLITE_OK; + IncrMerger *pIncr = pReadr->pIncr; + SortSubtask *pTask = pIncr->pTask; + sqlite3 *db = pTask->pSorter->db; + + /* eMode is always INCRINIT_NORMAL in single-threaded mode */ + assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL ); + + rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode); + + /* Set up the required files for pIncr. A multi-theaded IncrMerge object + ** requires two temp files to itself, whereas a single-threaded object + ** only requires a region of pTask->file2. */ + if( rc==SQLITE_OK ){ + int mxSz = pIncr->mxSz; +#if SQLITE_MAX_WORKER_THREADS>0 + if( pIncr->bUseThread ){ + rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[0].pFd); + if( rc==SQLITE_OK ){ + rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[1].pFd); + } + }else +#endif + /*if( !pIncr->bUseThread )*/{ + if( pTask->file2.pFd==0 ){ + assert( pTask->file2.iEof>0 ); + rc = vdbeSorterOpenTempFile(db, pTask->file2.iEof, &pTask->file2.pFd); + pTask->file2.iEof = 0; + } + if( rc==SQLITE_OK ){ + pIncr->aFile[1].pFd = pTask->file2.pFd; + pIncr->iStartOff = pTask->file2.iEof; + pTask->file2.iEof += mxSz; + } + } + } + +#if SQLITE_MAX_WORKER_THREADS>0 + if( rc==SQLITE_OK && pIncr->bUseThread ){ + /* Use the current thread to populate aFile[1], even though this + ** PmaReader is multi-threaded. If this is an INCRINIT_TASK object, + ** then this function is already running in background thread + ** pIncr->pTask->thread. + ** + ** If this is the INCRINIT_ROOT object, then it is running in the + ** main VDBE thread. But that is Ok, as that thread cannot return + ** control to the VDBE or proceed with anything useful until the + ** first results are ready from this merger object anyway. + */ + assert( eMode==INCRINIT_ROOT || eMode==INCRINIT_TASK ); + rc = vdbeIncrPopulate(pIncr); + } +#endif + + if( rc==SQLITE_OK && (SQLITE_MAX_WORKER_THREADS==0 || eMode!=INCRINIT_TASK) ){ + rc = vdbePmaReaderNext(pReadr); + } + + return rc; +} + +#if SQLITE_MAX_WORKER_THREADS>0 +/* +** The main routine for vdbePmaReaderIncrMergeInit() operations run in +** background threads. +*/ +static void *vdbePmaReaderBgIncrInit(void *pCtx){ + PmaReader *pReader = (PmaReader*)pCtx; + void *pRet = SQLITE_INT_TO_PTR( + vdbePmaReaderIncrMergeInit(pReader,INCRINIT_TASK) + ); + pReader->pIncr->pTask->bDone = 1; + return pRet; +} +#endif + +/* +** If the PmaReader passed as the first argument is not an incremental-reader +** (if pReadr->pIncr==0), then this function is a no-op. Otherwise, it invokes +** the vdbePmaReaderIncrMergeInit() function with the parameters passed to +** this routine to initialize the incremental merge. +** +** If the IncrMerger object is multi-threaded (IncrMerger.bUseThread==1), +** then a background thread is launched to call vdbePmaReaderIncrMergeInit(). +** Or, if the IncrMerger is single threaded, the same function is called +** using the current thread. +*/ +static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode){ + IncrMerger *pIncr = pReadr->pIncr; /* Incremental merger */ + int rc = SQLITE_OK; /* Return code */ + if( pIncr ){ +#if SQLITE_MAX_WORKER_THREADS>0 + assert( pIncr->bUseThread==0 || eMode==INCRINIT_TASK ); + if( pIncr->bUseThread ){ + void *pCtx = (void*)pReadr; + rc = vdbeSorterCreateThread(pIncr->pTask, vdbePmaReaderBgIncrInit, pCtx); + }else +#endif + { + rc = vdbePmaReaderIncrMergeInit(pReadr, eMode); + } + } + return rc; +} + +/* +** Allocate a new MergeEngine object to merge the contents of nPMA level-0 +** PMAs from pTask->file. If no error occurs, set *ppOut to point to +** the new object and return SQLITE_OK. Or, if an error does occur, set *ppOut +** to NULL and return an SQLite error code. +** +** When this function is called, *piOffset is set to the offset of the +** first PMA to read from pTask->file. Assuming no error occurs, it is +** set to the offset immediately following the last byte of the last +** PMA before returning. If an error does occur, then the final value of +** *piOffset is undefined. +*/ +static int vdbeMergeEngineLevel0( + SortSubtask *pTask, /* Sorter task to read from */ + int nPMA, /* Number of PMAs to read */ + i64 *piOffset, /* IN/OUT: Readr offset in pTask->file */ + MergeEngine **ppOut /* OUT: New merge-engine */ +){ + MergeEngine *pNew; /* Merge engine to return */ + i64 iOff = *piOffset; + int i; + int rc = SQLITE_OK; + + *ppOut = pNew = vdbeMergeEngineNew(nPMA); + if( pNew==0 ) rc = SQLITE_NOMEM; + + for(i=0; iaReadr[i]; + rc = vdbePmaReaderInit(pTask, &pTask->file, iOff, pReadr, &nDummy); + iOff = pReadr->iEof; + } + + if( rc!=SQLITE_OK ){ + vdbeMergeEngineFree(pNew); + *ppOut = 0; + } + *piOffset = iOff; + return rc; +} + +/* +** Return the depth of a tree comprising nPMA PMAs, assuming a fanout of +** SORTER_MAX_MERGE_COUNT. The returned value does not include leaf nodes. +** +** i.e. +** +** nPMA<=16 -> TreeDepth() == 0 +** nPMA<=256 -> TreeDepth() == 1 +** nPMA<=65536 -> TreeDepth() == 2 +*/ +static int vdbeSorterTreeDepth(int nPMA){ + int nDepth = 0; + i64 nDiv = SORTER_MAX_MERGE_COUNT; + while( nDiv < (i64)nPMA ){ + nDiv = nDiv * SORTER_MAX_MERGE_COUNT; + nDepth++; + } + return nDepth; +} + +/* +** pRoot is the root of an incremental merge-tree with depth nDepth (according +** to vdbeSorterTreeDepth()). pLeaf is the iSeq'th leaf to be added to the +** tree, counting from zero. This function adds pLeaf to the tree. +** +** If successful, SQLITE_OK is returned. If an error occurs, an SQLite error +** code is returned and pLeaf is freed. +*/ +static int vdbeSorterAddToTree( + SortSubtask *pTask, /* Task context */ + int nDepth, /* Depth of tree according to TreeDepth() */ + int iSeq, /* Sequence number of leaf within tree */ + MergeEngine *pRoot, /* Root of tree */ + MergeEngine *pLeaf /* Leaf to add to tree */ +){ + int rc = SQLITE_OK; + int nDiv = 1; + int i; + MergeEngine *p = pRoot; + IncrMerger *pIncr; + + rc = vdbeIncrMergerNew(pTask, pLeaf, &pIncr); + + for(i=1; iaReadr[iIter]; + + if( pReadr->pIncr==0 ){ + MergeEngine *pNew = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT); + if( pNew==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = vdbeIncrMergerNew(pTask, pNew, &pReadr->pIncr); + } + } + if( rc==SQLITE_OK ){ + p = pReadr->pIncr->pMerger; + nDiv = nDiv / SORTER_MAX_MERGE_COUNT; + } + } + + if( rc==SQLITE_OK ){ + p->aReadr[iSeq % SORTER_MAX_MERGE_COUNT].pIncr = pIncr; + }else{ + vdbeIncrFree(pIncr); + } + return rc; +} + +/* +** This function is called as part of a SorterRewind() operation on a sorter +** that has already written two or more level-0 PMAs to one or more temp +** files. It builds a tree of MergeEngine/IncrMerger/PmaReader objects that +** can be used to incrementally merge all PMAs on disk. +** +** If successful, SQLITE_OK is returned and *ppOut set to point to the +** MergeEngine object at the root of the tree before returning. Or, if an +** error occurs, an SQLite error code is returned and the final value +** of *ppOut is undefined. +*/ +static int vdbeSorterMergeTreeBuild( + VdbeSorter *pSorter, /* The VDBE cursor that implements the sort */ + MergeEngine **ppOut /* Write the MergeEngine here */ +){ + MergeEngine *pMain = 0; + int rc = SQLITE_OK; + int iTask; + +#if SQLITE_MAX_WORKER_THREADS>0 + /* If the sorter uses more than one task, then create the top-level + ** MergeEngine here. This MergeEngine will read data from exactly + ** one PmaReader per sub-task. */ + assert( pSorter->bUseThreads || pSorter->nTask==1 ); + if( pSorter->nTask>1 ){ + pMain = vdbeMergeEngineNew(pSorter->nTask); + if( pMain==0 ) rc = SQLITE_NOMEM; + } +#endif + + for(iTask=0; rc==SQLITE_OK && iTasknTask; iTask++){ + SortSubtask *pTask = &pSorter->aTask[iTask]; + assert( pTask->nPMA>0 || SQLITE_MAX_WORKER_THREADS>0 ); + if( SQLITE_MAX_WORKER_THREADS==0 || pTask->nPMA ){ + MergeEngine *pRoot = 0; /* Root node of tree for this task */ + int nDepth = vdbeSorterTreeDepth(pTask->nPMA); + i64 iReadOff = 0; + + if( pTask->nPMA<=SORTER_MAX_MERGE_COUNT ){ + rc = vdbeMergeEngineLevel0(pTask, pTask->nPMA, &iReadOff, &pRoot); + }else{ + int i; + int iSeq = 0; + pRoot = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT); + if( pRoot==0 ) rc = SQLITE_NOMEM; + for(i=0; inPMA && rc==SQLITE_OK; i += SORTER_MAX_MERGE_COUNT){ + MergeEngine *pMerger = 0; /* New level-0 PMA merger */ + int nReader; /* Number of level-0 PMAs to merge */ + + nReader = MIN(pTask->nPMA - i, SORTER_MAX_MERGE_COUNT); + rc = vdbeMergeEngineLevel0(pTask, nReader, &iReadOff, &pMerger); + if( rc==SQLITE_OK ){ + rc = vdbeSorterAddToTree(pTask, nDepth, iSeq++, pRoot, pMerger); + } + } + } + + if( rc==SQLITE_OK ){ +#if SQLITE_MAX_WORKER_THREADS>0 + if( pMain!=0 ){ + rc = vdbeIncrMergerNew(pTask, pRoot, &pMain->aReadr[iTask].pIncr); + }else +#endif + { + assert( pMain==0 ); + pMain = pRoot; + } + }else{ + vdbeMergeEngineFree(pRoot); + } + } + } + + if( rc!=SQLITE_OK ){ + vdbeMergeEngineFree(pMain); + pMain = 0; + } + *ppOut = pMain; + return rc; +} + +/* +** This function is called as part of an sqlite3VdbeSorterRewind() operation +** on a sorter that has written two or more PMAs to temporary files. It sets +** up either VdbeSorter.pMerger (for single threaded sorters) or pReader +** (for multi-threaded sorters) so that it can be used to iterate through +** all records stored in the sorter. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +static int vdbeSorterSetupMerge(VdbeSorter *pSorter){ + int rc; /* Return code */ + SortSubtask *pTask0 = &pSorter->aTask[0]; + MergeEngine *pMain = 0; +#if SQLITE_MAX_WORKER_THREADS + sqlite3 *db = pTask0->pSorter->db; + int i; + SorterCompare xCompare = vdbeSorterGetCompare(pSorter); + for(i=0; inTask; i++){ + pSorter->aTask[i].xCompare = xCompare; + } +#endif + + rc = vdbeSorterMergeTreeBuild(pSorter, &pMain); + if( rc==SQLITE_OK ){ +#if SQLITE_MAX_WORKER_THREADS + assert( pSorter->bUseThreads==0 || pSorter->nTask>1 ); + if( pSorter->bUseThreads ){ + int iTask; + PmaReader *pReadr = 0; + SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1]; + rc = vdbeSortAllocUnpacked(pLast); + if( rc==SQLITE_OK ){ + pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader)); + pSorter->pReader = pReadr; + if( pReadr==0 ) rc = SQLITE_NOMEM; + } + if( rc==SQLITE_OK ){ + rc = vdbeIncrMergerNew(pLast, pMain, &pReadr->pIncr); + if( rc==SQLITE_OK ){ + vdbeIncrMergerSetThreads(pReadr->pIncr); + for(iTask=0; iTask<(pSorter->nTask-1); iTask++){ + IncrMerger *pIncr; + if( (pIncr = pMain->aReadr[iTask].pIncr) ){ + vdbeIncrMergerSetThreads(pIncr); + assert( pIncr->pTask!=pLast ); + } + } + for(iTask=0; rc==SQLITE_OK && iTasknTask; iTask++){ + /* Check that: + ** + ** a) The incremental merge object is configured to use the + ** right task, and + ** b) If it is using task (nTask-1), it is configured to run + ** in single-threaded mode. This is important, as the + ** root merge (INCRINIT_ROOT) will be using the same task + ** object. + */ + PmaReader *p = &pMain->aReadr[iTask]; + assert( p->pIncr==0 || ( + (p->pIncr->pTask==&pSorter->aTask[iTask]) /* a */ + && (iTask!=pSorter->nTask-1 || p->pIncr->bUseThread==0) /* b */ + )); + rc = vdbePmaReaderIncrInit(p, INCRINIT_TASK); + } + } + pMain = 0; + } + if( rc==SQLITE_OK ){ + rc = vdbePmaReaderIncrMergeInit(pReadr, INCRINIT_ROOT); + } + }else +#endif + { + rc = vdbeMergeEngineInit(pTask0, pMain, INCRINIT_NORMAL); + pSorter->pMerger = pMain; + pMain = 0; + } + } + + if( rc!=SQLITE_OK ){ + vdbeMergeEngineFree(pMain); + } + return rc; +} + + +/* +** Once the sorter has been populated by calls to sqlite3VdbeSorterWrite, +** this function is called to prepare for iterating through the records +** in sorted order. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *pCsr, int *pbEof){ + VdbeSorter *pSorter = pCsr->pSorter; + int rc = SQLITE_OK; /* Return code */ + + assert( pSorter ); + + /* If no data has been written to disk, then do not do so now. Instead, + ** sort the VdbeSorter.pRecord list. The vdbe layer will read data directly + ** from the in-memory list. */ + if( pSorter->bUsePMA==0 ){ + if( pSorter->list.pList ){ + *pbEof = 0; + rc = vdbeSorterSort(&pSorter->aTask[0], &pSorter->list); + }else{ + *pbEof = 1; + } + return rc; + } + + /* Write the current in-memory list to a PMA. When the VdbeSorterWrite() + ** function flushes the contents of memory to disk, it immediately always + ** creates a new list consisting of a single key immediately afterwards. + ** So the list is never empty at this point. */ + assert( pSorter->list.pList ); + rc = vdbeSorterFlushPMA(pSorter); + + /* Join all threads */ + rc = vdbeSorterJoinAll(pSorter, rc); + + vdbeSorterRewindDebug("rewind"); + + /* Assuming no errors have occurred, set up a merger structure to + ** incrementally read and merge all remaining PMAs. */ + assert( pSorter->pReader==0 ); + if( rc==SQLITE_OK ){ + rc = vdbeSorterSetupMerge(pSorter); + *pbEof = 0; + } + + vdbeSorterRewindDebug("rewinddone"); + return rc; +} + +/* +** Advance to the next element in the sorter. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){ + VdbeSorter *pSorter = pCsr->pSorter; + int rc; /* Return code */ + + assert( pSorter->bUsePMA || (pSorter->pReader==0 && pSorter->pMerger==0) ); + if( pSorter->bUsePMA ){ + assert( pSorter->pReader==0 || pSorter->pMerger==0 ); + assert( pSorter->bUseThreads==0 || pSorter->pReader ); + assert( pSorter->bUseThreads==1 || pSorter->pMerger ); +#if SQLITE_MAX_WORKER_THREADS>0 + if( pSorter->bUseThreads ){ + rc = vdbePmaReaderNext(pSorter->pReader); + *pbEof = (pSorter->pReader->pFd==0); + }else +#endif + /*if( !pSorter->bUseThreads )*/ { + assert( pSorter->pMerger!=0 ); + assert( pSorter->pMerger->pTask==(&pSorter->aTask[0]) ); + rc = vdbeMergeEngineStep(pSorter->pMerger, pbEof); + } + }else{ + SorterRecord *pFree = pSorter->list.pList; + pSorter->list.pList = pFree->u.pNext; + pFree->u.pNext = 0; + if( pSorter->list.aMemory==0 ) vdbeSorterRecordFree(db, pFree); + *pbEof = !pSorter->list.pList; + rc = SQLITE_OK; + } + return rc; +} + +/* +** Return a pointer to a buffer owned by the sorter that contains the +** current key. +*/ +static void *vdbeSorterRowkey( + const VdbeSorter *pSorter, /* Sorter object */ + int *pnKey /* OUT: Size of current key in bytes */ +){ + void *pKey; + if( pSorter->bUsePMA ){ + PmaReader *pReader; +#if SQLITE_MAX_WORKER_THREADS>0 + if( pSorter->bUseThreads ){ + pReader = pSorter->pReader; + }else +#endif + /*if( !pSorter->bUseThreads )*/{ + pReader = &pSorter->pMerger->aReadr[pSorter->pMerger->aTree[1]]; + } + *pnKey = pReader->nKey; + pKey = pReader->aKey; + }else{ + *pnKey = pSorter->list.pList->nVal; + pKey = SRVAL(pSorter->list.pList); + } + return pKey; +} + +/* +** Copy the current sorter key into the memory cell pOut. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){ + VdbeSorter *pSorter = pCsr->pSorter; + void *pKey; int nKey; /* Sorter key to copy into pOut */ + + pKey = vdbeSorterRowkey(pSorter, &nKey); + if( sqlite3VdbeMemClearAndResize(pOut, nKey) ){ + return SQLITE_NOMEM; + } + pOut->n = nKey; + MemSetTypeFlag(pOut, MEM_Blob); + memcpy(pOut->z, pKey, nKey); + + return SQLITE_OK; +} + +/* +** Compare the key in memory cell pVal with the key that the sorter cursor +** passed as the first argument currently points to. For the purposes of +** the comparison, ignore the rowid field at the end of each record. +** +** If the sorter cursor key contains any NULL values, consider it to be +** less than pVal. Even if pVal also contains NULL values. +** +** If an error occurs, return an SQLite error code (i.e. SQLITE_NOMEM). +** Otherwise, set *pRes to a negative, zero or positive value if the +** key in pVal is smaller than, equal to or larger than the current sorter +** key. +** +** This routine forms the core of the OP_SorterCompare opcode, which in +** turn is used to verify uniqueness when constructing a UNIQUE INDEX. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterCompare( + const VdbeCursor *pCsr, /* Sorter cursor */ + Mem *pVal, /* Value to compare to current sorter key */ + int nKeyCol, /* Compare this many columns */ + int *pRes /* OUT: Result of comparison */ +){ + VdbeSorter *pSorter = pCsr->pSorter; + UnpackedRecord *r2 = pSorter->pUnpacked; + KeyInfo *pKeyInfo = pCsr->pKeyInfo; + int i; + void *pKey; int nKey; /* Sorter key to compare pVal with */ + + if( r2==0 ){ + char *p; + r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo,0,0,&p); + assert( pSorter->pUnpacked==(UnpackedRecord*)p ); + if( r2==0 ) return SQLITE_NOMEM; + r2->nField = nKeyCol; + } + assert( r2->nField==nKeyCol ); + + pKey = vdbeSorterRowkey(pSorter, &nKey); + sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, r2); + for(i=0; iaMem[i].flags & MEM_Null ){ + *pRes = -1; + return SQLITE_OK; + } + } + + *pRes = sqlite3VdbeRecordCompare(pVal->n, pVal->z, r2); + return SQLITE_OK; +} + +/************** End of vdbesort.c ********************************************/ +/************** Begin file journal.c *****************************************/ +/* +** 2007 August 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 file implements a special kind of sqlite3_file object used +** by SQLite to create journal files if the atomic-write optimization +** is enabled. +** +** The distinctive characteristic of this sqlite3_file is that the +** actual on disk file is created lazily. When the file is created, +** the caller specifies a buffer size for an in-memory buffer to +** be used to service read() and write() requests. The actual file +** on disk is not created or populated until either: +** +** 1) The in-memory representation grows too large for the allocated +** buffer, or +** 2) The sqlite3JournalCreate() function is called. +*/ +#ifdef SQLITE_ENABLE_ATOMIC_WRITE + + +/* +** A JournalFile object is a subclass of sqlite3_file used by +** as an open file handle for journal files. +*/ +struct JournalFile { + sqlite3_io_methods *pMethod; /* I/O methods on journal files */ + int nBuf; /* Size of zBuf[] in bytes */ + char *zBuf; /* Space to buffer journal writes */ + int iSize; /* Amount of zBuf[] currently used */ + int flags; /* xOpen flags */ + sqlite3_vfs *pVfs; /* The "real" underlying VFS */ + sqlite3_file *pReal; /* The "real" underlying file descriptor */ + const char *zJournal; /* Name of the journal file */ +}; +typedef struct JournalFile JournalFile; + +/* +** If it does not already exists, create and populate the on-disk file +** for JournalFile p. +*/ +static int createFile(JournalFile *p){ + int rc = SQLITE_OK; + if( !p->pReal ){ + sqlite3_file *pReal = (sqlite3_file *)&p[1]; + rc = sqlite3OsOpen(p->pVfs, p->zJournal, pReal, p->flags, 0); + if( rc==SQLITE_OK ){ + p->pReal = pReal; + if( p->iSize>0 ){ + assert(p->iSize<=p->nBuf); + rc = sqlite3OsWrite(p->pReal, p->zBuf, p->iSize, 0); + } + if( rc!=SQLITE_OK ){ + /* If an error occurred while writing to the file, close it before + ** returning. This way, SQLite uses the in-memory journal data to + ** roll back changes made to the internal page-cache before this + ** function was called. */ + sqlite3OsClose(pReal); + p->pReal = 0; + } + } + } + return rc; +} + +/* +** Close the file. +*/ +static int jrnlClose(sqlite3_file *pJfd){ + JournalFile *p = (JournalFile *)pJfd; + if( p->pReal ){ + sqlite3OsClose(p->pReal); + } + sqlite3_free(p->zBuf); + return SQLITE_OK; +} + +/* +** Read data from the file. +*/ +static int jrnlRead( + sqlite3_file *pJfd, /* The journal file from which to read */ + void *zBuf, /* Put the results here */ + int iAmt, /* Number of bytes to read */ + sqlite_int64 iOfst /* Begin reading at this offset */ +){ + int rc = SQLITE_OK; + JournalFile *p = (JournalFile *)pJfd; + if( p->pReal ){ + rc = sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst); + }else if( (iAmt+iOfst)>p->iSize ){ + rc = SQLITE_IOERR_SHORT_READ; + }else{ + memcpy(zBuf, &p->zBuf[iOfst], iAmt); + } + return rc; +} + +/* +** Write data to the file. +*/ +static int jrnlWrite( + sqlite3_file *pJfd, /* The journal file into which to write */ + const void *zBuf, /* Take data to be written from here */ + int iAmt, /* Number of bytes to write */ + sqlite_int64 iOfst /* Begin writing at this offset into the file */ +){ + int rc = SQLITE_OK; + JournalFile *p = (JournalFile *)pJfd; + if( !p->pReal && (iOfst+iAmt)>p->nBuf ){ + rc = createFile(p); + } + if( rc==SQLITE_OK ){ + if( p->pReal ){ + rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst); + }else{ + memcpy(&p->zBuf[iOfst], zBuf, iAmt); + if( p->iSize<(iOfst+iAmt) ){ + p->iSize = (iOfst+iAmt); + } + } + } + return rc; +} + +/* +** Truncate the file. +*/ +static int jrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){ + int rc = SQLITE_OK; + JournalFile *p = (JournalFile *)pJfd; + if( p->pReal ){ + rc = sqlite3OsTruncate(p->pReal, size); + }else if( sizeiSize ){ + p->iSize = size; + } + return rc; +} + +/* +** Sync the file. +*/ +static int jrnlSync(sqlite3_file *pJfd, int flags){ + int rc; + JournalFile *p = (JournalFile *)pJfd; + if( p->pReal ){ + rc = sqlite3OsSync(p->pReal, flags); + }else{ + rc = SQLITE_OK; + } + return rc; +} + +/* +** Query the size of the file in bytes. +*/ +static int jrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){ + int rc = SQLITE_OK; + JournalFile *p = (JournalFile *)pJfd; + if( p->pReal ){ + rc = sqlite3OsFileSize(p->pReal, pSize); + }else{ + *pSize = (sqlite_int64) p->iSize; + } + return rc; +} + +/* +** Table of methods for JournalFile sqlite3_file object. +*/ +static struct sqlite3_io_methods JournalFileMethods = { + 1, /* iVersion */ + jrnlClose, /* xClose */ + jrnlRead, /* xRead */ + jrnlWrite, /* xWrite */ + jrnlTruncate, /* xTruncate */ + jrnlSync, /* xSync */ + jrnlFileSize, /* xFileSize */ + 0, /* xLock */ + 0, /* xUnlock */ + 0, /* xCheckReservedLock */ + 0, /* xFileControl */ + 0, /* xSectorSize */ + 0, /* xDeviceCharacteristics */ + 0, /* xShmMap */ + 0, /* xShmLock */ + 0, /* xShmBarrier */ + 0 /* xShmUnmap */ +}; + +/* +** Open a journal file. +*/ +SQLITE_PRIVATE int sqlite3JournalOpen( + sqlite3_vfs *pVfs, /* The VFS to use for actual file I/O */ + const char *zName, /* Name of the journal file */ + sqlite3_file *pJfd, /* Preallocated, blank file handle */ + int flags, /* Opening flags */ + int nBuf /* Bytes buffered before opening the file */ +){ + JournalFile *p = (JournalFile *)pJfd; + memset(p, 0, sqlite3JournalSize(pVfs)); + if( nBuf>0 ){ + p->zBuf = sqlite3MallocZero(nBuf); + if( !p->zBuf ){ + return SQLITE_NOMEM; + } + }else{ + return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0); + } + p->pMethod = &JournalFileMethods; + p->nBuf = nBuf; + p->flags = flags; + p->zJournal = zName; + p->pVfs = pVfs; + return SQLITE_OK; +} + +/* +** If the argument p points to a JournalFile structure, and the underlying +** file has not yet been created, create it now. +*/ +SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *p){ + if( p->pMethods!=&JournalFileMethods ){ + return SQLITE_OK; + } + return createFile((JournalFile *)p); +} + +/* +** The file-handle passed as the only argument is guaranteed to be an open +** file. It may or may not be of class JournalFile. If the file is a +** JournalFile, and the underlying file on disk has not yet been opened, +** return 0. Otherwise, return 1. +*/ +SQLITE_PRIVATE int sqlite3JournalExists(sqlite3_file *p){ + return (p->pMethods!=&JournalFileMethods || ((JournalFile *)p)->pReal!=0); +} + +/* +** Return the number of bytes required to store a JournalFile that uses vfs +** pVfs to create the underlying on-disk files. +*/ +SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){ + return (pVfs->szOsFile+sizeof(JournalFile)); +} +#endif + +/************** End of journal.c *********************************************/ +/************** Begin file memjournal.c **************************************/ +/* +** 2008 October 7 +** +** 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 use to implement an in-memory rollback journal. +** The in-memory rollback journal is used to journal transactions for +** ":memory:" databases and when the journal_mode=MEMORY pragma is used. +*/ + +/* Forward references to internal structures */ +typedef struct MemJournal MemJournal; +typedef struct FilePoint FilePoint; +typedef struct FileChunk FileChunk; + +/* Space to hold the rollback journal is allocated in increments of +** this many bytes. +** +** The size chosen is a little less than a power of two. That way, +** the FileChunk object will have a size that almost exactly fills +** a power-of-two allocation. This minimizes wasted space in power-of-two +** memory allocators. +*/ +#define JOURNAL_CHUNKSIZE ((int)(1024-sizeof(FileChunk*))) + +/* +** The rollback journal is composed of a linked list of these structures. +*/ +struct FileChunk { + FileChunk *pNext; /* Next chunk in the journal */ + u8 zChunk[JOURNAL_CHUNKSIZE]; /* Content of this chunk */ +}; + +/* +** An instance of this object serves as a cursor into the rollback journal. +** The cursor can be either for reading or writing. +*/ +struct FilePoint { + sqlite3_int64 iOffset; /* Offset from the beginning of the file */ + FileChunk *pChunk; /* Specific chunk into which cursor points */ +}; + +/* +** This subclass is a subclass of sqlite3_file. Each open memory-journal +** is an instance of this class. +*/ +struct MemJournal { + sqlite3_io_methods *pMethod; /* Parent class. MUST BE FIRST */ + FileChunk *pFirst; /* Head of in-memory chunk-list */ + FilePoint endpoint; /* Pointer to the end of the file */ + FilePoint readpoint; /* Pointer to the end of the last xRead() */ +}; + +/* +** Read data from the in-memory journal file. This is the implementation +** of the sqlite3_vfs.xRead method. +*/ +static int memjrnlRead( + sqlite3_file *pJfd, /* The journal file from which to read */ + void *zBuf, /* Put the results here */ + int iAmt, /* Number of bytes to read */ + sqlite_int64 iOfst /* Begin reading at this offset */ +){ + MemJournal *p = (MemJournal *)pJfd; + u8 *zOut = zBuf; + int nRead = iAmt; + int iChunkOffset; + FileChunk *pChunk; + + /* SQLite never tries to read past the end of a rollback journal file */ + assert( iOfst+iAmt<=p->endpoint.iOffset ); + + if( p->readpoint.iOffset!=iOfst || iOfst==0 ){ + sqlite3_int64 iOff = 0; + for(pChunk=p->pFirst; + ALWAYS(pChunk) && (iOff+JOURNAL_CHUNKSIZE)<=iOfst; + pChunk=pChunk->pNext + ){ + iOff += JOURNAL_CHUNKSIZE; + } + }else{ + pChunk = p->readpoint.pChunk; + } + + iChunkOffset = (int)(iOfst%JOURNAL_CHUNKSIZE); + do { + int iSpace = JOURNAL_CHUNKSIZE - iChunkOffset; + int nCopy = MIN(nRead, (JOURNAL_CHUNKSIZE - iChunkOffset)); + memcpy(zOut, &pChunk->zChunk[iChunkOffset], nCopy); + zOut += nCopy; + nRead -= iSpace; + iChunkOffset = 0; + } while( nRead>=0 && (pChunk=pChunk->pNext)!=0 && nRead>0 ); + p->readpoint.iOffset = iOfst+iAmt; + p->readpoint.pChunk = pChunk; + + return SQLITE_OK; +} + +/* +** Write data to the file. +*/ +static int memjrnlWrite( + sqlite3_file *pJfd, /* The journal file into which to write */ + const void *zBuf, /* Take data to be written from here */ + int iAmt, /* Number of bytes to write */ + sqlite_int64 iOfst /* Begin writing at this offset into the file */ +){ + MemJournal *p = (MemJournal *)pJfd; + int nWrite = iAmt; + u8 *zWrite = (u8 *)zBuf; + + /* An in-memory journal file should only ever be appended to. Random + ** access writes are not required by sqlite. + */ + assert( iOfst==p->endpoint.iOffset ); + UNUSED_PARAMETER(iOfst); + + while( nWrite>0 ){ + FileChunk *pChunk = p->endpoint.pChunk; + int iChunkOffset = (int)(p->endpoint.iOffset%JOURNAL_CHUNKSIZE); + int iSpace = MIN(nWrite, JOURNAL_CHUNKSIZE - iChunkOffset); + + if( iChunkOffset==0 ){ + /* New chunk is required to extend the file. */ + FileChunk *pNew = sqlite3_malloc(sizeof(FileChunk)); + if( !pNew ){ + return SQLITE_IOERR_NOMEM; + } + pNew->pNext = 0; + if( pChunk ){ + assert( p->pFirst ); + pChunk->pNext = pNew; + }else{ + assert( !p->pFirst ); + p->pFirst = pNew; + } + p->endpoint.pChunk = pNew; + } + + memcpy(&p->endpoint.pChunk->zChunk[iChunkOffset], zWrite, iSpace); + zWrite += iSpace; + nWrite -= iSpace; + p->endpoint.iOffset += iSpace; + } + + return SQLITE_OK; +} + +/* +** Truncate the file. +*/ +static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){ + MemJournal *p = (MemJournal *)pJfd; + FileChunk *pChunk; + assert(size==0); + UNUSED_PARAMETER(size); + pChunk = p->pFirst; + while( pChunk ){ + FileChunk *pTmp = pChunk; + pChunk = pChunk->pNext; + sqlite3_free(pTmp); + } + sqlite3MemJournalOpen(pJfd); + return SQLITE_OK; +} + +/* +** Close the file. +*/ +static int memjrnlClose(sqlite3_file *pJfd){ + memjrnlTruncate(pJfd, 0); + return SQLITE_OK; +} + + +/* +** Sync the file. +** +** Syncing an in-memory journal is a no-op. And, in fact, this routine +** is never called in a working implementation. This implementation +** exists purely as a contingency, in case some malfunction in some other +** part of SQLite causes Sync to be called by mistake. +*/ +static int memjrnlSync(sqlite3_file *NotUsed, int NotUsed2){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + return SQLITE_OK; +} + +/* +** Query the size of the file in bytes. +*/ +static int memjrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){ + MemJournal *p = (MemJournal *)pJfd; + *pSize = (sqlite_int64) p->endpoint.iOffset; + return SQLITE_OK; +} + +/* +** Table of methods for MemJournal sqlite3_file object. +*/ +static const struct sqlite3_io_methods MemJournalMethods = { + 1, /* iVersion */ + memjrnlClose, /* xClose */ + memjrnlRead, /* xRead */ + memjrnlWrite, /* xWrite */ + memjrnlTruncate, /* xTruncate */ + memjrnlSync, /* xSync */ + memjrnlFileSize, /* xFileSize */ + 0, /* xLock */ + 0, /* xUnlock */ + 0, /* xCheckReservedLock */ + 0, /* xFileControl */ + 0, /* xSectorSize */ + 0, /* xDeviceCharacteristics */ + 0, /* xShmMap */ + 0, /* xShmLock */ + 0, /* xShmBarrier */ + 0, /* xShmUnmap */ + 0, /* xFetch */ + 0 /* xUnfetch */ +}; + +/* +** Open a journal file. +*/ +SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *pJfd){ + MemJournal *p = (MemJournal *)pJfd; + assert( EIGHT_BYTE_ALIGNMENT(p) ); + memset(p, 0, sqlite3MemJournalSize()); + p->pMethod = (sqlite3_io_methods*)&MemJournalMethods; +} + +/* +** Return true if the file-handle passed as an argument is +** an in-memory journal +*/ +SQLITE_PRIVATE int sqlite3IsMemJournal(sqlite3_file *pJfd){ + return pJfd->pMethods==&MemJournalMethods; +} + +/* +** Return the number of bytes required to store a MemJournal file descriptor. +*/ +SQLITE_PRIVATE int sqlite3MemJournalSize(void){ + return sizeof(MemJournal); +} + +/************** End of memjournal.c ******************************************/ +/************** Begin file walker.c ******************************************/ +/* +** 2008 August 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 contains routines used for walking the parser tree for +** an SQL statement. +*/ +/* #include */ +/* #include */ + + +/* +** Walk an expression tree. Invoke the callback once for each node +** of the expression, while descending. (In other words, the callback +** is invoked before visiting children.) +** +** The return value from the callback should be one of the WRC_* +** constants to specify how to proceed with the walk. +** +** WRC_Continue Continue descending down the tree. +** +** WRC_Prune Do not descend into child nodes. But allow +** the walk to continue with sibling nodes. +** +** WRC_Abort Do no more callbacks. Unwind the stack and +** return the top-level walk call. +** +** The return value from this routine is WRC_Abort to abandon the tree walk +** and WRC_Continue to continue. +*/ +SQLITE_PRIVATE int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){ + int rc; + if( pExpr==0 ) return WRC_Continue; + testcase( ExprHasProperty(pExpr, EP_TokenOnly) ); + testcase( ExprHasProperty(pExpr, EP_Reduced) ); + rc = pWalker->xExprCallback(pWalker, pExpr); + if( rc==WRC_Continue + && !ExprHasProperty(pExpr,EP_TokenOnly) ){ + if( sqlite3WalkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort; + if( sqlite3WalkExpr(pWalker, pExpr->pRight) ) return WRC_Abort; + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort; + }else{ + if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort; + } + } + return rc & WRC_Abort; +} + +/* +** Call sqlite3WalkExpr() for every expression in list p or until +** an abort request is seen. +*/ +SQLITE_PRIVATE int sqlite3WalkExprList(Walker *pWalker, ExprList *p){ + int i; + struct ExprList_item *pItem; + if( p ){ + for(i=p->nExpr, pItem=p->a; i>0; i--, pItem++){ + if( sqlite3WalkExpr(pWalker, pItem->pExpr) ) return WRC_Abort; + } + } + return WRC_Continue; +} + +/* +** Walk all expressions associated with SELECT statement p. Do +** not invoke the SELECT callback on p, but do (of course) invoke +** any expr callbacks and SELECT callbacks that come from subqueries. +** Return WRC_Abort or WRC_Continue. +*/ +SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ + if( sqlite3WalkExprList(pWalker, p->pEList) ) return WRC_Abort; + if( sqlite3WalkExpr(pWalker, p->pWhere) ) return WRC_Abort; + if( sqlite3WalkExprList(pWalker, p->pGroupBy) ) return WRC_Abort; + if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort; + if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort; + if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort; + if( sqlite3WalkExpr(pWalker, p->pOffset) ) return WRC_Abort; + return WRC_Continue; +} + +/* +** Walk the parse trees associated with all subqueries in the +** FROM clause of SELECT statement p. Do not invoke the select +** callback on p, but do invoke it on each FROM clause subquery +** and on any subqueries further down in the tree. Return +** WRC_Abort or WRC_Continue; +*/ +SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ + SrcList *pSrc; + int i; + struct SrcList_item *pItem; + + pSrc = p->pSrc; + if( ALWAYS(pSrc) ){ + for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ + if( sqlite3WalkSelect(pWalker, pItem->pSelect) ){ + return WRC_Abort; + } + } + } + return WRC_Continue; +} + +/* +** Call sqlite3WalkExpr() for every expression in Select statement p. +** Invoke sqlite3WalkSelect() for subqueries in the FROM clause and +** on the compound select chain, p->pPrior. +** +** If it is not NULL, the xSelectCallback() callback is invoked before +** the walk of the expressions and FROM clause. The xSelectCallback2() +** method, if it is not NULL, is invoked following the walk of the +** expressions and FROM clause. +** +** Return WRC_Continue under normal conditions. Return WRC_Abort if +** there is an abort request. +** +** If the Walker does not have an xSelectCallback() then this routine +** is a no-op returning WRC_Continue. +*/ +SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){ + int rc; + if( p==0 || (pWalker->xSelectCallback==0 && pWalker->xSelectCallback2==0) ){ + return WRC_Continue; + } + rc = WRC_Continue; + pWalker->walkerDepth++; + while( p ){ + if( pWalker->xSelectCallback ){ + rc = pWalker->xSelectCallback(pWalker, p); + if( rc ) break; + } + if( sqlite3WalkSelectExpr(pWalker, p) + || sqlite3WalkSelectFrom(pWalker, p) + ){ + pWalker->walkerDepth--; + return WRC_Abort; + } + if( pWalker->xSelectCallback2 ){ + pWalker->xSelectCallback2(pWalker, p); + } + p = p->pPrior; + } + pWalker->walkerDepth--; + return rc & WRC_Abort; +} + +/************** End of walker.c **********************************************/ +/************** Begin file resolve.c *****************************************/ +/* +** 2008 August 18 +** +** 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 routines used for walking the parser tree and +** resolve all identifiers by associating them with a particular +** table and column. +*/ +/* #include */ +/* #include */ + +/* +** Walk the expression tree pExpr and increase the aggregate function +** depth (the Expr.op2 field) by N on every TK_AGG_FUNCTION node. +** This needs to occur when copying a TK_AGG_FUNCTION node from an +** outer query into an inner subquery. +** +** incrAggFunctionDepth(pExpr,n) is the main routine. incrAggDepth(..) +** is a helper function - a callback for the tree walker. +*/ +static int incrAggDepth(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.n; + return WRC_Continue; +} +static void incrAggFunctionDepth(Expr *pExpr, int N){ + if( N>0 ){ + Walker w; + memset(&w, 0, sizeof(w)); + w.xExprCallback = incrAggDepth; + w.u.n = N; + sqlite3WalkExpr(&w, pExpr); + } +} + +/* +** Turn the pExpr expression into an alias for the iCol-th column of the +** result set in pEList. +** +** If the result set column is a simple column reference, then this routine +** makes an exact copy. But for any other kind of expression, this +** routine make a copy of the result set column as the argument to the +** TK_AS operator. The TK_AS operator causes the expression to be +** evaluated just once and then reused for each alias. +** +** The reason for suppressing the TK_AS term when the expression is a simple +** column reference is so that the column reference will be recognized as +** usable by indices within the WHERE clause processing logic. +** +** The TK_AS operator is inhibited if zType[0]=='G'. This means +** that in a GROUP BY clause, the expression is evaluated twice. Hence: +** +** SELECT random()%5 AS x, count(*) FROM tab GROUP BY x +** +** Is equivalent to: +** +** SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5 +** +** The result of random()%5 in the GROUP BY clause is probably different +** from the result in the result-set. On the other hand Standard SQL does +** not allow the GROUP BY clause to contain references to result-set columns. +** So this should never come up in well-formed queries. +** +** If the reference is followed by a COLLATE operator, then make sure +** the COLLATE operator is preserved. For example: +** +** SELECT a+b, c+d FROM t1 ORDER BY 1 COLLATE nocase; +** +** Should be transformed into: +** +** SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase; +** +** The nSubquery parameter specifies how many levels of subquery the +** alias is removed from the original expression. The usual value is +** zero but it might be more if the alias is contained within a subquery +** of the original expression. The Expr.op2 field of TK_AGG_FUNCTION +** structures must be increased by the nSubquery amount. +*/ +static void resolveAlias( + Parse *pParse, /* Parsing context */ + ExprList *pEList, /* A result set */ + int iCol, /* A column in the result set. 0..pEList->nExpr-1 */ + Expr *pExpr, /* Transform this into an alias to the result set */ + const char *zType, /* "GROUP" or "ORDER" or "" */ + int nSubquery /* Number of subqueries that the label is moving */ +){ + Expr *pOrig; /* The iCol-th column of the result set */ + Expr *pDup; /* Copy of pOrig */ + sqlite3 *db; /* The database connection */ + + assert( iCol>=0 && iColnExpr ); + pOrig = pEList->a[iCol].pExpr; + assert( pOrig!=0 ); + db = pParse->db; + pDup = sqlite3ExprDup(db, pOrig, 0); + if( pDup==0 ) return; + if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){ + incrAggFunctionDepth(pDup, nSubquery); + pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0); + if( pDup==0 ) return; + ExprSetProperty(pDup, EP_Skip); + if( pEList->a[iCol].u.x.iAlias==0 ){ + pEList->a[iCol].u.x.iAlias = (u16)(++pParse->nAlias); + } + pDup->iTable = pEList->a[iCol].u.x.iAlias; + } + if( pExpr->op==TK_COLLATE ){ + pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); + } + + /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This + ** prevents ExprDelete() from deleting the Expr structure itself, + ** allowing it to be repopulated by the memcpy() on the following line. + ** The pExpr->u.zToken might point into memory that will be freed by the + ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to + ** make a copy of the token before doing the sqlite3DbFree(). + */ + ExprSetProperty(pExpr, EP_Static); + sqlite3ExprDelete(db, pExpr); + memcpy(pExpr, pDup, sizeof(*pExpr)); + if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){ + assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 ); + pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken); + pExpr->flags |= EP_MemToken; + } + sqlite3DbFree(db, pDup); +} + + +/* +** Return TRUE if the name zCol occurs anywhere in the USING clause. +** +** Return FALSE if the USING clause is NULL or if it does not contain +** zCol. +*/ +static int nameInUsingClause(IdList *pUsing, const char *zCol){ + if( pUsing ){ + int k; + for(k=0; knId; k++){ + if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ) return 1; + } + } + return 0; +} + +/* +** Subqueries stores the original database, table and column names for their +** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN". +** Check to see if the zSpan given to this routine matches the zDb, zTab, +** and zCol. If any of zDb, zTab, and zCol are NULL then those fields will +** match anything. +*/ +SQLITE_PRIVATE int sqlite3MatchSpanName( + const char *zSpan, + const char *zCol, + const char *zTab, + const char *zDb +){ + int n; + for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){} + if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){ + return 0; + } + zSpan += n+1; + for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){} + if( zTab && (sqlite3StrNICmp(zSpan, zTab, n)!=0 || zTab[n]!=0) ){ + return 0; + } + zSpan += n+1; + if( zCol && sqlite3StrICmp(zSpan, zCol)!=0 ){ + return 0; + } + return 1; +} + +/* +** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up +** that name in the set of source tables in pSrcList and make the pExpr +** expression node refer back to that source column. The following changes +** are made to pExpr: +** +** pExpr->iDb Set the index in db->aDb[] of the database X +** (even if X is implied). +** pExpr->iTable Set to the cursor number for the table obtained +** from pSrcList. +** pExpr->pTab Points to the Table structure of X.Y (even if +** X and/or Y are implied.) +** pExpr->iColumn Set to the column number within the table. +** pExpr->op Set to TK_COLUMN. +** pExpr->pLeft Any expression this points to is deleted +** pExpr->pRight Any expression this points to is deleted. +** +** The zDb variable is the name of the database (the "X"). This value may be +** NULL meaning that name is of the form Y.Z or Z. Any available database +** can be used. The zTable variable is the name of the table (the "Y"). This +** value can be NULL if zDb is also NULL. If zTable is NULL it +** 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 WRC_Abort. Return WRC_Prune on success. +*/ +static int lookupName( + Parse *pParse, /* The parsing context */ + const char *zDb, /* Name of the database containing table, or NULL */ + const char *zTab, /* Name of table containing column, or NULL */ + const char *zCol, /* 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 */ +){ + int i, j; /* Loop counters */ + int cnt = 0; /* Number of matching column names */ + int cntTab = 0; /* Number of matching table names */ + int nSubquery = 0; /* How many levels of subquery */ + sqlite3 *db = pParse->db; /* The database connection */ + struct SrcList_item *pItem; /* Use for looping over pSrcList items */ + struct SrcList_item *pMatch = 0; /* The matching pSrcList item */ + NameContext *pTopNC = pNC; /* First namecontext in the list */ + Schema *pSchema = 0; /* Schema of the expression */ + int isTrigger = 0; /* True if resolved to a trigger column */ + Table *pTab = 0; /* Table hold the row */ + Column *pCol; /* A column of pTab */ + + assert( pNC ); /* the name context cannot be NULL. */ + assert( zCol ); /* The Z in X.Y.Z cannot be NULL */ + assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); + + /* Initialize the node to no-match */ + pExpr->iTable = -1; + pExpr->pTab = 0; + ExprSetVVAProperty(pExpr, EP_NoReduce); + + /* Translate the schema name in zDb into a pointer to the corresponding + ** schema. If not found, pSchema will remain NULL and nothing will match + ** resulting in an appropriate error message toward the end of this routine + */ + if( zDb ){ + testcase( pNC->ncFlags & NC_PartIdx ); + testcase( pNC->ncFlags & NC_IsCheck ); + if( (pNC->ncFlags & (NC_PartIdx|NC_IsCheck))!=0 ){ + /* Silently ignore database qualifiers inside CHECK constraints and + ** partial indices. Do not raise errors because that might break + ** legacy and because it does not hurt anything to just ignore the + ** database name. */ + zDb = 0; + }else{ + for(i=0; inDb; i++){ + assert( db->aDb[i].zName ); + if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){ + pSchema = db->aDb[i].pSchema; + break; + } + } + } + } + + /* Start at the inner-most context and move outward until a match is found */ + while( pNC && cnt==0 ){ + ExprList *pEList; + SrcList *pSrcList = pNC->pSrcList; + + if( pSrcList ){ + for(i=0, pItem=pSrcList->a; inSrc; i++, pItem++){ + pTab = pItem->pTab; + assert( pTab!=0 && pTab->zName!=0 ); + assert( pTab->nCol>0 ); + if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){ + int hit = 0; + pEList = pItem->pSelect->pEList; + for(j=0; jnExpr; j++){ + if( sqlite3MatchSpanName(pEList->a[j].zSpan, zCol, zTab, zDb) ){ + cnt++; + cntTab = 2; + pMatch = pItem; + pExpr->iColumn = j; + hit = 1; + } + } + if( hit || zTab==0 ) continue; + } + if( zDb && pTab->pSchema!=pSchema ){ + continue; + } + if( zTab ){ + const char *zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName; + assert( zTabName!=0 ); + if( sqlite3StrICmp(zTabName, zTab)!=0 ){ + continue; + } + } + if( 0==(cntTab++) ){ + pMatch = pItem; + } + for(j=0, pCol=pTab->aCol; jnCol; j++, pCol++){ + if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ + /* If there has been exactly one prior match and this match + ** is for the right-hand table of a NATURAL JOIN or is in a + ** USING clause, then skip this match. + */ + if( cnt==1 ){ + if( pItem->jointype & JT_NATURAL ) continue; + if( nameInUsingClause(pItem->pUsing, zCol) ) continue; + } + cnt++; + pMatch = pItem; + /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ + pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j; + break; + } + } + } + if( pMatch ){ + pExpr->iTable = pMatch->iCursor; + pExpr->pTab = pMatch->pTab; + /* RIGHT JOIN not (yet) supported */ + assert( (pMatch->jointype & JT_RIGHT)==0 ); + if( (pMatch->jointype & JT_LEFT)!=0 ){ + ExprSetProperty(pExpr, EP_CanBeNull); + } + pSchema = pExpr->pTab->pSchema; + } + } /* if( pSrcList ) */ + +#ifndef SQLITE_OMIT_TRIGGER + /* If we have not already resolved the name, then maybe + ** it is a new.* or old.* trigger argument reference + */ + if( zDb==0 && zTab!=0 && cntTab==0 && pParse->pTriggerTab!=0 ){ + int op = pParse->eTriggerOp; + assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT ); + if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){ + pExpr->iTable = 1; + pTab = pParse->pTriggerTab; + }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){ + pExpr->iTable = 0; + pTab = pParse->pTriggerTab; + }else{ + pTab = 0; + } + + if( pTab ){ + int iCol; + pSchema = pTab->pSchema; + cntTab++; + for(iCol=0, pCol=pTab->aCol; iColnCol; iCol++, pCol++){ + if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ + if( iCol==pTab->iPKey ){ + iCol = -1; + } + break; + } + } + if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && HasRowid(pTab) ){ + /* IMP: R-51414-32910 */ + /* IMP: R-44911-55124 */ + iCol = -1; + } + if( iColnCol ){ + cnt++; + if( iCol<0 ){ + pExpr->affinity = SQLITE_AFF_INTEGER; + }else if( pExpr->iTable==0 ){ + testcase( iCol==31 ); + testcase( iCol==32 ); + pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<iColumn = (i16)iCol; + pExpr->pTab = pTab; + isTrigger = 1; + } + } + } +#endif /* !defined(SQLITE_OMIT_TRIGGER) */ + + /* + ** Perhaps the name is a reference to the ROWID + */ + if( cnt==0 && cntTab==1 && pMatch && sqlite3IsRowid(zCol) + && HasRowid(pMatch->pTab) ){ + cnt = 1; + pExpr->iColumn = -1; /* IMP: R-44911-55124 */ + pExpr->affinity = SQLITE_AFF_INTEGER; + } + + /* + ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z + ** might refer to an result-set alias. This happens, for example, when + ** we are resolving names in the WHERE clause of the following command: + ** + ** 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. + ** + ** The ability to use an output result-set column in the WHERE, GROUP BY, + ** or HAVING clauses, or as part of a larger expression in the ORDRE BY + ** clause is not standard SQL. This is a (goofy) SQLite extension, that + ** is supported for backwards compatibility only. TO DO: Issue a warning + ** on sqlite3_log() whenever the capability is used. + */ + if( (pEList = pNC->pEList)!=0 + && zTab==0 + && cnt==0 + ){ + for(j=0; jnExpr; j++){ + char *zAs = pEList->a[j].zName; + if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){ + Expr *pOrig; + assert( pExpr->pLeft==0 && pExpr->pRight==0 ); + assert( pExpr->x.pList==0 ); + assert( pExpr->x.pSelect==0 ); + pOrig = pEList->a[j].pExpr; + if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){ + sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs); + return WRC_Abort; + } + resolveAlias(pParse, pEList, j, pExpr, "", nSubquery); + cnt = 1; + pMatch = 0; + assert( zTab==0 && zDb==0 ); + goto lookupname_end; + } + } + } + + /* 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; + nSubquery++; + } + } + + /* + ** 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 && ExprHasProperty(pExpr,EP_DblQuoted) ){ + pExpr->op = TK_STRING; + pExpr->pTab = 0; + return WRC_Prune; + } + + /* + ** 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 ){ + const char *zErr; + zErr = cnt==0 ? "no such column" : "ambiguous column name"; + if( zDb ){ + sqlite3ErrorMsg(pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol); + }else if( zTab ){ + sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol); + }else{ + sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol); + } + pParse->checkSchema = 1; + pTopNC->nErr++; + } + + /* If a column from a table in pSrcList is referenced, then record + ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes + ** bit 0 to be set. Column 1 sets bit 1. And so forth. If the + ** column number is greater than the number of bits in the bitmask + ** then set the high-order bit of the bitmask. + */ + if( pExpr->iColumn>=0 && pMatch!=0 ){ + int n = pExpr->iColumn; + testcase( n==BMS-1 ); + if( n>=BMS ){ + n = BMS-1; + } + assert( pMatch->iCursor==pExpr->iTable ); + pMatch->colUsed |= ((Bitmask)1)<pLeft); + pExpr->pLeft = 0; + sqlite3ExprDelete(db, pExpr->pRight); + pExpr->pRight = 0; + pExpr->op = (isTrigger ? TK_TRIGGER : TK_COLUMN); +lookupname_end: + if( cnt==1 ){ + assert( pNC!=0 ); + if( pExpr->op!=TK_AS ){ + sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); + } + /* 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 WRC_Prune; + } else { + return WRC_Abort; + } +} + +/* +** Allocate and return a pointer to an expression to load the column iCol +** from datasource iSrc in SrcList pSrc. +*/ +SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){ + Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0); + if( p ){ + struct SrcList_item *pItem = &pSrc->a[iSrc]; + p->pTab = pItem->pTab; + p->iTable = pItem->iCursor; + if( p->pTab->iPKey==iCol ){ + p->iColumn = -1; + }else{ + p->iColumn = (ynVar)iCol; + testcase( iCol==BMS ); + testcase( iCol==BMS-1 ); + pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol); + } + ExprSetProperty(p, EP_Resolved); + } + return p; +} + +/* +** Report an error that an expression is not valid for a partial index WHERE +** clause. +*/ +static void notValidPartIdxWhere( + Parse *pParse, /* Leave error message here */ + NameContext *pNC, /* The name context */ + const char *zMsg /* Type of error */ +){ + if( (pNC->ncFlags & NC_PartIdx)!=0 ){ + sqlite3ErrorMsg(pParse, "%s prohibited in partial index WHERE clauses", + zMsg); + } +} + +#ifndef SQLITE_OMIT_CHECK +/* +** Report an error that an expression is not valid for a CHECK constraint. +*/ +static void notValidCheckConstraint( + Parse *pParse, /* Leave error message here */ + NameContext *pNC, /* The name context */ + const char *zMsg /* Type of error */ +){ + if( (pNC->ncFlags & NC_IsCheck)!=0 ){ + sqlite3ErrorMsg(pParse,"%s prohibited in CHECK constraints", zMsg); + } +} +#else +# define notValidCheckConstraint(P,N,M) +#endif + +/* +** Expression p should encode a floating point value between 1.0 and 0.0. +** Return 1024 times this value. Or return -1 if p is not a floating point +** value between 1.0 and 0.0. +*/ +static int exprProbability(Expr *p){ + double r = -1.0; + if( p->op!=TK_FLOAT ) return -1; + sqlite3AtoF(p->u.zToken, &r, sqlite3Strlen30(p->u.zToken), SQLITE_UTF8); + assert( r>=0.0 ); + if( r>1.0 ) return -1; + return (int)(r*134217728.0); +} + +/* +** This routine is callback for sqlite3WalkExpr(). +** +** Resolve symbolic names into TK_COLUMN operators for the current +** node in the expression tree. Return 0 to continue the search down +** the tree or 2 to abort the tree walk. +** +** This routine also does error checking and name resolution for +** function names. The operator for aggregate functions is changed +** to TK_AGG_FUNCTION. +*/ +static int resolveExprStep(Walker *pWalker, Expr *pExpr){ + NameContext *pNC; + Parse *pParse; + + pNC = pWalker->u.pNC; + assert( pNC!=0 ); + pParse = pNC->pParse; + assert( pParse==pWalker->pParse ); + + if( ExprHasProperty(pExpr, EP_Resolved) ) return WRC_Prune; + ExprSetProperty(pExpr, EP_Resolved); +#ifndef NDEBUG + if( pNC->pSrcList && pNC->pSrcList->nAlloc>0 ){ + SrcList *pSrcList = pNC->pSrcList; + int i; + for(i=0; ipSrcList->nSrc; i++){ + assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursornTab); + } + } +#endif + switch( pExpr->op ){ + +#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) + /* The special operator TK_ROW means use the rowid for the first + ** column in the FROM clause. This is used by the LIMIT and ORDER BY + ** clause processing on UPDATE and DELETE statements. + */ + case TK_ROW: { + SrcList *pSrcList = pNC->pSrcList; + struct SrcList_item *pItem; + assert( pSrcList && pSrcList->nSrc==1 ); + pItem = pSrcList->a; + pExpr->op = TK_COLUMN; + pExpr->pTab = pItem->pTab; + pExpr->iTable = pItem->iCursor; + pExpr->iColumn = -1; + pExpr->affinity = SQLITE_AFF_INTEGER; + break; + } +#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) + && !defined(SQLITE_OMIT_SUBQUERY) */ + + /* A lone identifier is the name of a column. + */ + case TK_ID: { + return lookupName(pParse, 0, 0, pExpr->u.zToken, pNC, pExpr); + } + + /* A table name and column name: ID.ID + ** Or a database, table and column: ID.ID.ID + */ + case TK_DOT: { + const char *zColumn; + const char *zTable; + const char *zDb; + Expr *pRight; + + /* if( pSrcList==0 ) break; */ + pRight = pExpr->pRight; + if( pRight->op==TK_ID ){ + zDb = 0; + zTable = pExpr->pLeft->u.zToken; + zColumn = pRight->u.zToken; + }else{ + assert( pRight->op==TK_DOT ); + zDb = pExpr->pLeft->u.zToken; + zTable = pRight->pLeft->u.zToken; + zColumn = pRight->pRight->u.zToken; + } + return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr); + } + + /* Resolve function names + */ + case TK_FUNCTION: { + ExprList *pList = pExpr->x.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 auth; /* Authorization to use the function */ + int nId; /* Number of characters in function name */ + const char *zId; /* The function name. */ + FuncDef *pDef; /* Information about the function */ + u8 enc = ENC(pParse->db); /* The database encoding */ + + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + notValidPartIdxWhere(pParse, pNC, "functions"); + zId = pExpr->u.zToken; + nId = sqlite3Strlen30(zId); + pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0); + if( pDef==0 ){ + pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0); + if( pDef==0 ){ + no_such_func = 1; + }else{ + wrong_num_args = 1; + } + }else{ + is_agg = pDef->xFunc==0; + if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){ + ExprSetProperty(pExpr, EP_Unlikely|EP_Skip); + if( n==2 ){ + pExpr->iTable = exprProbability(pList->a[1].pExpr); + if( pExpr->iTable<0 ){ + sqlite3ErrorMsg(pParse, + "second argument to likelihood() must be a " + "constant between 0.0 and 1.0"); + pNC->nErr++; + } + }else{ + /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is + ** equivalent to likelihood(X, 0.0625). + ** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is + ** short-hand for likelihood(X,0.0625). + ** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand + ** for likelihood(X,0.9375). + ** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent + ** to likelihood(X,0.9375). */ + /* TUNING: unlikely() probability is 0.0625. likely() is 0.9375 */ + pExpr->iTable = pDef->zName[0]=='u' ? 8388608 : 125829120; + } + } +#ifndef SQLITE_OMIT_AUTHORIZATION + auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0); + if( auth!=SQLITE_OK ){ + if( auth==SQLITE_DENY ){ + sqlite3ErrorMsg(pParse, "not authorized to use function: %s", + pDef->zName); + pNC->nErr++; + } + pExpr->op = TK_NULL; + return WRC_Prune; + } +#endif + if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ){ + ExprSetProperty(pExpr,EP_ConstFunc); + } + } + if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){ + sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId); + pNC->nErr++; + is_agg = 0; + }else if( no_such_func && pParse->db->init.busy==0 ){ + sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); + pNC->nErr++; + }else if( wrong_num_args ){ + sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()", + nId, zId); + pNC->nErr++; + } + if( is_agg ) pNC->ncFlags &= ~NC_AllowAgg; + sqlite3WalkExprList(pWalker, pList); + if( is_agg ){ + NameContext *pNC2 = pNC; + pExpr->op = TK_AGG_FUNCTION; + pExpr->op2 = 0; + while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){ + pExpr->op2++; + pNC2 = pNC2->pNext; + } + assert( pDef!=0 ); + if( pNC2 ){ + assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg ); + testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 ); + pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX); + + } + pNC->ncFlags |= NC_AllowAgg; + } + /* FIX ME: Compute pExpr->affinity based on the expected return + ** type of the function + */ + return WRC_Prune; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_SELECT: + case TK_EXISTS: testcase( pExpr->op==TK_EXISTS ); +#endif + case TK_IN: { + testcase( pExpr->op==TK_IN ); + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + int nRef = pNC->nRef; + notValidCheckConstraint(pParse, pNC, "subqueries"); + notValidPartIdxWhere(pParse, pNC, "subqueries"); + sqlite3WalkSelect(pWalker, pExpr->x.pSelect); + assert( pNC->nRef>=nRef ); + if( nRef!=pNC->nRef ){ + ExprSetProperty(pExpr, EP_VarSelect); + } + } + break; + } + case TK_VARIABLE: { + notValidCheckConstraint(pParse, pNC, "parameters"); + notValidPartIdxWhere(pParse, pNC, "parameters"); + break; + } + } + return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue; +} + +/* +** pEList is a list of expressions which are really the result set of the +** a SELECT statement. pE is a term in an ORDER BY or GROUP BY clause. +** This routine checks to see if pE is a simple identifier which corresponds +** to the AS-name of one of the terms of the expression list. If it is, +** this routine return an integer between 1 and N where N is the number of +** elements in pEList, corresponding to the matching entry. If there is +** no match, or if pE is not a simple identifier, then this routine +** return 0. +** +** pEList has been resolved. pE has not. +*/ +static int resolveAsName( + Parse *pParse, /* Parsing context for error messages */ + ExprList *pEList, /* List of expressions to scan */ + Expr *pE /* Expression we are trying to match */ +){ + int i; /* Loop counter */ + + UNUSED_PARAMETER(pParse); + + if( pE->op==TK_ID ){ + char *zCol = pE->u.zToken; + for(i=0; inExpr; i++){ + char *zAs = pEList->a[i].zName; + if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){ + return i+1; + } + } + } + return 0; +} + +/* +** pE is a pointer to an expression which is a single term in the +** ORDER BY of a compound SELECT. The expression has not been +** name resolved. +** +** At the point this routine is called, we already know that the +** ORDER BY term is not an integer index into the result set. That +** case is handled by the calling routine. +** +** Attempt to match pE against result set columns in the left-most +** SELECT statement. Return the index i of the matching column, +** as an indication to the caller that it should sort by the i-th column. +** The left-most column is 1. In other words, the value returned is the +** same integer value that would be used in the SQL statement to indicate +** the column. +** +** If there is no match, return 0. Return -1 if an error occurs. +*/ +static int resolveOrderByTermToExprList( + Parse *pParse, /* Parsing context for error messages */ + Select *pSelect, /* The SELECT statement with the ORDER BY clause */ + Expr *pE /* The specific ORDER BY term */ +){ + int i; /* Loop counter */ + ExprList *pEList; /* The columns of the result set */ + NameContext nc; /* Name context for resolving pE */ + sqlite3 *db; /* Database connection */ + int rc; /* Return code from subprocedures */ + u8 savedSuppErr; /* Saved value of db->suppressErr */ + + assert( sqlite3ExprIsInteger(pE, &i)==0 ); + pEList = pSelect->pEList; + + /* Resolve all names in the ORDER BY term expression + */ + memset(&nc, 0, sizeof(nc)); + nc.pParse = pParse; + nc.pSrcList = pSelect->pSrc; + nc.pEList = pEList; + nc.ncFlags = NC_AllowAgg; + nc.nErr = 0; + db = pParse->db; + savedSuppErr = db->suppressErr; + db->suppressErr = 1; + rc = sqlite3ResolveExprNames(&nc, pE); + db->suppressErr = savedSuppErr; + if( rc ) return 0; + + /* Try to match the ORDER BY expression against an expression + ** in the result set. Return an 1-based index of the matching + ** result-set entry. + */ + for(i=0; inExpr; i++){ + if( sqlite3ExprCompare(pEList->a[i].pExpr, pE, -1)<2 ){ + return i+1; + } + } + + /* If no match, return 0. */ + return 0; +} + +/* +** Generate an ORDER BY or GROUP BY term out-of-range error. +*/ +static void resolveOutOfRangeError( + Parse *pParse, /* The error context into which to write the error */ + const char *zType, /* "ORDER" or "GROUP" */ + int i, /* The index (1-based) of the term out of range */ + int mx /* Largest permissible value of i */ +){ + sqlite3ErrorMsg(pParse, + "%r %s BY term out of range - should be " + "between 1 and %d", i, zType, mx); +} + +/* +** Analyze the ORDER BY clause in a compound SELECT statement. Modify +** each term of the ORDER BY clause is a constant integer between 1 +** and N where N is the number of columns in the compound SELECT. +** +** ORDER BY terms that are already an integer between 1 and N are +** unmodified. ORDER BY terms that are integers outside the range of +** 1 through N generate an error. ORDER BY terms that are expressions +** are matched against result set expressions of compound SELECT +** beginning with the left-most SELECT and working toward the right. +** At the first match, the ORDER BY expression is transformed into +** the integer column number. +** +** Return the number of errors seen. +*/ +static int resolveCompoundOrderBy( + Parse *pParse, /* Parsing context. Leave error messages here */ + Select *pSelect /* The SELECT statement containing the ORDER BY */ +){ + int i; + ExprList *pOrderBy; + ExprList *pEList; + sqlite3 *db; + int moreToDo = 1; + + pOrderBy = pSelect->pOrderBy; + if( pOrderBy==0 ) return 0; + db = pParse->db; +#if SQLITE_MAX_COLUMN + if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ + sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause"); + return 1; + } +#endif + for(i=0; inExpr; i++){ + pOrderBy->a[i].done = 0; + } + pSelect->pNext = 0; + while( pSelect->pPrior ){ + pSelect->pPrior->pNext = pSelect; + pSelect = pSelect->pPrior; + } + while( pSelect && moreToDo ){ + struct ExprList_item *pItem; + moreToDo = 0; + pEList = pSelect->pEList; + assert( pEList!=0 ); + for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ + int iCol = -1; + Expr *pE, *pDup; + if( pItem->done ) continue; + pE = sqlite3ExprSkipCollate(pItem->pExpr); + if( sqlite3ExprIsInteger(pE, &iCol) ){ + if( iCol<=0 || iCol>pEList->nExpr ){ + resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr); + return 1; + } + }else{ + iCol = resolveAsName(pParse, pEList, pE); + if( iCol==0 ){ + pDup = sqlite3ExprDup(db, pE, 0); + if( !db->mallocFailed ){ + assert(pDup); + iCol = resolveOrderByTermToExprList(pParse, pSelect, pDup); + } + sqlite3ExprDelete(db, pDup); + } + } + if( iCol>0 ){ + /* Convert the ORDER BY term into an integer column number iCol, + ** taking care to preserve the COLLATE clause if it exists */ + Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); + if( pNew==0 ) return 1; + pNew->flags |= EP_IntValue; + pNew->u.iValue = iCol; + if( pItem->pExpr==pE ){ + pItem->pExpr = pNew; + }else{ + Expr *pParent = pItem->pExpr; + assert( pParent->op==TK_COLLATE ); + while( pParent->pLeft->op==TK_COLLATE ) pParent = pParent->pLeft; + assert( pParent->pLeft==pE ); + pParent->pLeft = pNew; + } + sqlite3ExprDelete(db, pE); + pItem->u.x.iOrderByCol = (u16)iCol; + pItem->done = 1; + }else{ + moreToDo = 1; + } + } + pSelect = pSelect->pNext; + } + for(i=0; inExpr; i++){ + if( pOrderBy->a[i].done==0 ){ + sqlite3ErrorMsg(pParse, "%r ORDER BY term does not match any " + "column in the result set", i+1); + return 1; + } + } + return 0; +} + +/* +** Check every term in the ORDER BY or GROUP BY clause pOrderBy of +** the SELECT statement pSelect. If any term is reference to a +** result set expression (as determined by the ExprList.a.u.x.iOrderByCol +** field) then convert that term into a copy of the corresponding result set +** column. +** +** If any errors are detected, add an error message to pParse and +** return non-zero. Return zero if no errors are seen. +*/ +SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy( + Parse *pParse, /* Parsing context. Leave error messages here */ + Select *pSelect, /* The SELECT statement containing the clause */ + ExprList *pOrderBy, /* The ORDER BY or GROUP BY clause to be processed */ + const char *zType /* "ORDER" or "GROUP" */ +){ + int i; + sqlite3 *db = pParse->db; + ExprList *pEList; + struct ExprList_item *pItem; + + if( pOrderBy==0 || pParse->db->mallocFailed ) return 0; +#if SQLITE_MAX_COLUMN + if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ + sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType); + return 1; + } +#endif + pEList = pSelect->pEList; + assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */ + for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ + if( pItem->u.x.iOrderByCol ){ + if( pItem->u.x.iOrderByCol>pEList->nExpr ){ + resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr); + return 1; + } + resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr, + zType,0); + } + } + return 0; +} + +/* +** pOrderBy is an ORDER BY or GROUP BY clause in SELECT statement pSelect. +** The Name context of the SELECT statement is pNC. zType is either +** "ORDER" or "GROUP" depending on which type of clause pOrderBy is. +** +** This routine resolves each term of the clause into an expression. +** If the order-by term is an integer I between 1 and N (where N is the +** number of columns in the result set of the SELECT) then the expression +** in the resolution is a copy of the I-th result-set expression. If +** the order-by term is an identifier that corresponds to the AS-name of +** a result-set expression, then the term resolves to a copy of the +** result-set expression. Otherwise, the expression is resolved in +** the usual way - using sqlite3ResolveExprNames(). +** +** This routine returns the number of errors. If errors occur, then +** an appropriate error message might be left in pParse. (OOM errors +** excepted.) +*/ +static int resolveOrderGroupBy( + NameContext *pNC, /* The name context of the SELECT statement */ + Select *pSelect, /* The SELECT statement holding pOrderBy */ + ExprList *pOrderBy, /* An ORDER BY or GROUP BY clause to resolve */ + const char *zType /* Either "ORDER" or "GROUP", as appropriate */ +){ + int i, j; /* Loop counters */ + int iCol; /* Column number */ + struct ExprList_item *pItem; /* A term of the ORDER BY clause */ + Parse *pParse; /* Parsing context */ + int nResult; /* Number of terms in the result set */ + + if( pOrderBy==0 ) return 0; + nResult = pSelect->pEList->nExpr; + pParse = pNC->pParse; + for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ + Expr *pE = pItem->pExpr; + Expr *pE2 = sqlite3ExprSkipCollate(pE); + if( zType[0]!='G' ){ + iCol = resolveAsName(pParse, pSelect->pEList, pE2); + if( iCol>0 ){ + /* If an AS-name match is found, mark this ORDER BY column as being + ** a copy of the iCol-th result-set column. The subsequent call to + ** sqlite3ResolveOrderGroupBy() will convert the expression to a + ** copy of the iCol-th result-set expression. */ + pItem->u.x.iOrderByCol = (u16)iCol; + continue; + } + } + if( sqlite3ExprIsInteger(pE2, &iCol) ){ + /* The ORDER BY term is an integer constant. Again, set the column + ** number so that sqlite3ResolveOrderGroupBy() will convert the + ** order-by term to a copy of the result-set expression */ + if( iCol<1 || iCol>0xffff ){ + resolveOutOfRangeError(pParse, zType, i+1, nResult); + return 1; + } + pItem->u.x.iOrderByCol = (u16)iCol; + continue; + } + + /* Otherwise, treat the ORDER BY term as an ordinary expression */ + pItem->u.x.iOrderByCol = 0; + if( sqlite3ResolveExprNames(pNC, pE) ){ + return 1; + } + for(j=0; jpEList->nExpr; j++){ + if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ + pItem->u.x.iOrderByCol = j+1; + } + } + } + return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType); +} + +/* +** Resolve names in the SELECT statement p and all of its descendants. +*/ +static int resolveSelectStep(Walker *pWalker, Select *p){ + NameContext *pOuterNC; /* Context that contains this SELECT */ + NameContext sNC; /* Name context of this SELECT */ + int isCompound; /* True if p is a compound select */ + int nCompound; /* Number of compound terms processed so far */ + Parse *pParse; /* Parsing context */ + ExprList *pEList; /* Result set expression list */ + int i; /* Loop counter */ + ExprList *pGroupBy; /* The GROUP BY clause */ + Select *pLeftmost; /* Left-most of SELECT of a compound */ + sqlite3 *db; /* Database connection */ + + + assert( p!=0 ); + if( p->selFlags & SF_Resolved ){ + return WRC_Prune; + } + pOuterNC = pWalker->u.pNC; + pParse = pWalker->pParse; + db = pParse->db; + + /* Normally sqlite3SelectExpand() will be called first and will have + ** already expanded this SELECT. However, if this is a subquery within + ** an expression, sqlite3ResolveExprNames() will be called without a + ** prior call to sqlite3SelectExpand(). When that happens, let + ** sqlite3SelectPrep() do all of the processing for this SELECT. + ** sqlite3SelectPrep() will invoke both sqlite3SelectExpand() and + ** this routine in the correct order. + */ + if( (p->selFlags & SF_Expanded)==0 ){ + sqlite3SelectPrep(pParse, p, pOuterNC); + return (pParse->nErr || db->mallocFailed) ? WRC_Abort : WRC_Prune; + } + + isCompound = p->pPrior!=0; + nCompound = 0; + pLeftmost = p; + while( p ){ + assert( (p->selFlags & SF_Expanded)!=0 ); + assert( (p->selFlags & SF_Resolved)==0 ); + p->selFlags |= SF_Resolved; + + /* 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( sqlite3ResolveExprNames(&sNC, p->pLimit) || + sqlite3ResolveExprNames(&sNC, p->pOffset) ){ + return WRC_Abort; + } + + /* If the SF_Converted flags is set, then this Select object was + ** was created by the convertCompoundSelectToSubquery() function. + ** In this case the ORDER BY clause (p->pOrderBy) should be resolved + ** as if it were part of the sub-query, not the parent. This block + ** moves the pOrderBy down to the sub-query. It will be moved back + ** after the names have been resolved. */ + if( p->selFlags & SF_Converted ){ + Select *pSub = p->pSrc->a[0].pSelect; + assert( p->pSrc->nSrc==1 && p->pOrderBy ); + assert( pSub->pPrior && pSub->pOrderBy==0 ); + pSub->pOrderBy = p->pOrderBy; + p->pOrderBy = 0; + } + + /* Recursively resolve names in all subqueries + */ + for(i=0; ipSrc->nSrc; i++){ + struct SrcList_item *pItem = &p->pSrc->a[i]; + if( pItem->pSelect ){ + NameContext *pNC; /* Used to iterate name contexts */ + int nRef = 0; /* Refcount for pOuterNC and outer contexts */ + const char *zSavedContext = pParse->zAuthContext; + + /* Count the total number of references to pOuterNC and all of its + ** parent contexts. After resolving references to expressions in + ** pItem->pSelect, check if this value has changed. If so, then + ** SELECT statement pItem->pSelect must be correlated. Set the + ** pItem->isCorrelated flag if this is the case. */ + for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef += pNC->nRef; + + if( pItem->zName ) pParse->zAuthContext = pItem->zName; + sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC); + pParse->zAuthContext = zSavedContext; + if( pParse->nErr || db->mallocFailed ) return WRC_Abort; + + for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef -= pNC->nRef; + assert( pItem->isCorrelated==0 && nRef<=0 ); + pItem->isCorrelated = (nRef!=0); + } + } + + /* Set up the local name-context to pass to sqlite3ResolveExprNames() to + ** resolve the result-set expression list. + */ + sNC.ncFlags = NC_AllowAgg; + sNC.pSrcList = p->pSrc; + sNC.pNext = pOuterNC; + + /* Resolve names in the result set. */ + pEList = p->pEList; + assert( pEList!=0 ); + for(i=0; inExpr; i++){ + Expr *pX = pEList->a[i].pExpr; + if( sqlite3ResolveExprNames(&sNC, pX) ){ + return WRC_Abort; + } + } + + /* 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->selFlags & SF_Aggregate)==0 ); + pGroupBy = p->pGroupBy; + if( pGroupBy || (sNC.ncFlags & NC_HasAgg)!=0 ){ + assert( NC_MinMaxAgg==SF_MinMaxAgg ); + p->selFlags |= SF_Aggregate | (sNC.ncFlags&NC_MinMaxAgg); + }else{ + sNC.ncFlags &= ~NC_AllowAgg; + } + + /* 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 WRC_Abort; + } + + /* Add the output column 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( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; + if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort; + + /* The ORDER BY and GROUP BY clauses may not refer to terms in + ** outer queries + */ + sNC.pNext = 0; + sNC.ncFlags |= NC_AllowAgg; + + /* If this is a converted compound query, move the ORDER BY clause from + ** the sub-query back to the parent query. At this point each term + ** within the ORDER BY clause has been transformed to an integer value. + ** These integers will be replaced by copies of the corresponding result + ** set expressions by the call to resolveOrderGroupBy() below. */ + if( p->selFlags & SF_Converted ){ + Select *pSub = p->pSrc->a[0].pSelect; + p->pOrderBy = pSub->pOrderBy; + pSub->pOrderBy = 0; + } + + /* Process the ORDER BY clause for singleton SELECT statements. + ** The ORDER BY clause for compounds SELECT statements is handled + ** below, after all of the result-sets for all of the elements of + ** the compound have been resolved. + ** + ** If there is an ORDER BY clause on a term of a compound-select other + ** than the right-most term, then that is a syntax error. But the error + ** is not detected until much later, and so we need to go ahead and + ** resolve those symbols on the incorrect ORDER BY for consistency. + */ + if( isCompound<=nCompound /* Defer right-most ORDER BY of a compound */ + && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") + ){ + return WRC_Abort; + } + if( db->mallocFailed ){ + return WRC_Abort; + } + + /* Resolve the GROUP BY clause. At the same time, make sure + ** the GROUP BY clause does not contain aggregate functions. + */ + if( pGroupBy ){ + struct ExprList_item *pItem; + + if( resolveOrderGroupBy(&sNC, p, pGroupBy, "GROUP") || db->mallocFailed ){ + return WRC_Abort; + } + for(i=0, pItem=pGroupBy->a; inExpr; i++, pItem++){ + if( ExprHasProperty(pItem->pExpr, EP_Agg) ){ + sqlite3ErrorMsg(pParse, "aggregate functions are not allowed in " + "the GROUP BY clause"); + return WRC_Abort; + } + } + } + + /* Advance to the next term of the compound + */ + p = p->pPrior; + nCompound++; + } + + /* Resolve the ORDER BY on a compound SELECT after all terms of + ** the compound have been resolved. + */ + if( isCompound && resolveCompoundOrderBy(pParse, pLeftmost) ){ + return WRC_Abort; + } + + return WRC_Prune; +} + +/* +** This routine walks an expression tree and resolves references to +** table columns and result-set columns. At the same time, do error +** checking on function usage and set a flag if any aggregate functions +** are seen. +** +** To resolve table columns references we look for nodes (or subtrees) of the +** form X.Y.Z or Y.Z or just Z where +** +** X: The name of a database. Ex: "main" or "temp" or +** the symbolic name assigned to an ATTACH-ed database. +** +** Y: The name of a table in a FROM clause. Or in a trigger +** one of the special names "old" or "new". +** +** Z: The name of a column in table Y. +** +** The node at the root of the subtree is modified as follows: +** +** Expr.op Changed to TK_COLUMN +** Expr.pTab Points to the Table object for X.Y +** Expr.iColumn The column index in X.Y. -1 for the rowid. +** Expr.iTable The VDBE cursor number for X.Y +** +** +** To resolve result-set references, look for expression nodes of the +** form Z (with no X and Y prefix) where the Z matches the right-hand +** size of an AS clause in the result-set of a SELECT. The Z expression +** is replaced by a copy of the left-hand side of the result-set expression. +** Table-name and function resolution occurs on the substituted expression +** tree. For example, in: +** +** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY x; +** +** The "x" term of the order by is replaced by "a+b" to render: +** +** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY a+b; +** +** Function calls are checked to make sure that the function is +** defined and that the correct number of arguments are specified. +** If the function is an aggregate function, then the NC_HasAgg flag is +** set and the opcode is changed from TK_FUNCTION to TK_AGG_FUNCTION. +** If an expression contains aggregate functions then the EP_Agg +** property on the expression is set. +** +** An error message is left in pParse if anything is amiss. The number +** if errors is returned. +*/ +SQLITE_PRIVATE int sqlite3ResolveExprNames( + NameContext *pNC, /* Namespace to resolve expressions in. */ + Expr *pExpr /* The expression to be analyzed. */ +){ + u16 savedHasAgg; + Walker w; + + if( pExpr==0 ) return 0; +#if SQLITE_MAX_EXPR_DEPTH>0 + { + Parse *pParse = pNC->pParse; + if( sqlite3ExprCheckHeight(pParse, pExpr->nHeight+pNC->pParse->nHeight) ){ + return 1; + } + pParse->nHeight += pExpr->nHeight; + } +#endif + savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg); + pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg); + memset(&w, 0, sizeof(w)); + w.xExprCallback = resolveExprStep; + w.xSelectCallback = resolveSelectStep; + w.pParse = pNC->pParse; + w.u.pNC = pNC; + sqlite3WalkExpr(&w, pExpr); +#if SQLITE_MAX_EXPR_DEPTH>0 + pNC->pParse->nHeight -= pExpr->nHeight; +#endif + if( pNC->nErr>0 || w.pParse->nErr>0 ){ + ExprSetProperty(pExpr, EP_Error); + } + if( pNC->ncFlags & NC_HasAgg ){ + ExprSetProperty(pExpr, EP_Agg); + } + pNC->ncFlags |= savedHasAgg; + return ExprHasProperty(pExpr, EP_Error); +} + + +/* +** Resolve all names in all expressions of a SELECT and in all +** decendents of the SELECT, including compounds off of p->pPrior, +** subqueries in expressions, and subqueries used as FROM clause +** terms. +** +** See sqlite3ResolveExprNames() for a description of the kinds of +** transformations that occur. +** +** All SELECT statements should have been expanded using +** sqlite3SelectExpand() prior to invoking this routine. +*/ +SQLITE_PRIVATE void sqlite3ResolveSelectNames( + Parse *pParse, /* The parser context */ + Select *p, /* The SELECT statement being coded. */ + NameContext *pOuterNC /* Name context for parent SELECT statement */ +){ + Walker w; + + assert( p!=0 ); + memset(&w, 0, sizeof(w)); + w.xExprCallback = resolveExprStep; + w.xSelectCallback = resolveSelectStep; + w.pParse = pParse; + w.u.pNC = pOuterNC; + sqlite3WalkSelect(&w, p); +} + +/* +** Resolve names in expressions that can only reference a single table: +** +** * CHECK constraints +** * WHERE clauses on partial indices +** +** The Expr.iTable value for Expr.op==TK_COLUMN nodes of the expression +** is set to -1 and the Expr.iColumn value is set to the column number. +** +** Any errors cause an error message to be set in pParse. +*/ +SQLITE_PRIVATE void sqlite3ResolveSelfReference( + Parse *pParse, /* Parsing context */ + Table *pTab, /* The table being referenced */ + int type, /* NC_IsCheck or NC_PartIdx */ + Expr *pExpr, /* Expression to resolve. May be NULL. */ + ExprList *pList /* Expression list to resolve. May be NUL. */ +){ + SrcList sSrc; /* Fake SrcList for pParse->pNewTable */ + NameContext sNC; /* Name context for pParse->pNewTable */ + int i; /* Loop counter */ + + assert( type==NC_IsCheck || type==NC_PartIdx ); + memset(&sNC, 0, sizeof(sNC)); + memset(&sSrc, 0, sizeof(sSrc)); + sSrc.nSrc = 1; + sSrc.a[0].zName = pTab->zName; + sSrc.a[0].pTab = pTab; + sSrc.a[0].iCursor = -1; + sNC.pParse = pParse; + sNC.pSrcList = &sSrc; + sNC.ncFlags = type; + if( sqlite3ResolveExprNames(&sNC, pExpr) ) return; + if( pList ){ + for(i=0; inExpr; i++){ + if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){ + return; + } + } + } +} + +/************** End of resolve.c *********************************************/ +/************** Begin file expr.c ********************************************/ +/* +** 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. +** +************************************************************************* +** This file contains routines used for analyzing expressions and +** for generating VDBE code that evaluates expressions in SQLite. +*/ + +/* +** Return the 'affinity' of the expression pExpr if any. +** +** If pExpr is a column, a reference to a column via an 'AS' alias, +** or a sub-select with a column as the return value, then the +** affinity of that column is returned. Otherwise, 0x00 is returned, +** indicating no affinity for the expression. +** +** i.e. the WHERE clause expressions in the following statements all +** have an affinity: +** +** 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); +*/ +SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){ + int op; + pExpr = sqlite3ExprSkipCollate(pExpr); + if( pExpr->flags & EP_Generic ) return 0; + op = pExpr->op; + if( op==TK_SELECT ){ + assert( pExpr->flags&EP_xIsSelect ); + return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr); + } +#ifndef SQLITE_OMIT_CAST + if( op==TK_CAST ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + return sqlite3AffinityType(pExpr->u.zToken, 0); + } +#endif + if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER) + && pExpr->pTab!=0 + ){ + /* op==TK_REGISTER && pExpr->pTab!=0 happens when pExpr was originally + ** a TK_COLUMN but was previously evaluated and cached in a register */ + int j = pExpr->iColumn; + if( j<0 ) return SQLITE_AFF_INTEGER; + assert( pExpr->pTab && jpTab->nCol ); + return pExpr->pTab->aCol[j].affinity; + } + return pExpr->affinity; +} + +/* +** Set the collating sequence for expression pExpr to be the collating +** sequence named by pToken. Return a pointer to a new Expr node that +** implements the COLLATE operator. +** +** If a memory allocation error occurs, that fact is recorded in pParse->db +** and the pExpr parameter is returned unchanged. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* Add the "COLLATE" clause to this expression */ + const Token *pCollName, /* Name of collating sequence */ + int dequote /* True to dequote pCollName */ +){ + if( pCollName->n>0 ){ + Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote); + if( pNew ){ + pNew->pLeft = pExpr; + pNew->flags |= EP_Collate|EP_Skip; + pExpr = pNew; + } + } + return pExpr; +} +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){ + Token s; + assert( zC!=0 ); + s.z = zC; + s.n = sqlite3Strlen30(s.z); + return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0); +} + +/* +** Skip over any TK_COLLATE or TK_AS operators and any unlikely() +** or likelihood() function at the root of an expression. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){ + while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){ + if( ExprHasProperty(pExpr, EP_Unlikely) ){ + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + assert( pExpr->x.pList->nExpr>0 ); + assert( pExpr->op==TK_FUNCTION ); + pExpr = pExpr->x.pList->a[0].pExpr; + }else{ + assert( pExpr->op==TK_COLLATE || pExpr->op==TK_AS ); + pExpr = pExpr->pLeft; + } + } + return pExpr; +} + +/* +** Return the collation sequence for the expression pExpr. If +** there is no defined collating sequence, return NULL. +** +** The collating sequence might be determined by a COLLATE operator +** or by the presence of a column with a defined collating sequence. +** COLLATE operators take first precedence. Left operands take +** precedence over right operands. +*/ +SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ + sqlite3 *db = pParse->db; + CollSeq *pColl = 0; + Expr *p = pExpr; + while( p ){ + int op = p->op; + if( p->flags & EP_Generic ) break; + if( op==TK_CAST || op==TK_UPLUS ){ + p = p->pLeft; + continue; + } + if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){ + pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); + break; + } + if( (op==TK_AGG_COLUMN || op==TK_COLUMN + || op==TK_REGISTER || op==TK_TRIGGER) + && p->pTab!=0 + ){ + /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally + ** a TK_COLUMN but was previously evaluated and cached in a register */ + int j = p->iColumn; + if( j>=0 ){ + const char *zColl = p->pTab->aCol[j].zColl; + pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); + } + break; + } + if( p->flags & EP_Collate ){ + if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){ + p = p->pLeft; + }else{ + Expr *pNext = p->pRight; + /* The Expr.x union is never used at the same time as Expr.pRight */ + assert( p->x.pList==0 || p->pRight==0 ); + /* p->flags holds EP_Collate and p->pLeft->flags does not. And + ** p->x.pSelect cannot. So if p->x.pLeft exists, it must hold at + ** least one EP_Collate. Thus the following two ALWAYS. */ + if( p->x.pList!=0 && ALWAYS(!ExprHasProperty(p, EP_xIsSelect)) ){ + int i; + for(i=0; ALWAYS(ix.pList->nExpr); i++){ + if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){ + pNext = p->x.pList->a[i].pExpr; + break; + } + } + } + p = pNext; + } + }else{ + break; + } + } + 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. +*/ +SQLITE_PRIVATE 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. +*/ +static char comparisonAffinity(Expr *pExpr){ + char aff; + assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT || + pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE || + pExpr->op==TK_NE || pExpr->op==TK_IS || pExpr->op==TK_ISNOT ); + assert( pExpr->pLeft ); + aff = sqlite3ExprAffinity(pExpr->pLeft); + if( pExpr->pRight ){ + aff = sqlite3CompareAffinity(pExpr->pRight, aff); + }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff); + }else if( !aff ){ + aff = SQLITE_AFF_NONE; + } + return aff; +} + +/* +** 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. +*/ +SQLITE_PRIVATE 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 P5 value that should be used for a binary comparison +** opcode (OP_Eq, OP_Ge etc.) used to compare pExpr1 and pExpr2. +*/ +static u8 binaryCompareP5(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){ + u8 aff = (char)sqlite3ExprAffinity(pExpr2); + aff = (u8)sqlite3CompareAffinity(pExpr1, aff) | (u8)jumpIfNull; + return aff; +} + +/* +** 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 +** used. Otherwise the collation sequence for the right hand expression +** is used, or the default (BINARY) if neither expression has a collating +** type. +** +** Argument pRight (but not pLeft) may be a null pointer. In this case, +** it is not considered. +*/ +SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq( + Parse *pParse, + Expr *pLeft, + Expr *pRight +){ + CollSeq *pColl; + assert( pLeft ); + if( pLeft->flags & EP_Collate ){ + pColl = sqlite3ExprCollSeq(pParse, pLeft); + }else if( pRight && (pRight->flags & EP_Collate)!=0 ){ + pColl = sqlite3ExprCollSeq(pParse, pRight); + }else{ + pColl = sqlite3ExprCollSeq(pParse, pLeft); + if( !pColl ){ + pColl = sqlite3ExprCollSeq(pParse, pRight); + } + } + return pColl; +} + +/* +** Generate code for a comparison operator. +*/ +static int codeCompare( + Parse *pParse, /* The parsing (and code generating) context */ + Expr *pLeft, /* The left operand */ + Expr *pRight, /* The right operand */ + int opcode, /* The comparison opcode */ + int in1, int in2, /* Register holding operands */ + int dest, /* Jump here if true. */ + int jumpIfNull /* If true, jump if either operand is NULL */ +){ + int p5; + int addr; + CollSeq *p4; + + p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight); + p5 = binaryCompareP5(pLeft, pRight, jumpIfNull); + addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1, + (void*)p4, P4_COLLSEQ); + sqlite3VdbeChangeP5(pParse->pVdbe, (u8)p5); + return addr; +} + +#if SQLITE_MAX_EXPR_DEPTH>0 +/* +** Check that argument nHeight is less than or equal to the maximum +** expression depth allowed. If it is not, leave an error message in +** pParse. +*/ +SQLITE_PRIVATE int sqlite3ExprCheckHeight(Parse *pParse, int nHeight){ + int rc = SQLITE_OK; + int mxHeight = pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH]; + if( nHeight>mxHeight ){ + sqlite3ErrorMsg(pParse, + "Expression tree is too large (maximum depth %d)", mxHeight + ); + rc = SQLITE_ERROR; + } + return rc; +} + +/* The following three functions, heightOfExpr(), heightOfExprList() +** and heightOfSelect(), are used to determine the maximum height +** of any expression tree referenced by the structure passed as the +** first argument. +** +** If this maximum height is greater than the current value pointed +** to by pnHeight, the second parameter, then set *pnHeight to that +** value. +*/ +static void heightOfExpr(Expr *p, int *pnHeight){ + if( p ){ + if( p->nHeight>*pnHeight ){ + *pnHeight = p->nHeight; + } + } +} +static void heightOfExprList(ExprList *p, int *pnHeight){ + if( p ){ + int i; + for(i=0; inExpr; i++){ + heightOfExpr(p->a[i].pExpr, pnHeight); + } + } +} +static void heightOfSelect(Select *p, int *pnHeight){ + if( p ){ + heightOfExpr(p->pWhere, pnHeight); + heightOfExpr(p->pHaving, pnHeight); + heightOfExpr(p->pLimit, pnHeight); + heightOfExpr(p->pOffset, pnHeight); + heightOfExprList(p->pEList, pnHeight); + heightOfExprList(p->pGroupBy, pnHeight); + heightOfExprList(p->pOrderBy, pnHeight); + heightOfSelect(p->pPrior, pnHeight); + } +} + +/* +** Set the Expr.nHeight variable in the structure passed as an +** argument. An expression with no children, Expr.pList or +** Expr.pSelect member has a height of 1. Any other expression +** has a height equal to the maximum height of any other +** referenced Expr plus one. +** +** Also propagate EP_Propagate flags up from Expr.x.pList to Expr.flags, +** if appropriate. +*/ +static void exprSetHeight(Expr *p){ + int nHeight = 0; + heightOfExpr(p->pLeft, &nHeight); + heightOfExpr(p->pRight, &nHeight); + if( ExprHasProperty(p, EP_xIsSelect) ){ + heightOfSelect(p->x.pSelect, &nHeight); + }else if( p->x.pList ){ + heightOfExprList(p->x.pList, &nHeight); + p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList); + } + p->nHeight = nHeight + 1; +} + +/* +** Set the Expr.nHeight variable using the exprSetHeight() function. If +** the height is greater than the maximum allowed expression depth, +** leave an error in pParse. +** +** Also propagate all EP_Propagate flags from the Expr.x.pList into +** Expr.flags. +*/ +SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ + if( pParse->nErr ) return; + exprSetHeight(p); + sqlite3ExprCheckHeight(pParse, p->nHeight); +} + +/* +** Return the maximum height of any expression tree referenced +** by the select statement passed as an argument. +*/ +SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *p){ + int nHeight = 0; + heightOfSelect(p, &nHeight); + return nHeight; +} +#else /* ABOVE: Height enforcement enabled. BELOW: Height enforcement off */ +/* +** Propagate all EP_Propagate flags from the Expr.x.pList into +** Expr.flags. +*/ +SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ + if( p && p->x.pList && !ExprHasProperty(p, EP_xIsSelect) ){ + p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList); + } +} +#define exprSetHeight(y) +#endif /* SQLITE_MAX_EXPR_DEPTH>0 */ + +/* +** This routine is the core allocator for Expr nodes. +** +** Construct a new expression node and return a pointer to it. Memory +** for this node and for the pToken argument is a single allocation +** obtained from sqlite3DbMalloc(). The calling function +** is responsible for making sure the node eventually gets freed. +** +** If dequote is true, then the token (if it exists) is dequoted. +** If dequote is false, no dequoting is performance. The deQuote +** parameter is ignored if pToken is NULL or if the token does not +** appear to be quoted. If the quotes were of the form "..." (double-quotes) +** then the EP_DblQuoted flag is set on the expression node. +** +** Special case: If op==TK_INTEGER and pToken points to a string that +** can be translated into a 32-bit integer, then the token is not +** stored in u.zToken. Instead, the integer values is written +** into u.iValue and the EP_IntValue flag is set. No extra storage +** is allocated to hold the integer text and the dequote flag is ignored. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprAlloc( + sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */ + int op, /* Expression opcode */ + const Token *pToken, /* Token argument. Might be NULL */ + int dequote /* True to dequote */ +){ + Expr *pNew; + int nExtra = 0; + int iValue = 0; + + if( pToken ){ + if( op!=TK_INTEGER || pToken->z==0 + || sqlite3GetInt32(pToken->z, &iValue)==0 ){ + nExtra = pToken->n+1; + assert( iValue>=0 ); + } + } + pNew = sqlite3DbMallocZero(db, sizeof(Expr)+nExtra); + if( pNew ){ + pNew->op = (u8)op; + pNew->iAgg = -1; + if( pToken ){ + if( nExtra==0 ){ + pNew->flags |= EP_IntValue; + pNew->u.iValue = iValue; + }else{ + int c; + pNew->u.zToken = (char*)&pNew[1]; + assert( pToken->z!=0 || pToken->n==0 ); + if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n); + pNew->u.zToken[pToken->n] = 0; + if( dequote && nExtra>=3 + && ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){ + sqlite3Dequote(pNew->u.zToken); + if( c=='"' ) pNew->flags |= EP_DblQuoted; + } + } + } +#if SQLITE_MAX_EXPR_DEPTH>0 + pNew->nHeight = 1; +#endif + } + return pNew; +} + +/* +** Allocate a new expression node from a zero-terminated token that has +** already been dequoted. +*/ +SQLITE_PRIVATE Expr *sqlite3Expr( + sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */ + int op, /* Expression opcode */ + const char *zToken /* Token argument. Might be NULL */ +){ + Token x; + x.z = zToken; + x.n = zToken ? sqlite3Strlen30(zToken) : 0; + return sqlite3ExprAlloc(db, op, &x, 0); +} + +/* +** Attach subtrees pLeft and pRight to the Expr node pRoot. +** +** If pRoot==NULL that means that a memory allocation error has occurred. +** In that case, delete the subtrees pLeft and pRight. +*/ +SQLITE_PRIVATE void sqlite3ExprAttachSubtrees( + sqlite3 *db, + Expr *pRoot, + Expr *pLeft, + Expr *pRight +){ + if( pRoot==0 ){ + assert( db->mallocFailed ); + sqlite3ExprDelete(db, pLeft); + sqlite3ExprDelete(db, pRight); + }else{ + if( pRight ){ + pRoot->pRight = pRight; + pRoot->flags |= EP_Propagate & pRight->flags; + } + if( pLeft ){ + pRoot->pLeft = pLeft; + pRoot->flags |= EP_Propagate & pLeft->flags; + } + exprSetHeight(pRoot); + } +} + +/* +** Allocate an Expr node which joins as many as two subtrees. +** +** One or both of the subtrees can be NULL. Return a pointer to the new +** Expr node. Or, if an OOM error occurs, set pParse->db->mallocFailed, +** free the subtrees and return NULL. +*/ +SQLITE_PRIVATE Expr *sqlite3PExpr( + Parse *pParse, /* Parsing context */ + int op, /* Expression opcode */ + Expr *pLeft, /* Left operand */ + Expr *pRight, /* Right operand */ + const Token *pToken /* Argument token */ +){ + Expr *p; + if( op==TK_AND && pLeft && pRight && pParse->nErr==0 ){ + /* Take advantage of short-circuit false optimization for AND */ + p = sqlite3ExprAnd(pParse->db, pLeft, pRight); + }else{ + p = sqlite3ExprAlloc(pParse->db, op, pToken, 1); + sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight); + } + if( p ) { + sqlite3ExprCheckHeight(pParse, p->nHeight); + } + return p; +} + +/* +** If the expression is always either TRUE or FALSE (respectively), +** then return 1. If one cannot determine the truth value of the +** expression at compile-time return 0. +** +** This is an optimization. If is OK to return 0 here even if +** the expression really is always false or false (a false negative). +** But it is a bug to return 1 if the expression might have different +** boolean values in different circumstances (a false positive.) +** +** Note that if the expression is part of conditional for a +** LEFT JOIN, then we cannot determine at compile-time whether or not +** is it true or false, so always return 0. +*/ +static int exprAlwaysTrue(Expr *p){ + int v = 0; + if( ExprHasProperty(p, EP_FromJoin) ) return 0; + if( !sqlite3ExprIsInteger(p, &v) ) return 0; + return v!=0; +} +static int exprAlwaysFalse(Expr *p){ + int v = 0; + if( ExprHasProperty(p, EP_FromJoin) ) return 0; + if( !sqlite3ExprIsInteger(p, &v) ) return 0; + return v==0; +} + +/* +** Join two expressions using an AND operator. If either expression is +** NULL, then just return the other expression. +** +** If one side or the other of the AND is known to be false, then instead +** of returning an AND expression, just return a constant expression with +** a value of false. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){ + if( pLeft==0 ){ + return pRight; + }else if( pRight==0 ){ + return pLeft; + }else if( exprAlwaysFalse(pLeft) || exprAlwaysFalse(pRight) ){ + sqlite3ExprDelete(db, pLeft); + sqlite3ExprDelete(db, pRight); + return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0); + }else{ + Expr *pNew = sqlite3ExprAlloc(db, TK_AND, 0, 0); + sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight); + return pNew; + } +} + +/* +** Construct a new expression node for a function with multiple +** arguments. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){ + Expr *pNew; + sqlite3 *db = pParse->db; + assert( pToken ); + pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1); + if( pNew==0 ){ + sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */ + return 0; + } + pNew->x.pList = pList; + assert( !ExprHasProperty(pNew, EP_xIsSelect) ); + sqlite3ExprSetHeightAndFlags(pParse, pNew); + return pNew; +} + +/* +** Assign a variable number to an expression that encodes a wildcard +** in the original SQL statement. +** +** Wildcards consisting of a single "?" are assigned the next sequential +** variable number. +** +** Wildcards of the form "?nnn" are assigned the number "nnn". We make +** sure "nnn" is not too be to avoid a denial of service attack when +** the SQL statement comes from an external source. +** +** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number +** as the previous instance of the same wildcard. Or if this is the first +** instance of the wildcard, the next sequential variable number is +** assigned. +*/ +SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ + sqlite3 *db = pParse->db; + const char *z; + + if( pExpr==0 ) return; + assert( !ExprHasProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) ); + z = pExpr->u.zToken; + assert( z!=0 ); + assert( z[0]!=0 ); + if( z[1]==0 ){ + /* Wildcard of the form "?". Assign the next variable number */ + assert( z[0]=='?' ); + pExpr->iColumn = (ynVar)(++pParse->nVar); + }else{ + ynVar x = 0; + u32 n = sqlite3Strlen30(z); + if( z[0]=='?' ){ + /* Wildcard of the form "?nnn". Convert "nnn" to an integer and + ** use it as the variable number */ + i64 i; + int bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8); + pExpr->iColumn = x = (ynVar)i; + testcase( i==0 ); + testcase( i==1 ); + testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 ); + testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ); + if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ + sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", + db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); + x = 0; + } + if( i>pParse->nVar ){ + pParse->nVar = (int)i; + } + }else{ + /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable + ** number as the prior appearance of the same name, or if the name + ** has never appeared before, reuse the same variable number + */ + ynVar i; + for(i=0; inzVar; i++){ + if( pParse->azVar[i] && strcmp(pParse->azVar[i],z)==0 ){ + pExpr->iColumn = x = (ynVar)i+1; + break; + } + } + if( x==0 ) x = pExpr->iColumn = (ynVar)(++pParse->nVar); + } + if( x>0 ){ + if( x>pParse->nzVar ){ + char **a; + a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0])); + if( a==0 ) return; /* Error reported through db->mallocFailed */ + pParse->azVar = a; + memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0])); + pParse->nzVar = x; + } + if( z[0]!='?' || pParse->azVar[x-1]==0 ){ + sqlite3DbFree(db, pParse->azVar[x-1]); + pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n); + } + } + } + if( !pParse->nErr && pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ + sqlite3ErrorMsg(pParse, "too many SQL variables"); + } +} + +/* +** Recursively delete an expression tree. +*/ +SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ + if( p==0 ) return; + /* Sanity check: Assert that the IntValue is non-negative if it exists */ + assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 ); + if( !ExprHasProperty(p, EP_TokenOnly) ){ + /* The Expr.x union is never used at the same time as Expr.pRight */ + assert( p->x.pList==0 || p->pRight==0 ); + sqlite3ExprDelete(db, p->pLeft); + sqlite3ExprDelete(db, p->pRight); + if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken); + if( ExprHasProperty(p, EP_xIsSelect) ){ + sqlite3SelectDelete(db, p->x.pSelect); + }else{ + sqlite3ExprListDelete(db, p->x.pList); + } + } + if( !ExprHasProperty(p, EP_Static) ){ + sqlite3DbFree(db, p); + } +} + +/* +** Return the number of bytes allocated for the expression structure +** passed as the first argument. This is always one of EXPR_FULLSIZE, +** EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE. +*/ +static int exprStructSize(Expr *p){ + if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE; + if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE; + return EXPR_FULLSIZE; +} + +/* +** The dupedExpr*Size() routines each return the number of bytes required +** to store a copy of an expression or expression tree. They differ in +** how much of the tree is measured. +** +** dupedExprStructSize() Size of only the Expr structure +** dupedExprNodeSize() Size of Expr + space for token +** dupedExprSize() Expr + token + subtree components +** +*************************************************************************** +** +** The dupedExprStructSize() function returns two values OR-ed together: +** (1) the space required for a copy of the Expr structure only and +** (2) the EP_xxx flags that indicate what the structure size should be. +** The return values is always one of: +** +** EXPR_FULLSIZE +** EXPR_REDUCEDSIZE | EP_Reduced +** EXPR_TOKENONLYSIZE | EP_TokenOnly +** +** The size of the structure can be found by masking the return value +** of this routine with 0xfff. The flags can be found by masking the +** return value with EP_Reduced|EP_TokenOnly. +** +** Note that with flags==EXPRDUP_REDUCE, this routines works on full-size +** (unreduced) Expr objects as they or originally constructed by the parser. +** During expression analysis, extra information is computed and moved into +** later parts of teh Expr object and that extra information might get chopped +** off if the expression is reduced. Note also that it does not work to +** make an EXPRDUP_REDUCE copy of a reduced expression. It is only legal +** to reduce a pristine expression tree from the parser. The implementation +** of dupedExprStructSize() contain multiple assert() statements that attempt +** to enforce this constraint. +*/ +static int dupedExprStructSize(Expr *p, int flags){ + int nSize; + assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */ + assert( EXPR_FULLSIZE<=0xfff ); + assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 ); + if( 0==(flags&EXPRDUP_REDUCE) ){ + nSize = EXPR_FULLSIZE; + }else{ + assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); + assert( !ExprHasProperty(p, EP_FromJoin) ); + assert( !ExprHasProperty(p, EP_MemToken) ); + assert( !ExprHasProperty(p, EP_NoReduce) ); + if( p->pLeft || p->x.pList ){ + nSize = EXPR_REDUCEDSIZE | EP_Reduced; + }else{ + assert( p->pRight==0 ); + nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly; + } + } + return nSize; +} + +/* +** This function returns the space in bytes required to store the copy +** of the Expr structure and a copy of the Expr.u.zToken string (if that +** string is defined.) +*/ +static int dupedExprNodeSize(Expr *p, int flags){ + int nByte = dupedExprStructSize(p, flags) & 0xfff; + if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ + nByte += sqlite3Strlen30(p->u.zToken)+1; + } + return ROUND8(nByte); +} + +/* +** Return the number of bytes required to create a duplicate of the +** expression passed as the first argument. The second argument is a +** mask containing EXPRDUP_XXX flags. +** +** The value returned includes space to create a copy of the Expr struct +** itself and the buffer referred to by Expr.u.zToken, if any. +** +** If the EXPRDUP_REDUCE flag is set, then the return value includes +** space to duplicate all Expr nodes in the tree formed by Expr.pLeft +** and Expr.pRight variables (but not for any structures pointed to or +** descended from the Expr.x.pList or Expr.x.pSelect variables). +*/ +static int dupedExprSize(Expr *p, int flags){ + int nByte = 0; + if( p ){ + nByte = dupedExprNodeSize(p, flags); + if( flags&EXPRDUP_REDUCE ){ + nByte += dupedExprSize(p->pLeft, flags) + dupedExprSize(p->pRight, flags); + } + } + return nByte; +} + +/* +** This function is similar to sqlite3ExprDup(), except that if pzBuffer +** is not NULL then *pzBuffer is assumed to point to a buffer large enough +** to store the copy of expression p, the copies of p->u.zToken +** (if applicable), and the copies of the p->pLeft and p->pRight expressions, +** if any. Before returning, *pzBuffer is set to the first byte past the +** portion of the buffer copied into by this function. +*/ +static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){ + Expr *pNew = 0; /* Value to return */ + if( p ){ + const int isReduced = (flags&EXPRDUP_REDUCE); + u8 *zAlloc; + u32 staticFlag = 0; + + assert( pzBuffer==0 || isReduced ); + + /* Figure out where to write the new Expr structure. */ + if( pzBuffer ){ + zAlloc = *pzBuffer; + staticFlag = EP_Static; + }else{ + zAlloc = sqlite3DbMallocRaw(db, dupedExprSize(p, flags)); + } + pNew = (Expr *)zAlloc; + + if( pNew ){ + /* Set nNewSize to the size allocated for the structure pointed to + ** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or + ** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed + ** by the copy of the p->u.zToken string (if any). + */ + const unsigned nStructSize = dupedExprStructSize(p, flags); + const int nNewSize = nStructSize & 0xfff; + int nToken; + if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ + nToken = sqlite3Strlen30(p->u.zToken) + 1; + }else{ + nToken = 0; + } + if( isReduced ){ + assert( ExprHasProperty(p, EP_Reduced)==0 ); + memcpy(zAlloc, p, nNewSize); + }else{ + int nSize = exprStructSize(p); + memcpy(zAlloc, p, nSize); + memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize); + } + + /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */ + pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken); + pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly); + pNew->flags |= staticFlag; + + /* Copy the p->u.zToken string, if any. */ + if( nToken ){ + char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize]; + memcpy(zToken, p->u.zToken, nToken); + } + + if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){ + /* Fill in the pNew->x.pSelect or pNew->x.pList member. */ + if( ExprHasProperty(p, EP_xIsSelect) ){ + pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, isReduced); + }else{ + pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, isReduced); + } + } + + /* Fill in pNew->pLeft and pNew->pRight. */ + if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){ + zAlloc += dupedExprNodeSize(p, flags); + if( ExprHasProperty(pNew, EP_Reduced) ){ + pNew->pLeft = exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc); + pNew->pRight = exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc); + } + if( pzBuffer ){ + *pzBuffer = zAlloc; + } + }else{ + if( !ExprHasProperty(p, EP_TokenOnly) ){ + pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0); + pNew->pRight = sqlite3ExprDup(db, p->pRight, 0); + } + } + + } + } + return pNew; +} + +/* +** Create and return a deep copy of the object passed as the second +** argument. If an OOM condition is encountered, NULL is returned +** and the db->mallocFailed flag set. +*/ +#ifndef SQLITE_OMIT_CTE +static With *withDup(sqlite3 *db, With *p){ + With *pRet = 0; + if( p ){ + int nByte = sizeof(*p) + sizeof(p->a[0]) * (p->nCte-1); + pRet = sqlite3DbMallocZero(db, nByte); + if( pRet ){ + int i; + pRet->nCte = p->nCte; + for(i=0; inCte; i++){ + pRet->a[i].pSelect = sqlite3SelectDup(db, p->a[i].pSelect, 0); + pRet->a[i].pCols = sqlite3ExprListDup(db, p->a[i].pCols, 0); + pRet->a[i].zName = sqlite3DbStrDup(db, p->a[i].zName); + } + } + } + return pRet; +} +#else +# define withDup(x,y) 0 +#endif + +/* +** 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. +** +** The flags parameter contains a combination of the EXPRDUP_XXX flags. +** If the EXPRDUP_REDUCE flag is set, then the structure returned is a +** truncated version of the usual Expr structure that will be stored as +** part of the in-memory representation of the database schema. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3 *db, Expr *p, int flags){ + return exprDup(db, p, flags, 0); +} +SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ + ExprList *pNew; + struct ExprList_item *pItem, *pOldItem; + int i; + if( p==0 ) return 0; + pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) ); + if( pNew==0 ) return 0; + pNew->nExpr = i = p->nExpr; + if( (flags & EXPRDUP_REDUCE)==0 ) for(i=1; inExpr; i+=i){} + pNew->a = pItem = sqlite3DbMallocRaw(db, i*sizeof(p->a[0]) ); + if( pItem==0 ){ + sqlite3DbFree(db, pNew); + return 0; + } + pOldItem = p->a; + for(i=0; inExpr; i++, pItem++, pOldItem++){ + Expr *pOldExpr = pOldItem->pExpr; + pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags); + pItem->zName = sqlite3DbStrDup(db, pOldItem->zName); + pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan); + pItem->sortOrder = pOldItem->sortOrder; + pItem->done = 0; + pItem->bSpanIsTab = pOldItem->bSpanIsTab; + pItem->u = pOldItem->u; + } + return pNew; +} + +/* +** If cursors, triggers, views and subqueries are all omitted from +** the build, then none of the following routines, except for +** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes +** called with a NULL argument. +*/ +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \ + || !defined(SQLITE_OMIT_SUBQUERY) +SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ + SrcList *pNew; + int i; + int nByte; + if( p==0 ) return 0; + nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0); + pNew = sqlite3DbMallocRaw(db, nByte ); + if( pNew==0 ) return 0; + pNew->nSrc = pNew->nAlloc = p->nSrc; + for(i=0; inSrc; i++){ + struct SrcList_item *pNewItem = &pNew->a[i]; + struct SrcList_item *pOldItem = &p->a[i]; + Table *pTab; + pNewItem->pSchema = pOldItem->pSchema; + pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); + pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); + pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); + pNewItem->jointype = pOldItem->jointype; + pNewItem->iCursor = pOldItem->iCursor; + pNewItem->addrFillSub = pOldItem->addrFillSub; + pNewItem->regReturn = pOldItem->regReturn; + pNewItem->isCorrelated = pOldItem->isCorrelated; + pNewItem->viaCoroutine = pOldItem->viaCoroutine; + pNewItem->isRecursive = pOldItem->isRecursive; + pNewItem->zIndex = sqlite3DbStrDup(db, pOldItem->zIndex); + pNewItem->notIndexed = pOldItem->notIndexed; + pNewItem->pIndex = pOldItem->pIndex; + pTab = pNewItem->pTab = pOldItem->pTab; + if( pTab ){ + pTab->nRef++; + } + pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags); + pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn, flags); + pNewItem->pUsing = sqlite3IdListDup(db, pOldItem->pUsing); + pNewItem->colUsed = pOldItem->colUsed; + } + return pNew; +} +SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){ + IdList *pNew; + int i; + if( p==0 ) return 0; + pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) ); + if( pNew==0 ) return 0; + pNew->nId = p->nId; + pNew->a = sqlite3DbMallocRaw(db, p->nId*sizeof(p->a[0]) ); + if( pNew->a==0 ){ + sqlite3DbFree(db, pNew); + return 0; + } + /* Note that because the size of the allocation for p->a[] is not + ** necessarily a power of two, sqlite3IdListAppend() may not be called + ** on the duplicate created by this function. */ + for(i=0; inId; i++){ + struct IdList_item *pNewItem = &pNew->a[i]; + struct IdList_item *pOldItem = &p->a[i]; + pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); + pNewItem->idx = pOldItem->idx; + } + return pNew; +} +SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ + Select *pNew, *pPrior; + if( p==0 ) return 0; + pNew = sqlite3DbMallocRaw(db, sizeof(*p) ); + if( pNew==0 ) return 0; + pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags); + pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags); + pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags); + pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags); + pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags); + pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags); + pNew->op = p->op; + pNew->pPrior = pPrior = sqlite3SelectDup(db, p->pPrior, flags); + if( pPrior ) pPrior->pNext = pNew; + pNew->pNext = 0; + pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags); + pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags); + pNew->iLimit = 0; + pNew->iOffset = 0; + pNew->selFlags = p->selFlags & ~SF_UsesEphemeral; + pNew->addrOpenEphm[0] = -1; + pNew->addrOpenEphm[1] = -1; + pNew->nSelectRow = p->nSelectRow; + pNew->pWith = withDup(db, p->pWith); + sqlite3SelectSetName(pNew, p->zSelName); + return pNew; +} +#else +SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ + 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. +** +** If a memory allocation error occurs, the entire list is freed and +** NULL is returned. If non-NULL is returned, then it is guaranteed +** that the new entry was successfully appended. +*/ +SQLITE_PRIVATE ExprList *sqlite3ExprListAppend( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List to which to append. Might be NULL */ + Expr *pExpr /* Expression to be appended. Might be NULL */ +){ + sqlite3 *db = pParse->db; + if( pList==0 ){ + pList = sqlite3DbMallocZero(db, sizeof(ExprList) ); + if( pList==0 ){ + goto no_mem; + } + pList->a = sqlite3DbMallocRaw(db, sizeof(pList->a[0])); + if( pList->a==0 ) goto no_mem; + }else if( (pList->nExpr & (pList->nExpr-1))==0 ){ + struct ExprList_item *a; + assert( pList->nExpr>0 ); + a = sqlite3DbRealloc(db, pList->a, pList->nExpr*2*sizeof(pList->a[0])); + if( a==0 ){ + goto no_mem; + } + pList->a = a; + } + assert( pList->a!=0 ); + if( 1 ){ + struct ExprList_item *pItem = &pList->a[pList->nExpr++]; + memset(pItem, 0, sizeof(*pItem)); + pItem->pExpr = pExpr; + } + return pList; + +no_mem: + /* Avoid leaking memory if malloc has failed. */ + sqlite3ExprDelete(db, pExpr); + sqlite3ExprListDelete(db, pList); + return 0; +} + +/* +** Set the ExprList.a[].zName element of the most recently added item +** on the expression list. +** +** pList might be NULL following an OOM error. But pName should never be +** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag +** is set. +*/ +SQLITE_PRIVATE void sqlite3ExprListSetName( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List to which to add the span. */ + Token *pName, /* Name to be added */ + int dequote /* True to cause the name to be dequoted */ +){ + assert( pList!=0 || pParse->db->mallocFailed!=0 ); + if( pList ){ + struct ExprList_item *pItem; + assert( pList->nExpr>0 ); + pItem = &pList->a[pList->nExpr-1]; + assert( pItem->zName==0 ); + pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n); + if( dequote && pItem->zName ) sqlite3Dequote(pItem->zName); + } +} + +/* +** Set the ExprList.a[].zSpan element of the most recently added item +** on the expression list. +** +** pList might be NULL following an OOM error. But pSpan should never be +** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag +** is set. +*/ +SQLITE_PRIVATE void sqlite3ExprListSetSpan( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List to which to add the span. */ + ExprSpan *pSpan /* The span to be added */ +){ + sqlite3 *db = pParse->db; + assert( pList!=0 || db->mallocFailed!=0 ); + if( pList ){ + struct ExprList_item *pItem = &pList->a[pList->nExpr-1]; + assert( pList->nExpr>0 ); + assert( db->mallocFailed || pItem->pExpr==pSpan->pExpr ); + sqlite3DbFree(db, pItem->zSpan); + pItem->zSpan = sqlite3DbStrNDup(db, (char*)pSpan->zStart, + (int)(pSpan->zEnd - pSpan->zStart)); + } +} + +/* +** If the expression list pEList contains more than iLimit elements, +** leave an error message in pParse. +*/ +SQLITE_PRIVATE void sqlite3ExprListCheckLength( + Parse *pParse, + ExprList *pEList, + const char *zObject +){ + int mx = pParse->db->aLimit[SQLITE_LIMIT_COLUMN]; + testcase( pEList && pEList->nExpr==mx ); + testcase( pEList && pEList->nExpr==mx+1 ); + if( pEList && pEList->nExpr>mx ){ + sqlite3ErrorMsg(pParse, "too many columns in %s", zObject); + } +} + +/* +** Delete an entire expression list. +*/ +SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ + int i; + struct ExprList_item *pItem; + if( pList==0 ) return; + assert( pList->a!=0 || pList->nExpr==0 ); + for(pItem=pList->a, i=0; inExpr; i++, pItem++){ + sqlite3ExprDelete(db, pItem->pExpr); + sqlite3DbFree(db, pItem->zName); + sqlite3DbFree(db, pItem->zSpan); + } + sqlite3DbFree(db, pList->a); + sqlite3DbFree(db, pList); +} + +/* +** Return the bitwise-OR of all Expr.flags fields in the given +** ExprList. +*/ +SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList *pList){ + int i; + u32 m = 0; + if( pList ){ + for(i=0; inExpr; i++){ + Expr *pExpr = pList->a[i].pExpr; + if( ALWAYS(pExpr) ) m |= pExpr->flags; + } + } + return m; +} + +/* +** These routines are Walker callbacks used to check expressions to +** see if they are "constant" for some definition of constant. The +** Walker.eCode value determines the type of "constant" we are looking +** for. +** +** These callback routines are used to implement the following: +** +** sqlite3ExprIsConstant() pWalker->eCode==1 +** sqlite3ExprIsConstantNotJoin() pWalker->eCode==2 +** sqlite3ExprRefOneTableOnly() pWalker->eCode==3 +** sqlite3ExprIsConstantOrFunction() pWalker->eCode==4 or 5 +** +** In all cases, the callbacks set Walker.eCode=0 and abort if the expression +** is found to not be a constant. +** +** The sqlite3ExprIsConstantOrFunction() is used for evaluating expressions +** in a CREATE TABLE statement. The Walker.eCode value is 5 when parsing +** an existing schema and 4 when processing a new statement. A bound +** parameter raises an error for new statements, but is silently converted +** to NULL for existing schemas. This allows sqlite_master tables that +** contain a bound parameter because they were generated by older versions +** of SQLite to be parsed by newer versions of SQLite without raising a +** malformed schema error. +*/ +static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ + + /* If pWalker->eCode is 2 then any term of the expression that comes from + ** the ON or USING clauses of a left join disqualifies the expression + ** from being considered constant. */ + if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_FromJoin) ){ + pWalker->eCode = 0; + return WRC_Abort; + } + + switch( pExpr->op ){ + /* Consider functions to be constant if all their arguments are constant + ** and either pWalker->eCode==4 or 5 or the function has the + ** SQLITE_FUNC_CONST flag. */ + case TK_FUNCTION: + if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc) ){ + return WRC_Continue; + }else{ + pWalker->eCode = 0; + return WRC_Abort; + } + case TK_ID: + case TK_COLUMN: + case TK_AGG_FUNCTION: + case TK_AGG_COLUMN: + testcase( pExpr->op==TK_ID ); + testcase( pExpr->op==TK_COLUMN ); + testcase( pExpr->op==TK_AGG_FUNCTION ); + testcase( pExpr->op==TK_AGG_COLUMN ); + if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){ + return WRC_Continue; + }else{ + pWalker->eCode = 0; + return WRC_Abort; + } + case TK_VARIABLE: + if( pWalker->eCode==5 ){ + /* Silently convert bound parameters that appear inside of CREATE + ** statements into a NULL when parsing the CREATE statement text out + ** of the sqlite_master table */ + pExpr->op = TK_NULL; + }else if( pWalker->eCode==4 ){ + /* A bound parameter in a CREATE statement that originates from + ** sqlite3_prepare() causes an error */ + pWalker->eCode = 0; + return WRC_Abort; + } + /* Fall through */ + default: + testcase( pExpr->op==TK_SELECT ); /* selectNodeIsConstant will disallow */ + testcase( pExpr->op==TK_EXISTS ); /* selectNodeIsConstant will disallow */ + return WRC_Continue; + } +} +static int selectNodeIsConstant(Walker *pWalker, Select *NotUsed){ + UNUSED_PARAMETER(NotUsed); + pWalker->eCode = 0; + return WRC_Abort; +} +static int exprIsConst(Expr *p, int initFlag, int iCur){ + Walker w; + memset(&w, 0, sizeof(w)); + w.eCode = initFlag; + w.xExprCallback = exprNodeIsConstant; + w.xSelectCallback = selectNodeIsConstant; + w.u.iCur = iCur; + sqlite3WalkExpr(&w, p); + return w.eCode; +} + +/* +** Walk an expression tree. Return non-zero 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. +*/ +SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr *p){ + return exprIsConst(p, 1, 0); +} + +/* +** Walk an expression tree. Return non-zero if the expression is constant +** that does no originate from the ON or USING clauses of a join. +** Return 0 if it involves variables or function calls or terms from +** an ON or USING clause. +*/ +SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){ + return exprIsConst(p, 2, 0); +} + +/* +** Walk an expression tree. Return non-zero if the expression constant +** for any single row of the table with cursor iCur. In other words, the +** expression must not refer to any non-deterministic function nor any +** table other than iCur. +*/ +SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){ + return exprIsConst(p, 3, iCur); +} + +/* +** Walk an expression tree. Return non-zero 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. +*/ +SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){ + assert( isInit==0 || isInit==1 ); + return exprIsConst(p, 4+isInit, 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. +*/ +SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){ + int rc = 0; + + /* If an expression is an integer literal that fits in a signed 32-bit + ** integer, then the EP_IntValue flag will have already been set */ + assert( p->op!=TK_INTEGER || (p->flags & EP_IntValue)!=0 + || sqlite3GetInt32(p->u.zToken, &rc)==0 ); + + if( p->flags & EP_IntValue ){ + *pValue = p->u.iValue; + return 1; + } + switch( p->op ){ + case TK_UPLUS: { + rc = sqlite3ExprIsInteger(p->pLeft, pValue); + break; + } + case TK_UMINUS: { + int v; + if( sqlite3ExprIsInteger(p->pLeft, &v) ){ + assert( v!=(-2147483647-1) ); + *pValue = -v; + rc = 1; + } + break; + } + default: break; + } + return rc; +} + +/* +** Return FALSE if there is no chance that the expression can be NULL. +** +** If the expression might be NULL or if the expression is too complex +** to tell return TRUE. +** +** This routine is used as an optimization, to skip OP_IsNull opcodes +** when we know that a value cannot be NULL. Hence, a false positive +** (returning TRUE when in fact the expression can never be NULL) might +** be a small performance hit but is otherwise harmless. On the other +** hand, a false negative (returning FALSE when the result could be NULL) +** will likely result in an incorrect answer. So when in doubt, return +** TRUE. +*/ +SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){ + u8 op; + while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; } + op = p->op; + if( op==TK_REGISTER ) op = p->op2; + switch( op ){ + case TK_INTEGER: + case TK_STRING: + case TK_FLOAT: + case TK_BLOB: + return 0; + case TK_COLUMN: + assert( p->pTab!=0 ); + return ExprHasProperty(p, EP_CanBeNull) || + (p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0); + default: + return 1; + } +} + +/* +** Return TRUE if the given expression is a constant which would be +** unchanged by OP_Affinity with the affinity given in the second +** argument. +** +** This routine is used to determine if the OP_Affinity operation +** can be omitted. When in doubt return FALSE. A false negative +** is harmless. A false positive, however, can result in the wrong +** answer. +*/ +SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){ + u8 op; + if( aff==SQLITE_AFF_NONE ) return 1; + while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; } + op = p->op; + if( op==TK_REGISTER ) op = p->op2; + switch( op ){ + case TK_INTEGER: { + return aff==SQLITE_AFF_INTEGER || aff==SQLITE_AFF_NUMERIC; + } + case TK_FLOAT: { + return aff==SQLITE_AFF_REAL || aff==SQLITE_AFF_NUMERIC; + } + case TK_STRING: { + return aff==SQLITE_AFF_TEXT; + } + case TK_BLOB: { + return 1; + } + case TK_COLUMN: { + assert( p->iTable>=0 ); /* p cannot be part of a CHECK constraint */ + return p->iColumn<0 + && (aff==SQLITE_AFF_INTEGER || aff==SQLITE_AFF_NUMERIC); + } + default: { + return 0; + } + } +} + +/* +** Return TRUE if the given string is a row-id column name. +*/ +SQLITE_PRIVATE int sqlite3IsRowid(const char *z){ + if( sqlite3StrICmp(z, "_ROWID_")==0 ) return 1; + if( sqlite3StrICmp(z, "ROWID")==0 ) return 1; + if( sqlite3StrICmp(z, "OID")==0 ) return 1; + return 0; +} + +/* +** Return true if we are able to the IN operator optimization on a +** query of the form +** +** x IN (SELECT ...) +** +** Where the SELECT... clause is as specified by the parameter to this +** routine. +** +** The Select object passed in has already been preprocessed and no +** errors have been found. +*/ +#ifndef SQLITE_OMIT_SUBQUERY +static int isCandidateForInOpt(Select *p){ + SrcList *pSrc; + ExprList *pEList; + Table *pTab; + if( p==0 ) return 0; /* right-hand side of IN is SELECT */ + if( p->pPrior ) return 0; /* Not a compound SELECT */ + if( p->selFlags & (SF_Distinct|SF_Aggregate) ){ + testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ); + testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); + return 0; /* No DISTINCT keyword and no aggregate functions */ + } + assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */ + if( p->pLimit ) return 0; /* Has no LIMIT clause */ + assert( p->pOffset==0 ); /* No LIMIT means no OFFSET */ + if( p->pWhere ) return 0; /* Has no WHERE clause */ + pSrc = p->pSrc; + assert( pSrc!=0 ); + if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */ + if( pSrc->a[0].pSelect ) return 0; /* FROM is not a subquery or view */ + pTab = pSrc->a[0].pTab; + if( NEVER(pTab==0) ) return 0; + assert( pTab->pSelect==0 ); /* FROM clause is not a view */ + if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */ + pEList = p->pEList; + if( pEList->nExpr!=1 ) return 0; /* One column in the result set */ + if( pEList->a[0].pExpr->op!=TK_COLUMN ) return 0; /* Result is a column */ + return 1; +} +#endif /* SQLITE_OMIT_SUBQUERY */ + +/* +** Code an OP_Once instruction and allocate space for its flag. Return the +** address of the new instruction. +*/ +SQLITE_PRIVATE int sqlite3CodeOnce(Parse *pParse){ + Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ + return sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++); +} + +/* +** Generate code that checks the left-most column of index table iCur to see if +** it contains any NULL entries. Cause the register at regHasNull to be set +** to a non-NULL value if iCur contains no NULLs. Cause register regHasNull +** to be set to NULL if iCur contains one or more NULL values. +*/ +static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){ + int j1; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regHasNull); + j1 = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_Column, iCur, 0, regHasNull); + sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); + VdbeComment((v, "first_entry_in(%d)", iCur)); + sqlite3VdbeJumpHere(v, j1); +} + + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** The argument is an IN operator with a list (not a subquery) on the +** right-hand side. Return TRUE if that list is constant. +*/ +static int sqlite3InRhsIsConstant(Expr *pIn){ + Expr *pLHS; + int res; + assert( !ExprHasProperty(pIn, EP_xIsSelect) ); + pLHS = pIn->pLeft; + pIn->pLeft = 0; + res = sqlite3ExprIsConstant(pIn); + pIn->pLeft = pLHS; + return res; +} +#endif + +/* +** This function is used by the implementation of the IN (...) operator. +** The pX parameter is the expression on the RHS of the IN operator, which +** might be either a list of expressions or a subquery. +** +** The job of this routine is to find or create a b-tree object that can +** be used either to test for membership in the RHS set or to iterate through +** all members of the RHS set, skipping duplicates. +** +** A cursor is opened on the b-tree object that is the RHS of the IN operator +** and pX->iTable is set to the index of that cursor. +** +** The returned value of this function indicates the b-tree type, as follows: +** +** IN_INDEX_ROWID - The cursor was opened on a database table. +** IN_INDEX_INDEX_ASC - The cursor was opened on an ascending index. +** IN_INDEX_INDEX_DESC - The cursor was opened on a descending index. +** IN_INDEX_EPH - The cursor was opened on a specially created and +** populated epheremal table. +** IN_INDEX_NOOP - No cursor was allocated. The IN operator must be +** implemented as a sequence of comparisons. +** +** An existing b-tree might be used if the RHS expression pX is a simple +** subquery such as: +** +** SELECT FROM +** +** If the RHS of the IN operator is a list or a more complex subquery, then +** an ephemeral table might need to be generated from the RHS and then +** pX->iTable made to point to the ephemeral table instead of an +** existing table. +** +** The inFlags parameter must contain exactly one of the bits +** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP. If inFlags contains +** IN_INDEX_MEMBERSHIP, then the generated table will be used for a +** fast membership test. When the IN_INDEX_LOOP bit is set, the +** IN index will be used to loop over all values of the RHS of the +** IN operator. +** +** When IN_INDEX_LOOP is used (and the b-tree will be used to iterate +** through the set members) then the b-tree must not contain duplicates. +** An epheremal table must be used unless the selected is guaranteed +** to be unique - either because it is an INTEGER PRIMARY KEY or it +** has a UNIQUE constraint or UNIQUE index. +** +** When IN_INDEX_MEMBERSHIP is used (and the b-tree will be used +** for fast set membership tests) then an epheremal table must +** be used unless is an INTEGER PRIMARY KEY or an index can +** be found with as its left-most column. +** +** If the IN_INDEX_NOOP_OK and IN_INDEX_MEMBERSHIP are both set and +** if the RHS of the IN operator is a list (not a subquery) then this +** routine might decide that creating an ephemeral b-tree for membership +** testing is too expensive and return IN_INDEX_NOOP. In that case, the +** calling routine should implement the IN operator using a sequence +** of Eq or Ne comparison operations. +** +** When the b-tree is being used for membership tests, the calling function +** might need to know whether or not the RHS side of the IN operator +** contains a NULL. If prRhsHasNull is not a NULL pointer and +** if there is any chance that the (...) might contain a NULL value at +** runtime, then a register is allocated and the register number written +** to *prRhsHasNull. If there is no chance that the (...) contains a +** NULL value, then *prRhsHasNull is left unchanged. +** +** If a register is allocated and its location stored in *prRhsHasNull, then +** the value in that register will be NULL if the b-tree contains one or more +** NULL values, and it will be some non-NULL value if the b-tree contains no +** NULL values. +*/ +#ifndef SQLITE_OMIT_SUBQUERY +SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){ + Select *p; /* SELECT to the right of IN operator */ + int eType = 0; /* Type of RHS table. IN_INDEX_* */ + int iTab = pParse->nTab++; /* Cursor of the RHS table */ + int mustBeUnique; /* True if RHS must be unique */ + Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ + + assert( pX->op==TK_IN ); + mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0; + + /* Check to see if an existing table or index can be used to + ** satisfy the query. This is preferable to generating a new + ** ephemeral table. + */ + p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0); + if( pParse->nErr==0 && isCandidateForInOpt(p) ){ + sqlite3 *db = pParse->db; /* Database connection */ + Table *pTab; /* Table
    . */ + Expr *pExpr; /* Expression */ + i16 iCol; /* Index of column */ + i16 iDb; /* Database idx for pTab */ + + assert( p ); /* Because of isCandidateForInOpt(p) */ + assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */ + assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */ + assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */ + pTab = p->pSrc->a[0].pTab; + pExpr = p->pEList->a[0].pExpr; + iCol = (i16)pExpr->iColumn; + + /* Code an OP_Transaction and OP_TableLock for
    . */ + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + sqlite3CodeVerifySchema(pParse, iDb); + sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + + /* This function is only called from two places. In both cases the vdbe + ** has already been allocated. So assume sqlite3GetVdbe() is always + ** successful here. + */ + assert(v); + if( iCol<0 ){ + int iAddr = sqlite3CodeOnce(pParse); + VdbeCoverage(v); + + sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); + eType = IN_INDEX_ROWID; + + sqlite3VdbeJumpHere(v, iAddr); + }else{ + Index *pIdx; /* Iterator variable */ + + /* The collation sequence used by the comparison. If an index is to + ** be used in place of a temp-table, it must be ordered according + ** to this collation sequence. */ + CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pExpr); + + /* Check that the affinity that will be used to perform the + ** comparison is the same as the affinity of the column. If + ** it is not, it is not possible to use any index. + */ + int affinity_ok = sqlite3IndexAffinityOk(pX, pTab->aCol[iCol].affinity); + + for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){ + if( (pIdx->aiColumn[0]==iCol) + && sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq + && (!mustBeUnique || (pIdx->nKeyCol==1 && IsUniqueIndex(pIdx))) + ){ + int iAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); + VdbeComment((v, "%s", pIdx->zName)); + assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 ); + eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0]; + + if( prRhsHasNull && !pTab->aCol[iCol].notNull ){ + *prRhsHasNull = ++pParse->nMem; + sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull); + } + sqlite3VdbeJumpHere(v, iAddr); + } + } + } + } + + /* If no preexisting index is available for the IN clause + ** and IN_INDEX_NOOP is an allowed reply + ** and the RHS of the IN operator is a list, not a subquery + ** and the RHS is not contant or has two or fewer terms, + ** then it is not worth creating an ephemeral table to evaluate + ** the IN operator so return IN_INDEX_NOOP. + */ + if( eType==0 + && (inFlags & IN_INDEX_NOOP_OK) + && !ExprHasProperty(pX, EP_xIsSelect) + && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2) + ){ + eType = IN_INDEX_NOOP; + } + + + if( eType==0 ){ + /* Could not find an existing table or index to use as the RHS b-tree. + ** We will have to generate an ephemeral table to do the job. + */ + u32 savedNQueryLoop = pParse->nQueryLoop; + int rMayHaveNull = 0; + eType = IN_INDEX_EPH; + if( inFlags & IN_INDEX_LOOP ){ + pParse->nQueryLoop = 0; + if( pX->pLeft->iColumn<0 && !ExprHasProperty(pX, EP_xIsSelect) ){ + eType = IN_INDEX_ROWID; + } + }else if( prRhsHasNull ){ + *prRhsHasNull = rMayHaveNull = ++pParse->nMem; + } + sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID); + pParse->nQueryLoop = savedNQueryLoop; + }else{ + pX->iTable = iTab; + } + return eType; +} +#endif + +/* +** Generate code for scalar subqueries used as a subquery expression, EXISTS, +** or 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. +** +** If parameter isRowid is non-zero, then expression pExpr is guaranteed +** to be of the form " IN (?, ?, ?)", where is a reference +** to some integer key column of a table B-Tree. In this case, use an +** intkey B-Tree to store the set of IN(...) values instead of the usual +** (slower) variable length keys B-Tree. +** +** If rMayHaveNull is non-zero, that means that the operation is an IN +** (not a SELECT or EXISTS) and that the RHS might contains NULLs. +** All this routine does is initialize the register given by rMayHaveNull +** to NULL. Calling routines will take care of changing this register +** value to non-NULL if the RHS is NULL-free. +** +** For a SELECT or EXISTS operator, return the register that holds the +** result. For IN operators or if an error occurs, the return value is 0. +*/ +#ifndef SQLITE_OMIT_SUBQUERY +SQLITE_PRIVATE int sqlite3CodeSubselect( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* The IN, SELECT, or EXISTS operator */ + int rHasNullFlag, /* Register that records whether NULLs exist in RHS */ + int isRowid /* If true, LHS of IN operator is a rowid */ +){ + int jmpIfDynamic = -1; /* One-time test address */ + int rReg = 0; /* Register storing resulting */ + Vdbe *v = sqlite3GetVdbe(pParse); + if( NEVER(v==0) ) return 0; + sqlite3ExprCachePush(pParse); + + /* 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( !ExprHasProperty(pExpr, EP_VarSelect) ){ + jmpIfDynamic = sqlite3CodeOnce(pParse); VdbeCoverage(v); + } + +#ifndef SQLITE_OMIT_EXPLAIN + if( pParse->explain==2 ){ + char *zMsg = sqlite3MPrintf( + pParse->db, "EXECUTE %s%s SUBQUERY %d", jmpIfDynamic>=0?"":"CORRELATED ", + pExpr->op==TK_IN?"LIST":"SCALAR", pParse->iNextSelectId + ); + sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); + } +#endif + + switch( pExpr->op ){ + case TK_IN: { + char affinity; /* Affinity of the LHS of the IN */ + int addr; /* Address of OP_OpenEphemeral instruction */ + Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */ + KeyInfo *pKeyInfo = 0; /* Key information */ + + affinity = sqlite3ExprAffinity(pLeft); + + /* Whether this is an 'x IN(SELECT...)' or an 'x IN()' + ** expression it is handled the same way. An ephemeral table is + ** filled with single-field index keys representing the results + ** from the SELECT or the . + ** + ** 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 = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid); + pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, 1, 1); + + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + /* Case 1: expr IN (SELECT ...) + ** + ** Generate code to write the results of the select into the temporary + ** table allocated and opened above. + */ + Select *pSelect = pExpr->x.pSelect; + SelectDest dest; + ExprList *pEList; + + assert( !isRowid ); + sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable); + dest.affSdst = (u8)affinity; + assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable ); + pSelect->iLimit = 0; + testcase( pSelect->selFlags & SF_Distinct ); + testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ + if( sqlite3Select(pParse, pSelect, &dest) ){ + sqlite3KeyInfoUnref(pKeyInfo); + return 0; + } + pEList = pSelect->pEList; + assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */ + assert( pEList!=0 ); + assert( pEList->nExpr>0 ); + assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); + pKeyInfo->aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, + pEList->a[0].pExpr); + }else if( ALWAYS(pExpr->x.pList!=0) ){ + /* Case 2: expr IN (exprlist) + ** + ** For each expression, build an index key from the evaluation and + ** store it in the temporary table. If is a column, then use + ** that columns affinity when building index keys. If is not + ** a column, use numeric affinity. + */ + int i; + ExprList *pList = pExpr->x.pList; + struct ExprList_item *pItem; + int r1, r2, r3; + + if( !affinity ){ + affinity = SQLITE_AFF_NONE; + } + if( pKeyInfo ){ + assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); + pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft); + } + + /* Loop through each expression in . */ + r1 = sqlite3GetTempReg(pParse); + r2 = sqlite3GetTempReg(pParse); + if( isRowid ) sqlite3VdbeAddOp2(v, OP_Null, 0, r2); + for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){ + Expr *pE2 = pItem->pExpr; + int iValToIns; + + /* 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( jmpIfDynamic>=0 && !sqlite3ExprIsConstant(pE2) ){ + sqlite3VdbeChangeToNoop(v, jmpIfDynamic); + jmpIfDynamic = -1; + } + + /* Evaluate the expression and insert it into the temp table */ + if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){ + sqlite3VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns); + }else{ + r3 = sqlite3ExprCodeTarget(pParse, pE2, r1); + if( isRowid ){ + sqlite3VdbeAddOp2(v, OP_MustBeInt, r3, + sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3); + }else{ + sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1); + sqlite3ExprCacheAffinityChange(pParse, r3, 1); + sqlite3VdbeAddOp2(v, OP_IdxInsert, pExpr->iTable, r2); + } + } + } + sqlite3ReleaseTempReg(pParse, r1); + sqlite3ReleaseTempReg(pParse, r2); + } + if( pKeyInfo ){ + sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO); + } + break; + } + + case TK_EXISTS: + case TK_SELECT: + default: { + /* If 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. If this is an EXISTS, write + ** an integer 0 (not exists) or 1 (exists) into a memory cell + ** and record that memory cell in iColumn. + */ + Select *pSel; /* SELECT statement to encode */ + SelectDest dest; /* How to deal with SELECt result */ + + testcase( pExpr->op==TK_EXISTS ); + testcase( pExpr->op==TK_SELECT ); + assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT ); + + assert( ExprHasProperty(pExpr, EP_xIsSelect) ); + pSel = pExpr->x.pSelect; + sqlite3SelectDestInit(&dest, 0, ++pParse->nMem); + if( pExpr->op==TK_SELECT ){ + dest.eDest = SRT_Mem; + dest.iSdst = dest.iSDParm; + sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iSDParm); + VdbeComment((v, "Init subquery result")); + }else{ + dest.eDest = SRT_Exists; + sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm); + VdbeComment((v, "Init EXISTS result")); + } + sqlite3ExprDelete(pParse->db, pSel->pLimit); + pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, + &sqlite3IntTokens[1]); + pSel->iLimit = 0; + pSel->selFlags &= ~SF_MultiValue; + if( sqlite3Select(pParse, pSel, &dest) ){ + return 0; + } + rReg = dest.iSDParm; + ExprSetVVAProperty(pExpr, EP_NoReduce); + break; + } + } + + if( rHasNullFlag ){ + sqlite3SetHasNullFlag(v, pExpr->iTable, rHasNullFlag); + } + + if( jmpIfDynamic>=0 ){ + sqlite3VdbeJumpHere(v, jmpIfDynamic); + } + sqlite3ExprCachePop(pParse); + + return rReg; +} +#endif /* SQLITE_OMIT_SUBQUERY */ + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Generate code for an IN expression. +** +** x IN (SELECT ...) +** x IN (value, value, ...) +** +** The left-hand side (LHS) is a scalar expression. The right-hand side (RHS) +** is an array of zero or more values. The expression is true if the LHS is +** contained within the RHS. The value of the expression is unknown (NULL) +** if the LHS is NULL or if the LHS is not contained within the RHS and the +** RHS contains one or more NULL values. +** +** This routine generates code that jumps to destIfFalse if the LHS is not +** contained within the RHS. If due to NULLs we cannot determine if the LHS +** is contained in the RHS then jump to destIfNull. If the LHS is contained +** within the RHS then fall through. +*/ +static void sqlite3ExprCodeIN( + Parse *pParse, /* Parsing and code generating context */ + Expr *pExpr, /* The IN expression */ + int destIfFalse, /* Jump here if LHS is not contained in the RHS */ + int destIfNull /* Jump here if the results are unknown due to NULLs */ +){ + int rRhsHasNull = 0; /* Register that is true if RHS contains NULL values */ + char affinity; /* Comparison affinity to use */ + int eType; /* Type of the RHS */ + int r1; /* Temporary use register */ + Vdbe *v; /* Statement under construction */ + + /* Compute the RHS. After this step, the table with cursor + ** pExpr->iTable will contains the values that make up the RHS. + */ + v = pParse->pVdbe; + assert( v!=0 ); /* OOM detected prior to this routine */ + VdbeNoopComment((v, "begin IN expr")); + eType = sqlite3FindInIndex(pParse, pExpr, + IN_INDEX_MEMBERSHIP | IN_INDEX_NOOP_OK, + destIfFalse==destIfNull ? 0 : &rRhsHasNull); + + /* Figure out the affinity to use to create a key from the results + ** of the expression. affinityStr stores a static string suitable for + ** P4 of OP_MakeRecord. + */ + affinity = comparisonAffinity(pExpr); + + /* Code the LHS, the from " IN (...)". + */ + sqlite3ExprCachePush(pParse); + r1 = sqlite3GetTempReg(pParse); + sqlite3ExprCode(pParse, pExpr->pLeft, r1); + + /* If sqlite3FindInIndex() did not find or create an index that is + ** suitable for evaluating the IN operator, then evaluate using a + ** sequence of comparisons. + */ + if( eType==IN_INDEX_NOOP ){ + ExprList *pList = pExpr->x.pList; + CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft); + int labelOk = sqlite3VdbeMakeLabel(v); + int r2, regToFree; + int regCkNull = 0; + int ii; + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + if( destIfNull!=destIfFalse ){ + regCkNull = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_BitAnd, r1, r1, regCkNull); + } + for(ii=0; iinExpr; ii++){ + r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree); + if( regCkNull && sqlite3ExprCanBeNull(pList->a[ii].pExpr) ){ + sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull); + } + if( iinExpr-1 || destIfNull!=destIfFalse ){ + sqlite3VdbeAddOp4(v, OP_Eq, r1, labelOk, r2, + (void*)pColl, P4_COLLSEQ); + VdbeCoverageIf(v, iinExpr-1); + VdbeCoverageIf(v, ii==pList->nExpr-1); + sqlite3VdbeChangeP5(v, affinity); + }else{ + assert( destIfNull==destIfFalse ); + sqlite3VdbeAddOp4(v, OP_Ne, r1, destIfFalse, r2, + (void*)pColl, P4_COLLSEQ); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, affinity | SQLITE_JUMPIFNULL); + } + sqlite3ReleaseTempReg(pParse, regToFree); + } + if( regCkNull ){ + sqlite3VdbeAddOp2(v, OP_IsNull, regCkNull, destIfNull); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); + } + sqlite3VdbeResolveLabel(v, labelOk); + sqlite3ReleaseTempReg(pParse, regCkNull); + }else{ + + /* If the LHS is NULL, then the result is either false or NULL depending + ** on whether the RHS is empty or not, respectively. + */ + if( sqlite3ExprCanBeNull(pExpr->pLeft) ){ + if( destIfNull==destIfFalse ){ + /* Shortcut for the common case where the false and NULL outcomes are + ** the same. */ + sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull); VdbeCoverage(v); + }else{ + int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull); + sqlite3VdbeJumpHere(v, addr1); + } + } + + if( eType==IN_INDEX_ROWID ){ + /* In this case, the RHS is the ROWID of table b-tree + */ + sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, destIfFalse); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, destIfFalse, r1); + VdbeCoverage(v); + }else{ + /* In this case, the RHS is an index b-tree. + */ + sqlite3VdbeAddOp4(v, OP_Affinity, r1, 1, 0, &affinity, 1); + + /* If the set membership test fails, then the result of the + ** "x IN (...)" expression must be either 0 or NULL. If the set + ** contains no NULL values, then the result is 0. If the set + ** contains one or more NULL values, then the result of the + ** expression is also NULL. + */ + assert( destIfFalse!=destIfNull || rRhsHasNull==0 ); + if( rRhsHasNull==0 ){ + /* This branch runs if it is known at compile time that the RHS + ** cannot contain NULL values. This happens as the result + ** of a "NOT NULL" constraint in the database schema. + ** + ** Also run this branch if NULL is equivalent to FALSE + ** for this particular IN operator. + */ + sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, r1, 1); + VdbeCoverage(v); + }else{ + /* In this branch, the RHS of the IN might contain a NULL and + ** the presence of a NULL on the RHS makes a difference in the + ** outcome. + */ + int j1; + + /* First check to see if the LHS is contained in the RHS. If so, + ** then the answer is TRUE the presence of NULLs in the RHS does + ** not matter. If the LHS is not contained in the RHS, then the + ** answer is NULL if the RHS contains NULLs and the answer is + ** FALSE if the RHS is NULL-free. + */ + j1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_IsNull, rRhsHasNull, destIfNull); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); + sqlite3VdbeJumpHere(v, j1); + } + } + } + sqlite3ReleaseTempReg(pParse, r1); + sqlite3ExprCachePop(pParse); + VdbeComment((v, "end IN expr")); +} +#endif /* SQLITE_OMIT_SUBQUERY */ + +/* +** Duplicate an 8-byte value +*/ +static char *dup8bytes(Vdbe *v, const char *in){ + char *out = sqlite3DbMallocRaw(sqlite3VdbeDb(v), 8); + if( out ){ + memcpy(out, in, 8); + } + return out; +} + +#ifndef SQLITE_OMIT_FLOATING_POINT +/* +** Generate an instruction that will put the floating point +** value described by z[0..n-1] into register iMem. +** +** The z[] string will probably not be zero-terminated. But the +** z[n] character is guaranteed to be something that does not look +** like the continuation of the number. +*/ +static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){ + if( ALWAYS(z!=0) ){ + double value; + char *zV; + sqlite3AtoF(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); + assert( !sqlite3IsNaN(value) ); /* The new AtoF never returns NaN */ + if( negateFlag ) value = -value; + zV = dup8bytes(v, (char*)&value); + sqlite3VdbeAddOp4(v, OP_Real, 0, iMem, 0, zV, P4_REAL); + } +} +#endif + + +/* +** Generate an instruction that will put the integer describe by +** text z[0..n-1] into register iMem. +** +** Expr.u.zToken is always UTF8 and zero-terminated. +*/ +static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ + Vdbe *v = pParse->pVdbe; + if( pExpr->flags & EP_IntValue ){ + int i = pExpr->u.iValue; + assert( i>=0 ); + if( negFlag ) i = -i; + sqlite3VdbeAddOp2(v, OP_Integer, i, iMem); + }else{ + int c; + i64 value; + const char *z = pExpr->u.zToken; + assert( z!=0 ); + c = sqlite3DecOrHexToI64(z, &value); + if( c==0 || (c==2 && negFlag) ){ + char *zV; + if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; } + zV = dup8bytes(v, (char*)&value); + sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64); + }else{ +#ifdef SQLITE_OMIT_FLOATING_POINT + sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z); +#else +#ifndef SQLITE_OMIT_HEX_INTEGER + if( sqlite3_strnicmp(z,"0x",2)==0 ){ + sqlite3ErrorMsg(pParse, "hex literal too big: %s", z); + }else +#endif + { + codeReal(v, z, negFlag, iMem); + } +#endif + } + } +} + +/* +** Clear a cache entry. +*/ +static void cacheEntryClear(Parse *pParse, struct yColCache *p){ + if( p->tempReg ){ + if( pParse->nTempRegaTempReg) ){ + pParse->aTempReg[pParse->nTempReg++] = p->iReg; + } + p->tempReg = 0; + } +} + + +/* +** Record in the column cache that a particular column from a +** particular table is stored in a particular register. +*/ +SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){ + int i; + int minLru; + int idxLru; + struct yColCache *p; + + /* Unless an error has occurred, register numbers are always positive. */ + assert( iReg>0 || pParse->nErr || pParse->db->mallocFailed ); + assert( iCol>=-1 && iCol<32768 ); /* Finite column numbers */ + + /* The SQLITE_ColumnCache flag disables the column cache. This is used + ** for testing only - to verify that SQLite always gets the same answer + ** with and without the column cache. + */ + if( OptimizationDisabled(pParse->db, SQLITE_ColumnCache) ) return; + + /* First replace any existing entry. + ** + ** Actually, the way the column cache is currently used, we are guaranteed + ** that the object will never already be in cache. Verify this guarantee. + */ +#ifndef NDEBUG + for(i=0, p=pParse->aColCache; iiReg==0 || p->iTable!=iTab || p->iColumn!=iCol ); + } +#endif + + /* Find an empty slot and replace it */ + for(i=0, p=pParse->aColCache; iiReg==0 ){ + p->iLevel = pParse->iCacheLevel; + p->iTable = iTab; + p->iColumn = iCol; + p->iReg = iReg; + p->tempReg = 0; + p->lru = pParse->iCacheCnt++; + return; + } + } + + /* Replace the last recently used */ + minLru = 0x7fffffff; + idxLru = -1; + for(i=0, p=pParse->aColCache; ilrulru; + } + } + if( ALWAYS(idxLru>=0) ){ + p = &pParse->aColCache[idxLru]; + p->iLevel = pParse->iCacheLevel; + p->iTable = iTab; + p->iColumn = iCol; + p->iReg = iReg; + p->tempReg = 0; + p->lru = pParse->iCacheCnt++; + return; + } +} + +/* +** Indicate that registers between iReg..iReg+nReg-1 are being overwritten. +** Purge the range of registers from the column cache. +*/ +SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){ + int i; + int iLast = iReg + nReg - 1; + struct yColCache *p; + for(i=0, p=pParse->aColCache; iiReg; + if( r>=iReg && r<=iLast ){ + cacheEntryClear(pParse, p); + p->iReg = 0; + } + } +} + +/* +** Remember the current column cache context. Any new entries added +** added to the column cache after this call are removed when the +** corresponding pop occurs. +*/ +SQLITE_PRIVATE void sqlite3ExprCachePush(Parse *pParse){ + pParse->iCacheLevel++; +#ifdef SQLITE_DEBUG + if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ + printf("PUSH to %d\n", pParse->iCacheLevel); + } +#endif +} + +/* +** Remove from the column cache any entries that were added since the +** the previous sqlite3ExprCachePush operation. In other words, restore +** the cache to the state it was in prior the most recent Push. +*/ +SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse){ + int i; + struct yColCache *p; + assert( pParse->iCacheLevel>=1 ); + pParse->iCacheLevel--; +#ifdef SQLITE_DEBUG + if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ + printf("POP to %d\n", pParse->iCacheLevel); + } +#endif + for(i=0, p=pParse->aColCache; iiReg && p->iLevel>pParse->iCacheLevel ){ + cacheEntryClear(pParse, p); + p->iReg = 0; + } + } +} + +/* +** When a cached column is reused, make sure that its register is +** no longer available as a temp register. ticket #3879: that same +** register might be in the cache in multiple places, so be sure to +** get them all. +*/ +static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){ + int i; + struct yColCache *p; + for(i=0, p=pParse->aColCache; iiReg==iReg ){ + p->tempReg = 0; + } + } +} + +/* +** Generate code to extract the value of the iCol-th column of a table. +*/ +SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable( + Vdbe *v, /* The VDBE under construction */ + Table *pTab, /* The table containing the value */ + int iTabCur, /* The table cursor. Or the PK cursor for WITHOUT ROWID */ + int iCol, /* Index of the column to extract */ + int regOut /* Extract the value into this register */ +){ + if( iCol<0 || iCol==pTab->iPKey ){ + sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut); + }else{ + int op = IsVirtual(pTab) ? OP_VColumn : OP_Column; + int x = iCol; + if( !HasRowid(pTab) ){ + x = sqlite3ColumnOfIndex(sqlite3PrimaryKeyIndex(pTab), iCol); + } + sqlite3VdbeAddOp3(v, op, iTabCur, x, regOut); + } + if( iCol>=0 ){ + sqlite3ColumnDefault(v, pTab, iCol, regOut); + } +} + +/* +** Generate code that will extract the iColumn-th column from +** table pTab and store the column value in a register. An effort +** is made to store the column value in register iReg, but this is +** not guaranteed. The location of the column value is returned. +** +** There must be an open cursor to pTab in iTable when this routine +** is called. If iColumn<0 then code is generated that extracts the rowid. +*/ +SQLITE_PRIVATE int sqlite3ExprCodeGetColumn( + Parse *pParse, /* Parsing and code generating context */ + Table *pTab, /* Description of the table we are reading from */ + int iColumn, /* Index of the table column */ + int iTable, /* The cursor pointing to the table */ + int iReg, /* Store results here */ + u8 p5 /* P5 value for OP_Column */ +){ + Vdbe *v = pParse->pVdbe; + int i; + struct yColCache *p; + + for(i=0, p=pParse->aColCache; iiReg>0 && p->iTable==iTable && p->iColumn==iColumn ){ + p->lru = pParse->iCacheCnt++; + sqlite3ExprCachePinRegister(pParse, p->iReg); + return p->iReg; + } + } + assert( v!=0 ); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iTable, iColumn, iReg); + if( p5 ){ + sqlite3VdbeChangeP5(v, p5); + }else{ + sqlite3ExprCacheStore(pParse, iTable, iColumn, iReg); + } + return iReg; +} + +/* +** Clear all column cache entries. +*/ +SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse *pParse){ + int i; + struct yColCache *p; + +#if SQLITE_DEBUG + if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ + printf("CLEAR\n"); + } +#endif + for(i=0, p=pParse->aColCache; iiReg ){ + cacheEntryClear(pParse, p); + p->iReg = 0; + } + } +} + +/* +** Record the fact that an affinity change has occurred on iCount +** registers starting with iStart. +*/ +SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, int iCount){ + sqlite3ExprCacheRemove(pParse, iStart, iCount); +} + +/* +** Generate code to move content from registers iFrom...iFrom+nReg-1 +** over to iTo..iTo+nReg-1. Keep the column cache up-to-date. +*/ +SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){ + assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo ); + sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg); + sqlite3ExprCacheRemove(pParse, iFrom, nReg); +} + +#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) +/* +** Return true if any register in the range iFrom..iTo (inclusive) +** is used as part of the column cache. +** +** This routine is used within assert() and testcase() macros only +** and does not appear in a normal build. +*/ +static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){ + int i; + struct yColCache *p; + for(i=0, p=pParse->aColCache; iiReg; + if( r>=iFrom && r<=iTo ) return 1; /*NO_TEST*/ + } + return 0; +} +#endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */ + +/* +** Convert an expression node to a TK_REGISTER +*/ +static void exprToRegister(Expr *p, int iReg){ + p->op2 = p->op; + p->op = TK_REGISTER; + p->iTable = iReg; + ExprClearProperty(p, EP_Skip); +} + +/* +** Generate code into the current Vdbe to evaluate the given +** expression. Attempt to store the results in register "target". +** Return the register where results are stored. +** +** With this routine, there is no guarantee that results will +** be stored in target. The result might be stored in some other +** register if it is convenient to do so. The calling function +** must check the return code and move the results to the desired +** register. +*/ +SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ + Vdbe *v = pParse->pVdbe; /* The VM under construction */ + int op; /* The opcode being coded */ + int inReg = target; /* Results stored in register inReg */ + int regFree1 = 0; /* If non-zero free this temporary register */ + int regFree2 = 0; /* If non-zero free this temporary register */ + int r1, r2, r3, r4; /* Various register numbers */ + sqlite3 *db = pParse->db; /* The database connection */ + Expr tempX; /* Temporary expression node */ + + assert( target>0 && target<=pParse->nMem ); + if( v==0 ){ + assert( pParse->db->mallocFailed ); + return 0; + } + + if( pExpr==0 ){ + op = TK_NULL; + }else{ + op = pExpr->op; + } + switch( op ){ + case TK_AGG_COLUMN: { + AggInfo *pAggInfo = pExpr->pAggInfo; + struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg]; + if( !pAggInfo->directMode ){ + assert( pCol->iMem>0 ); + inReg = pCol->iMem; + break; + }else if( pAggInfo->useSortingIdx ){ + sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab, + pCol->iSorterColumn, target); + break; + } + /* Otherwise, fall thru into the TK_COLUMN case */ + } + case TK_COLUMN: { + int iTab = pExpr->iTable; + if( iTab<0 ){ + if( pParse->ckBase>0 ){ + /* Generating CHECK constraints or inserting into partial index */ + inReg = pExpr->iColumn + pParse->ckBase; + break; + }else{ + /* Deleting from a partial index */ + iTab = pParse->iPartIdxTab; + } + } + inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab, + pExpr->iColumn, iTab, target, + pExpr->op2); + break; + } + case TK_INTEGER: { + codeInteger(pParse, pExpr, 0, target); + break; + } +#ifndef SQLITE_OMIT_FLOATING_POINT + case TK_FLOAT: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + codeReal(v, pExpr->u.zToken, 0, target); + break; + } +#endif + case TK_STRING: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3VdbeAddOp4(v, OP_String8, 0, target, 0, pExpr->u.zToken, 0); + break; + } + case TK_NULL: { + sqlite3VdbeAddOp2(v, OP_Null, 0, target); + break; + } +#ifndef SQLITE_OMIT_BLOB_LITERAL + case TK_BLOB: { + int n; + const char *z; + char *zBlob; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' ); + assert( pExpr->u.zToken[1]=='\'' ); + z = &pExpr->u.zToken[2]; + n = sqlite3Strlen30(z) - 1; + assert( z[n]=='\'' ); + zBlob = sqlite3HexToBlob(sqlite3VdbeDb(v), z, n); + sqlite3VdbeAddOp4(v, OP_Blob, n/2, target, 0, zBlob, P4_DYNAMIC); + break; + } +#endif + case TK_VARIABLE: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + assert( pExpr->u.zToken!=0 ); + assert( pExpr->u.zToken[0]!=0 ); + sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); + if( pExpr->u.zToken[1]!=0 ){ + assert( pExpr->u.zToken[0]=='?' + || strcmp(pExpr->u.zToken, pParse->azVar[pExpr->iColumn-1])==0 ); + sqlite3VdbeChangeP4(v, -1, pParse->azVar[pExpr->iColumn-1], P4_STATIC); + } + break; + } + case TK_REGISTER: { + inReg = pExpr->iTable; + break; + } + case TK_AS: { + inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); + break; + } +#ifndef SQLITE_OMIT_CAST + case TK_CAST: { + /* Expressions of the form: CAST(pLeft AS token) */ + inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); + if( inReg!=target ){ + sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target); + inReg = target; + } + sqlite3VdbeAddOp2(v, OP_Cast, target, + sqlite3AffinityType(pExpr->u.zToken, 0)); + testcase( usedAsColumnCache(pParse, inReg, inReg) ); + sqlite3ExprCacheAffinityChange(pParse, inReg, 1); + break; + } +#endif /* SQLITE_OMIT_CAST */ + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: + case TK_NE: + case TK_EQ: { + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, inReg, SQLITE_STOREP2); + assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); + assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); + assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); + assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); + assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); + assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } + case TK_IS: + case TK_ISNOT: { + testcase( op==TK_IS ); + testcase( op==TK_ISNOT ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + op = (op==TK_IS) ? TK_EQ : TK_NE; + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, inReg, SQLITE_STOREP2 | SQLITE_NULLEQ); + VdbeCoverageIf(v, op==TK_EQ); + VdbeCoverageIf(v, op==TK_NE); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } + case TK_AND: + case TK_OR: + case TK_PLUS: + case TK_STAR: + case TK_MINUS: + case TK_REM: + case TK_BITAND: + case TK_BITOR: + case TK_SLASH: + case TK_LSHIFT: + case TK_RSHIFT: + case TK_CONCAT: { + assert( TK_AND==OP_And ); testcase( op==TK_AND ); + assert( TK_OR==OP_Or ); testcase( op==TK_OR ); + assert( TK_PLUS==OP_Add ); testcase( op==TK_PLUS ); + assert( TK_MINUS==OP_Subtract ); testcase( op==TK_MINUS ); + assert( TK_REM==OP_Remainder ); testcase( op==TK_REM ); + assert( TK_BITAND==OP_BitAnd ); testcase( op==TK_BITAND ); + assert( TK_BITOR==OP_BitOr ); testcase( op==TK_BITOR ); + assert( TK_SLASH==OP_Divide ); testcase( op==TK_SLASH ); + assert( TK_LSHIFT==OP_ShiftLeft ); testcase( op==TK_LSHIFT ); + assert( TK_RSHIFT==OP_ShiftRight ); testcase( op==TK_RSHIFT ); + assert( TK_CONCAT==OP_Concat ); testcase( op==TK_CONCAT ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + sqlite3VdbeAddOp3(v, op, r2, r1, target); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } + case TK_UMINUS: { + Expr *pLeft = pExpr->pLeft; + assert( pLeft ); + if( pLeft->op==TK_INTEGER ){ + codeInteger(pParse, pLeft, 1, target); +#ifndef SQLITE_OMIT_FLOATING_POINT + }else if( pLeft->op==TK_FLOAT ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + codeReal(v, pLeft->u.zToken, 1, target); +#endif + }else{ + tempX.op = TK_INTEGER; + tempX.flags = EP_IntValue|EP_TokenOnly; + tempX.u.iValue = 0; + r1 = sqlite3ExprCodeTemp(pParse, &tempX, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free2); + sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target); + testcase( regFree2==0 ); + } + inReg = target; + break; + } + case TK_BITNOT: + case TK_NOT: { + assert( TK_BITNOT==OP_BitNot ); testcase( op==TK_BITNOT ); + assert( TK_NOT==OP_Not ); testcase( op==TK_NOT ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + testcase( regFree1==0 ); + inReg = target; + sqlite3VdbeAddOp2(v, op, r1, inReg); + break; + } + case TK_ISNULL: + case TK_NOTNULL: { + int addr; + assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL ); + assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL ); + sqlite3VdbeAddOp2(v, OP_Integer, 1, target); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + testcase( regFree1==0 ); + addr = sqlite3VdbeAddOp1(v, op, r1); + VdbeCoverageIf(v, op==TK_ISNULL); + VdbeCoverageIf(v, op==TK_NOTNULL); + sqlite3VdbeAddOp2(v, OP_Integer, 0, target); + sqlite3VdbeJumpHere(v, addr); + break; + } + case TK_AGG_FUNCTION: { + AggInfo *pInfo = pExpr->pAggInfo; + if( pInfo==0 ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken); + }else{ + inReg = pInfo->aFunc[pExpr->iAgg].iMem; + } + break; + } + case TK_FUNCTION: { + ExprList *pFarg; /* List of function arguments */ + int nFarg; /* Number of function arguments */ + FuncDef *pDef; /* The function definition object */ + int nId; /* Length of the function name in bytes */ + const char *zId; /* The function name */ + u32 constMask = 0; /* Mask of function arguments that are constant */ + int i; /* Loop counter */ + u8 enc = ENC(db); /* The text encoding used by this database */ + CollSeq *pColl = 0; /* A collating sequence */ + + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + if( ExprHasProperty(pExpr, EP_TokenOnly) ){ + pFarg = 0; + }else{ + pFarg = pExpr->x.pList; + } + nFarg = pFarg ? pFarg->nExpr : 0; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + zId = pExpr->u.zToken; + nId = sqlite3Strlen30(zId); + pDef = sqlite3FindFunction(db, zId, nId, nFarg, enc, 0); + if( pDef==0 || pDef->xFunc==0 ){ + sqlite3ErrorMsg(pParse, "unknown function: %.*s()", nId, zId); + break; + } + + /* Attempt a direct implementation of the built-in COALESCE() and + ** IFNULL() functions. This avoids unnecessary evaluation of + ** arguments past the first non-NULL argument. + */ + if( pDef->funcFlags & SQLITE_FUNC_COALESCE ){ + int endCoalesce = sqlite3VdbeMakeLabel(v); + assert( nFarg>=2 ); + sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target); + for(i=1; ia[i].pExpr, target); + sqlite3ExprCachePop(pParse); + } + sqlite3VdbeResolveLabel(v, endCoalesce); + break; + } + + /* The UNLIKELY() function is a no-op. The result is the value + ** of the first argument. + */ + if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){ + assert( nFarg>=1 ); + sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target); + break; + } + + for(i=0; ia[i].pExpr) ){ + testcase( i==31 ); + constMask |= MASKBIT32(i); + } + if( (pDef->funcFlags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){ + pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr); + } + } + if( pFarg ){ + if( constMask ){ + r1 = pParse->nMem+1; + pParse->nMem += nFarg; + }else{ + r1 = sqlite3GetTempRange(pParse, nFarg); + } + + /* For length() and typeof() functions with a column argument, + ** set the P5 parameter to the OP_Column opcode to OPFLAG_LENGTHARG + ** or OPFLAG_TYPEOFARG respectively, to avoid unnecessary data + ** loading. + */ + if( (pDef->funcFlags & (SQLITE_FUNC_LENGTH|SQLITE_FUNC_TYPEOF))!=0 ){ + u8 exprOp; + assert( nFarg==1 ); + assert( pFarg->a[0].pExpr!=0 ); + exprOp = pFarg->a[0].pExpr->op; + if( exprOp==TK_COLUMN || exprOp==TK_AGG_COLUMN ){ + assert( SQLITE_FUNC_LENGTH==OPFLAG_LENGTHARG ); + assert( SQLITE_FUNC_TYPEOF==OPFLAG_TYPEOFARG ); + testcase( pDef->funcFlags & OPFLAG_LENGTHARG ); + pFarg->a[0].pExpr->op2 = + pDef->funcFlags & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG); + } + } + + sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */ + sqlite3ExprCodeExprList(pParse, pFarg, r1, + SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR); + sqlite3ExprCachePop(pParse); /* Ticket 2ea2425d34be */ + }else{ + r1 = 0; + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* Possibly overload the function if the first argument is + ** a virtual table column. + ** + ** For infix functions (LIKE, GLOB, REGEXP, and MATCH) use the + ** second argument, not the first, as the argument to test to + ** see if it is a column in a virtual table. This is done because + ** the left operand of infix functions (the operand we want to + ** control overloading) ends up as the second argument to the + ** function. The expression "A glob B" is equivalent to + ** "glob(B,A). We want to use the A in "A glob B" to test + ** for function overloading. But we use the B term in "glob(B,A)". + */ + if( nFarg>=2 && (pExpr->flags & EP_InfixFunc) ){ + pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr); + }else if( nFarg>0 ){ + pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr); + } +#endif + if( pDef->funcFlags & SQLITE_FUNC_NEEDCOLL ){ + if( !pColl ) pColl = db->pDfltColl; + sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ); + } + sqlite3VdbeAddOp4(v, OP_Function, constMask, r1, target, + (char*)pDef, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, (u8)nFarg); + if( nFarg && constMask==0 ){ + sqlite3ReleaseTempRange(pParse, r1, nFarg); + } + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_EXISTS: + case TK_SELECT: { + testcase( op==TK_EXISTS ); + testcase( op==TK_SELECT ); + inReg = sqlite3CodeSubselect(pParse, pExpr, 0, 0); + break; + } + case TK_IN: { + int destIfFalse = sqlite3VdbeMakeLabel(v); + int destIfNull = sqlite3VdbeMakeLabel(v); + sqlite3VdbeAddOp2(v, OP_Null, 0, target); + sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull); + sqlite3VdbeAddOp2(v, OP_Integer, 1, target); + sqlite3VdbeResolveLabel(v, destIfFalse); + sqlite3VdbeAddOp2(v, OP_AddImm, target, 0); + sqlite3VdbeResolveLabel(v, destIfNull); + break; + } +#endif /* SQLITE_OMIT_SUBQUERY */ + + + /* + ** x BETWEEN y AND z + ** + ** This is equivalent to + ** + ** x>=y AND x<=z + ** + ** X is stored in pExpr->pLeft. + ** Y is stored in pExpr->pList->a[0].pExpr. + ** Z is stored in pExpr->pList->a[1].pExpr. + */ + case TK_BETWEEN: { + Expr *pLeft = pExpr->pLeft; + struct ExprList_item *pLItem = pExpr->x.pList->a; + Expr *pRight = pLItem->pExpr; + + r1 = sqlite3ExprCodeTemp(pParse, pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pRight, ®Free2); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + r3 = sqlite3GetTempReg(pParse); + r4 = sqlite3GetTempReg(pParse); + codeCompare(pParse, pLeft, pRight, OP_Ge, + r1, r2, r3, SQLITE_STOREP2); VdbeCoverage(v); + pLItem++; + pRight = pLItem->pExpr; + sqlite3ReleaseTempReg(pParse, regFree2); + r2 = sqlite3ExprCodeTemp(pParse, pRight, ®Free2); + testcase( regFree2==0 ); + codeCompare(pParse, pLeft, pRight, OP_Le, r1, r2, r4, SQLITE_STOREP2); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_And, r3, r4, target); + sqlite3ReleaseTempReg(pParse, r3); + sqlite3ReleaseTempReg(pParse, r4); + break; + } + case TK_COLLATE: + case TK_UPLUS: { + inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); + break; + } + + case TK_TRIGGER: { + /* If the opcode is TK_TRIGGER, then the expression is a reference + ** to a column in the new.* or old.* pseudo-tables available to + ** trigger programs. In this case Expr.iTable is set to 1 for the + ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn + ** is set to the column of the pseudo-table to read, or to -1 to + ** read the rowid field. + ** + ** The expression is implemented using an OP_Param opcode. The p1 + ** parameter is set to 0 for an old.rowid reference, or to (i+1) + ** to reference another column of the old.* pseudo-table, where + ** i is the index of the column. For a new.rowid reference, p1 is + ** set to (n+1), where n is the number of columns in each pseudo-table. + ** For a reference to any other column in the new.* pseudo-table, p1 + ** is set to (n+2+i), where n and i are as defined previously. For + ** example, if the table on which triggers are being fired is + ** declared as: + ** + ** CREATE TABLE t1(a, b); + ** + ** Then p1 is interpreted as follows: + ** + ** p1==0 -> old.rowid p1==3 -> new.rowid + ** p1==1 -> old.a p1==4 -> new.a + ** p1==2 -> old.b p1==5 -> new.b + */ + Table *pTab = pExpr->pTab; + int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn; + + assert( pExpr->iTable==0 || pExpr->iTable==1 ); + assert( pExpr->iColumn>=-1 && pExpr->iColumnnCol ); + assert( pTab->iPKey<0 || pExpr->iColumn!=pTab->iPKey ); + assert( p1>=0 && p1<(pTab->nCol*2+2) ); + + sqlite3VdbeAddOp2(v, OP_Param, p1, target); + VdbeComment((v, "%s.%s -> $%d", + (pExpr->iTable ? "new" : "old"), + (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName), + target + )); + +#ifndef SQLITE_OMIT_FLOATING_POINT + /* If the column has REAL affinity, it may currently be stored as an + ** integer. Use OP_RealAffinity to make sure it is really real. + ** + ** EVIDENCE-OF: R-60985-57662 SQLite will convert the value back to + ** floating point when extracting it from the record. */ + if( pExpr->iColumn>=0 + && pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL + ){ + sqlite3VdbeAddOp1(v, OP_RealAffinity, target); + } +#endif + break; + } + + + /* + ** Form A: + ** CASE x WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END + ** + ** Form B: + ** CASE WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END + ** + ** Form A is can be transformed into the equivalent form B as follows: + ** CASE WHEN x=e1 THEN r1 WHEN x=e2 THEN r2 ... + ** WHEN x=eN THEN rN ELSE y END + ** + ** X (if it exists) is in pExpr->pLeft. + ** Y is in the last element of pExpr->x.pList if pExpr->x.pList->nExpr is + ** odd. The Y is also optional. If the number of elements in x.pList + ** is even, then Y is omitted and the "otherwise" result is NULL. + ** Ei is in pExpr->pList->a[i*2] and Ri is pExpr->pList->a[i*2+1]. + ** + ** The result of the expression is the Ri for the first matching Ei, + ** or if there is no matching Ei, the ELSE term Y, or if there is + ** no ELSE term, NULL. + */ + default: assert( op==TK_CASE ); { + int endLabel; /* GOTO label for end of CASE stmt */ + int nextCase; /* GOTO label for next WHEN clause */ + int nExpr; /* 2x number of WHEN terms */ + int i; /* Loop counter */ + ExprList *pEList; /* List of WHEN terms */ + struct ExprList_item *aListelem; /* Array of WHEN terms */ + Expr opCompare; /* The X==Ei expression */ + Expr *pX; /* The X expression */ + Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */ + VVA_ONLY( int iCacheLevel = pParse->iCacheLevel; ) + + assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList ); + assert(pExpr->x.pList->nExpr > 0); + pEList = pExpr->x.pList; + aListelem = pEList->a; + nExpr = pEList->nExpr; + endLabel = sqlite3VdbeMakeLabel(v); + if( (pX = pExpr->pLeft)!=0 ){ + tempX = *pX; + testcase( pX->op==TK_COLUMN ); + exprToRegister(&tempX, sqlite3ExprCodeTemp(pParse, pX, ®Free1)); + testcase( regFree1==0 ); + opCompare.op = TK_EQ; + opCompare.pLeft = &tempX; + pTest = &opCompare; + /* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001: + ** The value in regFree1 might get SCopy-ed into the file result. + ** So make sure that the regFree1 register is not reused for other + ** purposes and possibly overwritten. */ + regFree1 = 0; + } + for(i=0; iop==TK_COLUMN ); + sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL); + testcase( aListelem[i+1].pExpr->op==TK_COLUMN ); + sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target); + sqlite3VdbeAddOp2(v, OP_Goto, 0, endLabel); + sqlite3ExprCachePop(pParse); + sqlite3VdbeResolveLabel(v, nextCase); + } + if( (nExpr&1)!=0 ){ + sqlite3ExprCachePush(pParse); + sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target); + sqlite3ExprCachePop(pParse); + }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, target); + } + assert( db->mallocFailed || pParse->nErr>0 + || pParse->iCacheLevel==iCacheLevel ); + sqlite3VdbeResolveLabel(v, endLabel); + break; + } +#ifndef SQLITE_OMIT_TRIGGER + case TK_RAISE: { + assert( pExpr->affinity==OE_Rollback + || pExpr->affinity==OE_Abort + || pExpr->affinity==OE_Fail + || pExpr->affinity==OE_Ignore + ); + if( !pParse->pTriggerTab ){ + sqlite3ErrorMsg(pParse, + "RAISE() may only be used within a trigger-program"); + return 0; + } + if( pExpr->affinity==OE_Abort ){ + sqlite3MayAbort(pParse); + } + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + if( pExpr->affinity==OE_Ignore ){ + sqlite3VdbeAddOp4( + v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0); + VdbeCoverage(v); + }else{ + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER, + pExpr->affinity, pExpr->u.zToken, 0, 0); + } + + break; + } +#endif + } + sqlite3ReleaseTempReg(pParse, regFree1); + sqlite3ReleaseTempReg(pParse, regFree2); + return inReg; +} + +/* +** Factor out the code of the given expression to initialization time. +*/ +SQLITE_PRIVATE void sqlite3ExprCodeAtInit( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* The expression to code when the VDBE initializes */ + int regDest, /* Store the value in this register */ + u8 reusable /* True if this expression is reusable */ +){ + ExprList *p; + assert( ConstFactorOk(pParse) ); + p = pParse->pConstExpr; + pExpr = sqlite3ExprDup(pParse->db, pExpr, 0); + p = sqlite3ExprListAppend(pParse, p, pExpr); + if( p ){ + struct ExprList_item *pItem = &p->a[p->nExpr-1]; + pItem->u.iConstExprReg = regDest; + pItem->reusable = reusable; + } + pParse->pConstExpr = p; +} + +/* +** Generate code to evaluate an expression and store the results +** into a register. Return the register number where the results +** are stored. +** +** If the register is a temporary register that can be deallocated, +** then write its number into *pReg. If the result register is not +** a temporary, then set *pReg to zero. +** +** If pExpr is a constant, then this routine might generate this +** code to fill the register in the initialization section of the +** VDBE program, in order to factor it out of the evaluation loop. +*/ +SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ + int r2; + pExpr = sqlite3ExprSkipCollate(pExpr); + if( ConstFactorOk(pParse) + && pExpr->op!=TK_REGISTER + && sqlite3ExprIsConstantNotJoin(pExpr) + ){ + ExprList *p = pParse->pConstExpr; + int i; + *pReg = 0; + if( p ){ + struct ExprList_item *pItem; + for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){ + if( pItem->reusable && sqlite3ExprCompare(pItem->pExpr,pExpr,-1)==0 ){ + return pItem->u.iConstExprReg; + } + } + } + r2 = ++pParse->nMem; + sqlite3ExprCodeAtInit(pParse, pExpr, r2, 1); + }else{ + int r1 = sqlite3GetTempReg(pParse); + r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); + if( r2==r1 ){ + *pReg = r1; + }else{ + sqlite3ReleaseTempReg(pParse, r1); + *pReg = 0; + } + } + return r2; +} + +/* +** Generate code that will evaluate expression pExpr and store the +** results in register target. The results are guaranteed to appear +** in register target. +*/ +SQLITE_PRIVATE void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ + int inReg; + + assert( target>0 && target<=pParse->nMem ); + if( pExpr && pExpr->op==TK_REGISTER ){ + sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, pExpr->iTable, target); + }else{ + inReg = sqlite3ExprCodeTarget(pParse, pExpr, target); + assert( pParse->pVdbe || pParse->db->mallocFailed ); + if( inReg!=target && pParse->pVdbe ){ + sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target); + } + } +} + +/* +** Generate code that will evaluate expression pExpr and store the +** results in register target. The results are guaranteed to appear +** in register target. If the expression is constant, then this routine +** might choose to code the expression at initialization time. +*/ +SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){ + if( pParse->okConstFactor && sqlite3ExprIsConstant(pExpr) ){ + sqlite3ExprCodeAtInit(pParse, pExpr, target, 0); + }else{ + sqlite3ExprCode(pParse, pExpr, target); + } +} + +/* +** Generate code that evaluates the given expression and puts the result +** in register target. +** +** Also make a copy of the expression results into another "cache" register +** and modify the expression so that the next time it is evaluated, +** the result is a copy of the cache register. +** +** This routine is used for expressions that are used multiple +** times. They are evaluated once and the results of the expression +** are reused. +*/ +SQLITE_PRIVATE void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){ + Vdbe *v = pParse->pVdbe; + int iMem; + + assert( target>0 ); + assert( pExpr->op!=TK_REGISTER ); + sqlite3ExprCode(pParse, pExpr, target); + iMem = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Copy, target, iMem); + exprToRegister(pExpr, iMem); +} + +#ifdef SQLITE_DEBUG +/* +** Generate a human-readable explanation of an expression tree. +*/ +SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ + const char *zBinOp = 0; /* Binary operator */ + const char *zUniOp = 0; /* Unary operator */ + pView = sqlite3TreeViewPush(pView, moreToFollow); + if( pExpr==0 ){ + sqlite3TreeViewLine(pView, "nil"); + sqlite3TreeViewPop(pView); + return; + } + switch( pExpr->op ){ + case TK_AGG_COLUMN: { + sqlite3TreeViewLine(pView, "AGG{%d:%d}", + pExpr->iTable, pExpr->iColumn); + break; + } + case TK_COLUMN: { + if( pExpr->iTable<0 ){ + /* This only happens when coding check constraints */ + sqlite3TreeViewLine(pView, "COLUMN(%d)", pExpr->iColumn); + }else{ + sqlite3TreeViewLine(pView, "{%d:%d}", + pExpr->iTable, pExpr->iColumn); + } + break; + } + case TK_INTEGER: { + if( pExpr->flags & EP_IntValue ){ + sqlite3TreeViewLine(pView, "%d", pExpr->u.iValue); + }else{ + sqlite3TreeViewLine(pView, "%s", pExpr->u.zToken); + } + break; + } +#ifndef SQLITE_OMIT_FLOATING_POINT + case TK_FLOAT: { + sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken); + break; + } +#endif + case TK_STRING: { + sqlite3TreeViewLine(pView,"%Q", pExpr->u.zToken); + break; + } + case TK_NULL: { + sqlite3TreeViewLine(pView,"NULL"); + break; + } +#ifndef SQLITE_OMIT_BLOB_LITERAL + case TK_BLOB: { + sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken); + break; + } +#endif + case TK_VARIABLE: { + sqlite3TreeViewLine(pView,"VARIABLE(%s,%d)", + pExpr->u.zToken, pExpr->iColumn); + break; + } + case TK_REGISTER: { + sqlite3TreeViewLine(pView,"REGISTER(%d)", pExpr->iTable); + break; + } + case TK_AS: { + sqlite3TreeViewLine(pView,"AS %Q", pExpr->u.zToken); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + break; + } + case TK_ID: { + sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken); + break; + } +#ifndef SQLITE_OMIT_CAST + case TK_CAST: { + /* Expressions of the form: CAST(pLeft AS token) */ + sqlite3TreeViewLine(pView,"CAST %Q", pExpr->u.zToken); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + break; + } +#endif /* SQLITE_OMIT_CAST */ + case TK_LT: zBinOp = "LT"; break; + case TK_LE: zBinOp = "LE"; break; + case TK_GT: zBinOp = "GT"; break; + case TK_GE: zBinOp = "GE"; break; + case TK_NE: zBinOp = "NE"; break; + case TK_EQ: zBinOp = "EQ"; break; + case TK_IS: zBinOp = "IS"; break; + case TK_ISNOT: zBinOp = "ISNOT"; break; + case TK_AND: zBinOp = "AND"; break; + case TK_OR: zBinOp = "OR"; break; + case TK_PLUS: zBinOp = "ADD"; break; + case TK_STAR: zBinOp = "MUL"; break; + case TK_MINUS: zBinOp = "SUB"; break; + case TK_REM: zBinOp = "REM"; break; + case TK_BITAND: zBinOp = "BITAND"; break; + case TK_BITOR: zBinOp = "BITOR"; break; + case TK_SLASH: zBinOp = "DIV"; break; + case TK_LSHIFT: zBinOp = "LSHIFT"; break; + case TK_RSHIFT: zBinOp = "RSHIFT"; break; + case TK_CONCAT: zBinOp = "CONCAT"; break; + case TK_DOT: zBinOp = "DOT"; break; + + case TK_UMINUS: zUniOp = "UMINUS"; break; + case TK_UPLUS: zUniOp = "UPLUS"; break; + case TK_BITNOT: zUniOp = "BITNOT"; break; + case TK_NOT: zUniOp = "NOT"; break; + case TK_ISNULL: zUniOp = "ISNULL"; break; + case TK_NOTNULL: zUniOp = "NOTNULL"; break; + + case TK_COLLATE: { + sqlite3TreeViewLine(pView, "COLLATE %Q", pExpr->u.zToken); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + break; + } + + case TK_AGG_FUNCTION: + case TK_FUNCTION: { + ExprList *pFarg; /* List of function arguments */ + if( ExprHasProperty(pExpr, EP_TokenOnly) ){ + pFarg = 0; + }else{ + pFarg = pExpr->x.pList; + } + if( pExpr->op==TK_AGG_FUNCTION ){ + sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q", + pExpr->op2, pExpr->u.zToken); + }else{ + sqlite3TreeViewLine(pView, "FUNCTION %Q", pExpr->u.zToken); + } + if( pFarg ){ + sqlite3TreeViewExprList(pView, pFarg, 0, 0); + } + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_EXISTS: { + sqlite3TreeViewLine(pView, "EXISTS-expr"); + sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); + break; + } + case TK_SELECT: { + sqlite3TreeViewLine(pView, "SELECT-expr"); + sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); + break; + } + case TK_IN: { + sqlite3TreeViewLine(pView, "IN"); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); + }else{ + sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0); + } + break; + } +#endif /* SQLITE_OMIT_SUBQUERY */ + + /* + ** x BETWEEN y AND z + ** + ** This is equivalent to + ** + ** x>=y AND x<=z + ** + ** X is stored in pExpr->pLeft. + ** Y is stored in pExpr->pList->a[0].pExpr. + ** Z is stored in pExpr->pList->a[1].pExpr. + */ + case TK_BETWEEN: { + Expr *pX = pExpr->pLeft; + Expr *pY = pExpr->x.pList->a[0].pExpr; + Expr *pZ = pExpr->x.pList->a[1].pExpr; + sqlite3TreeViewLine(pView, "BETWEEN"); + sqlite3TreeViewExpr(pView, pX, 1); + sqlite3TreeViewExpr(pView, pY, 1); + sqlite3TreeViewExpr(pView, pZ, 0); + break; + } + case TK_TRIGGER: { + /* If the opcode is TK_TRIGGER, then the expression is a reference + ** to a column in the new.* or old.* pseudo-tables available to + ** trigger programs. In this case Expr.iTable is set to 1 for the + ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn + ** is set to the column of the pseudo-table to read, or to -1 to + ** read the rowid field. + */ + sqlite3TreeViewLine(pView, "%s(%d)", + pExpr->iTable ? "NEW" : "OLD", pExpr->iColumn); + break; + } + case TK_CASE: { + sqlite3TreeViewLine(pView, "CASE"); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); + sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0); + break; + } +#ifndef SQLITE_OMIT_TRIGGER + case TK_RAISE: { + const char *zType = "unk"; + switch( pExpr->affinity ){ + case OE_Rollback: zType = "rollback"; break; + case OE_Abort: zType = "abort"; break; + case OE_Fail: zType = "fail"; break; + case OE_Ignore: zType = "ignore"; break; + } + sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken); + break; + } +#endif + default: { + sqlite3TreeViewLine(pView, "op=%d", pExpr->op); + break; + } + } + if( zBinOp ){ + sqlite3TreeViewLine(pView, "%s", zBinOp); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); + sqlite3TreeViewExpr(pView, pExpr->pRight, 0); + }else if( zUniOp ){ + sqlite3TreeViewLine(pView, "%s", zUniOp); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + } + sqlite3TreeViewPop(pView); +} +#endif /* SQLITE_DEBUG */ + +#ifdef SQLITE_DEBUG +/* +** Generate a human-readable explanation of an expression list. +*/ +SQLITE_PRIVATE void sqlite3TreeViewExprList( + TreeView *pView, + const ExprList *pList, + u8 moreToFollow, + const char *zLabel +){ + int i; + pView = sqlite3TreeViewPush(pView, moreToFollow); + if( zLabel==0 || zLabel[0]==0 ) zLabel = "LIST"; + if( pList==0 ){ + sqlite3TreeViewLine(pView, "%s (empty)", zLabel); + }else{ + sqlite3TreeViewLine(pView, "%s", zLabel); + for(i=0; inExpr; i++){ + sqlite3TreeViewExpr(pView, pList->a[i].pExpr, inExpr-1); +#if 0 + if( pList->a[i].zName ){ + sqlite3ExplainPrintf(pOut, " AS %s", pList->a[i].zName); + } + if( pList->a[i].bSpanIsTab ){ + sqlite3ExplainPrintf(pOut, " (%s)", pList->a[i].zSpan); + } +#endif + } + } + sqlite3TreeViewPop(pView); +} +#endif /* SQLITE_DEBUG */ + +/* +** Generate code that pushes the value of every element of the given +** expression list into a sequence of registers beginning at target. +** +** Return the number of elements evaluated. +** +** The SQLITE_ECEL_DUP flag prevents the arguments from being +** filled using OP_SCopy. OP_Copy must be used instead. +** +** The SQLITE_ECEL_FACTOR argument allows constant arguments to be +** factored out into initialization code. +*/ +SQLITE_PRIVATE int sqlite3ExprCodeExprList( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* The expression list to be coded */ + int target, /* Where to write results */ + u8 flags /* SQLITE_ECEL_* flags */ +){ + struct ExprList_item *pItem; + int i, n; + u8 copyOp = (flags & SQLITE_ECEL_DUP) ? OP_Copy : OP_SCopy; + assert( pList!=0 ); + assert( target>0 ); + assert( pParse->pVdbe!=0 ); /* Never gets this far otherwise */ + n = pList->nExpr; + if( !ConstFactorOk(pParse) ) flags &= ~SQLITE_ECEL_FACTOR; + for(pItem=pList->a, i=0; ipExpr; + if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){ + sqlite3ExprCodeAtInit(pParse, pExpr, target+i, 0); + }else{ + int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i); + if( inReg!=target+i ){ + VdbeOp *pOp; + Vdbe *v = pParse->pVdbe; + if( copyOp==OP_Copy + && (pOp=sqlite3VdbeGetOp(v, -1))->opcode==OP_Copy + && pOp->p1+pOp->p3+1==inReg + && pOp->p2+pOp->p3+1==target+i + ){ + pOp->p3++; + }else{ + sqlite3VdbeAddOp2(v, copyOp, inReg, target+i); + } + } + } + } + return n; +} + +/* +** Generate code for a BETWEEN operator. +** +** x BETWEEN y AND z +** +** The above is equivalent to +** +** x>=y AND x<=z +** +** Code it as such, taking care to do the common subexpression +** elimination of x. +*/ +static void exprCodeBetween( + Parse *pParse, /* Parsing and code generating context */ + Expr *pExpr, /* The BETWEEN expression */ + int dest, /* Jump here if the jump is taken */ + int jumpIfTrue, /* Take the jump if the BETWEEN is true */ + int jumpIfNull /* Take the jump if the BETWEEN is NULL */ +){ + Expr exprAnd; /* The AND operator in x>=y AND x<=z */ + Expr compLeft; /* The x>=y term */ + Expr compRight; /* The x<=z term */ + Expr exprX; /* The x subexpression */ + int regFree1 = 0; /* Temporary use register */ + + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + exprX = *pExpr->pLeft; + exprAnd.op = TK_AND; + exprAnd.pLeft = &compLeft; + exprAnd.pRight = &compRight; + compLeft.op = TK_GE; + compLeft.pLeft = &exprX; + compLeft.pRight = pExpr->x.pList->a[0].pExpr; + compRight.op = TK_LE; + compRight.pLeft = &exprX; + compRight.pRight = pExpr->x.pList->a[1].pExpr; + exprToRegister(&exprX, sqlite3ExprCodeTemp(pParse, &exprX, ®Free1)); + if( jumpIfTrue ){ + sqlite3ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull); + }else{ + sqlite3ExprIfFalse(pParse, &exprAnd, dest, jumpIfNull); + } + sqlite3ReleaseTempReg(pParse, regFree1); + + /* Ensure adequate test coverage */ + testcase( jumpIfTrue==0 && jumpIfNull==0 && regFree1==0 ); + testcase( jumpIfTrue==0 && jumpIfNull==0 && regFree1!=0 ); + testcase( jumpIfTrue==0 && jumpIfNull!=0 && regFree1==0 ); + testcase( jumpIfTrue==0 && jumpIfNull!=0 && regFree1!=0 ); + testcase( jumpIfTrue!=0 && jumpIfNull==0 && regFree1==0 ); + testcase( jumpIfTrue!=0 && jumpIfNull==0 && regFree1!=0 ); + testcase( jumpIfTrue!=0 && jumpIfNull!=0 && regFree1==0 ); + testcase( jumpIfTrue!=0 && jumpIfNull!=0 && regFree1!=0 ); +} + +/* +** Generate code for a boolean expression such that a jump is made +** to the label "dest" if the expression is true but execution +** continues straight thru if the expression is false. +** +** If the expression evaluates to NULL (neither true nor false), then +** take the jump if the jumpIfNull flag is SQLITE_JUMPIFNULL. +** +** 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. +*/ +SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ + Vdbe *v = pParse->pVdbe; + int op = 0; + int regFree1 = 0; + int regFree2 = 0; + int r1, r2; + + assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 ); + if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */ + if( NEVER(pExpr==0) ) return; /* No way this can happen */ + op = pExpr->op; + switch( op ){ + case TK_AND: { + int d2 = sqlite3VdbeMakeLabel(v); + testcase( jumpIfNull==0 ); + sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL); + sqlite3ExprCachePush(pParse); + sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); + sqlite3VdbeResolveLabel(v, d2); + sqlite3ExprCachePop(pParse); + break; + } + case TK_OR: { + testcase( jumpIfNull==0 ); + sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); + sqlite3ExprCachePush(pParse); + sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); + sqlite3ExprCachePop(pParse); + break; + } + case TK_NOT: { + testcase( jumpIfNull==0 ); + sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); + break; + } + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: + case TK_NE: + case TK_EQ: { + testcase( jumpIfNull==0 ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, dest, jumpIfNull); + assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); + assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); + assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); + assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); + assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); + assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } + case TK_IS: + case TK_ISNOT: { + testcase( op==TK_IS ); + testcase( op==TK_ISNOT ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + op = (op==TK_IS) ? TK_EQ : TK_NE; + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, dest, SQLITE_NULLEQ); + VdbeCoverageIf(v, op==TK_EQ); + VdbeCoverageIf(v, op==TK_NE); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } + case TK_ISNULL: + case TK_NOTNULL: { + assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL ); + assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + sqlite3VdbeAddOp2(v, op, r1, dest); + VdbeCoverageIf(v, op==TK_ISNULL); + VdbeCoverageIf(v, op==TK_NOTNULL); + testcase( regFree1==0 ); + break; + } + case TK_BETWEEN: { + testcase( jumpIfNull==0 ); + exprCodeBetween(pParse, pExpr, dest, 1, jumpIfNull); + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_IN: { + int destIfFalse = sqlite3VdbeMakeLabel(v); + int destIfNull = jumpIfNull ? dest : destIfFalse; + sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull); + sqlite3VdbeAddOp2(v, OP_Goto, 0, dest); + sqlite3VdbeResolveLabel(v, destIfFalse); + break; + } +#endif + default: { + if( exprAlwaysTrue(pExpr) ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, dest); + }else if( exprAlwaysFalse(pExpr) ){ + /* No-op */ + }else{ + r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); + sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0); + VdbeCoverage(v); + testcase( regFree1==0 ); + testcase( jumpIfNull==0 ); + } + break; + } + } + sqlite3ReleaseTempReg(pParse, regFree1); + sqlite3ReleaseTempReg(pParse, regFree2); +} + +/* +** 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 SQLITE_JUMPIFNULL or fall through if jumpIfNull +** is 0. +*/ +SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ + Vdbe *v = pParse->pVdbe; + int op = 0; + int regFree1 = 0; + int regFree2 = 0; + int r1, r2; + + assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 ); + if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */ + if( pExpr==0 ) return; + + /* The value of pExpr->op and op are related as follows: + ** + ** pExpr->op op + ** --------- ---------- + ** TK_ISNULL OP_NotNull + ** TK_NOTNULL OP_IsNull + ** TK_NE OP_Eq + ** TK_EQ OP_Ne + ** TK_GT OP_Le + ** TK_LE OP_Gt + ** TK_GE OP_Lt + ** TK_LT OP_Ge + ** + ** For other values of pExpr->op, op is undefined and unused. + ** The value of TK_ and OP_ constants are arranged such that we + ** can compute the mapping above using the following expression. + ** Assert()s verify that the computation is correct. + */ + op = ((pExpr->op+(TK_ISNULL&1))^1)-(TK_ISNULL&1); + + /* Verify correct alignment of TK_ and OP_ constants + */ + assert( pExpr->op!=TK_ISNULL || op==OP_NotNull ); + assert( pExpr->op!=TK_NOTNULL || op==OP_IsNull ); + assert( pExpr->op!=TK_NE || op==OP_Eq ); + assert( pExpr->op!=TK_EQ || op==OP_Ne ); + assert( pExpr->op!=TK_LT || op==OP_Ge ); + assert( pExpr->op!=TK_LE || op==OP_Gt ); + assert( pExpr->op!=TK_GT || op==OP_Le ); + assert( pExpr->op!=TK_GE || op==OP_Lt ); + + switch( pExpr->op ){ + case TK_AND: { + testcase( jumpIfNull==0 ); + sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); + sqlite3ExprCachePush(pParse); + sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); + sqlite3ExprCachePop(pParse); + break; + } + case TK_OR: { + int d2 = sqlite3VdbeMakeLabel(v); + testcase( jumpIfNull==0 ); + sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL); + sqlite3ExprCachePush(pParse); + sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); + sqlite3VdbeResolveLabel(v, d2); + sqlite3ExprCachePop(pParse); + break; + } + case TK_NOT: { + testcase( jumpIfNull==0 ); + sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); + break; + } + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: + case TK_NE: + case TK_EQ: { + testcase( jumpIfNull==0 ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, dest, jumpIfNull); + assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); + assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); + assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); + assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); + assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); + assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } + case TK_IS: + case TK_ISNOT: { + testcase( pExpr->op==TK_IS ); + testcase( pExpr->op==TK_ISNOT ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ; + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, dest, SQLITE_NULLEQ); + VdbeCoverageIf(v, op==TK_EQ); + VdbeCoverageIf(v, op==TK_NE); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } + case TK_ISNULL: + case TK_NOTNULL: { + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + sqlite3VdbeAddOp2(v, op, r1, dest); + testcase( op==TK_ISNULL ); VdbeCoverageIf(v, op==TK_ISNULL); + testcase( op==TK_NOTNULL ); VdbeCoverageIf(v, op==TK_NOTNULL); + testcase( regFree1==0 ); + break; + } + case TK_BETWEEN: { + testcase( jumpIfNull==0 ); + exprCodeBetween(pParse, pExpr, dest, 0, jumpIfNull); + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_IN: { + if( jumpIfNull ){ + sqlite3ExprCodeIN(pParse, pExpr, dest, dest); + }else{ + int destIfNull = sqlite3VdbeMakeLabel(v); + sqlite3ExprCodeIN(pParse, pExpr, dest, destIfNull); + sqlite3VdbeResolveLabel(v, destIfNull); + } + break; + } +#endif + default: { + if( exprAlwaysFalse(pExpr) ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, dest); + }else if( exprAlwaysTrue(pExpr) ){ + /* no-op */ + }else{ + r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); + sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0); + VdbeCoverage(v); + testcase( regFree1==0 ); + testcase( jumpIfNull==0 ); + } + break; + } + } + sqlite3ReleaseTempReg(pParse, regFree1); + sqlite3ReleaseTempReg(pParse, regFree2); +} + +/* +** Do a deep comparison of two expression trees. Return 0 if the two +** expressions are completely identical. Return 1 if they differ only +** by a COLLATE operator at the top level. Return 2 if there are differences +** other than the top-level COLLATE operator. +** +** If any subelement of pB has Expr.iTable==(-1) then it is allowed +** to compare equal to an equivalent element in pA with Expr.iTable==iTab. +** +** The pA side might be using TK_REGISTER. If that is the case and pB is +** not using TK_REGISTER but is otherwise equivalent, then still return 0. +** +** Sometimes this routine will return 2 even if the two expressions +** really are equivalent. If we cannot prove that the expressions are +** identical, we return 2 just to be safe. So if this routine +** returns 2, then you do not really know for certain if the two +** expressions are the same. But if you get a 0 or 1 return, then you +** can be sure the expressions are the same. In the places where +** this routine is used, it does not hurt to get an extra 2 - that +** just might result in some slightly slower code. But returning +** an incorrect 0 or 1 could lead to a malfunction. +*/ +SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){ + u32 combinedFlags; + if( pA==0 || pB==0 ){ + return pB==pA ? 0 : 2; + } + combinedFlags = pA->flags | pB->flags; + if( combinedFlags & EP_IntValue ){ + if( (pA->flags&pB->flags&EP_IntValue)!=0 && pA->u.iValue==pB->u.iValue ){ + return 0; + } + return 2; + } + if( pA->op!=pB->op ){ + if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB, iTab)<2 ){ + return 1; + } + if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft, iTab)<2 ){ + return 1; + } + return 2; + } + if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken ){ + if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){ + return pA->op==TK_COLLATE ? 1 : 2; + } + } + if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; + if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){ + if( combinedFlags & EP_xIsSelect ) return 2; + if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2; + if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2; + if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2; + if( ALWAYS((combinedFlags & EP_Reduced)==0) && pA->op!=TK_STRING ){ + if( pA->iColumn!=pB->iColumn ) return 2; + if( pA->iTable!=pB->iTable + && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2; + } + } + return 0; +} + +/* +** Compare two ExprList objects. Return 0 if they are identical and +** non-zero if they differ in any way. +** +** If any subelement of pB has Expr.iTable==(-1) then it is allowed +** to compare equal to an equivalent element in pA with Expr.iTable==iTab. +** +** This routine might return non-zero for equivalent ExprLists. The +** only consequence will be disabled optimizations. But this routine +** must never return 0 if the two ExprList objects are different, or +** a malfunction will result. +** +** Two NULL pointers are considered to be the same. But a NULL pointer +** always differs from a non-NULL pointer. +*/ +SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){ + int i; + if( pA==0 && pB==0 ) return 0; + if( pA==0 || pB==0 ) return 1; + if( pA->nExpr!=pB->nExpr ) return 1; + for(i=0; inExpr; i++){ + Expr *pExprA = pA->a[i].pExpr; + Expr *pExprB = pB->a[i].pExpr; + if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1; + if( sqlite3ExprCompare(pExprA, pExprB, iTab) ) return 1; + } + return 0; +} + +/* +** Return true if we can prove the pE2 will always be true if pE1 is +** true. Return false if we cannot complete the proof or if pE2 might +** be false. Examples: +** +** pE1: x==5 pE2: x==5 Result: true +** pE1: x>0 pE2: x==5 Result: false +** pE1: x=21 pE2: x=21 OR y=43 Result: true +** pE1: x!=123 pE2: x IS NOT NULL Result: true +** pE1: x!=?1 pE2: x IS NOT NULL Result: true +** pE1: x IS NULL pE2: x IS NOT NULL Result: false +** pE1: x IS ?2 pE2: x IS NOT NULL Reuslt: false +** +** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has +** Expr.iTable<0 then assume a table number given by iTab. +** +** When in doubt, return false. Returning true might give a performance +** improvement. Returning false might cause a performance reduction, but +** it will always give the correct answer and is hence always safe. +*/ +SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr *pE1, Expr *pE2, int iTab){ + if( sqlite3ExprCompare(pE1, pE2, iTab)==0 ){ + return 1; + } + if( pE2->op==TK_OR + && (sqlite3ExprImpliesExpr(pE1, pE2->pLeft, iTab) + || sqlite3ExprImpliesExpr(pE1, pE2->pRight, iTab) ) + ){ + return 1; + } + if( pE2->op==TK_NOTNULL + && sqlite3ExprCompare(pE1->pLeft, pE2->pLeft, iTab)==0 + && (pE1->op!=TK_ISNULL && pE1->op!=TK_IS) + ){ + return 1; + } + return 0; +} + +/* +** An instance of the following structure is used by the tree walker +** to count references to table columns in the arguments of an +** aggregate function, in order to implement the +** sqlite3FunctionThisSrc() routine. +*/ +struct SrcCount { + SrcList *pSrc; /* One particular FROM clause in a nested query */ + int nThis; /* Number of references to columns in pSrcList */ + int nOther; /* Number of references to columns in other FROM clauses */ +}; + +/* +** Count the number of references to columns. +*/ +static int exprSrcCount(Walker *pWalker, Expr *pExpr){ + /* The NEVER() on the second term is because sqlite3FunctionUsesThisSrc() + ** is always called before sqlite3ExprAnalyzeAggregates() and so the + ** TK_COLUMNs have not yet been converted into TK_AGG_COLUMN. If + ** sqlite3FunctionUsesThisSrc() is used differently in the future, the + ** NEVER() will need to be removed. */ + if( pExpr->op==TK_COLUMN || NEVER(pExpr->op==TK_AGG_COLUMN) ){ + int i; + struct SrcCount *p = pWalker->u.pSrcCount; + SrcList *pSrc = p->pSrc; + int nSrc = pSrc ? pSrc->nSrc : 0; + for(i=0; iiTable==pSrc->a[i].iCursor ) break; + } + if( inThis++; + }else{ + p->nOther++; + } + } + return WRC_Continue; +} + +/* +** Determine if any of the arguments to the pExpr Function reference +** pSrcList. Return true if they do. Also return true if the function +** has no arguments or has only constant arguments. Return false if pExpr +** references columns but not columns of tables found in pSrcList. +*/ +SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){ + Walker w; + struct SrcCount cnt; + assert( pExpr->op==TK_AGG_FUNCTION ); + memset(&w, 0, sizeof(w)); + w.xExprCallback = exprSrcCount; + w.u.pSrcCount = &cnt; + cnt.pSrc = pSrcList; + cnt.nThis = 0; + cnt.nOther = 0; + sqlite3WalkExprList(&w, pExpr->x.pList); + return cnt.nThis>0 || cnt.nOther==0; +} + +/* +** 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(sqlite3 *db, AggInfo *pInfo){ + int i; + pInfo->aCol = sqlite3ArrayAllocate( + db, + pInfo->aCol, + sizeof(pInfo->aCol[0]), + &pInfo->nColumn, + &i + ); + 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(sqlite3 *db, AggInfo *pInfo){ + int i; + pInfo->aFunc = sqlite3ArrayAllocate( + db, + pInfo->aFunc, + sizeof(pInfo->aFunc[0]), + &pInfo->nFunc, + &i + ); + return i; +} + +/* +** This is the xExprCallback for a tree walker. It is used to +** implement sqlite3ExprAnalyzeAggregates(). See sqlite3ExprAnalyzeAggregates +** for additional information. +*/ +static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ + int i; + NameContext *pNC = pWalker->u.pNC; + Parse *pParse = pNC->pParse; + SrcList *pSrcList = pNC->pSrcList; + AggInfo *pAggInfo = pNC->pAggInfo; + + switch( pExpr->op ){ + case TK_AGG_COLUMN: + case TK_COLUMN: { + testcase( pExpr->op==TK_AGG_COLUMN ); + testcase( pExpr->op==TK_COLUMN ); + /* Check to see if the column is in one of the tables in the FROM + ** clause of the aggregate query */ + if( ALWAYS(pSrcList!=0) ){ + struct SrcList_item *pItem = pSrcList->a; + for(i=0; inSrc; i++, pItem++){ + struct AggInfo_col *pCol; + assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); + 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. + */ + int k; + pCol = pAggInfo->aCol; + for(k=0; knColumn; k++, pCol++){ + if( pCol->iTable==pExpr->iTable && + pCol->iColumn==pExpr->iColumn ){ + break; + } + } + if( (k>=pAggInfo->nColumn) + && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0 + ){ + pCol = &pAggInfo->aCol[k]; + pCol->pTab = pExpr->pTab; + 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; jpExpr; + 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. + */ + ExprSetVVAProperty(pExpr, EP_NoReduce); + pExpr->pAggInfo = pAggInfo; + pExpr->op = TK_AGG_COLUMN; + pExpr->iAgg = (i16)k; + break; + } /* endif pExpr->iTable==pItem->iCursor */ + } /* end loop over pSrcList */ + } + return WRC_Prune; + } + case TK_AGG_FUNCTION: { + if( (pNC->ncFlags & NC_InAggFunc)==0 + && pWalker->walkerDepth==pExpr->op2 + ){ + /* 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; inFunc; i++, pItem++){ + if( sqlite3ExprCompare(pItem->pExpr, pExpr, -1)==0 ){ + break; + } + } + if( i>=pAggInfo->nFunc ){ + /* pExpr is original. Make a new entry in pAggInfo->aFunc[] + */ + u8 enc = ENC(pParse->db); + i = addAggInfoFunc(pParse->db, pAggInfo); + if( i>=0 ){ + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + pItem = &pAggInfo->aFunc[i]; + pItem->pExpr = pExpr; + pItem->iMem = ++pParse->nMem; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + pItem->pFunc = sqlite3FindFunction(pParse->db, + pExpr->u.zToken, sqlite3Strlen30(pExpr->u.zToken), + pExpr->x.pList ? pExpr->x.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 + */ + assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); + ExprSetVVAProperty(pExpr, EP_NoReduce); + pExpr->iAgg = (i16)i; + pExpr->pAggInfo = pAggInfo; + return WRC_Prune; + }else{ + return WRC_Continue; + } + } + } + return WRC_Continue; +} +static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){ + UNUSED_PARAMETER(pWalker); + UNUSED_PARAMETER(pSelect); + return WRC_Continue; +} + +/* +** Analyze the pExpr expression looking for aggregate functions and +** for variables that need to be added to AggInfo object that pNC->pAggInfo +** points to. Additional entries are made on the AggInfo object as +** necessary. +** +** This routine should only be called after the expression has been +** analyzed by sqlite3ResolveExprNames(). +*/ +SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){ + Walker w; + memset(&w, 0, sizeof(w)); + w.xExprCallback = analyzeAggregate; + w.xSelectCallback = analyzeAggregatesInSelect; + w.u.pNC = pNC; + assert( pNC->pSrcList!=0 ); + sqlite3WalkExpr(&w, pExpr); +} + +/* +** Call sqlite3ExprAnalyzeAggregates() for every expression in an +** expression list. Return the number of errors. +** +** If an error is found, the analysis is cut short. +*/ +SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext *pNC, ExprList *pList){ + struct ExprList_item *pItem; + int i; + if( pList ){ + for(pItem=pList->a, i=0; inExpr; i++, pItem++){ + sqlite3ExprAnalyzeAggregates(pNC, pItem->pExpr); + } + } +} + +/* +** Allocate a single new register for use to hold some intermediate result. +*/ +SQLITE_PRIVATE int sqlite3GetTempReg(Parse *pParse){ + if( pParse->nTempReg==0 ){ + return ++pParse->nMem; + } + return pParse->aTempReg[--pParse->nTempReg]; +} + +/* +** Deallocate a register, making available for reuse for some other +** purpose. +** +** If a register is currently being used by the column cache, then +** the deallocation is deferred until the column cache line that uses +** the register becomes stale. +*/ +SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){ + if( iReg && pParse->nTempRegaTempReg) ){ + int i; + struct yColCache *p; + for(i=0, p=pParse->aColCache; iiReg==iReg ){ + p->tempReg = 1; + return; + } + } + pParse->aTempReg[pParse->nTempReg++] = iReg; + } +} + +/* +** Allocate or deallocate a block of nReg consecutive registers +*/ +SQLITE_PRIVATE int sqlite3GetTempRange(Parse *pParse, int nReg){ + int i, n; + i = pParse->iRangeReg; + n = pParse->nRangeReg; + if( nReg<=n ){ + assert( !usedAsColumnCache(pParse, i, i+n-1) ); + pParse->iRangeReg += nReg; + pParse->nRangeReg -= nReg; + }else{ + i = pParse->nMem+1; + pParse->nMem += nReg; + } + return i; +} +SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){ + sqlite3ExprCacheRemove(pParse, iReg, nReg); + if( nReg>pParse->nRangeReg ){ + pParse->nRangeReg = nReg; + pParse->iRangeReg = iReg; + } +} + +/* +** Mark all temporary registers as being unavailable for reuse. +*/ +SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse *pParse){ + pParse->nTempReg = 0; + pParse->nRangeReg = 0; +} + +/************** End of expr.c ************************************************/ +/************** Begin file alter.c *******************************************/ +/* +** 2005 February 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. +** +************************************************************************* +** This file contains C code routines that used to generate VDBE code +** that implements the ALTER TABLE command. +*/ + +/* +** The code in this file only exists if we are not omitting the +** ALTER TABLE logic from the build. +*/ +#ifndef SQLITE_OMIT_ALTERTABLE + + +/* +** This function is used by SQL generated to implement the +** ALTER TABLE command. The first argument is the text of a CREATE TABLE or +** CREATE INDEX command. The second is a table name. The table name in +** the CREATE TABLE or CREATE INDEX statement is replaced with the third +** argument and the result returned. Examples: +** +** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def') +** -> 'CREATE TABLE def(a, b, c)' +** +** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def') +** -> 'CREATE INDEX i ON def(a, b, c)' +*/ +static void renameTableFunc( + sqlite3_context *context, + int NotUsed, + 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; + + sqlite3 *db = sqlite3_context_db_handle(context); + + UNUSED_PARAMETER(NotUsed); + + /* The principle used to locate the table name in the CREATE TABLE + ** statement is that the table name is the first non-space token that + ** is immediately followed by a TK_LP or TK_USING token. + */ + if( zSql ){ + do { + if( !*zCsr ){ + /* Ran out of input before finding an opening bracket. Return NULL. */ + return; + } + + /* Store the token that zCsr points to in tname. */ + tname.z = (char*)zCsr; + tname.n = len; + + /* Advance zCsr to the next token. Store that token type in 'token', + ** and its length in 'len' (to be used next iteration of this loop). + */ + do { + zCsr += len; + len = sqlite3GetToken(zCsr, &token); + } while( token==TK_SPACE ); + assert( len>0 ); + } while( token!=TK_LP && token!=TK_USING ); + + zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql), + zSql, zTableName, tname.z+tname.n); + sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC); + } +} + +/* +** This C function implements an SQL user function that is used by SQL code +** generated by the ALTER TABLE ... RENAME command to modify the definition +** of any foreign key constraints that use the table being renamed as the +** parent table. It is passed three arguments: +** +** 1) The complete text of the CREATE TABLE statement being modified, +** 2) The old name of the table being renamed, and +** 3) The new name of the table being renamed. +** +** It returns the new CREATE TABLE statement. For example: +** +** sqlite_rename_parent('CREATE TABLE t1(a REFERENCES t2)', 't2', 't3') +** -> 'CREATE TABLE t1(a REFERENCES t3)' +*/ +#ifndef SQLITE_OMIT_FOREIGN_KEY +static void renameParentFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + char *zOutput = 0; + char *zResult; + unsigned char const *zInput = sqlite3_value_text(argv[0]); + unsigned char const *zOld = sqlite3_value_text(argv[1]); + unsigned char const *zNew = sqlite3_value_text(argv[2]); + + unsigned const char *z; /* Pointer to token */ + int n; /* Length of token z */ + int token; /* Type of token */ + + UNUSED_PARAMETER(NotUsed); + if( zInput==0 || zOld==0 ) return; + for(z=zInput; *z; z=z+n){ + n = sqlite3GetToken(z, &token); + if( token==TK_REFERENCES ){ + char *zParent; + do { + z += n; + n = sqlite3GetToken(z, &token); + }while( token==TK_SPACE ); + + if( token==TK_ILLEGAL ) break; + zParent = sqlite3DbStrNDup(db, (const char *)z, n); + if( zParent==0 ) break; + sqlite3Dequote(zParent); + if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){ + char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"", + (zOutput?zOutput:""), (int)(z-zInput), zInput, (const char *)zNew + ); + sqlite3DbFree(db, zOutput); + zOutput = zOut; + zInput = &z[n]; + } + sqlite3DbFree(db, zParent); + } + } + + zResult = sqlite3MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput), + sqlite3_result_text(context, zResult, -1, SQLITE_DYNAMIC); + sqlite3DbFree(db, zOutput); +} +#endif + +#ifndef SQLITE_OMIT_TRIGGER +/* This function is used by SQL generated to implement the +** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER +** statement. The second is a table name. The table name in the CREATE +** TRIGGER statement is replaced with the third argument and the result +** returned. This is analagous to renameTableFunc() above, except for CREATE +** TRIGGER, not CREATE INDEX and CREATE TABLE. +*/ +static void renameTriggerFunc( + sqlite3_context *context, + int NotUsed, + 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; + int dist = 3; + unsigned char const *zCsr = zSql; + int len = 0; + char *zRet; + sqlite3 *db = sqlite3_context_db_handle(context); + + UNUSED_PARAMETER(NotUsed); + + /* The principle used to locate the table name in the CREATE TRIGGER + ** statement is that the table name is the first token that is immediately + ** preceded by either TK_ON or TK_DOT and immediately followed by one + ** of TK_WHEN, TK_BEGIN or TK_FOR. + */ + if( zSql ){ + do { + + if( !*zCsr ){ + /* Ran out of input before finding the table name. Return NULL. */ + return; + } + + /* Store the token that zCsr points to in tname. */ + tname.z = (char*)zCsr; + tname.n = len; + + /* Advance zCsr to the next token. Store that token type in 'token', + ** and its length in 'len' (to be used next iteration of this loop). + */ + do { + zCsr += len; + len = sqlite3GetToken(zCsr, &token); + }while( token==TK_SPACE ); + assert( len>0 ); + + /* Variable 'dist' stores the number of tokens read since the most + ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN + ** token is read and 'dist' equals 2, the condition stated above + ** to be met. + ** + ** Note that ON cannot be a database, table or column name, so + ** there is no need to worry about syntax like + ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc. + */ + dist++; + if( token==TK_DOT || token==TK_ON ){ + dist = 0; + } + } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) ); + + /* Variable tname now contains the token that is the old table-name + ** in the CREATE TRIGGER statement. + */ + zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql), + zSql, zTableName, tname.z+tname.n); + sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC); + } +} +#endif /* !SQLITE_OMIT_TRIGGER */ + +/* +** Register built-in functions used to help implement ALTER TABLE +*/ +SQLITE_PRIVATE void sqlite3AlterFunctions(void){ + static SQLITE_WSD FuncDef aAlterTableFuncs[] = { + FUNCTION(sqlite_rename_table, 2, 0, 0, renameTableFunc), +#ifndef SQLITE_OMIT_TRIGGER + FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc), +#endif +#ifndef SQLITE_OMIT_FOREIGN_KEY + FUNCTION(sqlite_rename_parent, 3, 0, 0, renameParentFunc), +#endif + }; + int i; + FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions); + FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAlterTableFuncs); + + for(i=0; i OR name= OR ... +** +** If argument zWhere is NULL, then a pointer string containing the text +** "name=" is returned, where is the quoted version +** of the string passed as argument zConstant. The returned buffer is +** allocated using sqlite3DbMalloc(). It is the responsibility of the +** caller to ensure that it is eventually freed. +** +** If argument zWhere is not NULL, then the string returned is +** " OR name=", where is the contents of zWhere. +** In this case zWhere is passed to sqlite3DbFree() before returning. +** +*/ +static char *whereOrName(sqlite3 *db, char *zWhere, char *zConstant){ + char *zNew; + if( !zWhere ){ + zNew = sqlite3MPrintf(db, "name=%Q", zConstant); + }else{ + zNew = sqlite3MPrintf(db, "%s OR name=%Q", zWhere, zConstant); + sqlite3DbFree(db, zWhere); + } + return zNew; +} + +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) +/* +** Generate the text of a WHERE expression which can be used to select all +** tables that have foreign key constraints that refer to table pTab (i.e. +** constraints for which pTab is the parent table) from the sqlite_master +** table. +*/ +static char *whereForeignKeys(Parse *pParse, Table *pTab){ + FKey *p; + char *zWhere = 0; + for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ + zWhere = whereOrName(pParse->db, zWhere, p->pFrom->zName); + } + return zWhere; +} +#endif + +/* +** 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; + 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 ){ + sqlite3 *db = pParse->db; + for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){ + if( pTrig->pSchema==pTempSchema ){ + zWhere = whereOrName(db, zWhere, pTrig->zName); + } + } + } + if( zWhere ){ + char *zNew = sqlite3MPrintf(pParse->db, "type='trigger' AND (%s)", zWhere); + sqlite3DbFree(pParse->db, zWhere); + zWhere = zNew; + } + 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( NEVER(v==0) ) return; + assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); + iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + assert( iDb>=0 ); + +#ifndef SQLITE_OMIT_TRIGGER + /* Drop any table triggers from the internal schema. */ + for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){ + int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema); + assert( iTrigDb==iDb || iTrigDb==1 ); + sqlite3VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->zName, 0); + } +#endif + + /* Drop the table and index from the internal schema. */ + sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0); + + /* Reload the table, index and permanent trigger schemas. */ + zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName); + if( !zWhere ) return; + sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere); + +#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 ){ + sqlite3VdbeAddParseSchemaOp(v, 1, zWhere); + } +#endif +} + +/* +** Parameter zName is the name of a table that is about to be altered +** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN). +** If the table is a system table, this function leaves an error message +** in pParse->zErr (system tables may not be altered) and returns non-zero. +** +** Or, if zName is not a system table, zero is returned. +*/ +static int isSystemTable(Parse *pParse, const char *zName){ + if( sqlite3Strlen30(zName)>6 && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){ + sqlite3ErrorMsg(pParse, "table %s may not be altered", zName); + return 1; + } + return 0; +} + +/* +** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" +** command. +*/ +SQLITE_PRIVATE 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 */ + int nTabName; /* Number of UTF-8 characters in zTabName */ + const char *zTabName; /* Original name of the table */ + Vdbe *v; +#ifndef SQLITE_OMIT_TRIGGER + char *zWhere = 0; /* Where clause to locate temp triggers */ +#endif + VTable *pVTab = 0; /* Non-zero if this is a v-tab with an xRename() */ + int savedDbFlags; /* Saved value of db->flags */ + + savedDbFlags = db->flags; + if( NEVER(db->mallocFailed) ) goto exit_rename_table; + assert( pSrc->nSrc==1 ); + assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); + + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + if( !pTab ) goto exit_rename_table; + iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + zDb = db->aDb[iDb].zName; + db->flags |= SQLITE_PreferBuiltin; + + /* Get a NULL terminated version of the new table name. */ + zName = sqlite3NameFromToken(db, pName); + if( !zName ) goto exit_rename_table; + + /* Check that a table or index named 'zName' does not already exist + ** in database iDb. If so, this is an error. + */ + if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){ + sqlite3ErrorMsg(pParse, + "there is already another table or index with this name: %s", zName); + goto exit_rename_table; + } + + /* Make sure it is not a system table being altered, or a reserved name + ** that the table is being renamed to. + */ + if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){ + goto exit_rename_table; + } + if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto + exit_rename_table; + } + +#ifndef SQLITE_OMIT_VIEW + if( pTab->pSelect ){ + sqlite3ErrorMsg(pParse, "view %s may not be altered", pTab->zName); + goto exit_rename_table; + } +#endif + +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Invoke the authorization callback. */ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ + goto exit_rename_table; + } +#endif + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto exit_rename_table; + } + if( IsVirtual(pTab) ){ + pVTab = sqlite3GetVTable(db, pTab); + if( pVTab->pVtab->pModule->xRename==0 ){ + pVTab = 0; + } + } +#endif + + /* Begin a transaction for database iDb. + ** Then modify the schema cookie (since the ALTER TABLE modifies the + ** schema). Open a statement transaction if the table is a virtual + ** table. + */ + v = sqlite3GetVdbe(pParse); + if( v==0 ){ + goto exit_rename_table; + } + sqlite3BeginWriteOperation(pParse, pVTab!=0, iDb); + sqlite3ChangeCookie(pParse, iDb); + + /* If this is a virtual table, invoke the xRename() function if + ** one is defined. The xRename() callback will modify the names + ** of any resources used by the v-table implementation (including other + ** SQLite tables) that are identified by the name of the virtual table. + */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( pVTab ){ + int i = ++pParse->nMem; + sqlite3VdbeAddOp4(v, OP_String8, 0, i, 0, zName, 0); + sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB); + sqlite3MayAbort(pParse); + } +#endif + + /* figure out how many UTF-8 characters are in zName */ + zTabName = pTab->zName; + nTabName = sqlite3Utf8CharLen(zTabName, -1); + +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + if( db->flags&SQLITE_ForeignKeys ){ + /* If foreign-key support is enabled, rewrite the CREATE TABLE + ** statements corresponding to all child tables of foreign key constraints + ** for which the renamed table is the parent table. */ + if( (zWhere=whereForeignKeys(pParse, pTab))!=0 ){ + sqlite3NestedParse(pParse, + "UPDATE \"%w\".%s SET " + "sql = sqlite_rename_parent(sql, %Q, %Q) " + "WHERE %s;", zDb, SCHEMA_TABLE(iDb), zTabName, zName, zWhere); + sqlite3DbFree(db, zWhere); + } + } +#endif + + /* Modify the sqlite_master table to use the new table name. */ + sqlite3NestedParse(pParse, + "UPDATE %Q.%s SET " +#ifdef SQLITE_OMIT_TRIGGER + "sql = sqlite_rename_table(sql, %Q), " +#else + "sql = CASE " + "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)" + "ELSE sqlite_rename_table(sql, %Q) END, " +#endif + "tbl_name = %Q, " + "name = CASE " + "WHEN type='table' THEN %Q " + "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN " + "'sqlite_autoindex_' || %Q || substr(name,%d+18) " + "ELSE name END " + "WHERE tbl_name=%Q COLLATE nocase AND " + "(type='table' OR type='index' OR type='trigger');", + zDb, SCHEMA_TABLE(iDb), zName, zName, zName, +#ifndef SQLITE_OMIT_TRIGGER + zName, +#endif + zName, nTabName, zTabName + ); + +#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 \"%w\".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); + sqlite3DbFree(db, zWhere); + } +#endif + +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + if( db->flags&SQLITE_ForeignKeys ){ + FKey *p; + for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ + Table *pFrom = p->pFrom; + if( pFrom!=pTab ){ + reloadTableSchema(pParse, p->pFrom, pFrom->zName); + } + } + } +#endif + + /* Drop and reload the internal table schema. */ + reloadTableSchema(pParse, pTab, zName); + +exit_rename_table: + sqlite3SrcListDelete(db, pSrc); + sqlite3DbFree(db, zName); + db->flags = savedDbFlags; +} + + +/* +** Generate code to make sure the file format number is at least minFormat. +** The generated code will increase the file format number if necessary. +*/ +SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){ + Vdbe *v; + v = sqlite3GetVdbe(pParse); + /* The VDBE should have been allocated before this routine is called. + ** If that allocation failed, we would have quit before reaching this + ** point */ + if( ALWAYS(v) ){ + int r1 = sqlite3GetTempReg(pParse); + int r2 = sqlite3GetTempReg(pParse); + int j1; + sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT); + sqlite3VdbeUsesBtree(v, iDb); + sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2); + j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2); + sqlite3VdbeJumpHere(v, j1); + sqlite3ReleaseTempReg(pParse, r1); + sqlite3ReleaseTempReg(pParse, r2); + } +} + +/* +** 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. +*/ +SQLITE_PRIVATE 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 */ + sqlite3 *db; /* The database connection; */ + + db = pParse->db; + if( pParse->nErr || db->mallocFailed ) return; + pNew = pParse->pNewTable; + assert( pNew ); + + assert( sqlite3BtreeHoldsAllMutexes(db) ); + iDb = sqlite3SchemaToIndex(db, pNew->pSchema); + zDb = db->aDb[iDb].zName; + zTab = &pNew->zName[16]; /* Skip the "sqlite_altertab_" prefix on the name */ + pCol = &pNew->aCol[pNew->nCol-1]; + pDflt = pCol->pDflt; + pTab = sqlite3FindTable(db, zTab, zDb); + assert( pTab ); + +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Invoke the authorization callback. */ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ + return; + } +#endif + + /* 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->colFlags & COLFLAG_PRIMKEY ){ + sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column"); + return; + } + if( pNew->pIndex ){ + sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column"); + return; + } + if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){ + sqlite3ErrorMsg(pParse, + "Cannot add a REFERENCES column with non-NULL default value"); + 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 = 0; + int rc; + rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal); + assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); + if( rc!=SQLITE_OK ){ + db->mallocFailed = 1; + return; + } + if( !pVal ){ + sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default"); + return; + } + sqlite3ValueFree(pVal); + } + + /* Modify the CREATE TABLE statement. */ + zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n); + if( zCol ){ + char *zEnd = &zCol[pColDef->n-1]; + int savedDbFlags = db->flags; + while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){ + *zEnd-- = '\0'; + } + db->flags |= SQLITE_PreferBuiltin; + sqlite3NestedParse(pParse, + "UPDATE \"%w\".%s SET " + "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) " + "WHERE type = 'table' AND name = %Q", + zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1, + zTab + ); + sqlite3DbFree(db, zCol); + db->flags = savedDbFlags; + } + + /* 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 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. +*/ +SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ + Table *pNew; + Table *pTab; + Vdbe *v; + int iDb; + int i; + int nAlloc; + sqlite3 *db = pParse->db; + + /* Look up the table being altered. */ + assert( pParse->pNewTable==0 ); + assert( sqlite3BtreeHoldsAllMutexes(db) ); + if( db->mallocFailed ) goto exit_begin_add_column; + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + if( !pTab ) goto exit_begin_add_column; + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + sqlite3ErrorMsg(pParse, "virtual tables may not be altered"); + goto exit_begin_add_column; + } +#endif + + /* 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; + } + if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){ + goto exit_begin_add_column; + } + + assert( pTab->addColOffset>0 ); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + + /* Put a copy of the Table struct in Parse.pNewTable for the + ** sqlite3AddColumn() function and friends to modify. But modify + ** the name by adding an "sqlite_altertab_" prefix. By adding this + ** prefix, we insure that the name will not collide with an existing + ** table because user table are not allowed to have the "sqlite_" + ** prefix on their name. + */ + pNew = (Table*)sqlite3DbMallocZero(db, 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*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc); + pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName); + if( !pNew->aCol || !pNew->zName ){ + db->mallocFailed = 1; + goto exit_begin_add_column; + } + memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol); + for(i=0; inCol; i++){ + Column *pCol = &pNew->aCol[i]; + pCol->zName = sqlite3DbStrDup(db, pCol->zName); + pCol->zColl = 0; + pCol->zType = 0; + pCol->pDflt = 0; + pCol->zDflt = 0; + } + pNew->pSchema = 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, iDb); + +exit_begin_add_column: + sqlite3SrcListDelete(db, pSrc); + return; +} +#endif /* SQLITE_ALTER_TABLE */ + +/************** End of alter.c ***********************************************/ +/************** Begin file analyze.c *****************************************/ +/* +** 2005-07-08 +** +** 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. +** +** The ANALYZE command gather statistics about the content of tables +** and indices. These statistics are made available to the query planner +** to help it make better decisions about how to perform queries. +** +** The following system tables are or have been supported: +** +** CREATE TABLE sqlite_stat1(tbl, idx, stat); +** CREATE TABLE sqlite_stat2(tbl, idx, sampleno, sample); +** CREATE TABLE sqlite_stat3(tbl, idx, nEq, nLt, nDLt, sample); +** CREATE TABLE sqlite_stat4(tbl, idx, nEq, nLt, nDLt, sample); +** +** Additional tables might be added in future releases of SQLite. +** The sqlite_stat2 table is not created or used unless the SQLite version +** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled +** with SQLITE_ENABLE_STAT2. The sqlite_stat2 table is deprecated. +** The sqlite_stat2 table is superseded by sqlite_stat3, which is only +** created and used by SQLite versions 3.7.9 and later and with +** SQLITE_ENABLE_STAT3 defined. The functionality of sqlite_stat3 +** is a superset of sqlite_stat2. The sqlite_stat4 is an enhanced +** version of sqlite_stat3 and is only available when compiled with +** SQLITE_ENABLE_STAT4 and in SQLite versions 3.8.1 and later. It is +** not possible to enable both STAT3 and STAT4 at the same time. If they +** are both enabled, then STAT4 takes precedence. +** +** For most applications, sqlite_stat1 provides all the statistics required +** for the query planner to make good choices. +** +** Format of sqlite_stat1: +** +** There is normally one row per index, with the index identified by the +** name in the idx column. The tbl column is the name of the table to +** which the index belongs. In each such row, the stat column will be +** a string consisting of a list of integers. The first integer in this +** list is the number of rows in the index. (This is the same as the +** number of rows in the table, except for partial indices.) The second +** integer is the average number of rows in the index that have the same +** value in the first column of the index. The third integer is the average +** number of rows in the index that have the same value for the first two +** columns. The N-th integer (for N>1) is the average number of rows in +** the index which have the same value for the first N-1 columns. For +** a K-column index, there will be K+1 integers in the stat column. If +** the index is unique, then the last integer will be 1. +** +** The list of integers in the stat column can optionally be followed +** by the keyword "unordered". The "unordered" keyword, if it is present, +** must be separated from the last integer by a single space. If the +** "unordered" keyword is present, then the query planner assumes that +** the index is unordered and will not use the index for a range query. +** +** If the sqlite_stat1.idx column is NULL, then the sqlite_stat1.stat +** column contains a single integer which is the (estimated) number of +** rows in the table identified by sqlite_stat1.tbl. +** +** Format of sqlite_stat2: +** +** The sqlite_stat2 is only created and is only used if SQLite is compiled +** with SQLITE_ENABLE_STAT2 and if the SQLite version number is between +** 3.6.18 and 3.7.8. The "stat2" table contains additional information +** about the distribution of keys within an index. The index is identified by +** the "idx" column and the "tbl" column is the name of the table to which +** the index belongs. There are usually 10 rows in the sqlite_stat2 +** table for each index. +** +** The sqlite_stat2 entries for an index that have sampleno between 0 and 9 +** inclusive are samples of the left-most key value in the index taken at +** evenly spaced points along the index. Let the number of samples be S +** (10 in the standard build) and let C be the number of rows in the index. +** Then the sampled rows are given by: +** +** rownumber = (i*C*2 + C)/(S*2) +** +** For i between 0 and S-1. Conceptually, the index space is divided into +** S uniform buckets and the samples are the middle row from each bucket. +** +** The format for sqlite_stat2 is recorded here for legacy reference. This +** version of SQLite does not support sqlite_stat2. It neither reads nor +** writes the sqlite_stat2 table. This version of SQLite only supports +** sqlite_stat3. +** +** Format for sqlite_stat3: +** +** The sqlite_stat3 format is a subset of sqlite_stat4. Hence, the +** sqlite_stat4 format will be described first. Further information +** about sqlite_stat3 follows the sqlite_stat4 description. +** +** Format for sqlite_stat4: +** +** As with sqlite_stat2, the sqlite_stat4 table contains histogram data +** to aid the query planner in choosing good indices based on the values +** that indexed columns are compared against in the WHERE clauses of +** queries. +** +** The sqlite_stat4 table contains multiple entries for each index. +** The idx column names the index and the tbl column is the table of the +** index. If the idx and tbl columns are the same, then the sample is +** of the INTEGER PRIMARY KEY. The sample column is a blob which is the +** binary encoding of a key from the index. The nEq column is a +** list of integers. The first integer is the approximate number +** of entries in the index whose left-most column exactly matches +** the left-most column of the sample. The second integer in nEq +** is the approximate number of entries in the index where the +** first two columns match the first two columns of the sample. +** And so forth. nLt is another list of integers that show the approximate +** number of entries that are strictly less than the sample. The first +** integer in nLt contains the number of entries in the index where the +** left-most column is less than the left-most column of the sample. +** The K-th integer in the nLt entry is the number of index entries +** where the first K columns are less than the first K columns of the +** sample. The nDLt column is like nLt except that it contains the +** number of distinct entries in the index that are less than the +** sample. +** +** There can be an arbitrary number of sqlite_stat4 entries per index. +** The ANALYZE command will typically generate sqlite_stat4 tables +** that contain between 10 and 40 samples which are distributed across +** the key space, though not uniformly, and which include samples with +** large nEq values. +** +** Format for sqlite_stat3 redux: +** +** The sqlite_stat3 table is like sqlite_stat4 except that it only +** looks at the left-most column of the index. The sqlite_stat3.sample +** column contains the actual value of the left-most column instead +** of a blob encoding of the complete index key as is found in +** sqlite_stat4.sample. The nEq, nLt, and nDLt entries of sqlite_stat3 +** all contain just a single integer which is the same as the first +** integer in the equivalent columns in sqlite_stat4. +*/ +#ifndef SQLITE_OMIT_ANALYZE + +#if defined(SQLITE_ENABLE_STAT4) +# define IsStat4 1 +# define IsStat3 0 +#elif defined(SQLITE_ENABLE_STAT3) +# define IsStat4 0 +# define IsStat3 1 +#else +# define IsStat4 0 +# define IsStat3 0 +# undef SQLITE_STAT4_SAMPLES +# define SQLITE_STAT4_SAMPLES 1 +#endif +#define IsStat34 (IsStat3+IsStat4) /* 1 for STAT3 or STAT4. 0 otherwise */ + +/* +** This routine generates code that opens the sqlite_statN tables. +** The sqlite_stat1 table is always relevant. sqlite_stat2 is now +** obsolete. sqlite_stat3 and sqlite_stat4 are only opened when +** appropriate compile-time options are provided. +** +** If the sqlite_statN tables do not previously exist, it is created. +** +** Argument zWhere may be a pointer to a buffer containing a table name, +** or it may be a NULL pointer. If it is not NULL, then all entries in +** the sqlite_statN tables associated with the named table are deleted. +** If zWhere==0, then code is generated to delete all stat table entries. +*/ +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 for this table or index */ + const char *zWhereType /* Either "tbl" or "idx" */ +){ + static const struct { + const char *zName; + const char *zCols; + } aTable[] = { + { "sqlite_stat1", "tbl,idx,stat" }, +#if defined(SQLITE_ENABLE_STAT4) + { "sqlite_stat4", "tbl,idx,neq,nlt,ndlt,sample" }, + { "sqlite_stat3", 0 }, +#elif defined(SQLITE_ENABLE_STAT3) + { "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" }, + { "sqlite_stat4", 0 }, +#else + { "sqlite_stat3", 0 }, + { "sqlite_stat4", 0 }, +#endif + }; + int i; + sqlite3 *db = pParse->db; + Db *pDb; + Vdbe *v = sqlite3GetVdbe(pParse); + int aRoot[ArraySize(aTable)]; + u8 aCreateTbl[ArraySize(aTable)]; + + if( v==0 ) return; + assert( sqlite3BtreeHoldsAllMutexes(db) ); + assert( sqlite3VdbeDb(v)==db ); + pDb = &db->aDb[iDb]; + + /* Create new statistic tables if they do not exist, or clear them + ** if they do already exist. + */ + for(i=0; izName))==0 ){ + if( aTable[i].zCols ){ + /* The sqlite_statN table does not exist. Create it. Note that a + ** side-effect of the CREATE TABLE statement is to leave the rootpage + ** of the new table in register pParse->regRoot. This is important + ** because the OpenWrite opcode below will be needing it. */ + sqlite3NestedParse(pParse, + "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols + ); + aRoot[i] = pParse->regRoot; + aCreateTbl[i] = OPFLAG_P2ISREG; + } + }else{ + /* The table already exists. If zWhere is not NULL, delete all entries + ** associated with the table zWhere. If zWhere is NULL, delete the + ** entire contents of the table. */ + aRoot[i] = pStat->tnum; + aCreateTbl[i] = 0; + sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab); + if( zWhere ){ + sqlite3NestedParse(pParse, + "DELETE FROM %Q.%s WHERE %s=%Q", + pDb->zName, zTab, zWhereType, zWhere + ); + }else{ + /* The sqlite_stat[134] table already exists. Delete all rows. */ + sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb); + } + } + } + + /* Open the sqlite_stat[134] tables for writing. */ + for(i=0; aTable[i].zCols; i++){ + assert( inRowid ){ + sqlite3DbFree(db, p->u.aRowid); + p->nRowid = 0; + } +} +#endif + +/* Initialize the BLOB value of a ROWID +*/ +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 +static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){ + assert( db!=0 ); + if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid); + p->u.aRowid = sqlite3DbMallocRaw(db, n); + if( p->u.aRowid ){ + p->nRowid = n; + memcpy(p->u.aRowid, pData, n); + }else{ + p->nRowid = 0; + } +} +#endif + +/* Initialize the INTEGER value of a ROWID. +*/ +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 +static void sampleSetRowidInt64(sqlite3 *db, Stat4Sample *p, i64 iRowid){ + assert( db!=0 ); + if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid); + p->nRowid = 0; + p->u.iRowid = iRowid; +} +#endif + + +/* +** Copy the contents of object (*pFrom) into (*pTo). +*/ +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 +static void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){ + pTo->isPSample = pFrom->isPSample; + pTo->iCol = pFrom->iCol; + pTo->iHash = pFrom->iHash; + memcpy(pTo->anEq, pFrom->anEq, sizeof(tRowcnt)*p->nCol); + memcpy(pTo->anLt, pFrom->anLt, sizeof(tRowcnt)*p->nCol); + memcpy(pTo->anDLt, pFrom->anDLt, sizeof(tRowcnt)*p->nCol); + if( pFrom->nRowid ){ + sampleSetRowid(p->db, pTo, pFrom->nRowid, pFrom->u.aRowid); + }else{ + sampleSetRowidInt64(p->db, pTo, pFrom->u.iRowid); + } +} +#endif + +/* +** Reclaim all memory of a Stat4Accum structure. +*/ +static void stat4Destructor(void *pOld){ + Stat4Accum *p = (Stat4Accum*)pOld; +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + int i; + for(i=0; inCol; i++) sampleClear(p->db, p->aBest+i); + for(i=0; imxSample; i++) sampleClear(p->db, p->a+i); + sampleClear(p->db, &p->current); +#endif + sqlite3DbFree(p->db, p); +} + +/* +** Implementation of the stat_init(N,K,C) SQL function. The three parameters +** are: +** N: The number of columns in the index including the rowid/pk (note 1) +** K: The number of columns in the index excluding the rowid/pk. +** C: The number of rows in the index (note 2) +** +** Note 1: In the special case of the covering index that implements a +** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the +** total number of columns in the table. +** +** Note 2: C is only used for STAT3 and STAT4. +** +** For indexes on ordinary rowid tables, N==K+1. But for indexes on +** WITHOUT ROWID tables, N=K+P where P is the number of columns in the +** PRIMARY KEY of the table. The covering index that implements the +** original WITHOUT ROWID table as N==K as a special case. +** +** This routine allocates the Stat4Accum object in heap memory. The return +** value is a pointer to the Stat4Accum object. The datatype of the +** return value is BLOB, but it is really just a pointer to the Stat4Accum +** object. +*/ +static void statInit( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + Stat4Accum *p; + int nCol; /* Number of columns in index being sampled */ + int nKeyCol; /* Number of key columns */ + int nColUp; /* nCol rounded up for alignment */ + int n; /* Bytes of space to allocate */ + sqlite3 *db; /* Database connection */ +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + int mxSample = SQLITE_STAT4_SAMPLES; +#endif + + /* Decode the three function arguments */ + UNUSED_PARAMETER(argc); + nCol = sqlite3_value_int(argv[0]); + assert( nCol>0 ); + nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol; + nKeyCol = sqlite3_value_int(argv[1]); + assert( nKeyCol<=nCol ); + assert( nKeyCol>0 ); + + /* Allocate the space required for the Stat4Accum object */ + n = sizeof(*p) + + sizeof(tRowcnt)*nColUp /* Stat4Accum.anEq */ + + sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */ +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + + sizeof(tRowcnt)*nColUp /* Stat4Accum.anLt */ + + sizeof(Stat4Sample)*(nCol+mxSample) /* Stat4Accum.aBest[], a[] */ + + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample) +#endif + ; + db = sqlite3_context_db_handle(context); + p = sqlite3DbMallocZero(db, n); + if( p==0 ){ + sqlite3_result_error_nomem(context); + return; + } + + p->db = db; + p->nRow = 0; + p->nCol = nCol; + p->nKeyCol = nKeyCol; + p->current.anDLt = (tRowcnt*)&p[1]; + p->current.anEq = &p->current.anDLt[nColUp]; + +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + { + u8 *pSpace; /* Allocated space not yet assigned */ + int i; /* Used to iterate through p->aSample[] */ + + p->iGet = -1; + p->mxSample = mxSample; + p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1); + p->current.anLt = &p->current.anEq[nColUp]; + p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]); + + /* Set up the Stat4Accum.a[] and aBest[] arrays */ + p->a = (struct Stat4Sample*)&p->current.anLt[nColUp]; + p->aBest = &p->a[mxSample]; + pSpace = (u8*)(&p->a[mxSample+nCol]); + for(i=0; i<(mxSample+nCol); i++){ + p->a[i].anEq = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); + p->a[i].anLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); + p->a[i].anDLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); + } + assert( (pSpace - (u8*)p)==n ); + + for(i=0; iaBest[i].iCol = i; + } + } +#endif + + /* Return a pointer to the allocated object to the caller. Note that + ** only the pointer (the 2nd parameter) matters. The size of the object + ** (given by the 3rd parameter) is never used and can be any positive + ** value. */ + sqlite3_result_blob(context, p, sizeof(*p), stat4Destructor); +} +static const FuncDef statInitFuncdef = { + 2+IsStat34, /* nArg */ + SQLITE_UTF8, /* funcFlags */ + 0, /* pUserData */ + 0, /* pNext */ + statInit, /* xFunc */ + 0, /* xStep */ + 0, /* xFinalize */ + "stat_init", /* zName */ + 0, /* pHash */ + 0 /* pDestructor */ +}; + +#ifdef SQLITE_ENABLE_STAT4 +/* +** pNew and pOld are both candidate non-periodic samples selected for +** the same column (pNew->iCol==pOld->iCol). Ignoring this column and +** considering only any trailing columns and the sample hash value, this +** function returns true if sample pNew is to be preferred over pOld. +** In other words, if we assume that the cardinalities of the selected +** column for pNew and pOld are equal, is pNew to be preferred over pOld. +** +** This function assumes that for each argument sample, the contents of +** the anEq[] array from pSample->anEq[pSample->iCol+1] onwards are valid. +*/ +static int sampleIsBetterPost( + Stat4Accum *pAccum, + Stat4Sample *pNew, + Stat4Sample *pOld +){ + int nCol = pAccum->nCol; + int i; + assert( pNew->iCol==pOld->iCol ); + for(i=pNew->iCol+1; ianEq[i]>pOld->anEq[i] ) return 1; + if( pNew->anEq[i]anEq[i] ) return 0; + } + if( pNew->iHash>pOld->iHash ) return 1; + return 0; +} +#endif + +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 +/* +** Return true if pNew is to be preferred over pOld. +** +** This function assumes that for each argument sample, the contents of +** the anEq[] array from pSample->anEq[pSample->iCol] onwards are valid. +*/ +static int sampleIsBetter( + Stat4Accum *pAccum, + Stat4Sample *pNew, + Stat4Sample *pOld +){ + tRowcnt nEqNew = pNew->anEq[pNew->iCol]; + tRowcnt nEqOld = pOld->anEq[pOld->iCol]; + + assert( pOld->isPSample==0 && pNew->isPSample==0 ); + assert( IsStat4 || (pNew->iCol==0 && pOld->iCol==0) ); + + if( (nEqNew>nEqOld) ) return 1; +#ifdef SQLITE_ENABLE_STAT4 + if( nEqNew==nEqOld ){ + if( pNew->iColiCol ) return 1; + return (pNew->iCol==pOld->iCol && sampleIsBetterPost(pAccum, pNew, pOld)); + } + return 0; +#else + return (nEqNew==nEqOld && pNew->iHash>pOld->iHash); +#endif +} + +/* +** Copy the contents of sample *pNew into the p->a[] array. If necessary, +** remove the least desirable sample from p->a[] to make room. +*/ +static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){ + Stat4Sample *pSample = 0; + int i; + + assert( IsStat4 || nEqZero==0 ); + +#ifdef SQLITE_ENABLE_STAT4 + if( pNew->isPSample==0 ){ + Stat4Sample *pUpgrade = 0; + assert( pNew->anEq[pNew->iCol]>0 ); + + /* This sample is being added because the prefix that ends in column + ** iCol occurs many times in the table. However, if we have already + ** added a sample that shares this prefix, there is no need to add + ** this one. Instead, upgrade the priority of the highest priority + ** existing sample that shares this prefix. */ + for(i=p->nSample-1; i>=0; i--){ + Stat4Sample *pOld = &p->a[i]; + if( pOld->anEq[pNew->iCol]==0 ){ + if( pOld->isPSample ) return; + assert( pOld->iCol>pNew->iCol ); + assert( sampleIsBetter(p, pNew, pOld) ); + if( pUpgrade==0 || sampleIsBetter(p, pOld, pUpgrade) ){ + pUpgrade = pOld; + } + } + } + if( pUpgrade ){ + pUpgrade->iCol = pNew->iCol; + pUpgrade->anEq[pUpgrade->iCol] = pNew->anEq[pUpgrade->iCol]; + goto find_new_min; + } + } +#endif + + /* If necessary, remove sample iMin to make room for the new sample. */ + if( p->nSample>=p->mxSample ){ + Stat4Sample *pMin = &p->a[p->iMin]; + tRowcnt *anEq = pMin->anEq; + tRowcnt *anLt = pMin->anLt; + tRowcnt *anDLt = pMin->anDLt; + sampleClear(p->db, pMin); + memmove(pMin, &pMin[1], sizeof(p->a[0])*(p->nSample-p->iMin-1)); + pSample = &p->a[p->nSample-1]; + pSample->nRowid = 0; + pSample->anEq = anEq; + pSample->anDLt = anDLt; + pSample->anLt = anLt; + p->nSample = p->mxSample-1; + } + + /* The "rows less-than" for the rowid column must be greater than that + ** for the last sample in the p->a[] array. Otherwise, the samples would + ** be out of order. */ +#ifdef SQLITE_ENABLE_STAT4 + assert( p->nSample==0 + || pNew->anLt[p->nCol-1] > p->a[p->nSample-1].anLt[p->nCol-1] ); +#endif + + /* Insert the new sample */ + pSample = &p->a[p->nSample]; + sampleCopy(p, pSample, pNew); + p->nSample++; + + /* Zero the first nEqZero entries in the anEq[] array. */ + memset(pSample->anEq, 0, sizeof(tRowcnt)*nEqZero); + +#ifdef SQLITE_ENABLE_STAT4 + find_new_min: +#endif + if( p->nSample>=p->mxSample ){ + int iMin = -1; + for(i=0; imxSample; i++){ + if( p->a[i].isPSample ) continue; + if( iMin<0 || sampleIsBetter(p, &p->a[iMin], &p->a[i]) ){ + iMin = i; + } + } + assert( iMin>=0 ); + p->iMin = iMin; + } +} +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ + +/* +** Field iChng of the index being scanned has changed. So at this point +** p->current contains a sample that reflects the previous row of the +** index. The value of anEq[iChng] and subsequent anEq[] elements are +** correct at this point. +*/ +static void samplePushPrevious(Stat4Accum *p, int iChng){ +#ifdef SQLITE_ENABLE_STAT4 + int i; + + /* Check if any samples from the aBest[] array should be pushed + ** into IndexSample.a[] at this point. */ + for(i=(p->nCol-2); i>=iChng; i--){ + Stat4Sample *pBest = &p->aBest[i]; + pBest->anEq[i] = p->current.anEq[i]; + if( p->nSamplemxSample || sampleIsBetter(p, pBest, &p->a[p->iMin]) ){ + sampleInsert(p, pBest, i); + } + } + + /* Update the anEq[] fields of any samples already collected. */ + for(i=p->nSample-1; i>=0; i--){ + int j; + for(j=iChng; jnCol; j++){ + if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j]; + } + } +#endif + +#if defined(SQLITE_ENABLE_STAT3) && !defined(SQLITE_ENABLE_STAT4) + if( iChng==0 ){ + tRowcnt nLt = p->current.anLt[0]; + tRowcnt nEq = p->current.anEq[0]; + + /* Check if this is to be a periodic sample. If so, add it. */ + if( (nLt/p->nPSample)!=(nLt+nEq)/p->nPSample ){ + p->current.isPSample = 1; + sampleInsert(p, &p->current, 0); + p->current.isPSample = 0; + }else + + /* Or if it is a non-periodic sample. Add it in this case too. */ + if( p->nSamplemxSample + || sampleIsBetter(p, &p->current, &p->a[p->iMin]) + ){ + sampleInsert(p, &p->current, 0); + } + } +#endif + +#ifndef SQLITE_ENABLE_STAT3_OR_STAT4 + UNUSED_PARAMETER( p ); + UNUSED_PARAMETER( iChng ); +#endif +} + +/* +** Implementation of the stat_push SQL function: stat_push(P,C,R) +** Arguments: +** +** P Pointer to the Stat4Accum object created by stat_init() +** C Index of left-most column to differ from previous row +** R Rowid for the current row. Might be a key record for +** WITHOUT ROWID tables. +** +** This SQL function always returns NULL. It's purpose it to accumulate +** statistical data and/or samples in the Stat4Accum object about the +** index being analyzed. The stat_get() SQL function will later be used to +** extract relevant information for constructing the sqlite_statN tables. +** +** The R parameter is only used for STAT3 and STAT4 +*/ +static void statPush( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int i; + + /* The three function arguments */ + Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]); + int iChng = sqlite3_value_int(argv[1]); + + UNUSED_PARAMETER( argc ); + UNUSED_PARAMETER( context ); + assert( p->nCol>0 ); + assert( iChngnCol ); + + if( p->nRow==0 ){ + /* This is the first call to this function. Do initialization. */ + for(i=0; inCol; i++) p->current.anEq[i] = 1; + }else{ + /* Second and subsequent calls get processed here */ + samplePushPrevious(p, iChng); + + /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply + ** to the current row of the index. */ + for(i=0; icurrent.anEq[i]++; + } + for(i=iChng; inCol; i++){ + p->current.anDLt[i]++; +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + p->current.anLt[i] += p->current.anEq[i]; +#endif + p->current.anEq[i] = 1; + } + } + p->nRow++; +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){ + sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2])); + }else{ + sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]), + sqlite3_value_blob(argv[2])); + } + p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345; +#endif + +#ifdef SQLITE_ENABLE_STAT4 + { + tRowcnt nLt = p->current.anLt[p->nCol-1]; + + /* Check if this is to be a periodic sample. If so, add it. */ + if( (nLt/p->nPSample)!=(nLt+1)/p->nPSample ){ + p->current.isPSample = 1; + p->current.iCol = 0; + sampleInsert(p, &p->current, p->nCol-1); + p->current.isPSample = 0; + } + + /* Update the aBest[] array. */ + for(i=0; i<(p->nCol-1); i++){ + p->current.iCol = i; + if( i>=iChng || sampleIsBetterPost(p, &p->current, &p->aBest[i]) ){ + sampleCopy(p, &p->aBest[i], &p->current); + } + } + } +#endif +} +static const FuncDef statPushFuncdef = { + 2+IsStat34, /* nArg */ + SQLITE_UTF8, /* funcFlags */ + 0, /* pUserData */ + 0, /* pNext */ + statPush, /* xFunc */ + 0, /* xStep */ + 0, /* xFinalize */ + "stat_push", /* zName */ + 0, /* pHash */ + 0 /* pDestructor */ +}; + +#define STAT_GET_STAT1 0 /* "stat" column of stat1 table */ +#define STAT_GET_ROWID 1 /* "rowid" column of stat[34] entry */ +#define STAT_GET_NEQ 2 /* "neq" column of stat[34] entry */ +#define STAT_GET_NLT 3 /* "nlt" column of stat[34] entry */ +#define STAT_GET_NDLT 4 /* "ndlt" column of stat[34] entry */ + +/* +** Implementation of the stat_get(P,J) SQL function. This routine is +** used to query statistical information that has been gathered into +** the Stat4Accum object by prior calls to stat_push(). The P parameter +** has type BLOB but it is really just a pointer to the Stat4Accum object. +** The content to returned is determined by the parameter J +** which is one of the STAT_GET_xxxx values defined above. +** +** If neither STAT3 nor STAT4 are enabled, then J is always +** STAT_GET_STAT1 and is hence omitted and this routine becomes +** a one-parameter function, stat_get(P), that always returns the +** stat1 table entry information. +*/ +static void statGet( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]); +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + /* STAT3 and STAT4 have a parameter on this routine. */ + int eCall = sqlite3_value_int(argv[1]); + assert( argc==2 ); + assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ + || eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT + || eCall==STAT_GET_NDLT + ); + if( eCall==STAT_GET_STAT1 ) +#else + assert( argc==1 ); +#endif + { + /* Return the value to store in the "stat" column of the sqlite_stat1 + ** table for this index. + ** + ** The value is a string composed of a list of integers describing + ** the index. The first integer in the list is the total number of + ** entries in the index. There is one additional integer in the list + ** for each indexed column. This additional integer is an estimate of + ** the number of rows matched by a stabbing query on the index using + ** a key with the corresponding number of fields. In other words, + ** if the index is on columns (a,b) and the sqlite_stat1 value is + ** "100 10 2", then SQLite estimates that: + ** + ** * the index contains 100 rows, + ** * "WHERE a=?" matches 10 rows, and + ** * "WHERE a=? AND b=?" matches 2 rows. + ** + ** If D is the count of distinct values and K is the total number of + ** rows, then each estimate is computed as: + ** + ** I = (K+D-1)/D + */ + char *z; + int i; + + char *zRet = sqlite3MallocZero( (p->nKeyCol+1)*25 ); + if( zRet==0 ){ + sqlite3_result_error_nomem(context); + return; + } + + sqlite3_snprintf(24, zRet, "%llu", (u64)p->nRow); + z = zRet + sqlite3Strlen30(zRet); + for(i=0; inKeyCol; i++){ + u64 nDistinct = p->current.anDLt[i] + 1; + u64 iVal = (p->nRow + nDistinct - 1) / nDistinct; + sqlite3_snprintf(24, z, " %llu", iVal); + z += sqlite3Strlen30(z); + assert( p->current.anEq[i] ); + } + assert( z[0]=='\0' && z>zRet ); + + sqlite3_result_text(context, zRet, -1, sqlite3_free); + } +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + else if( eCall==STAT_GET_ROWID ){ + if( p->iGet<0 ){ + samplePushPrevious(p, 0); + p->iGet = 0; + } + if( p->iGetnSample ){ + Stat4Sample *pS = p->a + p->iGet; + if( pS->nRowid==0 ){ + sqlite3_result_int64(context, pS->u.iRowid); + }else{ + sqlite3_result_blob(context, pS->u.aRowid, pS->nRowid, + SQLITE_TRANSIENT); + } + } + }else{ + tRowcnt *aCnt = 0; + + assert( p->iGetnSample ); + switch( eCall ){ + case STAT_GET_NEQ: aCnt = p->a[p->iGet].anEq; break; + case STAT_GET_NLT: aCnt = p->a[p->iGet].anLt; break; + default: { + aCnt = p->a[p->iGet].anDLt; + p->iGet++; + break; + } + } + + if( IsStat3 ){ + sqlite3_result_int64(context, (i64)aCnt[0]); + }else{ + char *zRet = sqlite3MallocZero(p->nCol * 25); + if( zRet==0 ){ + sqlite3_result_error_nomem(context); + }else{ + int i; + char *z = zRet; + for(i=0; inCol; i++){ + sqlite3_snprintf(24, z, "%llu ", (u64)aCnt[i]); + z += sqlite3Strlen30(z); + } + assert( z[0]=='\0' && z>zRet ); + z[-1] = '\0'; + sqlite3_result_text(context, zRet, -1, sqlite3_free); + } + } + } +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ +#ifndef SQLITE_DEBUG + UNUSED_PARAMETER( argc ); +#endif +} +static const FuncDef statGetFuncdef = { + 1+IsStat34, /* nArg */ + SQLITE_UTF8, /* funcFlags */ + 0, /* pUserData */ + 0, /* pNext */ + statGet, /* xFunc */ + 0, /* xStep */ + 0, /* xFinalize */ + "stat_get", /* zName */ + 0, /* pHash */ + 0 /* pDestructor */ +}; + +static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){ + assert( regOut!=regStat4 && regOut!=regStat4+1 ); +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + sqlite3VdbeAddOp2(v, OP_Integer, iParam, regStat4+1); +#elif SQLITE_DEBUG + assert( iParam==STAT_GET_STAT1 ); +#else + UNUSED_PARAMETER( iParam ); +#endif + sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4, regOut); + sqlite3VdbeChangeP4(v, -1, (char*)&statGetFuncdef, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, 1 + IsStat34); +} + +/* +** 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 */ + Index *pOnlyIdx, /* If not NULL, only analyze this one index */ + int iStatCur, /* Index of VdbeCursor that writes the sqlite_stat1 table */ + int iMem, /* Available memory locations begin here */ + int iTab /* Next available cursor */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + Index *pIdx; /* An index to being analyzed */ + int iIdxCur; /* Cursor open on index being analyzed */ + int iTabCur; /* Table cursor */ + Vdbe *v; /* The virtual machine being built up */ + int i; /* Loop counter */ + int jZeroRows = -1; /* Jump from here if number of rows is zero */ + int iDb; /* Index of database containing pTab */ + u8 needTableCnt = 1; /* True to count the table */ + int regNewRowid = iMem++; /* Rowid for the inserted record */ + int regStat4 = iMem++; /* Register to hold Stat4Accum object */ + int regChng = iMem++; /* Index of changed index field */ +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + int regRowid = iMem++; /* Rowid argument passed to stat_push() */ +#endif + int regTemp = iMem++; /* Temporary use register */ + int regTabname = iMem++; /* Register containing table name */ + int regIdxname = iMem++; /* Register containing index name */ + int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */ + int regPrev = iMem; /* MUST BE LAST (see below) */ + + pParse->nMem = MAX(pParse->nMem, iMem); + v = sqlite3GetVdbe(pParse); + if( v==0 || NEVER(pTab==0) ){ + return; + } + if( pTab->tnum==0 ){ + /* Do not gather statistics on views or virtual tables */ + return; + } + if( sqlite3_strnicmp(pTab->zName, "sqlite_", 7)==0 ){ + /* Do not gather statistics on system tables */ + return; + } + assert( sqlite3BtreeHoldsAllMutexes(db) ); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDb>=0 ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); +#ifndef SQLITE_OMIT_AUTHORIZATION + if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0, + db->aDb[iDb].zName ) ){ + return; + } +#endif + + /* Establish a read-lock on the table at the shared-cache level. + ** Open a read-only cursor on the table. Also allocate a cursor number + ** to use for scanning indexes (iIdxCur). No index cursor is opened at + ** this time though. */ + sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + iTabCur = iTab++; + iIdxCur = iTab++; + pParse->nTab = MAX(pParse->nTab, iTab); + sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); + sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); + + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int nCol; /* Number of columns in pIdx. "N" */ + int addrRewind; /* Address of "OP_Rewind iIdxCur" */ + int addrNextRow; /* Address of "next_row:" */ + const char *zIdxName; /* Name of the index */ + int nColTest; /* Number of columns to test for changes */ + + if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; + if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0; + if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIdx) ){ + nCol = pIdx->nKeyCol; + zIdxName = pTab->zName; + nColTest = nCol - 1; + }else{ + nCol = pIdx->nColumn; + zIdxName = pIdx->zName; + nColTest = pIdx->uniqNotNull ? pIdx->nKeyCol-1 : nCol-1; + } + + /* Populate the register containing the index name. */ + sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, zIdxName, 0); + VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName)); + + /* + ** Pseudo-code for loop that calls stat_push(): + ** + ** Rewind csr + ** if eof(csr) goto end_of_scan; + ** regChng = 0 + ** goto chng_addr_0; + ** + ** next_row: + ** regChng = 0 + ** if( idx(0) != regPrev(0) ) goto chng_addr_0 + ** regChng = 1 + ** if( idx(1) != regPrev(1) ) goto chng_addr_1 + ** ... + ** regChng = N + ** goto chng_addr_N + ** + ** chng_addr_0: + ** regPrev(0) = idx(0) + ** chng_addr_1: + ** regPrev(1) = idx(1) + ** ... + ** + ** endDistinctTest: + ** regRowid = idx(rowid) + ** stat_push(P, regChng, regRowid) + ** Next csr + ** if !eof(csr) goto next_row; + ** + ** end_of_scan: + */ + + /* Make sure there are enough memory cells allocated to accommodate + ** the regPrev array and a trailing rowid (the rowid slot is required + ** when building a record to insert into the sample column of + ** the sqlite_stat4 table. */ + pParse->nMem = MAX(pParse->nMem, regPrev+nColTest); + + /* Open a read-only cursor on the index being analyzed. */ + assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); + sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); + VdbeComment((v, "%s", pIdx->zName)); + + /* Invoke the stat_init() function. The arguments are: + ** + ** (1) the number of columns in the index including the rowid + ** (or for a WITHOUT ROWID table, the number of PK columns), + ** (2) the number of columns in the key without the rowid/pk + ** (3) the number of rows in the index, + ** + ** + ** The third argument is only used for STAT3 and STAT4 + */ +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3); +#endif + sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1); + sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2); + sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4+1, regStat4); + sqlite3VdbeChangeP4(v, -1, (char*)&statInitFuncdef, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, 2+IsStat34); + + /* Implementation of the following: + ** + ** Rewind csr + ** if eof(csr) goto end_of_scan; + ** regChng = 0 + ** goto next_push_0; + ** + */ + addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); + addrNextRow = sqlite3VdbeCurrentAddr(v); + + if( nColTest>0 ){ + int endDistinctTest = sqlite3VdbeMakeLabel(v); + int *aGotoChng; /* Array of jump instruction addresses */ + aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*nColTest); + if( aGotoChng==0 ) continue; + + /* + ** next_row: + ** regChng = 0 + ** if( idx(0) != regPrev(0) ) goto chng_addr_0 + ** regChng = 1 + ** if( idx(1) != regPrev(1) ) goto chng_addr_1 + ** ... + ** regChng = N + ** goto endDistinctTest + */ + sqlite3VdbeAddOp0(v, OP_Goto); + addrNextRow = sqlite3VdbeCurrentAddr(v); + if( nColTest==1 && pIdx->nKeyCol==1 && IsUniqueIndex(pIdx) ){ + /* For a single-column UNIQUE index, once we have found a non-NULL + ** row, we know that all the rest will be distinct, so skip + ** subsequent distinctness tests. */ + sqlite3VdbeAddOp2(v, OP_NotNull, regPrev, endDistinctTest); + VdbeCoverage(v); + } + for(i=0; iazColl[i]); + sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); + aGotoChng[i] = + sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); + sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); + VdbeCoverage(v); + } + sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng); + sqlite3VdbeAddOp2(v, OP_Goto, 0, endDistinctTest); + + + /* + ** chng_addr_0: + ** regPrev(0) = idx(0) + ** chng_addr_1: + ** regPrev(1) = idx(1) + ** ... + */ + sqlite3VdbeJumpHere(v, addrNextRow-1); + for(i=0; ipTable); + int j, k, regKey; + regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol); + for(j=0; jnKeyCol; j++){ + k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]); + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j); + VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName)); + } + sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid); + sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol); + } +#endif + assert( regChng==(regStat4+1) ); + sqlite3VdbeAddOp3(v, OP_Function, 1, regStat4, regTemp); + sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, 2+IsStat34); + sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v); + + /* Add the entry to the stat1 table. */ + callStatGet(v, regStat4, STAT_GET_STAT1, regStat1); + assert( "BBB"[0]==SQLITE_AFF_TEXT ); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + + /* Add the entries to the stat3 or stat4 table. */ +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + { + int regEq = regStat1; + int regLt = regStat1+1; + int regDLt = regStat1+2; + int regSample = regStat1+3; + int regCol = regStat1+4; + int regSampleRowid = regCol + nCol; + int addrNext; + int addrIsNull; + u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound; + + pParse->nMem = MAX(pParse->nMem, regCol+nCol); + + addrNext = sqlite3VdbeCurrentAddr(v); + callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid); + addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid); + VdbeCoverage(v); + callStatGet(v, regStat4, STAT_GET_NEQ, regEq); + callStatGet(v, regStat4, STAT_GET_NLT, regLt); + callStatGet(v, regStat4, STAT_GET_NDLT, regDLt); + sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0); + /* We know that the regSampleRowid row exists because it was read by + ** the previous loop. Thus the not-found jump of seekOp will never + ** be taken */ + VdbeCoverageNeverTaken(v); +#ifdef SQLITE_ENABLE_STAT3 + sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, + pIdx->aiColumn[0], regSample); +#else + for(i=0; iaiColumn[i]; + sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i); + } + sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol, regSample); +#endif + sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp); + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid); + sqlite3VdbeAddOp2(v, OP_Goto, 1, addrNext); /* P1==1 for end-of-loop */ + sqlite3VdbeJumpHere(v, addrIsNull); + } +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ + + /* End of analysis */ + sqlite3VdbeJumpHere(v, addrRewind); + } + + + /* Create a single sqlite_stat1 entry containing NULL as the index + ** name and the row count as the content. + */ + if( pOnlyIdx==0 && needTableCnt ){ + VdbeComment((v, "%s", pTab->zName)); + sqlite3VdbeAddOp2(v, OP_Count, iTabCur, regStat1); + jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname); + assert( "BBB"[0]==SQLITE_AFF_TEXT ); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3VdbeJumpHere(v, jZeroRows); + } +} + + +/* +** Generate code that will cause the most recent index analysis to +** be loaded into internal hash tables where is can be used. +*/ +static void loadAnalysis(Parse *pParse, int iDb){ + Vdbe *v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3VdbeAddOp1(v, OP_LoadAnalysis, iDb); + } +} + +/* +** 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; + int iTab; + + sqlite3BeginWriteOperation(pParse, 0, iDb); + iStatCur = pParse->nTab; + pParse->nTab += 3; + openStatTable(pParse, iDb, iStatCur, 0, 0); + iMem = pParse->nMem+1; + iTab = pParse->nTab; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ + Table *pTab = (Table*)sqliteHashData(k); + analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab); + } + loadAnalysis(pParse, iDb); +} + +/* +** Generate code that will do an analysis of a single table in +** a database. If pOnlyIdx is not NULL then it is a single index +** in pTab that should be analyzed. +*/ +static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){ + int iDb; + int iStatCur; + + assert( pTab!=0 ); + assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); + iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + sqlite3BeginWriteOperation(pParse, 0, iDb); + iStatCur = pParse->nTab; + pParse->nTab += 3; + if( pOnlyIdx ){ + openStatTable(pParse, iDb, iStatCur, pOnlyIdx->zName, "idx"); + }else{ + openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl"); + } + analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur,pParse->nMem+1,pParse->nTab); + loadAnalysis(pParse, iDb); +} + +/* +** Generate code for the ANALYZE command. The parser calls this routine +** when it recognizes an ANALYZE command. +** +** ANALYZE -- 1 +** ANALYZE -- 2 +** ANALYZE ?.? -- 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. +*/ +SQLITE_PRIVATE void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ + sqlite3 *db = pParse->db; + int iDb; + int i; + char *z, *zDb; + Table *pTab; + Index *pIdx; + Token *pTableName; + Vdbe *v; + + /* Read the database schema. If an error occurs, leave an error message + ** and code in pParse and return NULL. */ + assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + return; + } + + assert( pName2!=0 || pName1==0 ); + if( pName1==0 ){ + /* Form 1: Analyze everything */ + for(i=0; inDb; i++){ + if( i==1 ) continue; /* Do not analyze the TEMP database */ + analyzeDatabase(pParse, i); + } + }else if( pName2->n==0 ){ + /* Form 2: Analyze the database or table named */ + iDb = sqlite3FindDb(db, pName1); + if( iDb>=0 ){ + analyzeDatabase(pParse, iDb); + }else{ + z = sqlite3NameFromToken(db, pName1); + if( z ){ + if( (pIdx = sqlite3FindIndex(db, z, 0))!=0 ){ + analyzeTable(pParse, pIdx->pTable, pIdx); + }else if( (pTab = sqlite3LocateTable(pParse, 0, z, 0))!=0 ){ + analyzeTable(pParse, pTab, 0); + } + sqlite3DbFree(db, z); + } + } + }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(db, pTableName); + if( z ){ + if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){ + analyzeTable(pParse, pIdx->pTable, pIdx); + }else if( (pTab = sqlite3LocateTable(pParse, 0, z, zDb))!=0 ){ + analyzeTable(pParse, pTab, 0); + } + sqlite3DbFree(db, z); + } + } + } + v = sqlite3GetVdbe(pParse); + if( v ) sqlite3VdbeAddOp0(v, OP_Expire); +} + +/* +** Used to pass information from the analyzer reader through to the +** callback routine. +*/ +typedef struct analysisInfo analysisInfo; +struct analysisInfo { + sqlite3 *db; + const char *zDatabase; +}; + +/* +** The first argument points to a nul-terminated string containing a +** list of space separated integers. Read the first nOut of these into +** the array aOut[]. +*/ +static void decodeIntArray( + char *zIntArray, /* String containing int array to decode */ + int nOut, /* Number of slots in aOut[] */ + tRowcnt *aOut, /* Store integers here */ + LogEst *aLog, /* Or, if aOut==0, here */ + Index *pIndex /* Handle extra flags for this index, if not NULL */ +){ + char *z = zIntArray; + int c; + int i; + tRowcnt v; + +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + if( z==0 ) z = ""; +#else + assert( z!=0 ); +#endif + for(i=0; *z && i='0' && c<='9' ){ + v = v*10 + c - '0'; + z++; + } +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + if( aOut ) aOut[i] = v; + if( aLog ) aLog[i] = sqlite3LogEst(v); +#else + assert( aOut==0 ); + UNUSED_PARAMETER(aOut); + assert( aLog!=0 ); + aLog[i] = sqlite3LogEst(v); +#endif + if( *z==' ' ) z++; + } +#ifndef SQLITE_ENABLE_STAT3_OR_STAT4 + assert( pIndex!=0 ); { +#else + if( pIndex ){ +#endif + pIndex->bUnordered = 0; + pIndex->noSkipScan = 0; + while( z[0] ){ + if( sqlite3_strglob("unordered*", z)==0 ){ + pIndex->bUnordered = 1; + }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ + pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3)); + }else if( sqlite3_strglob("noskipscan*", z)==0 ){ + pIndex->noSkipScan = 1; + } +#ifdef SQLITE_ENABLE_COSTMULT + else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){ + pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9)); + } +#endif + while( z[0]!=0 && z[0]!=' ' ) z++; + while( z[0]==' ' ) z++; + } + } +} + +/* +** This callback is invoked once for each index when reading the +** sqlite_stat1 table. +** +** argv[0] = name of the table +** argv[1] = name of the index (might be NULL) +** argv[2] = results of analysis - on integer for each column +** +** Entries for which argv[1]==NULL simply record the number of rows in +** the table. +*/ +static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ + analysisInfo *pInfo = (analysisInfo*)pData; + Index *pIndex; + Table *pTable; + const char *z; + + assert( argc==3 ); + UNUSED_PARAMETER2(NotUsed, argc); + + if( argv==0 || argv[0]==0 || argv[2]==0 ){ + return 0; + } + pTable = sqlite3FindTable(pInfo->db, argv[0], pInfo->zDatabase); + if( pTable==0 ){ + return 0; + } + if( argv[1]==0 ){ + pIndex = 0; + }else if( sqlite3_stricmp(argv[0],argv[1])==0 ){ + pIndex = sqlite3PrimaryKeyIndex(pTable); + }else{ + pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); + } + z = argv[2]; + + if( pIndex ){ + tRowcnt *aiRowEst = 0; + int nCol = pIndex->nKeyCol+1; +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + /* Index.aiRowEst may already be set here if there are duplicate + ** sqlite_stat1 entries for this index. In that case just clobber + ** the old data with the new instead of allocating a new array. */ + if( pIndex->aiRowEst==0 ){ + pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol); + if( pIndex->aiRowEst==0 ) pInfo->db->mallocFailed = 1; + } + aiRowEst = pIndex->aiRowEst; +#endif + pIndex->bUnordered = 0; + decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex); + if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0]; + }else{ + Index fakeIdx; + fakeIdx.szIdxRow = pTable->szTabRow; +#ifdef SQLITE_ENABLE_COSTMULT + fakeIdx.pTable = pTable; +#endif + decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx); + pTable->szTabRow = fakeIdx.szIdxRow; + } + + return 0; +} + +/* +** If the Index.aSample variable is not NULL, delete the aSample[] array +** and its contents. +*/ +SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + if( pIdx->aSample ){ + int j; + for(j=0; jnSample; j++){ + IndexSample *p = &pIdx->aSample[j]; + sqlite3DbFree(db, p->p); + } + sqlite3DbFree(db, pIdx->aSample); + } + if( db && db->pnBytesFreed==0 ){ + pIdx->nSample = 0; + pIdx->aSample = 0; + } +#else + UNUSED_PARAMETER(db); + UNUSED_PARAMETER(pIdx); +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ +} + +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 +/* +** Populate the pIdx->aAvgEq[] array based on the samples currently +** stored in pIdx->aSample[]. +*/ +static void initAvgEq(Index *pIdx){ + if( pIdx ){ + IndexSample *aSample = pIdx->aSample; + IndexSample *pFinal = &aSample[pIdx->nSample-1]; + int iCol; + int nCol = 1; + if( pIdx->nSampleCol>1 ){ + /* If this is stat4 data, then calculate aAvgEq[] values for all + ** sample columns except the last. The last is always set to 1, as + ** once the trailing PK fields are considered all index keys are + ** unique. */ + nCol = pIdx->nSampleCol-1; + pIdx->aAvgEq[nCol] = 1; + } + for(iCol=0; iColnSample; + int i; /* Used to iterate through samples */ + tRowcnt sumEq = 0; /* Sum of the nEq values */ + tRowcnt avgEq = 0; + tRowcnt nRow; /* Number of rows in index */ + i64 nSum100 = 0; /* Number of terms contributing to sumEq */ + i64 nDist100; /* Number of distinct values in index */ + + if( !pIdx->aiRowEst || iCol>=pIdx->nKeyCol || pIdx->aiRowEst[iCol+1]==0 ){ + nRow = pFinal->anLt[iCol]; + nDist100 = (i64)100 * pFinal->anDLt[iCol]; + nSample--; + }else{ + nRow = pIdx->aiRowEst[0]; + nDist100 = ((i64)100 * pIdx->aiRowEst[0]) / pIdx->aiRowEst[iCol+1]; + } + pIdx->nRowEst0 = nRow; + + /* Set nSum to the number of distinct (iCol+1) field prefixes that + ** occur in the stat4 table for this index. Set sumEq to the sum of + ** the nEq values for column iCol for the same set (adding the value + ** only once where there exist duplicate prefixes). */ + for(i=0; inSample-1) + || aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] + ){ + sumEq += aSample[i].anEq[iCol]; + nSum100 += 100; + } + } + + if( nDist100>nSum100 ){ + avgEq = ((i64)100 * (nRow - sumEq))/(nDist100 - nSum100); + } + if( avgEq==0 ) avgEq = 1; + pIdx->aAvgEq[iCol] = avgEq; + } + } +} + +/* +** Look up an index by name. Or, if the name of a WITHOUT ROWID table +** is supplied instead, find the PRIMARY KEY index for that table. +*/ +static Index *findIndexOrPrimaryKey( + sqlite3 *db, + const char *zName, + const char *zDb +){ + Index *pIdx = sqlite3FindIndex(db, zName, zDb); + if( pIdx==0 ){ + Table *pTab = sqlite3FindTable(db, zName, zDb); + if( pTab && !HasRowid(pTab) ) pIdx = sqlite3PrimaryKeyIndex(pTab); + } + return pIdx; +} + +/* +** Load the content from either the sqlite_stat4 or sqlite_stat3 table +** into the relevant Index.aSample[] arrays. +** +** Arguments zSql1 and zSql2 must point to SQL statements that return +** data equivalent to the following (statements are different for stat3, +** see the caller of this function for details): +** +** zSql1: SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx +** zSql2: SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4 +** +** where %Q is replaced with the database name before the SQL is executed. +*/ +static int loadStatTbl( + sqlite3 *db, /* Database handle */ + int bStat3, /* Assume single column records only */ + const char *zSql1, /* SQL statement 1 (see above) */ + const char *zSql2, /* SQL statement 2 (see above) */ + const char *zDb /* Database name (e.g. "main") */ +){ + int rc; /* Result codes from subroutines */ + sqlite3_stmt *pStmt = 0; /* An SQL statement being run */ + char *zSql; /* Text of the SQL statement */ + Index *pPrevIdx = 0; /* Previous index in the loop */ + IndexSample *pSample; /* A slot in pIdx->aSample[] */ + + assert( db->lookaside.bEnabled==0 ); + zSql = sqlite3MPrintf(db, zSql1, zDb); + if( !zSql ){ + return SQLITE_NOMEM; + } + rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); + sqlite3DbFree(db, zSql); + if( rc ) return rc; + + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + int nIdxCol = 1; /* Number of columns in stat4 records */ + + char *zIndex; /* Index name */ + Index *pIdx; /* Pointer to the index object */ + int nSample; /* Number of samples */ + int nByte; /* Bytes of space required */ + int i; /* Bytes of space required */ + tRowcnt *pSpace; + + zIndex = (char *)sqlite3_column_text(pStmt, 0); + if( zIndex==0 ) continue; + nSample = sqlite3_column_int(pStmt, 1); + pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); + assert( pIdx==0 || bStat3 || pIdx->nSample==0 ); + /* Index.nSample is non-zero at this point if data has already been + ** loaded from the stat4 table. In this case ignore stat3 data. */ + if( pIdx==0 || pIdx->nSample ) continue; + if( bStat3==0 ){ + assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 ); + if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){ + nIdxCol = pIdx->nKeyCol; + }else{ + nIdxCol = pIdx->nColumn; + } + } + pIdx->nSampleCol = nIdxCol; + nByte = sizeof(IndexSample) * nSample; + nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; + nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ + + pIdx->aSample = sqlite3DbMallocZero(db, nByte); + if( pIdx->aSample==0 ){ + sqlite3_finalize(pStmt); + return SQLITE_NOMEM; + } + pSpace = (tRowcnt*)&pIdx->aSample[nSample]; + pIdx->aAvgEq = pSpace; pSpace += nIdxCol; + for(i=0; iaSample[i].anEq = pSpace; pSpace += nIdxCol; + pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol; + pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol; + } + assert( ((u8*)pSpace)-nByte==(u8*)(pIdx->aSample) ); + } + rc = sqlite3_finalize(pStmt); + if( rc ) return rc; + + zSql = sqlite3MPrintf(db, zSql2, zDb); + if( !zSql ){ + return SQLITE_NOMEM; + } + rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); + sqlite3DbFree(db, zSql); + if( rc ) return rc; + + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + char *zIndex; /* Index name */ + Index *pIdx; /* Pointer to the index object */ + int nCol = 1; /* Number of columns in index */ + + zIndex = (char *)sqlite3_column_text(pStmt, 0); + if( zIndex==0 ) continue; + pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); + if( pIdx==0 ) continue; + /* This next condition is true if data has already been loaded from + ** the sqlite_stat4 table. In this case ignore stat3 data. */ + nCol = pIdx->nSampleCol; + if( bStat3 && nCol>1 ) continue; + if( pIdx!=pPrevIdx ){ + initAvgEq(pPrevIdx); + pPrevIdx = pIdx; + } + pSample = &pIdx->aSample[pIdx->nSample]; + decodeIntArray((char*)sqlite3_column_text(pStmt,1),nCol,pSample->anEq,0,0); + decodeIntArray((char*)sqlite3_column_text(pStmt,2),nCol,pSample->anLt,0,0); + decodeIntArray((char*)sqlite3_column_text(pStmt,3),nCol,pSample->anDLt,0,0); + + /* Take a copy of the sample. Add two 0x00 bytes the end of the buffer. + ** This is in case the sample record is corrupted. In that case, the + ** sqlite3VdbeRecordCompare() may read up to two varints past the + ** end of the allocated buffer before it realizes it is dealing with + ** a corrupt record. Adding the two 0x00 bytes prevents this from causing + ** a buffer overread. */ + pSample->n = sqlite3_column_bytes(pStmt, 4); + pSample->p = sqlite3DbMallocZero(db, pSample->n + 2); + if( pSample->p==0 ){ + sqlite3_finalize(pStmt); + return SQLITE_NOMEM; + } + memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n); + pIdx->nSample++; + } + rc = sqlite3_finalize(pStmt); + if( rc==SQLITE_OK ) initAvgEq(pPrevIdx); + return rc; +} + +/* +** Load content from the sqlite_stat4 and sqlite_stat3 tables into +** the Index.aSample[] arrays of all indices. +*/ +static int loadStat4(sqlite3 *db, const char *zDb){ + int rc = SQLITE_OK; /* Result codes from subroutines */ + + assert( db->lookaside.bEnabled==0 ); + if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){ + rc = loadStatTbl(db, 0, + "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", + "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4", + zDb + ); + } + + if( rc==SQLITE_OK && sqlite3FindTable(db, "sqlite_stat3", zDb) ){ + rc = loadStatTbl(db, 1, + "SELECT idx,count(*) FROM %Q.sqlite_stat3 GROUP BY idx", + "SELECT idx,neq,nlt,ndlt,sqlite_record(sample) FROM %Q.sqlite_stat3", + zDb + ); + } + + return rc; +} +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ + +/* +** Load the content of the sqlite_stat1 and sqlite_stat3/4 tables. The +** contents of sqlite_stat1 are used to populate the Index.aiRowEst[] +** arrays. The contents of sqlite_stat3/4 are used to populate the +** Index.aSample[] arrays. +** +** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR +** is returned. In this case, even if SQLITE_ENABLE_STAT3/4 was defined +** during compilation and the sqlite_stat3/4 table is present, no data is +** read from it. +** +** If SQLITE_ENABLE_STAT3/4 was defined during compilation and the +** sqlite_stat4 table is not present in the database, SQLITE_ERROR is +** returned. However, in this case, data is read from the sqlite_stat1 +** table (if it is present) before returning. +** +** If an OOM error occurs, this function always sets db->mallocFailed. +** This means if the caller does not care about other errors, the return +** code may be ignored. +*/ +SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ + analysisInfo sInfo; + HashElem *i; + char *zSql; + int rc; + + assert( iDb>=0 && iDbnDb ); + assert( db->aDb[iDb].pBt!=0 ); + + /* Clear any prior statistics */ + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ + Index *pIdx = sqliteHashData(i); + sqlite3DefaultRowEst(pIdx); +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + sqlite3DeleteIndexSamples(db, pIdx); + pIdx->aSample = 0; +#endif + } + + /* Check to make sure the sqlite_stat1 table exists */ + sInfo.db = db; + sInfo.zDatabase = db->aDb[iDb].zName; + if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){ + return SQLITE_ERROR; + } + + /* Load new statistics out of the sqlite_stat1 table */ + zSql = sqlite3MPrintf(db, + "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); + sqlite3DbFree(db, zSql); + } + + + /* Load the statistics from the sqlite_stat4 table. */ +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){ + int lookasideEnabled = db->lookaside.bEnabled; + db->lookaside.bEnabled = 0; + rc = loadStat4(db, sInfo.zDatabase); + db->lookaside.bEnabled = lookasideEnabled; + } + for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ + Index *pIdx = sqliteHashData(i); + sqlite3_free(pIdx->aiRowEst); + pIdx->aiRowEst = 0; + } +#endif + + if( rc==SQLITE_NOMEM ){ + db->mallocFailed = 1; + } + return rc; +} + + +#endif /* SQLITE_OMIT_ANALYZE */ + +/************** End of analyze.c *********************************************/ +/************** Begin file attach.c ******************************************/ +/* +** 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. +*/ + +#ifndef SQLITE_OMIT_ATTACH +/* +** 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. +*/ +static int resolveAttachExpr(NameContext *pName, Expr *pExpr) +{ + int rc = SQLITE_OK; + if( pExpr ){ + if( pExpr->op!=TK_ID ){ + rc = sqlite3ResolveExprNames(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 NotUsed, + sqlite3_value **argv +){ + int i; + int rc = 0; + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zName; + const char *zFile; + char *zPath = 0; + char *zErr = 0; + unsigned int flags; + Db *aNew; + char *zErrDyn = 0; + sqlite3_vfs *pVfs; + + UNUSED_PARAMETER(NotUsed); + + zFile = (const char *)sqlite3_value_text(argv[0]); + zName = (const char *)sqlite3_value_text(argv[1]); + if( zFile==0 ) zFile = ""; + if( zName==0 ) zName = ""; + + /* Check for the following errors: + ** + ** * Too many attached databases, + ** * Transaction currently open + ** * Specified database name already being used. + */ + if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){ + zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", + db->aLimit[SQLITE_LIMIT_ATTACHED] + ); + goto attach_error; + } + if( !db->autoCommit ){ + zErrDyn = sqlite3MPrintf(db, "cannot ATTACH database within transaction"); + goto attach_error; + } + for(i=0; inDb; i++){ + char *z = db->aDb[i].zName; + assert( z && zName ); + if( sqlite3StrICmp(z, zName)==0 ){ + zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName); + goto attach_error; + } + } + + /* Allocate the new entry in the db->aDb[] array and initialize the schema + ** hash tables. + */ + if( db->aDb==db->aDbStatic ){ + aNew = sqlite3DbMallocRaw(db, sizeof(db->aDb[0])*3 ); + if( aNew==0 ) return; + memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); + }else{ + aNew = sqlite3DbRealloc(db, 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 initialized. + */ + flags = db->openFlags; + rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; + sqlite3_result_error(context, zErr, -1); + sqlite3_free(zErr); + return; + } + assert( pVfs ); + flags |= SQLITE_OPEN_MAIN_DB; + rc = sqlite3BtreeOpen(pVfs, zPath, db, &aNew->pBt, 0, flags); + sqlite3_free( zPath ); + db->nDb++; + if( rc==SQLITE_CONSTRAINT ){ + rc = SQLITE_ERROR; + zErrDyn = sqlite3MPrintf(db, "database is already attached"); + }else if( rc==SQLITE_OK ){ + Pager *pPager; + aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt); + if( !aNew->pSchema ){ + rc = SQLITE_NOMEM; + }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){ + zErrDyn = sqlite3MPrintf(db, + "attached databases must use the same text encoding as main database"); + rc = SQLITE_ERROR; + } + sqlite3BtreeEnter(aNew->pBt); + pPager = sqlite3BtreePager(aNew->pBt); + sqlite3PagerLockingMode(pPager, db->dfltLockMode); + sqlite3BtreeSecureDelete(aNew->pBt, + sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); +#ifndef SQLITE_OMIT_PAGER_PRAGMAS + sqlite3BtreeSetPagerFlags(aNew->pBt, 3 | (db->flags & PAGER_FLAGS_MASK)); +#endif + sqlite3BtreeLeave(aNew->pBt); + } + aNew->safety_level = 3; + aNew->zName = sqlite3DbStrDup(db, zName); + if( rc==SQLITE_OK && aNew->zName==0 ){ + rc = SQLITE_NOMEM; + } + + +#ifdef SQLITE_HAS_CODEC + if( rc==SQLITE_OK ){ + extern int sqlite3CodecAttach(sqlite3*, int, const 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 = sqlite3DbStrDup(db, "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]); + rc = 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); + if( nKey>0 || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){ + rc = 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 ){ + sqlite3BtreeEnterAll(db); + rc = sqlite3Init(db, &zErrDyn); + sqlite3BtreeLeaveAll(db); + } +#ifdef SQLITE_USER_AUTHENTICATION + if( rc==SQLITE_OK ){ + u8 newAuth = 0; + rc = sqlite3UserAuthCheckLogin(db, zName, &newAuth); + if( newAuthauth.authLevel ){ + rc = SQLITE_AUTH_USER; + } + } +#endif + if( rc ){ + int iDb = db->nDb - 1; + assert( iDb>=2 ); + if( db->aDb[iDb].pBt ){ + sqlite3BtreeClose(db->aDb[iDb].pBt); + db->aDb[iDb].pBt = 0; + db->aDb[iDb].pSchema = 0; + } + sqlite3ResetAllSchemasOfConnection(db); + db->nDb = iDb; + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ + db->mallocFailed = 1; + sqlite3DbFree(db, zErrDyn); + zErrDyn = sqlite3MPrintf(db, "out of memory"); + }else if( zErrDyn==0 ){ + zErrDyn = sqlite3MPrintf(db, "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); + sqlite3DbFree(db, zErrDyn); + } + if( rc ) sqlite3_result_error_code(context, rc); +} + +/* +** 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 NotUsed, + sqlite3_value **argv +){ + const char *zName = (const char *)sqlite3_value_text(argv[0]); + sqlite3 *db = sqlite3_context_db_handle(context); + int i; + Db *pDb = 0; + char zErr[128]; + + UNUSED_PARAMETER(NotUsed); + + if( zName==0 ) zName = ""; + for(i=0; inDb; 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 ){ + sqlite3_snprintf(sizeof(zErr), zErr, + "cannot DETACH database within transaction"); + goto detach_error; + } + if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){ + sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName); + goto detach_error; + } + + sqlite3BtreeClose(pDb->pBt); + pDb->pBt = 0; + pDb->pSchema = 0; + sqlite3CollapseDatabaseArray(db); + 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 */ + FuncDef const *pFunc,/* FuncDef wrapper for detachFunc() or attachFunc() */ + 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; + sqlite3* db = pParse->db; + int regArgs; + + 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)) + ){ + goto attach_end; + } + +#ifndef SQLITE_OMIT_AUTHORIZATION + if( pAuthArg ){ + char *zAuthArg; + if( pAuthArg->op==TK_STRING ){ + zAuthArg = pAuthArg->u.zToken; + }else{ + zAuthArg = 0; + } + rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0); + if(rc!=SQLITE_OK ){ + goto attach_end; + } + } +#endif /* SQLITE_OMIT_AUTHORIZATION */ + + + v = sqlite3GetVdbe(pParse); + regArgs = sqlite3GetTempRange(pParse, 4); + sqlite3ExprCode(pParse, pFilename, regArgs); + sqlite3ExprCode(pParse, pDbname, regArgs+1); + sqlite3ExprCode(pParse, pKey, regArgs+2); + + assert( v || db->mallocFailed ); + if( v ){ + sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs+3-pFunc->nArg, regArgs+3); + assert( pFunc->nArg==-1 || (pFunc->nArg&0xff)==pFunc->nArg ); + sqlite3VdbeChangeP5(v, (u8)(pFunc->nArg)); + sqlite3VdbeChangeP4(v, -1, (char *)pFunc, P4_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). + */ + sqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH)); + } + +attach_end: + sqlite3ExprDelete(db, pFilename); + sqlite3ExprDelete(db, pDbname); + sqlite3ExprDelete(db, pKey); +} + +/* +** Called by the parser to compile a DETACH statement. +** +** DETACH pDbname +*/ +SQLITE_PRIVATE void sqlite3Detach(Parse *pParse, Expr *pDbname){ + static const FuncDef detach_func = { + 1, /* nArg */ + SQLITE_UTF8, /* funcFlags */ + 0, /* pUserData */ + 0, /* pNext */ + detachFunc, /* xFunc */ + 0, /* xStep */ + 0, /* xFinalize */ + "sqlite_detach", /* zName */ + 0, /* pHash */ + 0 /* pDestructor */ + }; + codeAttach(pParse, SQLITE_DETACH, &detach_func, pDbname, 0, 0, pDbname); +} + +/* +** Called by the parser to compile an ATTACH statement. +** +** ATTACH p AS pDbname KEY pKey +*/ +SQLITE_PRIVATE void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){ + static const FuncDef attach_func = { + 3, /* nArg */ + SQLITE_UTF8, /* funcFlags */ + 0, /* pUserData */ + 0, /* pNext */ + attachFunc, /* xFunc */ + 0, /* xStep */ + 0, /* xFinalize */ + "sqlite_attach", /* zName */ + 0, /* pHash */ + 0 /* pDestructor */ + }; + codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey); +} +#endif /* SQLITE_OMIT_ATTACH */ + +/* +** Initialize a DbFixer structure. This routine must be called prior +** to passing the structure to one of the sqliteFixAAAA() routines below. +*/ +SQLITE_PRIVATE void sqlite3FixInit( + DbFixer *pFix, /* The fixer to be initialized */ + Parse *pParse, /* Error messages will be written here */ + int iDb, /* This is the database that must be used */ + const char *zType, /* "view", "trigger", or "index" */ + const Token *pName /* Name of the view, trigger, or index */ +){ + sqlite3 *db; + + db = pParse->db; + assert( db->nDb>iDb ); + pFix->pParse = pParse; + pFix->zDb = db->aDb[iDb].zName; + pFix->pSchema = db->aDb[iDb].pSchema; + pFix->zType = zType; + pFix->pName = pName; + pFix->bVarOnly = (iDb==1); +} + +/* +** The following set of routines walk through the parse tree and assign +** a specific database to all table references where the database name +** was left unspecified in the original SQL statement. The pFix structure +** must have been initialized by a prior call to sqlite3FixInit(). +** +** These routines are used to make sure that an index, trigger, or +** view in one database does not refer to objects in a different database. +** (Exception: indices, triggers, and views in the TEMP database are +** allowed to refer to anything.) If a reference is explicitly made +** to an object in a different database, an error message is added to +** pParse->zErrMsg and these routines return non-zero. If everything +** checks out, these routines return 0. +*/ +SQLITE_PRIVATE int sqlite3FixSrcList( + DbFixer *pFix, /* Context of the fixation */ + SrcList *pList /* The Source list to check and modify */ +){ + int i; + const char *zDb; + struct SrcList_item *pItem; + + if( NEVER(pList==0) ) return 0; + zDb = pFix->zDb; + for(i=0, pItem=pList->a; inSrc; i++, pItem++){ + if( pFix->bVarOnly==0 ){ + if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){ + sqlite3ErrorMsg(pFix->pParse, + "%s %T cannot reference objects in database %s", + pFix->zType, pFix->pName, pItem->zDatabase); + return 1; + } + sqlite3DbFree(pFix->pParse->db, pItem->zDatabase); + pItem->zDatabase = 0; + pItem->pSchema = pFix->pSchema; + } +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) + if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; + if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1; +#endif + } + return 0; +} +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) +SQLITE_PRIVATE int sqlite3FixSelect( + DbFixer *pFix, /* Context of the fixation */ + Select *pSelect /* The SELECT statement to be fixed to one database */ +){ + while( pSelect ){ + if( sqlite3FixExprList(pFix, pSelect->pEList) ){ + return 1; + } + if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){ + return 1; + } + if( sqlite3FixExpr(pFix, pSelect->pWhere) ){ + return 1; + } + if( sqlite3FixExprList(pFix, pSelect->pGroupBy) ){ + return 1; + } + if( sqlite3FixExpr(pFix, pSelect->pHaving) ){ + return 1; + } + if( sqlite3FixExprList(pFix, pSelect->pOrderBy) ){ + return 1; + } + if( sqlite3FixExpr(pFix, pSelect->pLimit) ){ + return 1; + } + if( sqlite3FixExpr(pFix, pSelect->pOffset) ){ + return 1; + } + pSelect = pSelect->pPrior; + } + return 0; +} +SQLITE_PRIVATE int sqlite3FixExpr( + DbFixer *pFix, /* Context of the fixation */ + Expr *pExpr /* The expression to be fixed to one database */ +){ + while( pExpr ){ + if( pExpr->op==TK_VARIABLE ){ + if( pFix->pParse->db->init.busy ){ + pExpr->op = TK_NULL; + }else{ + sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); + return 1; + } + } + if( ExprHasProperty(pExpr, EP_TokenOnly) ) break; + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1; + }else{ + if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1; + } + if( sqlite3FixExpr(pFix, pExpr->pRight) ){ + return 1; + } + pExpr = pExpr->pLeft; + } + return 0; +} +SQLITE_PRIVATE int sqlite3FixExprList( + DbFixer *pFix, /* Context of the fixation */ + ExprList *pList /* The expression to be fixed to one database */ +){ + int i; + struct ExprList_item *pItem; + if( pList==0 ) return 0; + for(i=0, pItem=pList->a; inExpr; i++, pItem++){ + if( sqlite3FixExpr(pFix, pItem->pExpr) ){ + return 1; + } + } + return 0; +} +#endif + +#ifndef SQLITE_OMIT_TRIGGER +SQLITE_PRIVATE int sqlite3FixTriggerStep( + DbFixer *pFix, /* Context of the fixation */ + TriggerStep *pStep /* The trigger step be fixed to one database */ +){ + while( pStep ){ + if( sqlite3FixSelect(pFix, pStep->pSelect) ){ + return 1; + } + if( sqlite3FixExpr(pFix, pStep->pWhere) ){ + return 1; + } + if( sqlite3FixExprList(pFix, pStep->pExprList) ){ + return 1; + } + pStep = pStep->pNext; + } + return 0; +} +#endif + +/************** End of attach.c **********************************************/ +/************** Begin file auth.c ********************************************/ +/* +** 2003 January 11 +** +** 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 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 +*/ + +/* +** All of the code in this file may be omitted by defining a single +** macro. +*/ +#ifndef SQLITE_OMIT_AUTHORIZATION + +/* +** Set or clear the access authorization function. +** +** The access authorization function is be called during the compilation +** phase to verify that the user has read and/or write access permission on +** various fields of the database. The first argument to the auth function +** is a copy of the 3rd argument to this routine. The second argument +** to the auth function is one of these constants: +** +** SQLITE_CREATE_INDEX +** SQLITE_CREATE_TABLE +** SQLITE_CREATE_TEMP_INDEX +** SQLITE_CREATE_TEMP_TABLE +** SQLITE_CREATE_TEMP_TRIGGER +** SQLITE_CREATE_TEMP_VIEW +** SQLITE_CREATE_TRIGGER +** SQLITE_CREATE_VIEW +** SQLITE_DELETE +** SQLITE_DROP_INDEX +** SQLITE_DROP_TABLE +** SQLITE_DROP_TEMP_INDEX +** SQLITE_DROP_TEMP_TABLE +** SQLITE_DROP_TEMP_TRIGGER +** SQLITE_DROP_TEMP_VIEW +** SQLITE_DROP_TRIGGER +** SQLITE_DROP_VIEW +** SQLITE_INSERT +** SQLITE_PRAGMA +** SQLITE_READ +** SQLITE_SELECT +** SQLITE_TRANSACTION +** SQLITE_UPDATE +** +** The third and fourth arguments to the auth function are the name of +** the table and the column that are being accessed. The auth function +** should return either SQLITE_OK, SQLITE_DENY, or SQLITE_IGNORE. If +** SQLITE_OK is returned, it means that access is allowed. SQLITE_DENY +** means that the SQL statement will never-run - the sqlite3_exec() call +** will return with an error. SQLITE_IGNORE means that the SQL statement +** should run but attempts to read the specified column will return NULL +** and attempts to write the column will be ignored. +** +** Setting the auth function to NULL disables this hook. The default +** setting of the auth function is NULL. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer( + sqlite3 *db, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pArg +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + db->xAuth = (sqlite3_xauth)xAuth; + db->pAuthArg = pArg; + sqlite3ExpirePreparedStatements(db); + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +/* +** Write an error message into pParse->zErrMsg that explains that the +** user-supplied authorization function returned an illegal value. +*/ +static void sqliteAuthBadReturnCode(Parse *pParse){ + sqlite3ErrorMsg(pParse, "authorizer malfunction"); + pParse->rc = SQLITE_ERROR; +} + +/* +** Invoke the authorization callback for permission to read column zCol from +** table zTab in database zDb. This function assumes that an authorization +** callback has been registered (i.e. that sqlite3.xAuth is not NULL). +** +** If SQLITE_IGNORE is returned and pExpr is not NULL, then pExpr is changed +** to an SQL NULL expression. Otherwise, if pExpr is NULL, then SQLITE_IGNORE +** is treated as SQLITE_DENY. In this case an error is left in pParse. +*/ +SQLITE_PRIVATE int sqlite3AuthReadCol( + Parse *pParse, /* The parser context */ + const char *zTab, /* Table name */ + const char *zCol, /* Column name */ + int iDb /* Index of containing database. */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + char *zDb = db->aDb[iDb].zName; /* Name of attached database */ + int rc; /* Auth callback return code */ + + rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext +#ifdef SQLITE_USER_AUTHENTICATION + ,db->auth.zAuthUser +#endif + ); + if( rc==SQLITE_DENY ){ + if( db->nDb>2 || iDb!=0 ){ + sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",zDb,zTab,zCol); + }else{ + sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited", zTab, zCol); + } + pParse->rc = SQLITE_AUTH; + }else if( rc!=SQLITE_IGNORE && rc!=SQLITE_OK ){ + sqliteAuthBadReturnCode(pParse); + } + return rc; +} + +/* +** The pExpr should be a TK_COLUMN expression. The table referred to +** is in pTabList or else it is the NEW or OLD table of a trigger. +** Check to see if it is OK to read this particular column. +** +** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN +** instruction into a TK_NULL. If the auth function returns SQLITE_DENY, +** then generate an error. +*/ +SQLITE_PRIVATE void sqlite3AuthRead( + Parse *pParse, /* The parser context */ + Expr *pExpr, /* The expression to check authorization on */ + Schema *pSchema, /* The schema of the expression */ + SrcList *pTabList /* All table that pExpr might refer to */ +){ + sqlite3 *db = pParse->db; + Table *pTab = 0; /* The table being read */ + const char *zCol; /* Name of the column of the table */ + int iSrc; /* Index in pTabList->a[] of table being read */ + int iDb; /* The index of the database the expression refers to */ + int iCol; /* Index of column in table */ + + if( db->xAuth==0 ) return; + iDb = sqlite3SchemaToIndex(pParse->db, pSchema); + if( iDb<0 ){ + /* An attempt to read a column out of a subquery or other + ** temporary table. */ + return; + } + + assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ); + if( pExpr->op==TK_TRIGGER ){ + pTab = pParse->pTriggerTab; + }else{ + assert( pTabList ); + for(iSrc=0; ALWAYS(iSrcnSrc); iSrc++){ + if( pExpr->iTable==pTabList->a[iSrc].iCursor ){ + pTab = pTabList->a[iSrc].pTab; + break; + } + } + } + iCol = pExpr->iColumn; + if( NEVER(pTab==0) ) return; + + if( iCol>=0 ){ + assert( iColnCol ); + zCol = pTab->aCol[iCol].zName; + }else if( pTab->iPKey>=0 ){ + assert( pTab->iPKeynCol ); + zCol = pTab->aCol[pTab->iPKey].zName; + }else{ + zCol = "ROWID"; + } + assert( iDb>=0 && iDbnDb ); + if( SQLITE_IGNORE==sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){ + pExpr->op = TK_NULL; + } +} + +/* +** Do an authorization check using the code and arguments given. Return +** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY. If SQLITE_DENY +** is returned, then the error count and error message in pParse are +** modified appropriately. +*/ +SQLITE_PRIVATE int sqlite3AuthCheck( + Parse *pParse, + int code, + const char *zArg1, + const char *zArg2, + const char *zArg3 +){ + sqlite3 *db = pParse->db; + int rc; + + /* Don't do any authorization checks if the database is initialising + ** or if the parser is being invoked from within sqlite3_declare_vtab. + */ + if( db->init.busy || IN_DECLARE_VTAB ){ + return SQLITE_OK; + } + + if( db->xAuth==0 ){ + return SQLITE_OK; + } + rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext +#ifdef SQLITE_USER_AUTHENTICATION + ,db->auth.zAuthUser +#endif + ); + if( rc==SQLITE_DENY ){ + sqlite3ErrorMsg(pParse, "not authorized"); + pParse->rc = SQLITE_AUTH; + }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){ + rc = SQLITE_DENY; + sqliteAuthBadReturnCode(pParse); + } + return rc; +} + +/* +** Push an authorization context. After this routine is called, the +** zArg3 argument to authorization callbacks will be zContext until +** popped. Or if pParse==0, this routine is a no-op. +*/ +SQLITE_PRIVATE void sqlite3AuthContextPush( + Parse *pParse, + AuthContext *pContext, + const char *zContext +){ + assert( pParse ); + pContext->pParse = pParse; + pContext->zAuthContext = pParse->zAuthContext; + pParse->zAuthContext = zContext; +} + +/* +** Pop an authorization context that was previously pushed +** by sqlite3AuthContextPush +*/ +SQLITE_PRIVATE void sqlite3AuthContextPop(AuthContext *pContext){ + if( pContext->pParse ){ + pContext->pParse->zAuthContext = pContext->zAuthContext; + pContext->pParse = 0; + } +} + +#endif /* SQLITE_OMIT_AUTHORIZATION */ + +/************** End of auth.c ************************************************/ +/************** Begin file build.c *******************************************/ +/* +** 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. +** +************************************************************************* +** This file contains C code routines that are called by the SQLite parser +** when syntax rules are reduced. The routines in this file handle the +** following kinds of SQL syntax: +** +** CREATE TABLE +** DROP TABLE +** CREATE INDEX +** DROP INDEX +** creating ID lists +** BEGIN TRANSACTION +** COMMIT +** ROLLBACK +*/ + +/* +** This routine is called when a new SQL statement is beginning to +** be parsed. Initialize the pParse structure as needed. +*/ +SQLITE_PRIVATE void sqlite3BeginParse(Parse *pParse, int explainFlag){ + pParse->explain = (u8)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; /* The database containing the table to be locked */ + int iTab; /* The root page of the table to be locked */ + u8 isWriteLock; /* True for write lock. False for a read lock */ + const char *zName; /* Name of the table */ +}; + +/* +** Record the fact that we want to lock a table at run-time. +** +** The table to be locked has root page iTab and is found in database iDb. +** A read or a write lock can be taken depending on isWritelock. +** +** This routine just records the fact that the lock is desired. The +** code to make the lock occur is generated by a later call to +** codeTableLocks() which occurs during sqlite3FinishCoding(). +*/ +SQLITE_PRIVATE void sqlite3TableLock( + Parse *pParse, /* Parsing context */ + int iDb, /* Index of the database containing the table to lock */ + int iTab, /* Root page number of the table to be locked */ + u8 isWriteLock, /* True for a write lock */ + const char *zName /* Name of the table to be locked */ +){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + int i; + int nBytes; + TableLock *p; + assert( iDb>=0 ); + + for(i=0; inTableLock; i++){ + p = &pToplevel->aTableLock[i]; + if( p->iDb==iDb && p->iTab==iTab ){ + p->isWriteLock = (p->isWriteLock || isWriteLock); + return; + } + } + + nBytes = sizeof(TableLock) * (pToplevel->nTableLock+1); + pToplevel->aTableLock = + sqlite3DbReallocOrFree(pToplevel->db, pToplevel->aTableLock, nBytes); + if( pToplevel->aTableLock ){ + p = &pToplevel->aTableLock[pToplevel->nTableLock++]; + p->iDb = iDb; + p->iTab = iTab; + p->isWriteLock = isWriteLock; + p->zName = zName; + }else{ + pToplevel->nTableLock = 0; + pToplevel->db->mallocFailed = 1; + } +} + +/* +** 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; + + pVdbe = sqlite3GetVdbe(pParse); + assert( pVdbe!=0 ); /* sqlite3GetVdbe cannot fail: VDBE already allocated */ + + for(i=0; inTableLock; i++){ + TableLock *p = &pParse->aTableLock[i]; + int p1 = p->iDb; + sqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, p->isWriteLock, + p->zName, P4_STATIC); + } +} +#else + #define codeTableLocks(x) +#endif + +/* +** Return TRUE if the given yDbMask object is empty - if it contains no +** 1 bits. This routine is used by the DbMaskAllZero() and DbMaskNotZero() +** macros when SQLITE_MAX_ATTACHED is greater than 30. +*/ +#if SQLITE_MAX_ATTACHED>30 +SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask m){ + int i; + for(i=0; ipToplevel==0 ); + db = pParse->db; + if( pParse->nested ) return; + if( db->mallocFailed || pParse->nErr ){ + if( pParse->rc==SQLITE_OK ) pParse->rc = SQLITE_ERROR; + return; + } + + /* Begin by generating some termination code at the end of the + ** vdbe program + */ + v = sqlite3GetVdbe(pParse); + assert( !pParse->isMultiWrite + || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); + if( v ){ + while( sqlite3VdbeDeletePriorOpcode(v, OP_Close) ){} + sqlite3VdbeAddOp0(v, OP_Halt); + +#if SQLITE_USER_AUTHENTICATION + if( pParse->nTableLock>0 && db->init.busy==0 ){ + sqlite3UserAuthInit(db); + if( db->auth.authLevelrc = SQLITE_AUTH_USER; + sqlite3ErrorMsg(pParse, "user not authenticated"); + return; + } + } +#endif + + /* The cookie mask contains one bit for each database file open. + ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are + ** 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( db->mallocFailed==0 + && (DbMaskNonZero(pParse->cookieMask) || pParse->pConstExpr) + ){ + int iDb, i; + assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); + sqlite3VdbeJumpHere(v, 0); + for(iDb=0; iDbnDb; iDb++){ + if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue; + sqlite3VdbeUsesBtree(v, iDb); + sqlite3VdbeAddOp4Int(v, + OP_Transaction, /* Opcode */ + iDb, /* P1 */ + DbMaskTest(pParse->writeMask,iDb), /* P2 */ + pParse->cookieValue[iDb], /* P3 */ + db->aDb[iDb].pSchema->iGeneration /* P4 */ + ); + if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1); + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + for(i=0; inVtabLock; i++){ + char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]); + sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB); + } + pParse->nVtabLock = 0; +#endif + + /* 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); + + /* Initialize any AUTOINCREMENT data structures required. + */ + sqlite3AutoincrementBegin(pParse); + + /* Code constant expressions that where factored out of inner loops */ + if( pParse->pConstExpr ){ + ExprList *pEL = pParse->pConstExpr; + pParse->okConstFactor = 0; + for(i=0; inExpr; i++){ + sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg); + } + } + + /* Finally, jump back to the beginning of the executable code. */ + sqlite3VdbeAddOp2(v, OP_Goto, 0, 1); + } + } + + + /* Get the VDBE program ready for execution + */ + if( v && pParse->nErr==0 && !db->mallocFailed ){ + assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */ + /* A minimum of one cursor is required if autoincrement is used + * See ticket [a696379c1f08866] */ + if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1; + sqlite3VdbeMakeReady(v, pParse); + pParse->rc = SQLITE_DONE; + pParse->colNamesSet = 0; + }else{ + pParse->rc = SQLITE_ERROR; + } + pParse->nTab = 0; + pParse->nMem = 0; + pParse->nSet = 0; + pParse->nVar = 0; + DbMaskZero(pParse->cookieMask); +} + +/* +** Run the parser and code generator recursively in order to generate +** code for the SQL statement given onto the end of the pParse context +** currently under construction. When the parser is run recursively +** this way, the final OP_Halt is not appended and other initialization +** and finalization steps are omitted because those are handling by the +** outermost parser. +** +** 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. +*/ +SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ + va_list ap; + char *zSql; + char *zErrMsg = 0; + sqlite3 *db = pParse->db; +# 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(db, 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, &zErrMsg); + sqlite3DbFree(db, zErrMsg); + sqlite3DbFree(db, zSql); + memcpy(&pParse->nVar, saveBuf, SAVE_SZ); + pParse->nested--; +} + +#if SQLITE_USER_AUTHENTICATION +/* +** Return TRUE if zTable is the name of the system table that stores the +** list of users and their access credentials. +*/ +SQLITE_PRIVATE int sqlite3UserAuthTable(const char *zTable){ + return sqlite3_stricmp(zTable, "sqlite_user")==0; +} +#endif + +/* +** Locate the in-memory structure that describes a particular database +** table given the name of that table and (optionally) the name of the +** database containing the table. Return NULL if not found. +** +** If zDatabase is 0, all databases are searched for the table and the +** first matching table is returned. (No checking for duplicate table +** names is done.) The search order is TEMP first, then MAIN, then any +** auxiliary databases added using the ATTACH command. +** +** See also sqlite3LocateTable(). +*/ +SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){ + Table *p = 0; + int i; + + /* All mutexes are required for schema access. Make sure we hold them. */ + assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) ); +#if SQLITE_USER_AUTHENTICATION + /* Only the admin user is allowed to know that the sqlite_user table + ** exists */ + if( db->auth.authLevelnDb; i++){ + int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ + if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue; + assert( sqlite3SchemaMutexHeld(db, j, 0) ); + p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName); + if( p ) break; + } + return p; +} + +/* +** Locate the in-memory structure that describes a particular database +** table given the name of that table and (optionally) the name of the +** database containing the table. Return NULL if not found. Also leave an +** error message in pParse->zErrMsg. +** +** The difference between this routine and sqlite3FindTable() is that this +** routine leaves an error message in pParse->zErrMsg where +** sqlite3FindTable() does not. +*/ +SQLITE_PRIVATE Table *sqlite3LocateTable( + Parse *pParse, /* context in which to report errors */ + int isView, /* True if looking for a VIEW rather than a TABLE */ + const char *zName, /* Name of the table we are looking for */ + const char *zDbase /* Name of the database. Might be NULL */ +){ + Table *p; + + /* 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 0; + } + + p = sqlite3FindTable(pParse->db, zName, zDbase); + if( p==0 ){ + const char *zMsg = isView ? "no such view" : "no such table"; + if( zDbase ){ + sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName); + }else{ + sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName); + } + pParse->checkSchema = 1; + } +#if SQLITE_USER_AUTHENICATION + else if( pParse->db->auth.authLevelpSchema) if it is not NULL. p->pSchema may be +** non-NULL if it is part of a view or trigger program definition. See +** sqlite3FixSrcList() for details. +*/ +SQLITE_PRIVATE Table *sqlite3LocateTableItem( + Parse *pParse, + int isView, + struct SrcList_item *p +){ + const char *zDb; + assert( p->pSchema==0 || p->zDatabase==0 ); + if( p->pSchema ){ + int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema); + zDb = pParse->db->aDb[iDb].zName; + }else{ + zDb = p->zDatabase; + } + return sqlite3LocateTable(pParse, isView, p->zName, zDb); +} + +/* +** Locate the in-memory structure that describes +** a particular index given the name of that index +** and the name of the database that contains the index. +** Return NULL if not found. +** +** If zDatabase is 0, all databases are searched for the +** table and the first matching index is returned. (No checking +** for duplicate index names is done.) The search order is +** TEMP first, then MAIN, then any auxiliary databases added +** using the ATTACH command. +*/ +SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){ + Index *p = 0; + int i; + /* All mutexes are required for schema access. Make sure we hold them. */ + assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); + for(i=OMIT_TEMPDB; inDb; i++){ + int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ + Schema *pSchema = db->aDb[j].pSchema; + assert( pSchema ); + if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue; + assert( sqlite3SchemaMutexHeld(db, j, 0) ); + p = sqlite3HashFind(&pSchema->idxHash, zName); + if( p ) break; + } + return p; +} + +/* +** Reclaim the memory used by an index +*/ +static void freeIndex(sqlite3 *db, Index *p){ +#ifndef SQLITE_OMIT_ANALYZE + sqlite3DeleteIndexSamples(db, p); +#endif + sqlite3ExprDelete(db, p->pPartIdxWhere); + sqlite3DbFree(db, p->zColAff); + if( p->isResized ) sqlite3DbFree(db, p->azColl); +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + sqlite3_free(p->aiRowEst); +#endif + sqlite3DbFree(db, 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. +*/ +SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){ + Index *pIndex; + Hash *pHash; + + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pHash = &db->aDb[iDb].pSchema->idxHash; + pIndex = sqlite3HashInsert(pHash, zIdxName, 0); + if( ALWAYS(pIndex) ){ + if( pIndex->pTable->pIndex==pIndex ){ + pIndex->pTable->pIndex = pIndex->pNext; + }else{ + Index *p; + /* Justification of ALWAYS(); The index must be on the list of + ** indices. */ + p = pIndex->pTable->pIndex; + while( ALWAYS(p) && p->pNext!=pIndex ){ p = p->pNext; } + if( ALWAYS(p && p->pNext==pIndex) ){ + p->pNext = pIndex->pNext; + } + } + freeIndex(db, pIndex); + } + db->flags |= SQLITE_InternChanges; +} + +/* +** Look through the list of open database files in db->aDb[] and if +** any have been closed, remove them from the list. Reallocate the +** db->aDb[] structure to a smaller size, if possible. +** +** Entry 0 (the "main" database) and entry 1 (the "temp" database) +** are never candidates for being collapsed. +*/ +SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3 *db){ + int i, j; + for(i=j=2; inDb; i++){ + struct Db *pDb = &db->aDb[i]; + if( pDb->pBt==0 ){ + sqlite3DbFree(db, pDb->zName); + pDb->zName = 0; + continue; + } + if( jaDb[j] = db->aDb[i]; + } + j++; + } + memset(&db->aDb[j], 0, (db->nDb-j)*sizeof(db->aDb[j])); + db->nDb = j; + if( db->nDb<=2 && db->aDb!=db->aDbStatic ){ + memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0])); + sqlite3DbFree(db, db->aDb); + db->aDb = db->aDbStatic; + } +} + +/* +** Reset the schema for the database at index iDb. Also reset the +** TEMP schema. +*/ +SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3 *db, int iDb){ + Db *pDb; + assert( iDbnDb ); + + /* Case 1: Reset the single schema identified by iDb */ + pDb = &db->aDb[iDb]; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( pDb->pSchema!=0 ); + sqlite3SchemaClear(pDb->pSchema); + + /* If any database other than TEMP is reset, then also reset TEMP + ** since TEMP might be holding triggers that reference tables in the + ** other database. + */ + if( iDb!=1 ){ + pDb = &db->aDb[1]; + assert( pDb->pSchema!=0 ); + sqlite3SchemaClear(pDb->pSchema); + } + return; +} + +/* +** Erase all schema information from all attached databases (including +** "main" and "temp") for a single database connection. +*/ +SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){ + int i; + sqlite3BtreeEnterAll(db); + for(i=0; inDb; i++){ + Db *pDb = &db->aDb[i]; + if( pDb->pSchema ){ + sqlite3SchemaClear(pDb->pSchema); + } + } + db->flags &= ~SQLITE_InternChanges; + sqlite3VtabUnlockList(db); + sqlite3BtreeLeaveAll(db); + sqlite3CollapseDatabaseArray(db); +} + +/* +** This routine is called when a commit occurs. +*/ +SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3 *db){ + db->flags &= ~SQLITE_InternChanges; +} + +/* +** Delete memory allocated for the column names of a table or view (the +** Table.aCol[] array). +*/ +static void sqliteDeleteColumnNames(sqlite3 *db, Table *pTable){ + int i; + Column *pCol; + assert( pTable!=0 ); + if( (pCol = pTable->aCol)!=0 ){ + for(i=0; inCol; i++, pCol++){ + sqlite3DbFree(db, pCol->zName); + sqlite3ExprDelete(db, pCol->pDflt); + sqlite3DbFree(db, pCol->zDflt); + sqlite3DbFree(db, pCol->zType); + sqlite3DbFree(db, pCol->zColl); + } + sqlite3DbFree(db, pTable->aCol); + } +} + +/* +** Remove the memory data structures associated with the given +** Table. No changes are made to disk by this routine. +** +** This routine just deletes the data structure. It does not unlink +** the table data structure from the hash table. But it does destroy +** memory structures of the indices and foreign keys associated with +** the table. +** +** The db parameter is optional. It is needed if the Table object +** contains lookaside memory. (Table objects in the schema do not use +** lookaside memory, but some ephemeral Table objects do.) Or the +** db parameter can be used with db->pnBytesFreed to measure the memory +** used by the Table object. +*/ +SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ + Index *pIndex, *pNext; + TESTONLY( int nLookaside; ) /* Used to verify lookaside not used for schema */ + + assert( !pTable || pTable->nRef>0 ); + + /* Do not delete the table until the reference count reaches zero. */ + if( !pTable ) return; + if( ((!db || db->pnBytesFreed==0) && (--pTable->nRef)>0) ) return; + + /* Record the number of outstanding lookaside allocations in schema Tables + ** prior to doing any free() operations. Since schema Tables do not use + ** lookaside, this number should not change. */ + TESTONLY( nLookaside = (db && (pTable->tabFlags & TF_Ephemeral)==0) ? + db->lookaside.nOut : 0 ); + + /* Delete all indices associated with this table. */ + for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){ + pNext = pIndex->pNext; + assert( pIndex->pSchema==pTable->pSchema ); + if( !db || db->pnBytesFreed==0 ){ + char *zName = pIndex->zName; + TESTONLY ( Index *pOld = ) sqlite3HashInsert( + &pIndex->pSchema->idxHash, zName, 0 + ); + assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); + assert( pOld==pIndex || pOld==0 ); + } + freeIndex(db, pIndex); + } + + /* Delete any foreign keys attached to this table. */ + sqlite3FkDelete(db, pTable); + + /* Delete the Table structure itself. + */ + sqliteDeleteColumnNames(db, pTable); + sqlite3DbFree(db, pTable->zName); + sqlite3DbFree(db, pTable->zColAff); + sqlite3SelectDelete(db, pTable->pSelect); +#ifndef SQLITE_OMIT_CHECK + sqlite3ExprListDelete(db, pTable->pCheck); +#endif +#ifndef SQLITE_OMIT_VIRTUALTABLE + sqlite3VtabClear(db, pTable); +#endif + sqlite3DbFree(db, pTable); + + /* Verify that no lookaside memory was used by schema tables */ + assert( nLookaside==0 || nLookaside==db->lookaside.nOut ); +} + +/* +** Unlink the given table from the hash tables and the delete the +** table structure with all its indices and foreign keys. +*/ +SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){ + Table *p; + Db *pDb; + + assert( db!=0 ); + assert( iDb>=0 && iDbnDb ); + assert( zTabName ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + testcase( zTabName[0]==0 ); /* Zero-length table names are allowed */ + pDb = &db->aDb[iDb]; + p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, 0); + sqlite3DeleteTable(db, p); + db->flags |= SQLITE_InternChanges; +} + +/* +** Given a token, return a string that consists of the text of that +** token. Space to hold the returned string +** is obtained from sqliteMalloc() and must be freed by the calling +** function. +** +** Any quotation marks (ex: "name", 'name', [name], or `name`) that +** surround the body of the token are removed. +** +** 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. +*/ +SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3 *db, Token *pName){ + char *zName; + if( pName ){ + zName = sqlite3DbStrNDup(db, (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. +*/ +SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *p, int iDb){ + Vdbe *v = sqlite3GetVdbe(p); + sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb)); + sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, MASTER_ROOT, iDb, 5); + if( p->nTab==0 ){ + p->nTab = 1; + } +} + +/* +** Parameter zName points to a nul-terminated buffer containing the name +** of a database ("main", "temp" or the name of an attached db). This +** function returns the index of the named database in db->aDb[], or +** -1 if the named db cannot be found. +*/ +SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *db, const char *zName){ + int i = -1; /* Database number */ + if( zName ){ + Db *pDb; + int n = sqlite3Strlen30(zName); + for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){ + if( (!OMIT_TEMPDB || i!=1 ) && n==sqlite3Strlen30(pDb->zName) && + 0==sqlite3StrICmp(pDb->zName, zName) ){ + break; + } + } + } + return i; +} + +/* +** 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. +*/ +SQLITE_PRIVATE int sqlite3FindDb(sqlite3 *db, Token *pName){ + int i; /* Database number */ + char *zName; /* Name we are searching for */ + zName = sqlite3NameFromToken(db, pName); + i = sqlite3FindDbName(db, zName); + sqlite3DbFree(db, zName); + return i; +} + +/* The table or view or trigger name is passed to this routine via tokens +** pName1 and pName2. If the table name was fully qualified, for example: +** +** CREATE TABLE xxx.yyy (...); +** +** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if +** the table name is not fully qualified, i.e.: +** +** CREATE TABLE yyy(...); +** +** Then pName1 is set to "yyy" and pName2 is "". +** +** This routine sets the *ppUnqual pointer to point at the token (pName1 or +** pName2) that stores the unqualified table name. The index of the +** database "xxx" is returned. +*/ +SQLITE_PRIVATE int sqlite3TwoPartName( + Parse *pParse, /* Parsing and code generating context */ + Token *pName1, /* The "xxx" in the name "xxx.yyy" or "xxx" */ + Token *pName2, /* The "yyy" in the name "xxx.yyy" */ + Token **pUnqual /* Write the unqualified object name here */ +){ + int iDb; /* Database holding the object */ + sqlite3 *db = pParse->db; + + if( ALWAYS(pName2!=0) && pName2->n>0 ){ + if( db->init.busy ) { + sqlite3ErrorMsg(pParse, "corrupt database"); + return -1; + } + *pUnqual = pName2; + iDb = sqlite3FindDb(db, pName1); + if( iDb<0 ){ + sqlite3ErrorMsg(pParse, "unknown database %T", pName1); + return -1; + } + }else{ + assert( db->init.iDb==0 || db->init.busy ); + iDb = db->init.iDb; + *pUnqual = pName1; + } + return iDb; +} + +/* +** This routine is used to check if the UTF-8 string zName is a legal +** 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. +*/ +SQLITE_PRIVATE 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; +} + +/* +** Return the PRIMARY KEY index of a table +*/ +SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table *pTab){ + Index *p; + for(p=pTab->pIndex; p && !IsPrimaryKeyIndex(p); p=p->pNext){} + return p; +} + +/* +** Return the column of index pIdx that corresponds to table +** column iCol. Return -1 if not found. +*/ +SQLITE_PRIVATE i16 sqlite3ColumnOfIndex(Index *pIdx, i16 iCol){ + int i; + for(i=0; inColumn; i++){ + if( iCol==pIdx->aiColumn[i] ) return i; + } + return -1; +} + +/* +** Begin constructing a new table representation in memory. This is +** the first of several action routines that get called in response +** to a CREATE TABLE statement. In particular, this routine is called +** after seeing tokens "CREATE" and "TABLE" and the table name. The isTemp +** flag is true if the table should be stored in the auxiliary database +** file instead of in the main database file. This is normally the case +** when the "TEMP" or "TEMPORARY" keyword occurs in between +** CREATE and TABLE. +** +** The new table record is initialized and put in pParse->pNewTable. +** As more of the CREATE TABLE statement is parsed, additional action +** routines will be called to add more information to this record. +** At the end of the CREATE TABLE statement, the sqlite3EndTable() routine +** is called to complete the construction of the new table record. +*/ +SQLITE_PRIVATE void sqlite3StartTable( + Parse *pParse, /* Parser context */ + 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 isVirtual, /* True if this is a VIRTUAL table */ + 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 + ** pName1 and pName2. If the table name was fully qualified, for example: + ** + ** CREATE TABLE xxx.yyy (...); + ** + ** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if + ** the table name is not fully qualified, i.e.: + ** + ** CREATE TABLE yyy(...); + ** + ** Then pName1 is set to "yyy" and pName2 is "". + ** + ** 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 && pName2->n>0 && iDb!=1 ){ + /* If creating a temp table, the name may not be qualified. Unless + ** the database name is "temp" anyway. */ + sqlite3ErrorMsg(pParse, "temporary table name must be unqualified"); + return; + } + if( !OMIT_TEMPDB && isTemp ) iDb = 1; + + pParse->sNameToken = *pName; + zName = sqlite3NameFromToken(db, 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( !isVirtual && 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. The exception is if the statement being parsed was passed + ** to an sqlite3_declare_vtab() call. In that case only the column names + ** and types will be used, so there is no need to test for namespace + ** collisions. + */ + if( !IN_DECLARE_VTAB ){ + char *zDb = db->aDb[iDb].zName; + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + goto begin_table_error; + } + pTable = sqlite3FindTable(db, zName, zDb); + if( pTable ){ + if( !noErr ){ + sqlite3ErrorMsg(pParse, "table %T already exists", pName); + }else{ + assert( !db->init.busy || CORRUPT_DB ); + sqlite3CodeVerifySchema(pParse, iDb); + } + goto begin_table_error; + } + if( sqlite3FindIndex(db, zName, zDb)!=0 ){ + sqlite3ErrorMsg(pParse, "there is already an index named %s", zName); + goto begin_table_error; + } + } + + pTable = sqlite3DbMallocZero(db, sizeof(Table)); + if( pTable==0 ){ + db->mallocFailed = 1; + pParse->rc = SQLITE_NOMEM; + pParse->nErr++; + goto begin_table_error; + } + pTable->zName = zName; + pTable->iPKey = -1; + pTable->pSchema = db->aDb[iDb].pSchema; + pTable->nRef = 1; + pTable->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); + assert( pParse->pNewTable==0 ); + 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 ){ + assert( sqlite3SchemaMutexHeld(db, iDb, 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 j1; + int fileFormat; + int reg1, reg2, reg3; + sqlite3BeginWriteOperation(pParse, 0, iDb); + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( isVirtual ){ + sqlite3VdbeAddOp0(v, OP_VBegin); + } +#endif + + /* If the file format and encoding in the database have not been set, + ** set them now. + */ + reg1 = pParse->regRowid = ++pParse->nMem; + reg2 = pParse->regRoot = ++pParse->nMem; + reg3 = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT); + sqlite3VdbeUsesBtree(v, iDb); + j1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v); + fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ? + 1 : SQLITE_MAX_FILE_FORMAT; + sqlite3VdbeAddOp2(v, OP_Integer, fileFormat, reg3); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, reg3); + sqlite3VdbeAddOp2(v, OP_Integer, ENC(db), reg3); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, reg3); + sqlite3VdbeJumpHere(v, j1); + + /* 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 in register pParse->regRowid. + ** The root page number of the new table is left in reg pParse->regRoot. + ** The rowid and root page number values are needed by the code that + ** sqlite3EndTable will generate. + */ +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) + if( isView || isVirtual ){ + sqlite3VdbeAddOp2(v, OP_Integer, 0, reg2); + }else +#endif + { + pParse->addrCrTab = sqlite3VdbeAddOp2(v, OP_CreateTable, iDb, reg2); + } + sqlite3OpenMasterTable(pParse, iDb); + sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1); + sqlite3VdbeAddOp2(v, OP_Null, 0, reg3); + sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3VdbeAddOp0(v, OP_Close); + } + + /* Normal (non-error) return. */ + return; + + /* If an error occurs, we jump here */ +begin_table_error: + sqlite3DbFree(db, zName); + return; +} + +/* +** This macro is used to compare two strings in a case-insensitive manner. +** It is slightly faster than calling sqlite3StrICmp() directly, but +** produces larger code. +** +** WARNING: This macro is not compatible with the strcmp() family. It +** returns true if the two strings are equal, otherwise false. +*/ +#define STRICMP(x, y) (\ +sqlite3UpperToLower[*(unsigned char *)(x)]== \ +sqlite3UpperToLower[*(unsigned char *)(y)] \ +&& sqlite3StrICmp((x)+1,(y)+1)==0 ) + +/* +** Add a new column to the table currently being constructed. +** +** The parser calls this routine once for each column declaration +** in a CREATE TABLE statement. sqlite3StartTable() gets called +** first to get things going. Then this routine is called for each +** column. +*/ +SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName){ + Table *p; + int i; + char *z; + Column *pCol; + sqlite3 *db = pParse->db; + if( (p = pParse->pNewTable)==0 ) return; +#if SQLITE_MAX_COLUMN + if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){ + sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName); + return; + } +#endif + z = sqlite3NameFromToken(db, pName); + if( z==0 ) return; + for(i=0; inCol; i++){ + if( STRICMP(z, p->aCol[i].zName) ){ + sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); + sqlite3DbFree(db, z); + return; + } + } + if( (p->nCol & 0x7)==0 ){ + Column *aNew; + aNew = sqlite3DbRealloc(db,p->aCol,(p->nCol+8)*sizeof(p->aCol[0])); + if( aNew==0 ){ + sqlite3DbFree(db, 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; + pCol->szEst = 1; + 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 +** the column currently under construction. +*/ +SQLITE_PRIVATE void sqlite3AddNotNull(Parse *pParse, int onError){ + Table *p; + p = pParse->pNewTable; + if( p==0 || NEVER(p->nCol<1) ) return; + p->aCol[p->nCol-1].notNull = (u8)onError; +} + +/* +** Scan the column type name zType (length nType) and return the +** associated affinity type. +** +** This routine does a case-independent search of zType for the +** substrings in the following table. If one of the substrings is +** found, the corresponding affinity is returned. If zType contains +** more than one of the substrings, entries toward the top of +** the table take priority. For example, if zType is 'BLOBINT', +** SQLITE_AFF_INTEGER is returned. +** +** 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. +*/ +SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, u8 *pszEst){ + u32 h = 0; + char aff = SQLITE_AFF_NUMERIC; + const char *zChar = 0; + + if( zIn==0 ) return aff; + while( zIn[0] ){ + h = (h<<8) + sqlite3UpperToLower[(*zIn)&0xff]; + zIn++; + if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */ + aff = SQLITE_AFF_TEXT; + zChar = zIn; + }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; + if( zIn[0]=='(' ) zChar = zIn; +#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; + } + } + + /* If pszEst is not NULL, store an estimate of the field size. The + ** estimate is scaled so that the size of an integer is 1. */ + if( pszEst ){ + *pszEst = 1; /* default size is approx 4 bytes */ + if( aff255 ) v = 255; + *pszEst = v; /* BLOB(k), VARCHAR(k), CHAR(k) -> r=(k/4+1) */ + break; + } + zChar++; + } + }else{ + *pszEst = 5; /* BLOB, TEXT, CLOB -> r=5 (approx 20 bytes)*/ + } + } + } + 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. +*/ +SQLITE_PRIVATE void sqlite3AddColumnType(Parse *pParse, Token *pType){ + Table *p; + Column *pCol; + + p = pParse->pNewTable; + if( p==0 || NEVER(p->nCol<1) ) return; + pCol = &p->aCol[p->nCol-1]; + assert( pCol->zType==0 || CORRUPT_DB ); + sqlite3DbFree(pParse->db, pCol->zType); + pCol->zType = sqlite3NameFromToken(pParse->db, pType); + pCol->affinity = sqlite3AffinityType(pCol->zType, &pCol->szEst); +} + +/* +** 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. +*/ +SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){ + Table *p; + Column *pCol; + sqlite3 *db = pParse->db; + p = pParse->pNewTable; + if( p!=0 ){ + pCol = &(p->aCol[p->nCol-1]); + if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr, db->init.busy) ){ + sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", + pCol->zName); + }else{ + /* A copy of pExpr is used instead of the original, as pExpr contains + ** tokens that point to volatile memory. The 'span' of the expression + ** is required by pragma table_info. + */ + sqlite3ExprDelete(db, pCol->pDflt); + pCol->pDflt = sqlite3ExprDup(db, pSpan->pExpr, EXPRDUP_REDUCE); + sqlite3DbFree(db, pCol->zDflt); + pCol->zDflt = sqlite3DbStrNDup(db, (char*)pSpan->zStart, + (int)(pSpan->zEnd - pSpan->zStart)); + } + } + sqlite3ExprDelete(db, pSpan->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 +** most recently added column of the table is the primary key. +** +** A table can have at most one primary key. If the table already has +** a primary key (and this is the second primary key) then create an +** error. +** +** If the PRIMARY KEY is on a single column whose datatype is INTEGER, +** then we will try to use that column as the rowid. Set the Table.iPKey +** field of the table under construction to be the index of the +** INTEGER PRIMARY KEY column. Table.iPKey is set to -1 if there is +** no INTEGER PRIMARY KEY. +** +** 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. +*/ +SQLITE_PRIVATE 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; + int nTerm; + if( pTab==0 || IN_DECLARE_VTAB ) goto primary_key_exit; + if( pTab->tabFlags & TF_HasPrimaryKey ){ + sqlite3ErrorMsg(pParse, + "table \"%s\" has more than one primary key", pTab->zName); + goto primary_key_exit; + } + pTab->tabFlags |= TF_HasPrimaryKey; + if( pList==0 ){ + iCol = pTab->nCol - 1; + pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY; + zType = pTab->aCol[iCol].zType; + nTerm = 1; + }else{ + nTerm = pList->nExpr; + for(i=0; inCol; iCol++){ + if( sqlite3StrICmp(pList->a[i].zName, pTab->aCol[iCol].zName)==0 ){ + pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY; + zType = pTab->aCol[iCol].zType; + break; + } + } + } + } + if( nTerm==1 + && zType && sqlite3StrICmp(zType, "INTEGER")==0 + && sortOrder==SQLITE_SO_ASC + ){ + pTab->iPKey = iCol; + pTab->keyConf = (u8)onError; + assert( autoInc==0 || autoInc==1 ); + pTab->tabFlags |= autoInc*TF_Autoincrement; + if( pList ) pParse->iPkSortOrder = pList->a[0].sortOrder; + }else if( autoInc ){ +#ifndef SQLITE_OMIT_AUTOINCREMENT + sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an " + "INTEGER PRIMARY KEY"); +#endif + }else{ + Vdbe *v = pParse->pVdbe; + Index *p; + if( v ) pParse->addrSkipPK = sqlite3VdbeAddOp0(v, OP_Noop); + p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, + 0, sortOrder, 0); + if( p ){ + p->idxType = SQLITE_IDXTYPE_PRIMARYKEY; + if( v ) sqlite3VdbeJumpHere(v, pParse->addrSkipPK); + } + pList = 0; + } + +primary_key_exit: + sqlite3ExprListDelete(pParse->db, pList); + return; +} + +/* +** Add a new CHECK constraint to the table currently under construction. +*/ +SQLITE_PRIVATE void sqlite3AddCheckConstraint( + Parse *pParse, /* Parsing context */ + Expr *pCheckExpr /* The check expression */ +){ +#ifndef SQLITE_OMIT_CHECK + Table *pTab = pParse->pNewTable; + sqlite3 *db = pParse->db; + if( pTab && !IN_DECLARE_VTAB + && !sqlite3BtreeIsReadonly(db->aDb[db->init.iDb].pBt) + ){ + pTab->pCheck = sqlite3ExprListAppend(pParse, pTab->pCheck, pCheckExpr); + if( pParse->constraintName.n ){ + sqlite3ExprListSetName(pParse, pTab->pCheck, &pParse->constraintName, 1); + } + }else +#endif + { + sqlite3ExprDelete(pParse->db, pCheckExpr); + } +} + +/* +** Set the collation function of the most recently parsed table column +** to the CollSeq given. +*/ +SQLITE_PRIVATE void sqlite3AddCollateType(Parse *pParse, Token *pToken){ + Table *p; + int i; + char *zColl; /* Dequoted name of collation sequence */ + sqlite3 *db; + + if( (p = pParse->pNewTable)==0 ) return; + i = p->nCol-1; + db = pParse->db; + zColl = sqlite3NameFromToken(db, pToken); + if( !zColl ) return; + + if( sqlite3LocateCollSeq(pParse, zColl) ){ + Index *pIdx; + sqlite3DbFree(db, p->aCol[i].zColl); + p->aCol[i].zColl = zColl; + + /* If the column is declared as " PRIMARY KEY COLLATE ", + ** 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->nKeyCol==1 ); + if( pIdx->aiColumn[0]==i ){ + pIdx->azColl[0] = p->aCol[i].zColl; + } + } + }else{ + sqlite3DbFree(db, 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. +** +** This routine is a wrapper around sqlite3FindCollSeq(). This routine +** invokes the collation factory if the named collation cannot be found +** and generates an error message. +** +** See also: sqlite3FindCollSeq(), sqlite3GetCollSeq() +*/ +SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){ + sqlite3 *db = pParse->db; + u8 enc = ENC(db); + u8 initbusy = db->init.busy; + CollSeq *pColl; + + pColl = sqlite3FindCollSeq(db, enc, zName, initbusy); + if( !initbusy && (!pColl || !pColl->xCmp) ){ + pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName); + } + + return pColl; +} + + +/* +** Generate code that will increment the schema cookie. +** +** The schema cookie is used to determine when the schema for the +** database changes. After each schema change, the cookie value +** changes. When a process first reads the schema it records the +** cookie. Thereafter, whenever it goes to access the database, +** it checks the cookie to make sure the schema has not changed +** since it was last read. +** +** 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. +*/ +SQLITE_PRIVATE void sqlite3ChangeCookie(Parse *pParse, int iDb){ + int r1 = sqlite3GetTempReg(pParse); + sqlite3 *db = pParse->db; + Vdbe *v = pParse->pVdbe; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + sqlite3VdbeAddOp2(v, OP_Integer, db->aDb[iDb].pSchema->schema_cookie+1, r1); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, r1); + sqlite3ReleaseTempReg(pParse, r1); +} + +/* +** 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. +** +** The estimate is conservative. It might be larger that what is +** really needed. +*/ +static int identLength(const char *z){ + int n; + for(n=0; *z; n++, z++){ + if( *z=='"' ){ n++; } + } + return n + 2; +} + +/* +** The first parameter is a pointer to an output buffer. The second +** parameter is a pointer to an integer that contains the offset at +** which to write into the output buffer. This function copies the +** nul-terminated string pointed to by the third parameter, zSignedIdent, +** to the specified offset in the buffer and updates *pIdx to refer +** to the first byte after the last byte written before returning. +** +** If the string zSignedIdent consists entirely of alpha-numeric +** characters, does not begin with a digit and is not an SQL keyword, +** then it is copied to the output buffer exactly as it is. Otherwise, +** it is quoted using double-quotes. +*/ +static void identPut(char *z, int *pIdx, char *zSignedIdent){ + unsigned char *zIdent = (unsigned char*)zSignedIdent; + int i, j, needQuote; + i = *pIdx; + + for(j=0; zIdent[j]; j++){ + if( !sqlite3Isalnum(zIdent[j]) && zIdent[j]!='_' ) break; + } + needQuote = sqlite3Isdigit(zIdent[0]) + || sqlite3KeywordCode(zIdent, j)!=TK_ID + || zIdent[j]!=0 + || j==0; + + if( needQuote ) z[i++] = '"'; + for(j=0; zIdent[j]; j++){ + z[i++] = zIdent[j]; + if( zIdent[j]=='"' ) z[i++] = '"'; + } + if( needQuote ) z[i++] = '"'; + z[i] = 0; + *pIdx = i; +} + +/* +** 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(sqlite3 *db, Table *p){ + int i, k, n; + char *zStmt; + char *zSep, *zSep2, *zEnd; + Column *pCol; + n = 0; + for(pCol = p->aCol, i=0; inCol; i++, pCol++){ + n += identLength(pCol->zName) + 5; + } + n += identLength(p->zName); + if( n<50 ){ + zSep = ""; + zSep2 = ","; + zEnd = ")"; + }else{ + zSep = "\n "; + zSep2 = ",\n "; + zEnd = "\n)"; + } + n += 35 + 6*p->nCol; + zStmt = sqlite3DbMallocRaw(0, n); + if( zStmt==0 ){ + db->mallocFailed = 1; + return 0; + } + sqlite3_snprintf(n, zStmt, "CREATE TABLE "); + k = sqlite3Strlen30(zStmt); + identPut(zStmt, &k, p->zName); + zStmt[k++] = '('; + for(pCol=p->aCol, i=0; inCol; i++, pCol++){ + static const char * const azType[] = { + /* SQLITE_AFF_NONE */ "", + /* SQLITE_AFF_TEXT */ " TEXT", + /* SQLITE_AFF_NUMERIC */ " NUM", + /* SQLITE_AFF_INTEGER */ " INT", + /* SQLITE_AFF_REAL */ " REAL" + }; + int len; + const char *zType; + + sqlite3_snprintf(n-k, &zStmt[k], zSep); + k += sqlite3Strlen30(&zStmt[k]); + zSep = zSep2; + identPut(zStmt, &k, pCol->zName); + assert( pCol->affinity-SQLITE_AFF_NONE >= 0 ); + assert( pCol->affinity-SQLITE_AFF_NONE < ArraySize(azType) ); + testcase( pCol->affinity==SQLITE_AFF_NONE ); + testcase( pCol->affinity==SQLITE_AFF_TEXT ); + testcase( pCol->affinity==SQLITE_AFF_NUMERIC ); + testcase( pCol->affinity==SQLITE_AFF_INTEGER ); + testcase( pCol->affinity==SQLITE_AFF_REAL ); + + zType = azType[pCol->affinity - SQLITE_AFF_NONE]; + len = sqlite3Strlen30(zType); + assert( pCol->affinity==SQLITE_AFF_NONE + || pCol->affinity==sqlite3AffinityType(zType, 0) ); + memcpy(&zStmt[k], zType, len); + k += len; + assert( k<=n ); + } + sqlite3_snprintf(n-k, &zStmt[k], "%s", zEnd); + return zStmt; +} + +/* +** Resize an Index object to hold N columns total. Return SQLITE_OK +** on success and SQLITE_NOMEM on an OOM error. +*/ +static int resizeIndexObject(sqlite3 *db, Index *pIdx, int N){ + char *zExtra; + int nByte; + if( pIdx->nColumn>=N ) return SQLITE_OK; + assert( pIdx->isResized==0 ); + nByte = (sizeof(char*) + sizeof(i16) + 1)*N; + zExtra = sqlite3DbMallocZero(db, nByte); + if( zExtra==0 ) return SQLITE_NOMEM; + memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn); + pIdx->azColl = (char**)zExtra; + zExtra += sizeof(char*)*N; + memcpy(zExtra, pIdx->aiColumn, sizeof(i16)*pIdx->nColumn); + pIdx->aiColumn = (i16*)zExtra; + zExtra += sizeof(i16)*N; + memcpy(zExtra, pIdx->aSortOrder, pIdx->nColumn); + pIdx->aSortOrder = (u8*)zExtra; + pIdx->nColumn = N; + pIdx->isResized = 1; + return SQLITE_OK; +} + +/* +** Estimate the total row width for a table. +*/ +static void estimateTableWidth(Table *pTab){ + unsigned wTable = 0; + const Column *pTabCol; + int i; + for(i=pTab->nCol, pTabCol=pTab->aCol; i>0; i--, pTabCol++){ + wTable += pTabCol->szEst; + } + if( pTab->iPKey<0 ) wTable++; + pTab->szTabRow = sqlite3LogEst(wTable*4); +} + +/* +** Estimate the average size of a row for an index. +*/ +static void estimateIndexWidth(Index *pIdx){ + unsigned wIndex = 0; + int i; + const Column *aCol = pIdx->pTable->aCol; + for(i=0; inColumn; i++){ + i16 x = pIdx->aiColumn[i]; + assert( xpTable->nCol ); + wIndex += x<0 ? 1 : aCol[pIdx->aiColumn[i]].szEst; + } + pIdx->szIdxRow = sqlite3LogEst(wIndex*4); +} + +/* Return true if value x is found any of the first nCol entries of aiCol[] +*/ +static int hasColumn(const i16 *aiCol, int nCol, int x){ + while( nCol-- > 0 ) if( x==*(aiCol++) ) return 1; + return 0; +} + +/* +** This routine runs at the end of parsing a CREATE TABLE statement that +** has a WITHOUT ROWID clause. The job of this routine is to convert both +** internal schema data structures and the generated VDBE code so that they +** are appropriate for a WITHOUT ROWID table instead of a rowid table. +** Changes include: +** +** (1) Convert the OP_CreateTable into an OP_CreateIndex. There is +** no rowid btree for a WITHOUT ROWID. Instead, the canonical +** data storage is a covering index btree. +** (2) Bypass the creation of the sqlite_master table entry +** for the PRIMARY KEY as the primary key index is now +** identified by the sqlite_master table entry of the table itself. +** (3) Set the Index.tnum of the PRIMARY KEY Index object in the +** schema to the rootpage from the main table. +** (4) Set all columns of the PRIMARY KEY schema object to be NOT NULL. +** (5) Add all table columns to the PRIMARY KEY Index object +** so that the PRIMARY KEY is a covering index. The surplus +** columns are part of KeyInfo.nXField and are not used for +** sorting or lookup or uniqueness checks. +** (6) Replace the rowid tail on all automatically generated UNIQUE +** indices with the PRIMARY KEY columns. +*/ +static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ + Index *pIdx; + Index *pPk; + int nPk; + int i, j; + sqlite3 *db = pParse->db; + Vdbe *v = pParse->pVdbe; + + /* Convert the OP_CreateTable opcode that would normally create the + ** root-page for the table into an OP_CreateIndex opcode. The index + ** created will become the PRIMARY KEY index. + */ + if( pParse->addrCrTab ){ + assert( v ); + sqlite3VdbeGetOp(v, pParse->addrCrTab)->opcode = OP_CreateIndex; + } + + /* Bypass the creation of the PRIMARY KEY btree and the sqlite_master + ** table entry. + */ + if( pParse->addrSkipPK ){ + assert( v ); + sqlite3VdbeGetOp(v, pParse->addrSkipPK)->opcode = OP_Goto; + } + + /* Locate the PRIMARY KEY index. Or, if this table was originally + ** an INTEGER PRIMARY KEY table, create a new PRIMARY KEY index. + */ + if( pTab->iPKey>=0 ){ + ExprList *pList; + pList = sqlite3ExprListAppend(pParse, 0, 0); + if( pList==0 ) return; + pList->a[0].zName = sqlite3DbStrDup(pParse->db, + pTab->aCol[pTab->iPKey].zName); + pList->a[0].sortOrder = pParse->iPkSortOrder; + assert( pParse->pNewTable==pTab ); + pPk = sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0); + if( pPk==0 ) return; + pPk->idxType = SQLITE_IDXTYPE_PRIMARYKEY; + pTab->iPKey = -1; + }else{ + pPk = sqlite3PrimaryKeyIndex(pTab); + /* + ** Remove all redundant columns from the PRIMARY KEY. For example, change + ** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)". Later + ** code assumes the PRIMARY KEY contains no repeated columns. + */ + for(i=j=1; inKeyCol; i++){ + if( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ){ + pPk->nColumn--; + }else{ + pPk->aiColumn[j++] = pPk->aiColumn[i]; + } + } + pPk->nKeyCol = j; + } + pPk->isCovering = 1; + assert( pPk!=0 ); + nPk = pPk->nKeyCol; + + /* Make sure every column of the PRIMARY KEY is NOT NULL. (Except, + ** do not enforce this for imposter tables.) */ + if( !db->init.imposterTable ){ + for(i=0; iaCol[pPk->aiColumn[i]].notNull = 1; + } + pPk->uniqNotNull = 1; + } + + /* The root page of the PRIMARY KEY is the table root page */ + pPk->tnum = pTab->tnum; + + /* Update the in-memory representation of all UNIQUE indices by converting + ** the final rowid column into one or more columns of the PRIMARY KEY. + */ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int n; + if( IsPrimaryKeyIndex(pIdx) ) continue; + for(i=n=0; iaiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ) n++; + } + if( n==0 ){ + /* This index is a superset of the primary key */ + pIdx->nColumn = pIdx->nKeyCol; + continue; + } + if( resizeIndexObject(db, pIdx, pIdx->nKeyCol+n) ) return; + for(i=0, j=pIdx->nKeyCol; iaiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ){ + pIdx->aiColumn[j] = pPk->aiColumn[i]; + pIdx->azColl[j] = pPk->azColl[i]; + j++; + } + } + assert( pIdx->nColumn>=pIdx->nKeyCol+n ); + assert( pIdx->nColumn>=j ); + } + + /* Add all table columns to the PRIMARY KEY index + */ + if( nPknCol ){ + if( resizeIndexObject(db, pPk, pTab->nCol) ) return; + for(i=0, j=nPk; inCol; i++){ + if( !hasColumn(pPk->aiColumn, j, i) ){ + assert( jnColumn ); + pPk->aiColumn[j] = i; + pPk->azColl[j] = "BINARY"; + j++; + } + } + assert( pPk->nColumn==j ); + assert( pTab->nCol==j ); + }else{ + pPk->nColumn = pTab->nCol; + } +} + +/* +** This routine is called to report the final ")" that terminates +** a CREATE TABLE statement. +** +** The table structure that other action routines have been building +** 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. +*/ +SQLITE_PRIVATE void sqlite3EndTable( + Parse *pParse, /* Parse context */ + Token *pCons, /* The ',' token after the last column defn. */ + Token *pEnd, /* The ')' before options in the CREATE TABLE */ + u8 tabOpts, /* Extra table options. Usually 0. */ + Select *pSelect /* Select from a "CREATE ... AS SELECT" */ +){ + Table *p; /* The new table */ + sqlite3 *db = pParse->db; /* The database connection */ + int iDb; /* Database in which the table lives */ + Index *pIdx; /* An implied index of the table */ + + if( (pEnd==0 && pSelect==0) || db->mallocFailed ){ + 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 ){ + p->tnum = db->init.newTnum; + } + + /* Special processing for WITHOUT ROWID Tables */ + if( tabOpts & TF_WithoutRowid ){ + if( (p->tabFlags & TF_Autoincrement) ){ + sqlite3ErrorMsg(pParse, + "AUTOINCREMENT not allowed on WITHOUT ROWID tables"); + return; + } + if( (p->tabFlags & TF_HasPrimaryKey)==0 ){ + sqlite3ErrorMsg(pParse, "PRIMARY KEY missing on table %s", p->zName); + }else{ + p->tabFlags |= TF_WithoutRowid; + convertToWithoutRowidTable(pParse, p); + } + } + + iDb = sqlite3SchemaToIndex(db, p->pSchema); + +#ifndef SQLITE_OMIT_CHECK + /* Resolve names in all CHECK constraint expressions. + */ + if( p->pCheck ){ + sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck); + } +#endif /* !defined(SQLITE_OMIT_CHECK) */ + + /* Estimate the average row size for the table and for all implied indices */ + estimateTableWidth(p); + for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){ + estimateIndexWidth(pIdx); + } + + /* If not initializing, then create a record for the new table + ** in the SQLITE_MASTER table of the database. + ** + ** If this is a TEMPORARY table, write the entry into the auxiliary + ** file instead of into the main database file. + */ + if( !db->init.busy ){ + int n; + Vdbe *v; + char *zType; /* "view" or "table" */ + char *zType2; /* "VIEW" or "TABLE" */ + char *zStmt; /* Text of the CREATE TABLE or CREATE VIEW statement */ + + v = sqlite3GetVdbe(pParse); + if( NEVER(v==0) ) return; + + sqlite3VdbeAddOp1(v, OP_Close, 0); + + /* + ** Initialize zType for the new view or table. + */ + 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 in register pParse->regRoot. + ** + ** 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 ){ + SelectDest dest; + Table *pSelTab; + + assert(pParse->nTab==1); + sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb); + sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG); + pParse->nTab = 2; + sqlite3SelectDestInit(&dest, SRT_Table, 1); + sqlite3Select(pParse, pSelect, &dest); + sqlite3VdbeAddOp1(v, OP_Close, 1); + if( pParse->nErr==0 ){ + pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect); + if( pSelTab==0 ) return; + assert( p->aCol==0 ); + p->nCol = pSelTab->nCol; + p->aCol = pSelTab->aCol; + pSelTab->nCol = 0; + pSelTab->aCol = 0; + sqlite3DeleteTable(db, pSelTab); + } + } + + /* Compute the complete text of the CREATE statement */ + if( pSelect ){ + zStmt = createTableStmt(db, p); + }else{ + Token *pEnd2 = tabOpts ? &pParse->sLastToken : pEnd; + n = (int)(pEnd2->z - pParse->sNameToken.z); + if( pEnd2->z[0]!=';' ) n += pEnd2->n; + zStmt = sqlite3MPrintf(db, + "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. + */ + sqlite3NestedParse(pParse, + "UPDATE %Q.%s " + "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q " + "WHERE rowid=#%d", + db->aDb[iDb].zName, SCHEMA_TABLE(iDb), + zType, + p->zName, + p->zName, + pParse->regRoot, + zStmt, + pParse->regRowid + ); + sqlite3DbFree(db, zStmt); + sqlite3ChangeCookie(pParse, 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->tabFlags & TF_Autoincrement ){ + Db *pDb = &db->aDb[iDb]; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + 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 */ + sqlite3VdbeAddParseSchemaOp(v, iDb, + sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName)); + } + + + /* Add the table to the in-memory representation of the database. + */ + if( db->init.busy ){ + Table *pOld; + Schema *pSchema = p->pSchema; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, p); + if( pOld ){ + assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ + db->mallocFailed = 1; + return; + } + pParse->pNewTable = 0; + db->flags |= SQLITE_InternChanges; + +#ifndef SQLITE_OMIT_ALTERTABLE + if( !p->pSelect ){ + const char *zName = (const char *)pParse->sNameToken.z; + int nName; + assert( !pSelect && pCons && pEnd ); + if( pCons->z==0 ){ + pCons = pEnd; + } + nName = (int)((const char *)pCons->z - zName); + p->addColOffset = 13 + sqlite3Utf8CharLen(zName, nName); + } +#endif + } +} + +#ifndef SQLITE_OMIT_VIEW +/* +** The parser calls this routine in order to create a new VIEW +*/ +SQLITE_PRIVATE void sqlite3CreateView( + Parse *pParse, /* The parsing context */ + Token *pBegin, /* The CREATE token that begins the statement */ + Token *pName1, /* The token that holds the name of the view */ + Token *pName2, /* The token that holds the name of the view */ + Select *pSelect, /* A SELECT statement that will become the new view */ + int isTemp, /* TRUE for a TEMPORARY view */ + int noErr /* Suppress error messages if VIEW already exists */ +){ + Table *p; + int n; + const char *z; + Token sEnd; + DbFixer sFix; + Token *pName = 0; + int iDb; + sqlite3 *db = pParse->db; + + if( pParse->nVar>0 ){ + sqlite3ErrorMsg(pParse, "parameters are not allowed in views"); + sqlite3SelectDelete(db, pSelect); + return; + } + sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr); + p = pParse->pNewTable; + if( p==0 || pParse->nErr ){ + sqlite3SelectDelete(db, pSelect); + return; + } + sqlite3TwoPartName(pParse, pName1, pName2, &pName); + iDb = sqlite3SchemaToIndex(db, p->pSchema); + sqlite3FixInit(&sFix, pParse, iDb, "view", pName); + if( sqlite3FixSelect(&sFix, pSelect) ){ + sqlite3SelectDelete(db, 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(db, pSelect, EXPRDUP_REDUCE); + sqlite3SelectDelete(db, pSelect); + if( db->mallocFailed ){ + return; + } + if( !db->init.busy ){ + sqlite3ViewGetColumnNames(pParse, p); + } + + /* Locate the end of the CREATE VIEW statement. Make sEnd point to + ** the end. + */ + sEnd = pParse->sLastToken; + if( ALWAYS(sEnd.z[0]!=0) && sEnd.z[0]!=';' ){ + sEnd.z += sEnd.n; + } + sEnd.n = 0; + n = (int)(sEnd.z - pBegin->z); + z = pBegin->z; + while( ALWAYS(n>0) && sqlite3Isspace(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, 0); + return; +} +#endif /* SQLITE_OMIT_VIEW */ + +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) +/* +** The Table structure pTable is really a VIEW. Fill in the names of +** the columns of the view in the pTable structure. Return the number +** of errors. If an error is seen leave an error message in pParse->zErrMsg. +*/ +SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ + Table *pSelTab; /* A fake table from which we get the result set */ + Select *pSel; /* Copy of the SELECT that implements the view */ + int nErr = 0; /* Number of errors encountered */ + int n; /* Temporarily holds the number of cursors assigned */ + sqlite3 *db = pParse->db; /* Database connection for malloc errors */ + sqlite3_xauth xAuth; /* Saved xAuth pointer */ + + assert( pTable ); + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( sqlite3VtabCallConnect(pParse, pTable) ){ + return SQLITE_ERROR; + } + if( IsVirtual(pTable) ) return 0; +#endif + +#ifndef SQLITE_OMIT_VIEW + /* A positive nCol means the columns names for this view are + ** already known. + */ + if( pTable->nCol>0 ) return 0; + + /* A negative nCol is a special marker meaning that we are currently + ** trying to compute the column names. If we enter this routine with + ** a negative nCol, it means two or more views form a loop, like this: + ** + ** CREATE VIEW one AS SELECT * FROM two; + ** CREATE VIEW two AS SELECT * FROM one; + ** + ** Actually, the error above is now caught prior to reaching this point. + ** But the following test is still important as it does come up + ** in the following: + ** + ** CREATE TABLE main.ex1(a); + ** CREATE TEMP VIEW ex1 AS SELECT a FROM ex1; + ** SELECT * FROM temp.ex1; + */ + if( pTable->nCol<0 ){ + sqlite3ErrorMsg(pParse, "view %s is circularly defined", pTable->zName); + return 1; + } + 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(db, pTable->pSelect, 0); + if( pSel ){ + u8 enableLookaside = db->lookaside.bEnabled; + n = pParse->nTab; + sqlite3SrcListAssignCursors(pParse, pSel->pSrc); + pTable->nCol = -1; + db->lookaside.bEnabled = 0; +#ifndef SQLITE_OMIT_AUTHORIZATION + xAuth = db->xAuth; + db->xAuth = 0; + pSelTab = sqlite3ResultSetOfSelect(pParse, pSel); + db->xAuth = xAuth; +#else + pSelTab = sqlite3ResultSetOfSelect(pParse, pSel); +#endif + db->lookaside.bEnabled = enableLookaside; + pParse->nTab = n; + if( pSelTab ){ + assert( pTable->aCol==0 ); + pTable->nCol = pSelTab->nCol; + pTable->aCol = pSelTab->aCol; + pSelTab->nCol = 0; + pSelTab->aCol = 0; + sqlite3DeleteTable(db, pSelTab); + assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) ); + pTable->pSchema->schemaFlags |= DB_UnresetViews; + }else{ + pTable->nCol = 0; + nErr++; + } + sqlite3SelectDelete(db, pSel); + } else { + nErr++; + } +#endif /* SQLITE_OMIT_VIEW */ + return nErr; +} +#endif /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */ + +#ifndef SQLITE_OMIT_VIEW +/* +** Clear the column names from every VIEW in database idx. +*/ +static void sqliteViewResetAll(sqlite3 *db, int idx){ + HashElem *i; + assert( sqlite3SchemaMutexHeld(db, idx, 0) ); + 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 ){ + sqliteDeleteColumnNames(db, pTab); + pTab->aCol = 0; + pTab->nCol = 0; + } + } + 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. +** +** Ticket #1728: The symbol table might still contain information +** on tables and/or indices that are the process of being deleted. +** If you are unlucky, one of those deleted indices or tables might +** have the same rootpage number as the real table or index that is +** being moved. So we cannot stop searching after the first match +** because the first match might be for one of the deleted indices +** or tables and not the table/index that is actually being moved. +** We must continue looping until all tables and indices with +** rootpage==iFrom have been converted to have a rootpage of iTo +** in order to be certain that we got the right one. +*/ +#ifndef SQLITE_OMIT_AUTOVACUUM +SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3 *db, int iDb, int iFrom, int iTo){ + HashElem *pElem; + Hash *pHash; + Db *pDb; + + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pDb = &db->aDb[iDb]; + pHash = &pDb->pSchema->tblHash; + for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){ + Table *pTab = sqliteHashData(pElem); + if( pTab->tnum==iFrom ){ + pTab->tnum = iTo; + } + } + pHash = &pDb->pSchema->idxHash; + for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){ + Index *pIdx = sqliteHashData(pElem); + if( pIdx->tnum==iFrom ){ + pIdx->tnum = iTo; + } + } +} +#endif + +/* +** Write code to erase the table with root-page iTable from database iDb. +** Also write code to modify the sqlite_master table and internal schema +** if a root-page of another table is moved by the btree-layer whilst +** erasing iTable (this can happen with an auto-vacuum database). +*/ +static void destroyRootPage(Parse *pParse, int iTable, int iDb){ + Vdbe *v = sqlite3GetVdbe(pParse); + int r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb); + sqlite3MayAbort(pParse); +#ifndef SQLITE_OMIT_AUTOVACUUM + /* OP_Destroy stores an in integer r1. If this integer + ** is non-zero, then it is the root page number of a table moved to + ** location iTable. The following code modifies the sqlite_master table to + ** reflect this. + ** + ** The "#NNN" in the SQL is a special constant that means whatever value + ** is in register NNN. See grammar rules associated with the TK_REGISTER + ** token for additional information. + */ + sqlite3NestedParse(pParse, + "UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d", + pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable, r1, r1); +#endif + sqlite3ReleaseTempReg(pParse, r1); +} + +/* +** Write VDBE code to erase table pTab and all associated indices on disk. +** 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 + ** following were coded: + ** + ** OP_Destroy 4 0 + ** ... + ** OP_Destroy 5 0 + ** + ** and root page 5 happened to be the largest root-page number in the + ** database, then root page 5 would be moved to page 4 by the + ** "OP_Destroy 4 0" opcode. The subsequent "OP_Destroy 5 0" would hit + ** a free-list page. + */ + int iTab = pTab->tnum; + int iDestroyed = 0; + + while( 1 ){ + Index *pIdx; + int iLargest = 0; + + if( iDestroyed==0 || iTabpIndex; pIdx; pIdx=pIdx->pNext){ + int iIdx = pIdx->tnum; + assert( pIdx->pSchema==pTab->pSchema ); + if( (iDestroyed==0 || (iIdxiLargest ){ + iLargest = iIdx; + } + } + if( iLargest==0 ){ + return; + }else{ + int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + assert( iDb>=0 && iDbdb->nDb ); + destroyRootPage(pParse, iLargest, iDb); + iDestroyed = iLargest; + } + } +#endif +} + +/* +** Remove entries from the sqlite_statN tables (for N in (1,2,3)) +** after a DROP INDEX or DROP TABLE command. +*/ +static void sqlite3ClearStatTables( + Parse *pParse, /* The parsing context */ + int iDb, /* The database number */ + const char *zType, /* "idx" or "tbl" */ + const char *zName /* Name of index or table */ +){ + int i; + const char *zDbName = pParse->db->aDb[iDb].zName; + for(i=1; i<=4; i++){ + char zTab[24]; + sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i); + if( sqlite3FindTable(pParse->db, zTab, zDbName) ){ + sqlite3NestedParse(pParse, + "DELETE FROM %Q.%s WHERE %s=%Q", + zDbName, zTab, zType, zName + ); + } + } +} + +/* +** Generate code to drop a table. +*/ +SQLITE_PRIVATE void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){ + Vdbe *v; + sqlite3 *db = pParse->db; + Trigger *pTrigger; + Db *pDb = &db->aDb[iDb]; + + v = sqlite3GetVdbe(pParse); + assert( v!=0 ); + sqlite3BeginWriteOperation(pParse, 1, iDb); + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + sqlite3VdbeAddOp0(v, OP_VBegin); + } +#endif + + /* 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 = sqlite3TriggerList(pParse, pTab); + while( pTrigger ){ + assert( pTrigger->pSchema==pTab->pSchema || + pTrigger->pSchema==db->aDb[1].pSchema ); + sqlite3DropTriggerPtr(pParse, pTrigger); + 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 + ** at the btree level, in case the sqlite_sequence table needs to + ** move as a result of the drop (can happen in auto-vacuum mode). + */ + if( pTab->tabFlags & TF_Autoincrement ){ + sqlite3NestedParse(pParse, + "DELETE FROM %Q.sqlite_sequence WHERE name=%Q", + pDb->zName, pTab->zName + ); + } +#endif + + /* Drop all SQLITE_MASTER table and index entries that refer to the + ** table. The program name loops through the master table and deletes + ** every row that refers to a table of the same name as the one being + ** dropped. Triggers are handled separately because a trigger can be + ** created in the temp database that refers to a table in another + ** database. + */ + sqlite3NestedParse(pParse, + "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'", + pDb->zName, SCHEMA_TABLE(iDb), pTab->zName); + if( !isView && !IsVirtual(pTab) ){ + destroyTable(pParse, pTab); + } + + /* Remove the table entry from SQLite's internal schema and modify + ** the schema cookie. + */ + if( IsVirtual(pTab) ){ + sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0); + } + sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0); + sqlite3ChangeCookie(pParse, iDb); + sqliteViewResetAll(db, iDb); +} + +/* +** This routine is called to do the work of a DROP TABLE statement. +** pName is the name of the table to be dropped. +*/ +SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ + Table *pTab; + Vdbe *v; + sqlite3 *db = pParse->db; + int iDb; + + if( db->mallocFailed ){ + goto exit_drop_table; + } + assert( pParse->nErr==0 ); + assert( pName->nSrc==1 ); + if( sqlite3ReadSchema(pParse) ) goto exit_drop_table; + if( noErr ) db->suppressErr++; + pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]); + if( noErr ) db->suppressErr--; + + if( pTab==0 ){ + if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); + goto exit_drop_table; + } + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDb>=0 && iDbnDb ); + + /* If pTab is a virtual table, call ViewGetColumnNames() to ensure + ** it is initialized. + */ + if( IsVirtual(pTab) && sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto exit_drop_table; + } +#ifndef SQLITE_OMIT_AUTHORIZATION + { + int code; + const char *zTab = SCHEMA_TABLE(iDb); + const char *zDb = db->aDb[iDb].zName; + const char *zArg2 = 0; + 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; + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + }else if( IsVirtual(pTab) ){ + code = SQLITE_DROP_VTABLE; + zArg2 = sqlite3GetVTable(db, pTab)->pMod->zName; +#endif + }else{ + if( !OMIT_TEMPDB && iDb==1 ){ + code = SQLITE_DROP_TEMP_TABLE; + }else{ + code = SQLITE_DROP_TABLE; + } + } + if( sqlite3AuthCheck(pParse, code, pTab->zName, zArg2, zDb) ){ + goto exit_drop_table; + } + if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){ + goto exit_drop_table; + } + } +#endif + if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 + && sqlite3StrNICmp(pTab->zName, "sqlite_stat", 11)!=0 ){ + 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. + */ + if( isView && pTab->pSelect==0 ){ + sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName); + goto exit_drop_table; + } + if( !isView && pTab->pSelect ){ + sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName); + goto exit_drop_table; + } +#endif + + /* Generate code to remove the table from the master table + ** on disk. + */ + v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3BeginWriteOperation(pParse, 1, iDb); + sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName); + sqlite3FkDropTable(pParse, pName, pTab); + sqlite3CodeDropTable(pParse, pTab, iDb, isView); + } + +exit_drop_table: + sqlite3SrcListDelete(db, pName); +} + +/* +** This routine is called to create a new foreign key on the table +** currently under construction. pFromCol determines which columns +** in the current table point to the foreign key. If pFromCol==0 then +** connect the key to the last column inserted. pTo is the name of +** the table referred to (a.k.a the "parent" table). pToCol is a list +** of tables in the parent pTo table. flags contains all +** information about the conflict resolution algorithms specified +** in the ON DELETE, ON UPDATE and ON INSERT clauses. +** +** An FKey structure is created and added to the table currently +** under construction in the pParse->pNewTable field. +** +** The foreign key is set for IMMEDIATE processing. A subsequent call +** to sqlite3DeferForeignKey() might change this to DEFERRED. +*/ +SQLITE_PRIVATE void sqlite3CreateForeignKey( + Parse *pParse, /* Parsing context */ + ExprList *pFromCol, /* Columns in this table that point to other table */ + Token *pTo, /* Name of the other table */ + ExprList *pToCol, /* Columns in the other table */ + int flags /* Conflict resolution algorithms. */ +){ + sqlite3 *db = pParse->db; +#ifndef SQLITE_OMIT_FOREIGN_KEY + FKey *pFKey = 0; + FKey *pNextTo; + Table *p = pParse->pNewTable; + int nByte; + int i; + int nCol; + char *z; + + assert( pTo!=0 ); + if( p==0 || IN_DECLARE_VTAB ) goto fk_end; + if( pFromCol==0 ){ + int iCol = p->nCol-1; + if( NEVER(iCol<0) ) goto fk_end; + if( pToCol && pToCol->nExpr!=1 ){ + sqlite3ErrorMsg(pParse, "foreign key on %s" + " should reference only one column of table %T", + p->aCol[iCol].zName, pTo); + goto fk_end; + } + nCol = 1; + }else if( pToCol && pToCol->nExpr!=pFromCol->nExpr ){ + sqlite3ErrorMsg(pParse, + "number of columns in foreign key does not match the number of " + "columns in the referenced table"); + goto fk_end; + }else{ + nCol = pFromCol->nExpr; + } + nByte = sizeof(*pFKey) + (nCol-1)*sizeof(pFKey->aCol[0]) + pTo->n + 1; + if( pToCol ){ + for(i=0; inExpr; i++){ + nByte += sqlite3Strlen30(pToCol->a[i].zName) + 1; + } + } + pFKey = sqlite3DbMallocZero(db, nByte ); + if( pFKey==0 ){ + goto fk_end; + } + pFKey->pFrom = p; + pFKey->pNextFrom = p->pFKey; + z = (char*)&pFKey->aCol[nCol]; + pFKey->zTo = z; + memcpy(z, pTo->z, pTo->n); + z[pTo->n] = 0; + sqlite3Dequote(z); + z += pTo->n+1; + pFKey->nCol = nCol; + if( pFromCol==0 ){ + pFKey->aCol[0].iFrom = p->nCol-1; + }else{ + for(i=0; inCol; j++){ + if( sqlite3StrICmp(p->aCol[j].zName, pFromCol->a[i].zName)==0 ){ + pFKey->aCol[i].iFrom = j; + break; + } + } + if( j>=p->nCol ){ + sqlite3ErrorMsg(pParse, + "unknown column \"%s\" in foreign key definition", + pFromCol->a[i].zName); + goto fk_end; + } + } + } + if( pToCol ){ + for(i=0; ia[i].zName); + pFKey->aCol[i].zCol = z; + memcpy(z, pToCol->a[i].zName, n); + z[n] = 0; + z += n+1; + } + } + pFKey->isDeferred = 0; + pFKey->aAction[0] = (u8)(flags & 0xff); /* ON DELETE action */ + pFKey->aAction[1] = (u8)((flags >> 8 ) & 0xff); /* ON UPDATE action */ + + assert( sqlite3SchemaMutexHeld(db, 0, p->pSchema) ); + pNextTo = (FKey *)sqlite3HashInsert(&p->pSchema->fkeyHash, + pFKey->zTo, (void *)pFKey + ); + if( pNextTo==pFKey ){ + db->mallocFailed = 1; + goto fk_end; + } + if( pNextTo ){ + assert( pNextTo->pPrevTo==0 ); + pFKey->pNextTo = pNextTo; + pNextTo->pPrevTo = pFKey; + } + + /* Link the foreign key to the table as the last step. + */ + p->pFKey = pFKey; + pFKey = 0; + +fk_end: + sqlite3DbFree(db, pFKey); +#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ + sqlite3ExprListDelete(db, pFromCol); + sqlite3ExprListDelete(db, pToCol); +} + +/* +** This routine is called when an INITIALLY IMMEDIATE or INITIALLY DEFERRED +** clause is seen as part of a foreign key definition. The isDeferred +** parameter is 1 for INITIALLY DEFERRED and 0 for INITIALLY IMMEDIATE. +** The behavior of the most recently created foreign key is adjusted +** accordingly. +*/ +SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){ +#ifndef SQLITE_OMIT_FOREIGN_KEY + Table *pTab; + FKey *pFKey; + if( (pTab = pParse->pNewTable)==0 || (pFKey = pTab->pFKey)==0 ) return; + assert( isDeferred==0 || isDeferred==1 ); /* EV: R-30323-21917 */ + pFKey->isDeferred = (u8)isDeferred; +#endif +} + +/* +** Generate code that will erase and refill index *pIdx. This is +** used to initialize a newly created index or to recompute the +** content of an index in response to a REINDEX command. +** +** if memRootPage is not negative, it means that the index is newly +** created. The register specified by memRootPage contains the +** root page number of the index. If memRootPage is negative, then +** the index already exists and must be cleared before being refilled and +** the root page number of the index is taken from pIndex->tnum. +*/ +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++; /* Btree cursor used for pIndex */ + int iSorter; /* Cursor opened by OpenSorter (if in use) */ + int addr1; /* Address of top of loop */ + int addr2; /* Address to jump to for next iteration */ + int tnum; /* Root page of index */ + int iPartIdxLabel; /* Jump to this label to skip a row */ + Vdbe *v; /* Generate code into this virtual machine */ + KeyInfo *pKey; /* KeyInfo for index */ + int regRecord; /* Register holding assembled index record */ + sqlite3 *db = pParse->db; /* The database connection */ + int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); + +#ifndef SQLITE_OMIT_AUTHORIZATION + if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0, + 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 ){ + tnum = memRootPage; + }else{ + tnum = pIndex->tnum; + } + pKey = sqlite3KeyInfoOfIndex(pParse, pIndex); + + /* Open the sorter cursor if we are to use one. */ + iSorter = pParse->nTab++; + sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, pIndex->nKeyCol, (char*) + sqlite3KeyInfoRef(pKey), P4_KEYINFO); + + /* Open the table. Loop through all rows of the table, inserting index + ** records into the sorter. */ + sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); + addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeCoverage(v); + regRecord = sqlite3GetTempReg(pParse); + + sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0); + sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord); + sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); + sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr1); + if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb); + sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, + (char *)pKey, P4_KEYINFO); + sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0)); + + addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v); + assert( pKey!=0 || db->mallocFailed || pParse->nErr ); + if( IsUniqueIndex(pIndex) && pKey!=0 ){ + int j2 = sqlite3VdbeCurrentAddr(v) + 3; + sqlite3VdbeAddOp2(v, OP_Goto, 0, j2); + addr2 = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord, + pIndex->nKeyCol); VdbeCoverage(v); + sqlite3UniqueConstraint(pParse, OE_Abort, pIndex); + }else{ + addr2 = sqlite3VdbeCurrentAddr(v); + } + sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx); + sqlite3VdbeAddOp3(v, OP_Last, iIdx, 0, -1); + sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + sqlite3ReleaseTempReg(pParse, regRecord); + sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr1); + + sqlite3VdbeAddOp1(v, OP_Close, iTab); + sqlite3VdbeAddOp1(v, OP_Close, iIdx); + sqlite3VdbeAddOp1(v, OP_Close, iSorter); +} + +/* +** Allocate heap space to hold an Index object with nCol columns. +** +** Increase the allocation size to provide an extra nExtra bytes +** of 8-byte aligned space after the Index object and return a +** pointer to this extra space in *ppExtra. +*/ +SQLITE_PRIVATE Index *sqlite3AllocateIndexObject( + sqlite3 *db, /* Database connection */ + i16 nCol, /* Total number of columns in the index */ + int nExtra, /* Number of bytes of extra space to alloc */ + char **ppExtra /* Pointer to the "extra" space */ +){ + Index *p; /* Allocated index object */ + int nByte; /* Bytes of space for Index object + arrays */ + + nByte = ROUND8(sizeof(Index)) + /* Index structure */ + ROUND8(sizeof(char*)*nCol) + /* Index.azColl */ + ROUND8(sizeof(LogEst)*(nCol+1) + /* Index.aiRowLogEst */ + sizeof(i16)*nCol + /* Index.aiColumn */ + sizeof(u8)*nCol); /* Index.aSortOrder */ + p = sqlite3DbMallocZero(db, nByte + nExtra); + if( p ){ + char *pExtra = ((char*)p)+ROUND8(sizeof(Index)); + p->azColl = (char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol); + p->aiRowLogEst = (LogEst*)pExtra; pExtra += sizeof(LogEst)*(nCol+1); + p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol; + p->aSortOrder = (u8*)pExtra; + p->nColumn = nCol; + p->nKeyCol = nCol - 1; + *ppExtra = ((char*)p) + nByte; + } + return p; +} + +/* +** 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 +** be NULL for a primary key or an index that is created to satisfy a +** UNIQUE constraint. If pTable and pIndex are NULL, use pParse->pNewTable +** as the table to be indexed. pParse->pNewTable is a table that is +** currently being constructed by a CREATE TABLE statement. +** +** pList is a list of columns to be indexed. pList will be NULL if this +** is a primary key or unique-constraint on the most recent column added +** to the table currently under construction. +** +** If the index is created successfully, return a pointer to the new Index +** structure. This is used by sqlite3AddPrimaryKey() to mark the index +** as the tables primary key (Index.idxType==SQLITE_IDXTYPE_PRIMARYKEY) +*/ +SQLITE_PRIVATE Index *sqlite3CreateIndex( + 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 this statement */ + Expr *pPIWhere, /* WHERE clause for partial indices */ + int sortOrder, /* Sort order of primary key when pList==NULL */ + int ifNotExist /* Omit error if index already exists */ +){ + Index *pRet = 0; /* Pointer to return */ + 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; + 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 */ + const Column *pTabCol; /* A column in the table */ + int nExtra = 0; /* Space allocated for zExtra[] */ + int nExtraCol; /* Number of extra columns needed */ + char *zExtra = 0; /* Extra space after the Index object */ + Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */ + + if( db->mallocFailed || IN_DECLARE_VTAB || pParse->nErr>0 ){ + goto exit_create_index; + } + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + 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; + assert( pName && pName->z ); + +#ifndef SQLITE_OMIT_TEMPDB + /* If the index name was unqualified, check if the table + ** is a temp table. If so, set the database to 1. Do not do this + ** if initialising a database schema. + */ + if( !db->init.busy ){ + pTab = sqlite3SrcListLookup(pParse, pTblName); + if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){ + iDb = 1; + } + } +#endif + + sqlite3FixInit(&sFix, pParse, iDb, "index", pName); + if( sqlite3FixSrcList(&sFix, pTblName) ){ + /* Because the parser constructs pTblName from a single identifier, + ** sqlite3FixSrcList can never fail. */ + assert(0); + } + pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]); + assert( db->mallocFailed==0 || pTab==0 ); + if( pTab==0 ) goto exit_create_index; + if( iDb==1 && db->aDb[iDb].pSchema!=pTab->pSchema ){ + sqlite3ErrorMsg(pParse, + "cannot create a TEMP index on non-TEMP table \"%s\"", + pTab->zName); + goto exit_create_index; + } + if( !HasRowid(pTab) ) pPk = sqlite3PrimaryKeyIndex(pTab); + }else{ + assert( pName==0 ); + assert( pStart==0 ); + pTab = pParse->pNewTable; + if( !pTab ) goto exit_create_index; + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + } + pDb = &db->aDb[iDb]; + + assert( pTab!=0 ); + assert( pParse->nErr==0 ); + if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 + && db->init.busy==0 +#if SQLITE_USER_AUTHENTICATION + && sqlite3UserAuthTable(pTab->zName)==0 +#endif + && sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0 ){ + 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 +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + sqlite3ErrorMsg(pParse, "virtual tables 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 + ** one of the index names collides with the name of a temporary table or + ** index, then we will continue to process this index. + ** + ** If pName==0 it means that we are + ** dealing with a primary key or UNIQUE constraint. We have to invent our + ** own name. + */ + if( pName ){ + zName = sqlite3NameFromToken(db, pName); + if( zName==0 ) goto exit_create_index; + assert( pName->z!=0 ); + if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ + goto exit_create_index; + } + if( !db->init.busy ){ + if( sqlite3FindTable(db, zName, 0)!=0 ){ + sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); + goto exit_create_index; + } + } + if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){ + if( !ifNotExist ){ + sqlite3ErrorMsg(pParse, "index %s already exists", zName); + }else{ + assert( !db->init.busy ); + sqlite3CodeVerifySchema(pParse, iDb); + } + goto exit_create_index; + } + }else{ + int n; + Index *pLoop; + for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){} + zName = sqlite3MPrintf(db, "sqlite_autoindex_%s_%d", pTab->zName, n); + 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 ){ + pList = sqlite3ExprListAppend(pParse, 0, 0); + if( pList==0 ) goto exit_create_index; + pList->a[0].zName = sqlite3DbStrDup(pParse->db, + pTab->aCol[pTab->nCol-1].zName); + pList->a[0].sortOrder = (u8)sortOrder; + } + + /* Figure out how many bytes of space are required to store explicitly + ** specified collation sequence names. + */ + for(i=0; inExpr; i++){ + Expr *pExpr = pList->a[i].pExpr; + if( pExpr ){ + assert( pExpr->op==TK_COLLATE ); + nExtra += (1 + sqlite3Strlen30(pExpr->u.zToken)); + } + } + + /* + ** Allocate the index structure. + */ + nName = sqlite3Strlen30(zName); + nExtraCol = pPk ? pPk->nKeyCol : 1; + pIndex = sqlite3AllocateIndexObject(db, pList->nExpr + nExtraCol, + nName + nExtra + 1, &zExtra); + if( db->mallocFailed ){ + goto exit_create_index; + } + assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowLogEst) ); + assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) ); + pIndex->zName = zExtra; + zExtra += nName + 1; + memcpy(pIndex->zName, zName, nName+1); + pIndex->pTable = pTab; + pIndex->onError = (u8)onError; + pIndex->uniqNotNull = onError!=OE_None; + pIndex->idxType = pName ? SQLITE_IDXTYPE_APPDEF : SQLITE_IDXTYPE_UNIQUE; + pIndex->pSchema = db->aDb[iDb].pSchema; + pIndex->nKeyCol = pList->nExpr; + if( pPIWhere ){ + sqlite3ResolveSelfReference(pParse, pTab, NC_PartIdx, pPIWhere, 0); + pIndex->pPartIdxWhere = pPIWhere; + pPIWhere = 0; + } + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + + /* 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. + ** + ** TODO: Add a test to make sure that the same column is not named + ** more than once within the same index. Only the first instance of + ** the column will ever be used by the optimizer. Note that using the + ** same column more than once cannot be an error because that would + ** break backwards compatibility - it needs to be a warning. + */ + for(i=0, pListItem=pList->a; inExpr; i++, pListItem++){ + const char *zColName = pListItem->zName; + int requestedSortOrder; + char *zColl; /* Collation sequence name */ + + for(j=0, pTabCol=pTab->aCol; jnCol; 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); + pParse->checkSchema = 1; + goto exit_create_index; + } + assert( j<=0x7fff ); + pIndex->aiColumn[i] = (i16)j; + if( pListItem->pExpr ){ + int nColl; + assert( pListItem->pExpr->op==TK_COLLATE ); + zColl = pListItem->pExpr->u.zToken; + nColl = sqlite3Strlen30(zColl) + 1; + assert( nExtra>=nColl ); + memcpy(zExtra, zColl, nColl); + zColl = zExtra; + zExtra += nColl; + nExtra -= nColl; + }else{ + zColl = pTab->aCol[j].zColl; + if( !zColl ) zColl = "BINARY"; + } + if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){ + goto exit_create_index; + } + pIndex->azColl[i] = zColl; + requestedSortOrder = pListItem->sortOrder & sortOrderMask; + pIndex->aSortOrder[i] = (u8)requestedSortOrder; + if( pTab->aCol[j].notNull==0 ) pIndex->uniqNotNull = 0; + } + if( pPk ){ + for(j=0; jnKeyCol; j++){ + int x = pPk->aiColumn[j]; + if( hasColumn(pIndex->aiColumn, pIndex->nKeyCol, x) ){ + pIndex->nColumn--; + }else{ + pIndex->aiColumn[i] = x; + pIndex->azColl[i] = pPk->azColl[j]; + pIndex->aSortOrder[i] = pPk->aSortOrder[j]; + i++; + } + } + assert( i==pIndex->nColumn ); + }else{ + pIndex->aiColumn[i] = -1; + pIndex->azColl[i] = "BINARY"; + } + sqlite3DefaultRowEst(pIndex); + if( pParse->pNewTable==0 ) estimateIndexWidth(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: + ** + ** CREATE TABLE t(x PRIMARY KEY, y); + ** CREATE TABLE t(x, y, UNIQUE(x, y)); + ** + ** Either way, check to see if the table already has such an index. If + ** so, don't bother creating this one. This only applies to + ** automatically created indices. Users can do as they wish with + ** explicit indices. + ** + ** Two UNIQUE or PRIMARY KEY constraints are considered equivalent + ** (and thus suppressing the second one) even if they have different + ** sort orders. + ** + ** If there are different collating sequences or if the columns of + ** the constraint occur in different orders, then the constraints are + ** considered distinct and both result in separate indices. + */ + Index *pIdx; + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int k; + assert( IsUniqueIndex(pIdx) ); + assert( pIdx->idxType!=SQLITE_IDXTYPE_APPDEF ); + assert( IsUniqueIndex(pIndex) ); + + if( pIdx->nKeyCol!=pIndex->nKeyCol ) continue; + for(k=0; knKeyCol; k++){ + const char *z1; + const char *z2; + if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break; + z1 = pIdx->azColl[k]; + z2 = pIndex->azColl[k]; + if( z1!=z2 && sqlite3StrICmp(z1, z2) ) break; + } + if( k==pIdx->nKeyCol ){ + 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 + ** ON CONFLICT clauses this is an error. Otherwise, use the + ** explicitly specified behavior for the index. + */ + if( !(pIdx->onError==OE_Default || pIndex->onError==OE_Default) ){ + sqlite3ErrorMsg(pParse, + "conflicting ON CONFLICT clauses specified", 0); + } + if( pIdx->onError==OE_Default ){ + pIdx->onError = pIndex->onError; + } + } + pRet = pIdx; + goto exit_create_index; + } + } + } + + /* Link the new Index structure to its table and to the other + ** in-memory database structures. + */ + if( db->init.busy ){ + Index *p; + assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); + p = sqlite3HashInsert(&pIndex->pSchema->idxHash, + pIndex->zName, pIndex); + if( p ){ + assert( p==pIndex ); /* Malloc must have failed */ + db->mallocFailed = 1; + goto exit_create_index; + } + db->flags |= SQLITE_InternChanges; + if( pTblName!=0 ){ + pIndex->tnum = db->init.newTnum; + } + } + + /* If this is the initial CREATE INDEX statement (or CREATE TABLE if the + ** index is an implied index for a UNIQUE or PRIMARY KEY constraint) then + ** emit code to allocate the index rootpage on disk and make an entry for + ** the index in the sqlite_master table and populate the index with + ** content. But, do not do this if we are simply reading the sqlite_master + ** table to parse the schema, or if this index is the PRIMARY KEY index + ** of a WITHOUT ROWID table. + ** + ** If pTblName==0 it means this index is generated as an implied PRIMARY KEY + ** or UNIQUE index in a CREATE TABLE statement. Since the table + ** has just been created, it contains no data and the index initialization + ** step can be skipped. + */ + else if( pParse->nErr==0 && (HasRowid(pTab) || pTblName!=0) ){ + 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); + sqlite3VdbeAddOp2(v, OP_CreateIndex, iDb, iMem); + + /* Gather the complete text of the CREATE INDEX statement into + ** the zStmt variable + */ + if( pStart ){ + int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n; + if( pName->z[n-1]==';' ) n--; + /* A named index with an explicit CREATE INDEX statement */ + zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s", + onError==OE_None ? "" : " UNIQUE", n, pName->z); + }else{ + /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */ + /* zStmt = sqlite3MPrintf(""); */ + zStmt = 0; + } + + /* Add an entry in sqlite_master for this index + */ + sqlite3NestedParse(pParse, + "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);", + db->aDb[iDb].zName, SCHEMA_TABLE(iDb), + pIndex->zName, + pTab->zName, + iMem, + zStmt + ); + sqlite3DbFree(db, zStmt); + + /* Fill the index with data and reparse the schema. Code an OP_Expire + ** to invalidate all pre-compiled statements. + */ + if( pTblName ){ + sqlite3RefillIndex(pParse, pIndex, iMem); + sqlite3ChangeCookie(pParse, iDb); + sqlite3VdbeAddParseSchemaOp(v, iDb, + sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName)); + sqlite3VdbeAddOp1(v, OP_Expire, 0); + } + } + + /* When adding an index to the list of indices for a table, make + ** sure all indices labeled OE_Replace come after all those labeled + ** OE_Ignore. This is necessary for the correct constraint check + ** processing (in sqlite3GenerateConstraintChecks()) as part of + ** UPDATE and INSERT statements. + */ + if( db->init.busy || pTblName==0 ){ + if( onError!=OE_Replace || pTab->pIndex==0 + || pTab->pIndex->onError==OE_Replace){ + pIndex->pNext = pTab->pIndex; + pTab->pIndex = pIndex; + }else{ + Index *pOther = pTab->pIndex; + while( pOther->pNext && pOther->pNext->onError!=OE_Replace ){ + pOther = pOther->pNext; + } + pIndex->pNext = pOther->pNext; + pOther->pNext = pIndex; + } + pRet = pIndex; + pIndex = 0; + } + + /* Clean up before exiting */ +exit_create_index: + if( pIndex ) freeIndex(db, pIndex); + sqlite3ExprDelete(db, pPIWhere); + sqlite3ExprListDelete(db, pList); + sqlite3SrcListDelete(db, pTblName); + sqlite3DbFree(db, zName); + return pRet; +} + +/* +** Fill the Index.aiRowEst[] array with default information - information +** to be used when we have not run the ANALYZE command. +** +** aiRowEst[0] is supposed 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 combination 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. +*/ +SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){ + /* 10, 9, 8, 7, 6 */ + LogEst aVal[] = { 33, 32, 30, 28, 26 }; + LogEst *a = pIdx->aiRowLogEst; + int nCopy = MIN(ArraySize(aVal), pIdx->nKeyCol); + int i; + + /* Set the first entry (number of rows in the index) to the estimated + ** number of rows in the table. Or 10, if the estimated number of rows + ** in the table is less than that. */ + a[0] = pIdx->pTable->nRowLogEst; + if( a[0]<33 ) a[0] = 33; assert( 33==sqlite3LogEst(10) ); + + /* Estimate that a[1] is 10, a[2] is 9, a[3] is 8, a[4] is 7, a[5] is + ** 6 and each subsequent value (if any) is 5. */ + memcpy(&a[1], aVal, nCopy*sizeof(LogEst)); + for(i=nCopy+1; i<=pIdx->nKeyCol; i++){ + a[i] = 23; assert( 23==sqlite3LogEst(5) ); + } + + assert( 0==sqlite3LogEst(1) ); + if( IsUniqueIndex(pIdx) ) a[pIdx->nKeyCol] = 0; +} + +/* +** This routine will drop an existing named index. This routine +** implements the DROP INDEX statement. +*/ +SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){ + Index *pIndex; + Vdbe *v; + sqlite3 *db = pParse->db; + int iDb; + + assert( pParse->nErr==0 ); /* Never called with prior errors */ + if( db->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); + }else{ + sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); + } + pParse->checkSchema = 1; + goto exit_drop_index; + } + if( pIndex->idxType!=SQLITE_IDXTYPE_APPDEF ){ + 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 ){ + sqlite3BeginWriteOperation(pParse, 1, iDb); + sqlite3NestedParse(pParse, + "DELETE FROM %Q.%s WHERE name=%Q AND type='index'", + db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pIndex->zName + ); + sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName); + sqlite3ChangeCookie(pParse, iDb); + destroyRootPage(pParse, pIndex->tnum, iDb); + sqlite3VdbeAddOp4(v, OP_DropIndex, iDb, 0, 0, pIndex->zName, 0); + } + +exit_drop_index: + sqlite3SrcListDelete(db, pName); +} + +/* +** pArray is a pointer to an array of objects. Each object in the +** array is szEntry bytes in size. This routine uses sqlite3DbRealloc() +** to extend the array so that there is space for a new object at the end. +** +** When this function is called, *pnEntry contains the current size of +** the array (in entries - so the allocation is ((*pnEntry) * szEntry) bytes +** in total). +** +** If the realloc() is successful (i.e. if no OOM condition occurs), the +** space allocated for the new object is zeroed, *pnEntry updated to +** reflect the new size of the array and a pointer to the new allocation +** returned. *pIdx is set to the index of the new array entry in this case. +** +** Otherwise, if the realloc() fails, *pIdx is set to -1, *pnEntry remains +** unchanged and a copy of pArray returned. +*/ +SQLITE_PRIVATE void *sqlite3ArrayAllocate( + sqlite3 *db, /* Connection to notify of malloc failures */ + void *pArray, /* Array of objects. Might be reallocated */ + int szEntry, /* Size of each object in the array */ + int *pnEntry, /* Number of objects currently in use */ + int *pIdx /* Write the index of a new slot here */ +){ + char *z; + int n = *pnEntry; + if( (n & (n-1))==0 ){ + int sz = (n==0) ? 1 : 2*n; + void *pNew = sqlite3DbRealloc(db, pArray, sz*szEntry); + if( pNew==0 ){ + *pIdx = -1; + return pArray; + } + pArray = pNew; + } + z = (char*)pArray; + memset(&z[n * szEntry], 0, szEntry); + *pIdx = n; + ++*pnEntry; + return pArray; +} + +/* +** 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. +*/ +SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){ + int i; + if( pList==0 ){ + pList = sqlite3DbMallocZero(db, sizeof(IdList) ); + if( pList==0 ) return 0; + } + pList->a = sqlite3ArrayAllocate( + db, + pList->a, + sizeof(pList->a[0]), + &pList->nId, + &i + ); + if( i<0 ){ + sqlite3IdListDelete(db, pList); + return 0; + } + pList->a[i].zName = sqlite3NameFromToken(db, pToken); + return pList; +} + +/* +** Delete an IdList. +*/ +SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){ + int i; + if( pList==0 ) return; + for(i=0; inId; i++){ + sqlite3DbFree(db, pList->a[i].zName); + } + sqlite3DbFree(db, pList->a); + sqlite3DbFree(db, pList); +} + +/* +** Return the index in pList of the identifier named zId. Return -1 +** if not found. +*/ +SQLITE_PRIVATE int sqlite3IdListIndex(IdList *pList, const char *zName){ + int i; + if( pList==0 ) return -1; + for(i=0; inId; i++){ + if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i; + } + return -1; +} + +/* +** Expand the space allocated for the given SrcList object by +** creating nExtra new slots beginning at iStart. iStart is zero based. +** New slots are zeroed. +** +** For example, suppose a SrcList initially contains two entries: A,B. +** To append 3 new entries onto the end, do this: +** +** sqlite3SrcListEnlarge(db, pSrclist, 3, 2); +** +** After the call above it would contain: A, B, nil, nil, nil. +** If the iStart argument had been 1 instead of 2, then the result +** would have been: A, nil, nil, nil, B. To prepend the new slots, +** the iStart value would be 0. The result then would +** be: nil, nil, nil, A, B. +** +** If a memory allocation fails the SrcList is unchanged. The +** db->mallocFailed flag will be set to true. +*/ +SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge( + sqlite3 *db, /* Database connection to notify of OOM errors */ + SrcList *pSrc, /* The SrcList to be enlarged */ + int nExtra, /* Number of new slots to add to pSrc->a[] */ + int iStart /* Index in pSrc->a[] of first new slot */ +){ + int i; + + /* Sanity checking on calling parameters */ + assert( iStart>=0 ); + assert( nExtra>=1 ); + assert( pSrc!=0 ); + assert( iStart<=pSrc->nSrc ); + + /* Allocate additional space if needed */ + if( (u32)pSrc->nSrc+nExtra>pSrc->nAlloc ){ + SrcList *pNew; + int nAlloc = pSrc->nSrc+nExtra; + int nGot; + pNew = sqlite3DbRealloc(db, pSrc, + sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) ); + if( pNew==0 ){ + assert( db->mallocFailed ); + return pSrc; + } + pSrc = pNew; + nGot = (sqlite3DbMallocSize(db, pNew) - sizeof(*pSrc))/sizeof(pSrc->a[0])+1; + pSrc->nAlloc = nGot; + } + + /* Move existing slots that come after the newly inserted slots + ** out of the way */ + for(i=pSrc->nSrc-1; i>=iStart; i--){ + pSrc->a[i+nExtra] = pSrc->a[i]; + } + pSrc->nSrc += nExtra; + + /* Zero the newly allocated slots */ + memset(&pSrc->a[iStart], 0, sizeof(pSrc->a[0])*nExtra); + for(i=iStart; ia[i].iCursor = -1; + } + + /* Return a pointer to the enlarged SrcList */ + return pSrc; +} + + +/* +** 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 pTable is NULL. +** +** A SrcList is returned, or NULL if there is an OOM error. The returned +** SrcList might be the same as the SrcList that was input or it might be +** a new one. If an OOM error does occurs, then the prior value of pList +** that is input to this routine is automatically freed. +** +** If pDatabase is not null, it means that the table has an optional +** database name prefix. Like this: "database.table". The pDatabase +** points to the table name and the pTable points to the database name. +** The SrcList.a[].zName field is filled with the table name which might +** come from pTable (if pDatabase is NULL) or from pDatabase. +** SrcList.a[].zDatabase is filled with the database name from pTable, +** or with NULL if no database is specified. +** +** In other words, if call like this: +** +** sqlite3SrcListAppend(D,A,B,0); +** +** Then B is a table name and the database name is unspecified. If called +** like this: +** +** sqlite3SrcListAppend(D,A,B,C); +** +** Then C is the table name and B is the database name. If C is defined +** then so is B. In other words, we never have a case where: +** +** sqlite3SrcListAppend(D,A,0,C); +** +** Both pTable and pDatabase are assumed to be quoted. They are dequoted +** before being added to the SrcList. +*/ +SQLITE_PRIVATE SrcList *sqlite3SrcListAppend( + sqlite3 *db, /* Connection to notify of malloc failures */ + SrcList *pList, /* Append to this SrcList. NULL creates a new SrcList */ + Token *pTable, /* Table to append */ + Token *pDatabase /* Database of the table */ +){ + struct SrcList_item *pItem; + assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */ + if( pList==0 ){ + pList = sqlite3DbMallocZero(db, sizeof(SrcList) ); + if( pList==0 ) return 0; + pList->nAlloc = 1; + } + pList = sqlite3SrcListEnlarge(db, pList, 1, pList->nSrc); + if( db->mallocFailed ){ + sqlite3SrcListDelete(db, pList); + return 0; + } + pItem = &pList->a[pList->nSrc-1]; + if( pDatabase && pDatabase->z==0 ){ + pDatabase = 0; + } + if( pDatabase ){ + Token *pTemp = pDatabase; + pDatabase = pTable; + pTable = pTemp; + } + pItem->zName = sqlite3NameFromToken(db, pTable); + pItem->zDatabase = sqlite3NameFromToken(db, pDatabase); + return pList; +} + +/* +** Assign VdbeCursor index numbers to all tables in a SrcList +*/ +SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ + int i; + struct SrcList_item *pItem; + assert(pList || pParse->db->mallocFailed ); + if( pList ){ + for(i=0, pItem=pList->a; inSrc; i++, pItem++){ + if( pItem->iCursor>=0 ) break; + pItem->iCursor = pParse->nTab++; + if( pItem->pSelect ){ + sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc); + } + } + } +} + +/* +** Delete an entire SrcList including all its substructure. +*/ +SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ + int i; + struct SrcList_item *pItem; + if( pList==0 ) return; + for(pItem=pList->a, i=0; inSrc; i++, pItem++){ + sqlite3DbFree(db, pItem->zDatabase); + sqlite3DbFree(db, pItem->zName); + sqlite3DbFree(db, pItem->zAlias); + sqlite3DbFree(db, pItem->zIndex); + sqlite3DeleteTable(db, pItem->pTab); + sqlite3SelectDelete(db, pItem->pSelect); + sqlite3ExprDelete(db, pItem->pOn); + sqlite3IdListDelete(db, pItem->pUsing); + } + sqlite3DbFree(db, pList); +} + +/* +** This routine is called by the parser to add a new term to the +** end of a growing FROM clause. The "p" parameter is the part of +** the FROM clause that has already been constructed. "p" is NULL +** if this is the first term of the FROM clause. pTable and pDatabase +** are the name of the table and database named in the FROM clause term. +** pDatabase is NULL if the database name qualifier is missing - the +** usual case. If the term has an alias, then pAlias points to the +** alias token. If the term is a subquery, then pSubquery is the +** SELECT statement that the subquery encodes. The pTable and +** pDatabase parameters are NULL for subqueries. The pOn and pUsing +** parameters are the content of the ON and USING clauses. +** +** Return a new SrcList which encodes is the FROM with the new +** term added. +*/ +SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm( + Parse *pParse, /* Parsing context */ + SrcList *p, /* The left part of the FROM clause already seen */ + Token *pTable, /* Name of the table to add to the FROM clause */ + Token *pDatabase, /* Name of the database containing pTable */ + Token *pAlias, /* The right-hand side of the AS subexpression */ + Select *pSubquery, /* A subquery used in place of a table name */ + Expr *pOn, /* The ON clause of a join */ + IdList *pUsing /* The USING clause of a join */ +){ + struct SrcList_item *pItem; + sqlite3 *db = pParse->db; + if( !p && (pOn || pUsing) ){ + sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s", + (pOn ? "ON" : "USING") + ); + goto append_from_error; + } + p = sqlite3SrcListAppend(db, p, pTable, pDatabase); + if( p==0 || NEVER(p->nSrc==0) ){ + goto append_from_error; + } + pItem = &p->a[p->nSrc-1]; + assert( pAlias!=0 ); + if( pAlias->n ){ + pItem->zAlias = sqlite3NameFromToken(db, pAlias); + } + pItem->pSelect = pSubquery; + pItem->pOn = pOn; + pItem->pUsing = pUsing; + return p; + + append_from_error: + assert( p==0 ); + sqlite3ExprDelete(db, pOn); + sqlite3IdListDelete(db, pUsing); + sqlite3SelectDelete(db, pSubquery); + return 0; +} + +/* +** Add an INDEXED BY or NOT INDEXED clause to the most recently added +** element of the source-list passed as the second argument. +*/ +SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ + assert( pIndexedBy!=0 ); + if( p && ALWAYS(p->nSrc>0) ){ + struct SrcList_item *pItem = &p->a[p->nSrc-1]; + assert( pItem->notIndexed==0 && pItem->zIndex==0 ); + if( pIndexedBy->n==1 && !pIndexedBy->z ){ + /* A "NOT INDEXED" clause was supplied. See parse.y + ** construct "indexed_opt" for details. */ + pItem->notIndexed = 1; + }else{ + pItem->zIndex = sqlite3NameFromToken(pParse->db, pIndexedBy); + } + } +} + +/* +** When building up a FROM clause in the parser, the join operator +** is initially attached to the left operand. But the code generator +** expects the join operator to be on the right operand. This routine +** Shifts all join operators from left to right for an entire FROM +** clause. +** +** Example: Suppose the join is like this: +** +** A natural cross join B +** +** The operator is "natural cross join". The A and B operands are stored +** in p->a[0] and p->a[1], respectively. The parser initially stores the +** operator with A. This routine shifts that operator over to B. +*/ +SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList *p){ + if( p ){ + int i; + for(i=p->nSrc-1; i>0; i--){ + p->a[i].jointype = p->a[i-1].jointype; + } + p->a[0].jointype = 0; + } +} + +/* +** Begin a transaction +*/ +SQLITE_PRIVATE void sqlite3BeginTransaction(Parse *pParse, int type){ + sqlite3 *db; + Vdbe *v; + int i; + + assert( pParse!=0 ); + db = pParse->db; + assert( db!=0 ); +/* if( db->aDb[0].pBt==0 ) return; */ + if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ){ + return; + } + v = sqlite3GetVdbe(pParse); + if( !v ) return; + if( type!=TK_DEFERRED ){ + for(i=0; inDb; i++){ + sqlite3VdbeAddOp2(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1); + sqlite3VdbeUsesBtree(v, i); + } + } + sqlite3VdbeAddOp2(v, OP_AutoCommit, 0, 0); +} + +/* +** Commit a transaction +*/ +SQLITE_PRIVATE void sqlite3CommitTransaction(Parse *pParse){ + Vdbe *v; + + assert( pParse!=0 ); + assert( pParse->db!=0 ); + if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ){ + return; + } + v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 0); + } +} + +/* +** Rollback a transaction +*/ +SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse *pParse){ + Vdbe *v; + + assert( pParse!=0 ); + assert( pParse->db!=0 ); + if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ){ + return; + } + v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 1); + } +} + +/* +** This function is called by the parser when it parses a command to create, +** release or rollback an SQL savepoint. +*/ +SQLITE_PRIVATE void sqlite3Savepoint(Parse *pParse, int op, Token *pName){ + char *zName = sqlite3NameFromToken(pParse->db, pName); + if( zName ){ + Vdbe *v = sqlite3GetVdbe(pParse); +#ifndef SQLITE_OMIT_AUTHORIZATION + static const char * const az[] = { "BEGIN", "RELEASE", "ROLLBACK" }; + assert( !SAVEPOINT_BEGIN && SAVEPOINT_RELEASE==1 && SAVEPOINT_ROLLBACK==2 ); +#endif + if( !v || sqlite3AuthCheck(pParse, SQLITE_SAVEPOINT, az[op], zName, 0) ){ + sqlite3DbFree(pParse->db, zName); + return; + } + sqlite3VdbeAddOp4(v, OP_Savepoint, op, 0, 0, zName, P4_DYNAMIC); + } +} + +/* +** Make sure the TEMP database is open and available for use. Return +** the number of errors. Leave any error messages in the pParse structure. +*/ +SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){ + sqlite3 *db = pParse->db; + if( db->aDb[1].pBt==0 && !pParse->explain ){ + int rc; + Btree *pBt; + static const int flags = + SQLITE_OPEN_READWRITE | + SQLITE_OPEN_CREATE | + SQLITE_OPEN_EXCLUSIVE | + SQLITE_OPEN_DELETEONCLOSE | + SQLITE_OPEN_TEMP_DB; + + rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pBt, 0, flags); + if( rc!=SQLITE_OK ){ + sqlite3ErrorMsg(pParse, "unable to open a temporary database " + "file for storing temporary tables"); + pParse->rc = rc; + return 1; + } + db->aDb[1].pBt = pBt; + assert( db->aDb[1].pSchema ); + if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){ + db->mallocFailed = 1; + return 1; + } + } + return 0; +} + +/* +** Record the fact that the schema cookie will need to be verified +** for database iDb. The code to actually verify the schema cookie +** will occur at the end of the top-level VDBE and will be generated +** later, by sqlite3FinishCoding(). +*/ +SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + sqlite3 *db = pToplevel->db; + + assert( iDb>=0 && iDbnDb ); + assert( db->aDb[iDb].pBt!=0 || iDb==1 ); + assert( iDbcookieMask, iDb)==0 ){ + DbMaskSet(pToplevel->cookieMask, iDb); + pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie; + if( !OMIT_TEMPDB && iDb==1 ){ + sqlite3OpenTempDatabase(pToplevel); + } + } +} + +/* +** If argument zDb is NULL, then call sqlite3CodeVerifySchema() for each +** attached database. Otherwise, invoke it for the database named zDb only. +*/ +SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){ + sqlite3 *db = pParse->db; + int i; + for(i=0; inDb; i++){ + Db *pDb = &db->aDb[i]; + if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zName)) ){ + sqlite3CodeVerifySchema(pParse, i); + } + } +} + +/* +** Generate VDBE code that prepares for doing an operation that +** might change the database. +** +** This routine starts a new transaction if we are not already within +** a transaction. If we are already within a transaction, then a checkpoint +** is set if the setStatement parameter is true. A checkpoint should +** be set for operations that might fail (due to a constraint) part of +** the way through and which will need to undo some writes without having to +** rollback the whole transaction. For operations where all constraints +** can be checked before any changes are made to the database, it is never +** necessary to undo a write and the checkpoint should not be set. +*/ +SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + sqlite3CodeVerifySchema(pParse, iDb); + DbMaskSet(pToplevel->writeMask, iDb); + pToplevel->isMultiWrite |= setStatement; +} + +/* +** Indicate that the statement currently under construction might write +** more than one entry (example: deleting one row then inserting another, +** inserting multiple rows in a table, or inserting a row and index entries.) +** If an abort occurs after some of these writes have completed, then it will +** be necessary to undo the completed writes. +*/ +SQLITE_PRIVATE void sqlite3MultiWrite(Parse *pParse){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + pToplevel->isMultiWrite = 1; +} + +/* +** The code generator calls this routine if is discovers that it is +** possible to abort a statement prior to completion. In order to +** perform this abort without corrupting the database, we need to make +** sure that the statement is protected by a statement transaction. +** +** Technically, we only need to set the mayAbort flag if the +** isMultiWrite flag was previously set. There is a time dependency +** such that the abort must occur after the multiwrite. This makes +** some statements involving the REPLACE conflict resolution algorithm +** go a little faster. But taking advantage of this time dependency +** makes it more difficult to prove that the code is correct (in +** particular, it prevents us from writing an effective +** implementation of sqlite3AssertMayAbort()) and so we have chosen +** to take the safe route and skip the optimization. +*/ +SQLITE_PRIVATE void sqlite3MayAbort(Parse *pParse){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + pToplevel->mayAbort = 1; +} + +/* +** Code an OP_Halt that causes the vdbe to return an SQLITE_CONSTRAINT +** error. The onError parameter determines which (if any) of the statement +** and/or current transaction is rolled back. +*/ +SQLITE_PRIVATE void sqlite3HaltConstraint( + Parse *pParse, /* Parsing context */ + int errCode, /* extended error code */ + int onError, /* Constraint type */ + char *p4, /* Error message */ + i8 p4type, /* P4_STATIC or P4_TRANSIENT */ + u8 p5Errmsg /* P5_ErrMsg type */ +){ + Vdbe *v = sqlite3GetVdbe(pParse); + assert( (errCode&0xff)==SQLITE_CONSTRAINT ); + if( onError==OE_Abort ){ + sqlite3MayAbort(pParse); + } + sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type); + if( p5Errmsg ) sqlite3VdbeChangeP5(v, p5Errmsg); +} + +/* +** Code an OP_Halt due to UNIQUE or PRIMARY KEY constraint violation. +*/ +SQLITE_PRIVATE void sqlite3UniqueConstraint( + Parse *pParse, /* Parsing context */ + int onError, /* Constraint type */ + Index *pIdx /* The index that triggers the constraint */ +){ + char *zErr; + int j; + StrAccum errMsg; + Table *pTab = pIdx->pTable; + + sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200); + for(j=0; jnKeyCol; j++){ + char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName; + if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2); + sqlite3StrAccumAppendAll(&errMsg, pTab->zName); + sqlite3StrAccumAppend(&errMsg, ".", 1); + sqlite3StrAccumAppendAll(&errMsg, zCol); + } + zErr = sqlite3StrAccumFinish(&errMsg); + sqlite3HaltConstraint(pParse, + IsPrimaryKeyIndex(pIdx) ? SQLITE_CONSTRAINT_PRIMARYKEY + : SQLITE_CONSTRAINT_UNIQUE, + onError, zErr, P4_DYNAMIC, P5_ConstraintUnique); +} + + +/* +** Code an OP_Halt due to non-unique rowid. +*/ +SQLITE_PRIVATE void sqlite3RowidConstraint( + Parse *pParse, /* Parsing context */ + int onError, /* Conflict resolution algorithm */ + Table *pTab /* The table with the non-unique rowid */ +){ + char *zMsg; + int rc; + if( pTab->iPKey>=0 ){ + zMsg = sqlite3MPrintf(pParse->db, "%s.%s", pTab->zName, + pTab->aCol[pTab->iPKey].zName); + rc = SQLITE_CONSTRAINT_PRIMARYKEY; + }else{ + zMsg = sqlite3MPrintf(pParse->db, "%s.rowid", pTab->zName); + rc = SQLITE_CONSTRAINT_ROWID; + } + sqlite3HaltConstraint(pParse, rc, onError, zMsg, P4_DYNAMIC, + P5_ConstraintUnique); +} + +/* +** 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; + assert( zColl!=0 ); + for(i=0; inColumn; i++){ + const char *z = pIndex->azColl[i]; + assert( z!=0 || pIndex->aiColumn[i]<0 ); + if( pIndex->aiColumn[i]>=0 && 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 */ + + assert( sqlite3BtreeHoldsAllMutexes(db) ); /* Needed for schema access */ + for(iDb=0, pDb=db->aDb; iDbnDb; iDb++, pDb++){ + assert( pDb!=0 ); + 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. +** +** REINDEX -- 1 +** REINDEX -- 2 +** REINDEX ?.? -- 3 +** REINDEX ?.? -- 4 +** +** Form 1 causes all indices in all attached databases to be rebuilt. +** Form 2 rebuilds all indices in all databases that use the named +** collating function. Forms 3 and 4 rebuild the named index or all +** indices associated with the named table. +*/ +#ifndef SQLITE_OMIT_REINDEX +SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ + CollSeq *pColl; /* Collating sequence to be reindexed, or NULL */ + char *z; /* Name of a table or index */ + const char *zDb; /* Name of the database */ + Table *pTab; /* A table in the database */ + Index *pIndex; /* An index associated with pTab */ + int iDb; /* The database index number */ + sqlite3 *db = pParse->db; /* The database connection */ + Token *pObjName; /* Name of the table or index to be reindexed */ + + /* 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 ){ + reindexDatabases(pParse, 0); + return; + }else if( NEVER(pName2==0) || pName2->z==0 ){ + char *zColl; + assert( pName1->z ); + zColl = sqlite3NameFromToken(pParse->db, pName1); + if( !zColl ) return; + pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); + if( pColl ){ + reindexDatabases(pParse, zColl); + sqlite3DbFree(db, zColl); + return; + } + sqlite3DbFree(db, zColl); + } + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName); + if( iDb<0 ) return; + z = sqlite3NameFromToken(db, pObjName); + if( z==0 ) return; + zDb = db->aDb[iDb].zName; + pTab = sqlite3FindTable(db, z, zDb); + if( pTab ){ + reindexTable(pParse, pTab, 0); + sqlite3DbFree(db, z); + return; + } + pIndex = sqlite3FindIndex(db, z, zDb); + sqlite3DbFree(db, z); + if( pIndex ){ + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3RefillIndex(pParse, pIndex, -1); + return; + } + sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed"); +} +#endif + +/* +** Return a KeyInfo structure that is appropriate for the given Index. +** +** The KeyInfo structure for an index is cached in the Index object. +** So there might be multiple references to the returned pointer. The +** caller should not try to modify the KeyInfo object. +** +** The caller should invoke sqlite3KeyInfoUnref() on the returned object +** when it has finished using it. +*/ +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ + int i; + int nCol = pIdx->nColumn; + int nKey = pIdx->nKeyCol; + KeyInfo *pKey; + if( pParse->nErr ) return 0; + if( pIdx->uniqNotNull ){ + pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey); + }else{ + pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0); + } + if( pKey ){ + assert( sqlite3KeyInfoIsWriteable(pKey) ); + for(i=0; iazColl[i]; + assert( zColl!=0 ); + pKey->aColl[i] = strcmp(zColl,"BINARY")==0 ? 0 : + sqlite3LocateCollSeq(pParse, zColl); + pKey->aSortOrder[i] = pIdx->aSortOrder[i]; + } + if( pParse->nErr ){ + sqlite3KeyInfoUnref(pKey); + pKey = 0; + } + } + return pKey; +} + +#ifndef SQLITE_OMIT_CTE +/* +** This routine is invoked once per CTE by the parser while parsing a +** WITH clause. +*/ +SQLITE_PRIVATE With *sqlite3WithAdd( + Parse *pParse, /* Parsing context */ + With *pWith, /* Existing WITH clause, or NULL */ + Token *pName, /* Name of the common-table */ + ExprList *pArglist, /* Optional column name list for the table */ + Select *pQuery /* Query used to initialize the table */ +){ + sqlite3 *db = pParse->db; + With *pNew; + char *zName; + + /* Check that the CTE name is unique within this WITH clause. If + ** not, store an error in the Parse structure. */ + zName = sqlite3NameFromToken(pParse->db, pName); + if( zName && pWith ){ + int i; + for(i=0; inCte; i++){ + if( sqlite3StrICmp(zName, pWith->a[i].zName)==0 ){ + sqlite3ErrorMsg(pParse, "duplicate WITH table name: %s", zName); + } + } + } + + if( pWith ){ + int nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte); + pNew = sqlite3DbRealloc(db, pWith, nByte); + }else{ + pNew = sqlite3DbMallocZero(db, sizeof(*pWith)); + } + assert( zName!=0 || pNew==0 ); + assert( db->mallocFailed==0 || pNew==0 ); + + if( pNew==0 ){ + sqlite3ExprListDelete(db, pArglist); + sqlite3SelectDelete(db, pQuery); + sqlite3DbFree(db, zName); + pNew = pWith; + }else{ + pNew->a[pNew->nCte].pSelect = pQuery; + pNew->a[pNew->nCte].pCols = pArglist; + pNew->a[pNew->nCte].zName = zName; + pNew->a[pNew->nCte].zErr = 0; + pNew->nCte++; + } + + return pNew; +} + +/* +** Free the contents of the With object passed as the second argument. +*/ +SQLITE_PRIVATE void sqlite3WithDelete(sqlite3 *db, With *pWith){ + if( pWith ){ + int i; + for(i=0; inCte; i++){ + struct Cte *pCte = &pWith->a[i]; + sqlite3ExprListDelete(db, pCte->pCols); + sqlite3SelectDelete(db, pCte->pSelect); + sqlite3DbFree(db, pCte->zName); + } + sqlite3DbFree(db, pWith); + } +} +#endif /* !defined(SQLITE_OMIT_CTE) */ + +/************** End of build.c ***********************************************/ +/************** Begin file callback.c ****************************************/ +/* +** 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. +*/ + + +/* +** Invoke the 'collation needed' callback to request a collation sequence +** in the encoding enc of name zName, length nName. +*/ +static void callCollNeeded(sqlite3 *db, int enc, const char *zName){ + assert( !db->xCollNeeded || !db->xCollNeeded16 ); + if( db->xCollNeeded ){ + char *zExternal = sqlite3DbStrDup(db, zName); + if( !zExternal ) return; + db->xCollNeeded(db->pCollNeededArg, db, enc, zExternal); + sqlite3DbFree(db, zExternal); + } +#ifndef SQLITE_OMIT_UTF16 + if( db->xCollNeeded16 ){ + char const *zExternal; + sqlite3_value *pTmp = sqlite3ValueNew(db); + sqlite3ValueSetStr(pTmp, -1, 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 i; + static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 }; + for(i=0; i<3; i++){ + pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, 0); + if( pColl2->xCmp!=0 ){ + memcpy(pColl, pColl2, sizeof(CollSeq)); + pColl->xDel = 0; /* Do not copy the destructor */ + 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 desired 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. If no collation is found, leave an error message. +** +** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq() +*/ +SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq( + Parse *pParse, /* Parsing context */ + u8 enc, /* The desired encoding for the collating sequence */ + CollSeq *pColl, /* Collating sequence with native encoding, or NULL */ + const char *zName /* Collating sequence name */ +){ + CollSeq *p; + sqlite3 *db = pParse->db; + + p = pColl; + if( !p ){ + p = sqlite3FindCollSeq(db, enc, zName, 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, enc, zName); + p = sqlite3FindCollSeq(db, enc, zName, 0); + } + if( p && !p->xCmp && synthCollSeq(db, p) ){ + p = 0; + } + assert( !p || p->xCmp ); + if( p==0 ){ + sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); + } + 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. +*/ +SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ + if( pColl ){ + const char *zName = pColl->zName; + sqlite3 *db = pParse->db; + CollSeq *p = sqlite3GetCollSeq(pParse, ENC(db), pColl, zName); + if( !p ){ + 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 +** preferred 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, /* Database connection */ + const char *zName, /* Name of the collating sequence */ + int create /* Create a new entry if true */ +){ + CollSeq *pColl; + pColl = sqlite3HashFind(&db->aCollSeq, zName); + + if( 0==pColl && create ){ + int nName = sqlite3Strlen30(zName); + pColl = sqlite3DbMallocZero(db, 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, pColl); + + /* If a malloc() failure occurred in sqlite3HashInsert(), it will + ** return the pColl pointer to be deleted (because it wasn't added + ** to the hash table). + */ + assert( pDel==0 || pDel==pColl ); + if( pDel!=0 ){ + db->mallocFailed = 1; + sqlite3DbFree(db, pDel); + pColl = 0; + } + } + } + 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. +** +** A separate function sqlite3LocateCollSeq() is a wrapper around +** this routine. sqlite3LocateCollSeq() invokes the collation factory +** if necessary and generates an error message if the collating sequence +** cannot be found. +** +** See also: sqlite3LocateCollSeq(), sqlite3GetCollSeq() +*/ +SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq( + sqlite3 *db, + u8 enc, + const char *zName, + int create +){ + CollSeq *pColl; + if( zName ){ + pColl = findCollSeqEntry(db, zName, 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; +} + +/* During the search for the best function definition, this procedure +** is called to test how well the function passed as the first argument +** matches the request for a function with nArg arguments in a system +** that uses encoding enc. The value returned indicates how well the +** request is matched. A higher value indicates a better match. +** +** If nArg is -1 that means to only return a match (non-zero) if p->nArg +** is also -1. In other words, we are searching for a function that +** takes a variable number of arguments. +** +** If nArg is -2 that means that we are searching for any function +** regardless of the number of arguments it uses, so return a positive +** match score for any +** +** The returned value is always between 0 and 6, as follows: +** +** 0: Not a match. +** 1: UTF8/16 conversion required and function takes any number of arguments. +** 2: UTF16 byte order change required and function takes any number of args. +** 3: encoding matches and function takes any number of arguments +** 4: UTF8/16 conversion required - argument count matches exactly +** 5: UTF16 byte order conversion required - argument count matches exactly +** 6: Perfect match: encoding and argument count match exactly. +** +** If nArg==(-2) then any function with a non-null xStep or xFunc is +** a perfect match and any function with both xStep and xFunc NULL is +** a non-match. +*/ +#define FUNC_PERFECT_MATCH 6 /* The score for a perfect match */ +static int matchQuality( + FuncDef *p, /* The function we are evaluating for match quality */ + int nArg, /* Desired number of arguments. (-1)==any */ + u8 enc /* Desired text encoding */ +){ + int match; + + /* nArg of -2 is a special case */ + if( nArg==(-2) ) return (p->xFunc==0 && p->xStep==0) ? 0 : FUNC_PERFECT_MATCH; + + /* Wrong number of arguments means "no match" */ + if( p->nArg!=nArg && p->nArg>=0 ) return 0; + + /* Give a better score to a function with a specific number of arguments + ** than to function that accepts any number of arguments. */ + if( p->nArg==nArg ){ + match = 4; + }else{ + match = 1; + } + + /* Bonus points if the text encoding matches */ + if( enc==(p->funcFlags & SQLITE_FUNC_ENCMASK) ){ + match += 2; /* Exact encoding match */ + }else if( (enc & p->funcFlags & 2)!=0 ){ + match += 1; /* Both are UTF16, but with different byte orders */ + } + + return match; +} + +/* +** Search a FuncDefHash for a function with the given name. Return +** a pointer to the matching FuncDef if found, or 0 if there is no match. +*/ +static FuncDef *functionSearch( + FuncDefHash *pHash, /* Hash table to search */ + int h, /* Hash of the name */ + const char *zFunc, /* Name of function */ + int nFunc /* Number of bytes in zFunc */ +){ + FuncDef *p; + for(p=pHash->a[h]; p; p=p->pHash){ + if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 && p->zName[nFunc]==0 ){ + return p; + } + } + return 0; +} + +/* +** Insert a new FuncDef into a FuncDefHash hash table. +*/ +SQLITE_PRIVATE void sqlite3FuncDefInsert( + FuncDefHash *pHash, /* The hash table into which to insert */ + FuncDef *pDef /* The function definition to insert */ +){ + FuncDef *pOther; + int nName = sqlite3Strlen30(pDef->zName); + u8 c1 = (u8)pDef->zName[0]; + int h = (sqlite3UpperToLower[c1] + nName) % ArraySize(pHash->a); + pOther = functionSearch(pHash, h, pDef->zName, nName); + if( pOther ){ + assert( pOther!=pDef && pOther->pNext!=pDef ); + pDef->pNext = pOther->pNext; + pOther->pNext = pDef; + }else{ + pDef->pNext = 0; + pDef->pHash = pHash->a[h]; + pHash->a[h] = pDef; + } +} + + + +/* +** 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. +** +** If nArg is -2, then the first valid function found is returned. A +** function is valid if either xFunc or xStep is non-zero. The nArg==(-2) +** case is used to see if zName is a valid function name for some number +** of arguments. If nArg is -2, then createFlag must be 0. +** +** 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. +*/ +SQLITE_PRIVATE 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 */ + u8 createFlag /* Create new entry if true and does not otherwise exist */ +){ + FuncDef *p; /* Iterator variable */ + FuncDef *pBest = 0; /* Best match found so far */ + int bestScore = 0; /* Score of best match */ + int h; /* Hash value */ + + assert( nArg>=(-2) ); + assert( nArg>=(-1) || createFlag==0 ); + h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a); + + /* First search for a match amongst the application-defined functions. + */ + p = functionSearch(&db->aFunc, h, zName, nName); + while( p ){ + int score = matchQuality(p, nArg, enc); + if( score>bestScore ){ + pBest = p; + bestScore = score; + } + p = p->pNext; + } + + /* If no match is found, search the built-in functions. + ** + ** If the SQLITE_PreferBuiltin flag is set, then search the built-in + ** functions even if a prior app-defined function was found. And give + ** priority to built-in functions. + ** + ** Except, if createFlag is true, that means that we are trying to + ** install a new function. Whatever FuncDef structure is returned it will + ** have fields overwritten with new information appropriate for the + ** new function. But the FuncDefs for built-in functions are read-only. + ** So we must not search for built-ins when creating a new function. + */ + if( !createFlag && (pBest==0 || (db->flags & SQLITE_PreferBuiltin)!=0) ){ + FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions); + bestScore = 0; + p = functionSearch(pHash, h, zName, nName); + while( p ){ + int score = matchQuality(p, nArg, enc); + if( score>bestScore ){ + pBest = p; + bestScore = score; + } + p = p->pNext; + } + } + + /* If the createFlag parameter is true and the search 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 && bestScorezName = (char *)&pBest[1]; + pBest->nArg = (u16)nArg; + pBest->funcFlags = enc; + memcpy(pBest->zName, zName, nName); + pBest->zName[nName] = 0; + sqlite3FuncDefInsert(&db->aFunc, pBest); + } + + if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){ + return pBest; + } + return 0; +} + +/* +** Free all resources held by the schema structure. The void* argument points +** at a Schema struct. This function does not call sqlite3DbFree(db, ) on the +** pointer itself, it just cleans up subsidiary resources (i.e. the contents +** of the schema hash tables). +** +** The Schema.cache_size variable is not cleared. +*/ +SQLITE_PRIVATE void sqlite3SchemaClear(void *p){ + Hash temp1; + Hash temp2; + HashElem *pElem; + Schema *pSchema = (Schema *)p; + + temp1 = pSchema->tblHash; + temp2 = pSchema->trigHash; + sqlite3HashInit(&pSchema->trigHash); + sqlite3HashClear(&pSchema->idxHash); + for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){ + sqlite3DeleteTrigger(0, (Trigger*)sqliteHashData(pElem)); + } + sqlite3HashClear(&temp2); + sqlite3HashInit(&pSchema->tblHash); + for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){ + Table *pTab = sqliteHashData(pElem); + sqlite3DeleteTable(0, pTab); + } + sqlite3HashClear(&temp1); + sqlite3HashClear(&pSchema->fkeyHash); + pSchema->pSeqTab = 0; + if( pSchema->schemaFlags & DB_SchemaLoaded ){ + pSchema->iGeneration++; + pSchema->schemaFlags &= ~DB_SchemaLoaded; + } +} + +/* +** Find and return the schema associated with a BTree. Create +** a new one if necessary. +*/ +SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ + Schema * p; + if( pBt ){ + p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaClear); + }else{ + p = (Schema *)sqlite3DbMallocZero(0, sizeof(Schema)); + } + if( !p ){ + db->mallocFailed = 1; + }else if ( 0==p->file_format ){ + sqlite3HashInit(&p->tblHash); + sqlite3HashInit(&p->idxHash); + sqlite3HashInit(&p->trigHash); + sqlite3HashInit(&p->fkeyHash); + p->enc = SQLITE_UTF8; + } + return p; +} + +/************** End of callback.c ********************************************/ +/************** Begin file delete.c ******************************************/ +/* +** 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. +** +************************************************************************* +** This file contains C code routines that are called by the parser +** in order to generate code for DELETE FROM statements. +*/ + +/* +** While a SrcList can in general represent multiple tables and subqueries +** (as in the FROM clause of a SELECT statement) in this case it contains +** the name of a single table, as one might find in an INSERT, DELETE, +** or UPDATE statement. Look up that table in the symbol table and +** return a pointer. Set an error message and return NULL if the table +** name is not found or if any other error occurs. +** +** The following fields are initialized appropriate in pSrc: +** +** pSrc->a[0].pTab Pointer to the Table object +** pSrc->a[0].pIndex Pointer to the INDEXED BY index, if there is one +** +*/ +SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ + struct SrcList_item *pItem = pSrc->a; + Table *pTab; + assert( pItem && pSrc->nSrc==1 ); + pTab = sqlite3LocateTableItem(pParse, 0, pItem); + sqlite3DeleteTable(pParse->db, pItem->pTab); + pItem->pTab = pTab; + if( pTab ){ + pTab->nRef++; + } + if( sqlite3IndexedByLookup(pParse, pItem) ){ + pTab = 0; + } + 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 +** writable return 0; +*/ +SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ + /* A table is not writable under the following circumstances: + ** + ** 1) It is a virtual table and no implementation of the xUpdate method + ** has been provided, or + ** 2) It is a system table (i.e. sqlite_master), this call is not + ** part of a nested parse and writable_schema pragma has not + ** been specified. + ** + ** In either case leave an error message in pParse and return non-zero. + */ + if( ( IsVirtual(pTab) + && sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ) + || ( (pTab->tabFlags & TF_Readonly)!=0 + && (pParse->db->flags & SQLITE_WriteSchema)==0 + && pParse->nested==0 ) + ){ + sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName); + return 1; + } + +#ifndef SQLITE_OMIT_VIEW + if( !viewOk && pTab->pSelect ){ + sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName); + return 1; + } +#endif + return 0; +} + + +#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) +/* +** Evaluate a view and store its result in an ephemeral table. The +** pWhere argument is an optional WHERE clause that restricts the +** set of rows in the view that are to be added to the ephemeral table. +*/ +SQLITE_PRIVATE void sqlite3MaterializeView( + Parse *pParse, /* Parsing context */ + Table *pView, /* View definition */ + Expr *pWhere, /* Optional WHERE clause to be added */ + int iCur /* Cursor number for ephemeral table */ +){ + SelectDest dest; + Select *pSel; + SrcList *pFrom; + sqlite3 *db = pParse->db; + int iDb = sqlite3SchemaToIndex(db, pView->pSchema); + pWhere = sqlite3ExprDup(db, pWhere, 0); + pFrom = sqlite3SrcListAppend(db, 0, 0, 0); + if( pFrom ){ + assert( pFrom->nSrc==1 ); + pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName); + pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName); + assert( pFrom->a[0].pOn==0 ); + assert( pFrom->a[0].pUsing==0 ); + } + pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0); + sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); + sqlite3Select(pParse, pSel, &dest); + sqlite3SelectDelete(db, pSel); +} +#endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */ + +#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) +/* +** Generate an expression tree to implement the WHERE, ORDER BY, +** and LIMIT/OFFSET portion of DELETE and UPDATE statements. +** +** DELETE FROM table_wxyz WHERE a<5 ORDER BY a LIMIT 1; +** \__________________________/ +** pLimitWhere (pInClause) +*/ +SQLITE_PRIVATE Expr *sqlite3LimitWhere( + Parse *pParse, /* The parser context */ + SrcList *pSrc, /* the FROM clause -- which tables to scan */ + Expr *pWhere, /* The WHERE clause. May be null */ + ExprList *pOrderBy, /* The ORDER BY clause. May be null */ + Expr *pLimit, /* The LIMIT clause. May be null */ + Expr *pOffset, /* The OFFSET clause. May be null */ + char *zStmtType /* Either DELETE or UPDATE. For err msgs. */ +){ + Expr *pWhereRowid = NULL; /* WHERE rowid .. */ + Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */ + Expr *pSelectRowid = NULL; /* SELECT rowid ... */ + ExprList *pEList = NULL; /* Expression list contaning only pSelectRowid */ + SrcList *pSelectSrc = NULL; /* SELECT rowid FROM x ... (dup of pSrc) */ + Select *pSelect = NULL; /* Complete SELECT tree */ + + /* Check that there isn't an ORDER BY without a LIMIT clause. + */ + if( pOrderBy && (pLimit == 0) ) { + sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType); + goto limit_where_cleanup_2; + } + + /* We only need to generate a select expression if there + ** is a limit/offset term to enforce. + */ + if( pLimit == 0 ) { + /* if pLimit is null, pOffset will always be null as well. */ + assert( pOffset == 0 ); + return pWhere; + } + + /* Generate a select expression tree to enforce the limit/offset + ** term for the DELETE or UPDATE statement. For example: + ** DELETE FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1 + ** becomes: + ** DELETE FROM table_a WHERE rowid IN ( + ** SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1 + ** ); + */ + + pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0); + if( pSelectRowid == 0 ) goto limit_where_cleanup_2; + pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid); + if( pEList == 0 ) goto limit_where_cleanup_2; + + /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree + ** and the SELECT subtree. */ + pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0); + if( pSelectSrc == 0 ) { + sqlite3ExprListDelete(pParse->db, pEList); + goto limit_where_cleanup_2; + } + + /* generate the SELECT expression tree. */ + pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0, + pOrderBy,0,pLimit,pOffset); + if( pSelect == 0 ) return 0; + + /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */ + pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0); + if( pWhereRowid == 0 ) goto limit_where_cleanup_1; + pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0); + if( pInClause == 0 ) goto limit_where_cleanup_1; + + pInClause->x.pSelect = pSelect; + pInClause->flags |= EP_xIsSelect; + sqlite3ExprSetHeightAndFlags(pParse, pInClause); + return pInClause; + + /* something went wrong. clean up anything allocated. */ +limit_where_cleanup_1: + sqlite3SelectDelete(pParse->db, pSelect); + return 0; + +limit_where_cleanup_2: + sqlite3ExprDelete(pParse->db, pWhere); + sqlite3ExprListDelete(pParse->db, pOrderBy); + sqlite3ExprDelete(pParse->db, pLimit); + sqlite3ExprDelete(pParse->db, pOffset); + return 0; +} +#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) */ + /* && !defined(SQLITE_OMIT_SUBQUERY) */ + +/* +** Generate code for a DELETE FROM statement. +** +** DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL; +** \________/ \________________/ +** pTabList pWhere +*/ +SQLITE_PRIVATE void sqlite3DeleteFrom( + Parse *pParse, /* The parser context */ + SrcList *pTabList, /* The table from which we should delete things */ + Expr *pWhere /* The WHERE clause. May be null */ +){ + Vdbe *v; /* The virtual database engine */ + Table *pTab; /* The table from which records will be deleted */ + const char *zDb; /* Name of database holding pTab */ + int i; /* Loop counter */ + WhereInfo *pWInfo; /* Information about the WHERE clause */ + Index *pIdx; /* For looping over indices of the table */ + int iTabCur; /* Cursor number for the table */ + int iDataCur = 0; /* VDBE cursor for the canonical data source */ + int iIdxCur = 0; /* Cursor number of the first index */ + int nIdx; /* Number of indices */ + sqlite3 *db; /* Main database structure */ + AuthContext sContext; /* Authorization context */ + NameContext sNC; /* Name context to resolve expressions in */ + int iDb; /* Database number */ + int memCnt = -1; /* Memory cell used for change counting */ + int rcauth; /* Value returned by authorization callback */ + int okOnePass; /* True for one-pass algorithm without the FIFO */ + int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */ + u8 *aToOpen = 0; /* Open cursor iTabCur+j if aToOpen[j] is true */ + Index *pPk; /* The PRIMARY KEY index on the table */ + int iPk = 0; /* First of nPk registers holding PRIMARY KEY value */ + i16 nPk = 1; /* Number of columns in the PRIMARY KEY */ + int iKey; /* Memory cell holding key of row to be deleted */ + i16 nKey; /* Number of memory cells in the row key */ + int iEphCur = 0; /* Ephemeral table holding all primary key values */ + int iRowSet = 0; /* Register for rowset of rows to delete */ + int addrBypass = 0; /* Address of jump over the delete logic */ + int addrLoop = 0; /* Top of the delete loop */ + int addrDelete = 0; /* Jump directly to the delete logic */ + int addrEphOpen = 0; /* Instruction to open the Ephemeral table */ + +#ifndef SQLITE_OMIT_TRIGGER + int isView; /* True if attempting to delete from a view */ + Trigger *pTrigger; /* List of table triggers, if required */ +#endif + + memset(&sContext, 0, sizeof(sContext)); + db = pParse->db; + if( pParse->nErr || db->mallocFailed ){ + goto delete_from_cleanup; + } + 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 + ** will be calling are designed to work with multiple tables and expect + ** an SrcList* parameter instead of just a Table* parameter. + */ + pTab = sqlite3SrcListLookup(pParse, pTabList); + if( pTab==0 ) goto delete_from_cleanup; + + /* Figure out if we have any triggers and if the table being + ** deleted from is a view + */ +#ifndef SQLITE_OMIT_TRIGGER + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); + isView = pTab->pSelect!=0; +#else +# define pTrigger 0 +# define isView 0 +#endif +#ifdef SQLITE_OMIT_VIEW +# undef isView +# define isView 0 +#endif + + /* If pTab is really a view, make sure it has been initialized. + */ + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto delete_from_cleanup; + } + + if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){ + goto delete_from_cleanup; + } + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDbnDb ); + zDb = db->aDb[iDb].zName; + rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb); + assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE ); + if( rcauth==SQLITE_DENY ){ + goto delete_from_cleanup; + } + assert(!isView || pTrigger); + + /* Assign cursor numbers to the table and all its indices. + */ + assert( pTabList->nSrc==1 ); + iTabCur = pTabList->a[0].iCursor = pParse->nTab++; + for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ + pParse->nTab++; + } + + /* Start the view context + */ + if( isView ){ + sqlite3AuthContextPush(pParse, &sContext, pTab->zName); + } + + /* Begin generating code. + */ + v = sqlite3GetVdbe(pParse); + if( v==0 ){ + goto delete_from_cleanup; + } + if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); + sqlite3BeginWriteOperation(pParse, 1, iDb); + + /* If we are trying to delete from a view, realize that view into + ** an ephemeral table. + */ +#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) + if( isView ){ + sqlite3MaterializeView(pParse, pTab, pWhere, iTabCur); + iDataCur = iIdxCur = iTabCur; + } +#endif + + /* Resolve the column names in the WHERE clause. + */ + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + sNC.pSrcList = pTabList; + if( sqlite3ResolveExprNames(&sNC, pWhere) ){ + goto delete_from_cleanup; + } + + /* Initialize the counter of the number of rows deleted, if + ** we are counting rows. + */ + if( db->flags & SQLITE_CountRows ){ + memCnt = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt); + } + +#ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION + /* Special case: A DELETE without a WHERE clause deletes everything. + ** It is easier just to erase the whole table. Prior to version 3.6.5, + ** this optimization caused the row change count (the value returned by + ** API function sqlite3_count_changes) to be set incorrectly. */ + if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab) + && 0==sqlite3FkRequired(pParse, pTab, 0, 0) + ){ + assert( !isView ); + sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName); + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt, + pTab->zName, P4_STATIC); + } + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + assert( pIdx->pSchema==pTab->pSchema ); + sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb); + } + }else +#endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */ + { + if( HasRowid(pTab) ){ + /* For a rowid table, initialize the RowSet to an empty set */ + pPk = 0; + nPk = 1; + iRowSet = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); + }else{ + /* For a WITHOUT ROWID table, create an ephemeral table used to + ** hold all primary keys for rows to be deleted. */ + pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pPk!=0 ); + nPk = pPk->nKeyCol; + iPk = pParse->nMem+1; + pParse->nMem += nPk; + iEphCur = pParse->nTab++; + addrEphOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEphCur, nPk); + sqlite3VdbeSetP4KeyInfo(pParse, pPk); + } + + /* Construct a query to find the rowid or primary key for every row + ** to be deleted, based on the WHERE clause. + */ + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, + WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK, + iTabCur+1); + if( pWInfo==0 ) goto delete_from_cleanup; + okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); + + /* Keep track of the number of rows to be deleted */ + if( db->flags & SQLITE_CountRows ){ + sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1); + } + + /* Extract the rowid or primary key for the current row */ + if( pPk ){ + for(i=0; iaiColumn[i], iPk+i); + } + iKey = iPk; + }else{ + iKey = pParse->nMem + 1; + iKey = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iTabCur, iKey, 0); + if( iKey>pParse->nMem ) pParse->nMem = iKey; + } + + if( okOnePass ){ + /* For ONEPASS, no need to store the rowid/primary-key. There is only + ** one, so just keep it in its register(s) and fall through to the + ** delete code. + */ + nKey = nPk; /* OP_Found will use an unpacked key */ + aToOpen = sqlite3DbMallocRaw(db, nIdx+2); + if( aToOpen==0 ){ + sqlite3WhereEnd(pWInfo); + goto delete_from_cleanup; + } + memset(aToOpen, 1, nIdx+1); + aToOpen[nIdx+1] = 0; + if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0; + if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0; + if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen); + addrDelete = sqlite3VdbeAddOp0(v, OP_Goto); /* Jump to DELETE logic */ + }else if( pPk ){ + /* Construct a composite key for the row to be deleted and remember it */ + iKey = ++pParse->nMem; + nKey = 0; /* Zero tells OP_Found to use a composite key */ + sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey, + sqlite3IndexAffinityStr(v, pPk), nPk); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iEphCur, iKey); + }else{ + /* Get the rowid of the row to be deleted and remember it in the RowSet */ + nKey = 1; /* OP_Seek always uses a single rowid */ + sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey); + } + + /* End of the WHERE loop */ + sqlite3WhereEnd(pWInfo); + if( okOnePass ){ + /* Bypass the delete logic below if the WHERE loop found zero rows */ + addrBypass = sqlite3VdbeMakeLabel(v); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrBypass); + sqlite3VdbeJumpHere(v, addrDelete); + } + + /* Unless this is a view, open cursors for the table we are + ** deleting from and all its indices. If this is a view, then the + ** only effect this statement has is to fire the INSTEAD OF + ** triggers. + */ + if( !isView ){ + testcase( IsVirtual(pTab) ); + sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, aToOpen, + &iDataCur, &iIdxCur); + assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur ); + assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 ); + } + + /* Set up a loop over the rowids/primary-keys that were found in the + ** where-clause loop above. + */ + if( okOnePass ){ + /* Just one row. Hence the top-of-loop is a no-op */ + assert( nKey==nPk ); /* OP_Found will use an unpacked key */ + assert( !IsVirtual(pTab) ); + if( aToOpen[iDataCur-iTabCur] ){ + assert( pPk!=0 || pTab->pSelect!=0 ); + sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey); + VdbeCoverage(v); + } + }else if( pPk ){ + addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey); + assert( nKey==0 ); /* OP_Found will use a composite key */ + }else{ + addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey); + VdbeCoverage(v); + assert( nKey==1 ); + } + + /* Delete the row */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); + sqlite3VtabMakeWritable(pParse, pTab); + sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB); + sqlite3VdbeChangeP5(v, OE_Abort); + sqlite3MayAbort(pParse); + }else +#endif + { + int count = (pParse->nested==0); /* True to count changes */ + sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, + iKey, nKey, count, OE_Default, okOnePass); + } + + /* End of the loop over all rowids/primary-keys. */ + if( okOnePass ){ + sqlite3VdbeResolveLabel(v, addrBypass); + }else if( pPk ){ + sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addrLoop); + }else{ + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrLoop); + sqlite3VdbeJumpHere(v, addrLoop); + } + + /* Close the cursors open on the table and its indexes. */ + if( !isView && !IsVirtual(pTab) ){ + if( !pPk ) sqlite3VdbeAddOp1(v, OP_Close, iDataCur); + for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ + sqlite3VdbeAddOp1(v, OP_Close, iIdxCur + i); + } + } + } /* End non-truncate path */ + + /* Update the sqlite_sequence table by storing the content of the + ** maximum rowid counter values recorded while inserting into + ** autoincrement tables. + */ + if( pParse->nested==0 && pParse->pTriggerTab==0 ){ + sqlite3AutoincrementEnd(pParse); + } + + /* Return the number of rows that were deleted. 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 && !pParse->pTriggerTab ){ + sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC); + } + +delete_from_cleanup: + sqlite3AuthContextPop(&sContext); + sqlite3SrcListDelete(db, pTabList); + sqlite3ExprDelete(db, pWhere); + sqlite3DbFree(db, aToOpen); + return; +} +/* Make sure "isView" and other macros defined above are undefined. Otherwise +** they may interfere with compilation of other functions in this file +** (or in another file, if this file becomes part of the amalgamation). */ +#ifdef isView + #undef isView +#endif +#ifdef pTrigger + #undef pTrigger +#endif + +/* +** This routine generates VDBE code that causes a single row of a +** single table to be deleted. Both the original table entry and +** all indices are removed. +** +** Preconditions: +** +** 1. iDataCur is an open cursor on the btree that is the canonical data +** store for the table. (This will be either the table itself, +** in the case of a rowid table, or the PRIMARY KEY index in the case +** of a WITHOUT ROWID table.) +** +** 2. Read/write cursors for all indices of pTab must be open as +** cursor number iIdxCur+i for the i-th index. +** +** 3. The primary key for the row to be deleted must be stored in a +** sequence of nPk memory cells starting at iPk. If nPk==0 that means +** that a search record formed from OP_MakeRecord is contained in the +** single memory location iPk. +*/ +SQLITE_PRIVATE void sqlite3GenerateRowDelete( + Parse *pParse, /* Parsing context */ + Table *pTab, /* Table containing the row to be deleted */ + Trigger *pTrigger, /* List of triggers to (potentially) fire */ + int iDataCur, /* Cursor from which column data is extracted */ + int iIdxCur, /* First index cursor */ + int iPk, /* First memory cell containing the PRIMARY KEY */ + i16 nPk, /* Number of PRIMARY KEY memory cells */ + u8 count, /* If non-zero, increment the row change counter */ + u8 onconf, /* Default ON CONFLICT policy for triggers */ + u8 bNoSeek /* iDataCur is already pointing to the row to delete */ +){ + Vdbe *v = pParse->pVdbe; /* Vdbe */ + int iOld = 0; /* First register in OLD.* array */ + int iLabel; /* Label resolved to end of generated code */ + u8 opSeek; /* Seek opcode */ + + /* Vdbe is guaranteed to have been allocated by this stage. */ + assert( v ); + VdbeModuleComment((v, "BEGIN: GenRowDel(%d,%d,%d,%d)", + iDataCur, iIdxCur, iPk, (int)nPk)); + + /* Seek cursor iCur to the row to delete. If this row no longer exists + ** (this can happen if a trigger program has already deleted it), do + ** not attempt to delete it or fire any DELETE triggers. */ + iLabel = sqlite3VdbeMakeLabel(v); + opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound; + if( !bNoSeek ){ + sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk); + VdbeCoverageIf(v, opSeek==OP_NotExists); + VdbeCoverageIf(v, opSeek==OP_NotFound); + } + + /* If there are any triggers to fire, allocate a range of registers to + ** use for the old.* references in the triggers. */ + if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){ + u32 mask; /* Mask of OLD.* columns in use */ + int iCol; /* Iterator used while populating OLD.* */ + int addrStart; /* Start of BEFORE trigger programs */ + + /* TODO: Could use temporary registers here. Also could attempt to + ** avoid copying the contents of the rowid register. */ + mask = sqlite3TriggerColmask( + pParse, pTrigger, 0, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onconf + ); + mask |= sqlite3FkOldmask(pParse, pTab); + iOld = pParse->nMem+1; + pParse->nMem += (1 + pTab->nCol); + + /* Populate the OLD.* pseudo-table register array. These values will be + ** used by any BEFORE and AFTER triggers that exist. */ + sqlite3VdbeAddOp2(v, OP_Copy, iPk, iOld); + for(iCol=0; iColnCol; iCol++){ + testcase( mask!=0xffffffff && iCol==31 ); + testcase( mask!=0xffffffff && iCol==32 ); + if( mask==0xffffffff || (iCol<=31 && (mask & MASKBIT32(iCol))!=0) ){ + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, iCol, iOld+iCol+1); + } + } + + /* Invoke BEFORE DELETE trigger programs. */ + addrStart = sqlite3VdbeCurrentAddr(v); + sqlite3CodeRowTrigger(pParse, pTrigger, + TK_DELETE, 0, TRIGGER_BEFORE, pTab, iOld, onconf, iLabel + ); + + /* If any BEFORE triggers were coded, then seek the cursor to the + ** row to be deleted again. It may be that the BEFORE triggers moved + ** the cursor or of already deleted the row that the cursor was + ** pointing to. + */ + if( addrStartpSelect==0 ){ + sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, 0); + sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0)); + if( count ){ + sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT); + } + } + + /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to + ** handle rows (possibly in other tables) that refer via a foreign key + ** to the row just deleted. */ + sqlite3FkActions(pParse, pTab, 0, iOld, 0, 0); + + /* Invoke AFTER DELETE trigger programs. */ + sqlite3CodeRowTrigger(pParse, pTrigger, + TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel + ); + + /* Jump here if the row had already been deleted before any BEFORE + ** trigger programs were invoked. Or if a trigger program throws a + ** RAISE(IGNORE) exception. */ + sqlite3VdbeResolveLabel(v, iLabel); + VdbeModuleComment((v, "END: GenRowDel()")); +} + +/* +** This routine generates VDBE code that causes the deletion of all +** index entries associated with a single row of a single table, pTab +** +** Preconditions: +** +** 1. A read/write cursor "iDataCur" must be open on the canonical storage +** btree for the table pTab. (This will be either the table itself +** for rowid tables or to the primary key index for WITHOUT ROWID +** tables.) +** +** 2. Read/write cursors for all indices of pTab must be open as +** cursor number iIdxCur+i for the i-th index. (The pTab->pIndex +** index is the 0-th index.) +** +** 3. The "iDataCur" cursor must be already be positioned on the row +** that is to be deleted. +*/ +SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete( + Parse *pParse, /* Parsing and code generating context */ + Table *pTab, /* Table containing the row to be deleted */ + int iDataCur, /* Cursor of table holding data. */ + int iIdxCur, /* First index cursor */ + int *aRegIdx /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */ +){ + int i; /* Index loop counter */ + int r1 = -1; /* Register holding an index key */ + int iPartIdxLabel; /* Jump destination for skipping partial index entries */ + Index *pIdx; /* Current index */ + Index *pPrior = 0; /* Prior index */ + Vdbe *v; /* The prepared statement under construction */ + Index *pPk; /* PRIMARY KEY index, or NULL for rowid tables */ + + v = pParse->pVdbe; + pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); + for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ + assert( iIdxCur+i!=iDataCur || pPk==pIdx ); + if( aRegIdx!=0 && aRegIdx[i]==0 ) continue; + if( pIdx==pPk ) continue; + VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName)); + r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, + &iPartIdxLabel, pPrior, r1); + sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1, + pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn); + sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); + pPrior = pIdx; + } +} + +/* +** Generate code that will assemble an index key and stores it in register +** regOut. The key with be for index pIdx which is an index on pTab. +** iCur is the index of a cursor open on the pTab table and pointing to +** the entry that needs indexing. If pTab is a WITHOUT ROWID table, then +** iCur must be the cursor of the PRIMARY KEY index. +** +** Return a register number which is the first in a block of +** registers that holds the elements of the index key. The +** block of registers has already been deallocated by the time +** this routine returns. +** +** If *piPartIdxLabel is not NULL, fill it in with a label and jump +** to that label if pIdx is a partial index that should be skipped. +** The label should be resolved using sqlite3ResolvePartIdxLabel(). +** A partial index should be skipped if its WHERE clause evaluates +** to false or null. If pIdx is not a partial index, *piPartIdxLabel +** will be set to zero which is an empty label that is ignored by +** sqlite3ResolvePartIdxLabel(). +** +** The pPrior and regPrior parameters are used to implement a cache to +** avoid unnecessary register loads. If pPrior is not NULL, then it is +** a pointer to a different index for which an index key has just been +** computed into register regPrior. If the current pIdx index is generating +** its key into the same sequence of registers and if pPrior and pIdx share +** a column in common, then the register corresponding to that column already +** holds the correct value and the loading of that register is skipped. +** This optimization is helpful when doing a DELETE or an INTEGRITY_CHECK +** on a table with multiple indices, and especially with the ROWID or +** PRIMARY KEY columns of the index. +*/ +SQLITE_PRIVATE int sqlite3GenerateIndexKey( + Parse *pParse, /* Parsing context */ + Index *pIdx, /* The index for which to generate a key */ + int iDataCur, /* Cursor number from which to take column data */ + int regOut, /* Put the new key into this register if not 0 */ + int prefixOnly, /* Compute only a unique prefix of the key */ + int *piPartIdxLabel, /* OUT: Jump to this label to skip partial index */ + Index *pPrior, /* Previously generated index key */ + int regPrior /* Register holding previous generated key */ +){ + Vdbe *v = pParse->pVdbe; + int j; + Table *pTab = pIdx->pTable; + int regBase; + int nCol; + + if( piPartIdxLabel ){ + if( pIdx->pPartIdxWhere ){ + *piPartIdxLabel = sqlite3VdbeMakeLabel(v); + pParse->iPartIdxTab = iDataCur; + sqlite3ExprCachePush(pParse); + sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, + SQLITE_JUMPIFNULL); + }else{ + *piPartIdxLabel = 0; + } + } + nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn; + regBase = sqlite3GetTempRange(pParse, nCol); + if( pPrior && (regBase!=regPrior || pPrior->pPartIdxWhere) ) pPrior = 0; + for(j=0; jaiColumn[j]==pIdx->aiColumn[j] ) continue; + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, pIdx->aiColumn[j], + regBase+j); + /* If the column affinity is REAL but the number is an integer, then it + ** might be stored in the table as an integer (using a compact + ** representation) then converted to REAL by an OP_RealAffinity opcode. + ** But we are getting ready to store this value back into an index, where + ** it should be converted by to INTEGER again. So omit the OP_RealAffinity + ** opcode if it is present */ + sqlite3VdbeDeletePriorOpcode(v, OP_RealAffinity); + } + if( regOut ){ + sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut); + } + sqlite3ReleaseTempRange(pParse, regBase, nCol); + return regBase; +} + +/* +** If a prior call to sqlite3GenerateIndexKey() generated a jump-over label +** because it was a partial index, then this routine should be called to +** resolve that label. +*/ +SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){ + if( iLabel ){ + sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel); + sqlite3ExprCachePop(pParse); + } +} + +/************** End of delete.c **********************************************/ +/************** Begin file func.c ********************************************/ +/* +** 2002 February 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 the C-language implementations for many of the SQL +** functions of SQLite. (Some function, and in particular the date and +** time functions, are implemented separately.) +*/ +/* #include */ +/* #include */ + +/* +** Return the collating function associated with a function. +*/ +static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){ + VdbeOp *pOp; + assert( context->pVdbe!=0 ); + pOp = &context->pVdbe->aOp[context->iOp-1]; + assert( pOp->opcode==OP_CollSeq ); + assert( pOp->p4type==P4_COLLSEQ ); + return pOp->p4.pColl; +} + +/* +** Indicate that the accumulator load should be skipped on this +** iteration of the aggregate loop. +*/ +static void sqlite3SkipAccumulatorLoad(sqlite3_context *context){ + context->skipFlag = 1; +} + +/* +** Implementation of the non-aggregate min() and max() functions +*/ +static void minmaxFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int i; + int mask; /* 0 for min() or 0xffffffff for max() */ + int iBest; + CollSeq *pColl; + + assert( argc>1 ); + mask = sqlite3_user_data(context)==0 ? 0 : -1; + pColl = sqlite3GetFuncCollSeq(context); + assert( pColl ); + assert( mask==-1 || mask==0 ); + iBest = 0; + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + for(i=1; i=0 ){ + testcase( mask==0 ); + iBest = i; + } + } + sqlite3_result_value(context, argv[iBest]); +} + +/* +** Return the type of the argument. +*/ +static void typeofFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + const char *z = 0; + UNUSED_PARAMETER(NotUsed); + switch( sqlite3_value_type(argv[0]) ){ + case SQLITE_INTEGER: z = "integer"; break; + case SQLITE_TEXT: z = "text"; break; + case SQLITE_FLOAT: z = "real"; break; + case SQLITE_BLOB: z = "blob"; break; + default: z = "null"; 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 ); + UNUSED_PARAMETER(argc); + 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]); + if( z==0 ) return; + len = 0; + while( *z ){ + len++; + SQLITE_SKIP_UTF8(z); + } + sqlite3_result_int(context, len); + break; + } + default: { + sqlite3_result_null(context); + break; + } + } +} + +/* +** Implementation of the abs() function. +** +** IMP: R-23979-26855 The abs(X) function returns the absolute value of +** the numeric argument X. +*/ +static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ + assert( argc==1 ); + UNUSED_PARAMETER(argc); + switch( sqlite3_value_type(argv[0]) ){ + case SQLITE_INTEGER: { + i64 iVal = sqlite3_value_int64(argv[0]); + if( iVal<0 ){ + if( iVal==SMALLEST_INT64 ){ + /* IMP: R-31676-45509 If X is the integer -9223372036854775808 + ** then abs(X) throws an integer overflow error since there is no + ** equivalent positive 64-bit two complement value. */ + sqlite3_result_error(context, "integer overflow", -1); + return; + } + iVal = -iVal; + } + sqlite3_result_int64(context, iVal); + break; + } + case SQLITE_NULL: { + /* IMP: R-37434-19929 Abs(X) returns NULL if X is NULL. */ + sqlite3_result_null(context); + break; + } + default: { + /* Because sqlite3_value_double() returns 0.0 if the argument is not + ** something that can be converted into a number, we have: + ** IMP: R-01992-00519 Abs(X) returns 0.0 if X is a string or blob + ** that cannot be converted to a numeric value. + */ + double rVal = sqlite3_value_double(argv[0]); + if( rVal<0 ) rVal = -rVal; + sqlite3_result_double(context, rVal); + break; + } + } +} + +/* +** Implementation of the instr() function. +** +** instr(haystack,needle) finds the first occurrence of needle +** in haystack and returns the number of previous characters plus 1, +** or 0 if needle does not occur within haystack. +** +** If both haystack and needle are BLOBs, then the result is one more than +** the number of bytes in haystack prior to the first occurrence of needle, +** or 0 if needle never occurs in haystack. +*/ +static void instrFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *zHaystack; + const unsigned char *zNeedle; + int nHaystack; + int nNeedle; + int typeHaystack, typeNeedle; + int N = 1; + int isText; + + UNUSED_PARAMETER(argc); + typeHaystack = sqlite3_value_type(argv[0]); + typeNeedle = sqlite3_value_type(argv[1]); + if( typeHaystack==SQLITE_NULL || typeNeedle==SQLITE_NULL ) return; + nHaystack = sqlite3_value_bytes(argv[0]); + nNeedle = sqlite3_value_bytes(argv[1]); + if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){ + zHaystack = sqlite3_value_blob(argv[0]); + zNeedle = sqlite3_value_blob(argv[1]); + isText = 0; + }else{ + zHaystack = sqlite3_value_text(argv[0]); + zNeedle = sqlite3_value_text(argv[1]); + isText = 1; + } + while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){ + N++; + do{ + nHaystack--; + zHaystack++; + }while( isText && (zHaystack[0]&0xc0)==0x80 ); + } + if( nNeedle>nHaystack ) N = 0; + sqlite3_result_int(context, N); +} + +/* +** Implementation of the printf() function. +*/ +static void printfFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + PrintfArguments x; + StrAccum str; + const char *zFormat; + int n; + sqlite3 *db = sqlite3_context_db_handle(context); + + if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){ + x.nArg = argc-1; + x.nUsed = 0; + x.apArg = argv+1; + sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); + sqlite3XPrintf(&str, SQLITE_PRINTF_SQLFUNC, zFormat, &x); + n = str.nChar; + sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n, + SQLITE_DYNAMIC); + } +} + +/* +** Implementation of the substr() function. +** +** substr(x,p1,p2) returns p2 characters of x[] beginning with p1. +** p1 is 1-indexed. So substr(x,1,1) returns the first character +** of x. If x is text, then we actually count UTF-8 characters. +** If x is a blob, then we count bytes. +** +** If p1 is negative, then we begin abs(p1) from the end of x[]. +** +** If p2 is negative, return the p2 characters preceding p1. +*/ +static void substrFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *z; + const unsigned char *z2; + int len; + int p0type; + i64 p1, p2; + int negP2 = 0; + + assert( argc==3 || argc==2 ); + if( sqlite3_value_type(argv[1])==SQLITE_NULL + || (argc==3 && sqlite3_value_type(argv[2])==SQLITE_NULL) + ){ + return; + } + p0type = sqlite3_value_type(argv[0]); + p1 = sqlite3_value_int(argv[1]); + if( p0type==SQLITE_BLOB ){ + len = sqlite3_value_bytes(argv[0]); + z = sqlite3_value_blob(argv[0]); + if( z==0 ) return; + assert( len==sqlite3_value_bytes(argv[0]) ); + }else{ + z = sqlite3_value_text(argv[0]); + if( z==0 ) return; + len = 0; + if( p1<0 ){ + for(z2=z; *z2; len++){ + SQLITE_SKIP_UTF8(z2); + } + } + } +#ifdef SQLITE_SUBSTR_COMPATIBILITY + /* If SUBSTR_COMPATIBILITY is defined then substr(X,0,N) work the same as + ** as substr(X,1,N) - it returns the first N characters of X. This + ** is essentially a back-out of the bug-fix in check-in [5fc125d362df4b8] + ** from 2009-02-02 for compatibility of applications that exploited the + ** old buggy behavior. */ + if( p1==0 ) p1 = 1; /* */ +#endif + if( argc==3 ){ + p2 = sqlite3_value_int(argv[2]); + if( p2<0 ){ + p2 = -p2; + negP2 = 1; + } + }else{ + p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH]; + } + if( p1<0 ){ + p1 += len; + if( p1<0 ){ + p2 += p1; + if( p2<0 ) p2 = 0; + p1 = 0; + } + }else if( p1>0 ){ + p1--; + }else if( p2>0 ){ + p2--; + } + if( negP2 ){ + p1 -= p2; + if( p1<0 ){ + p2 += p1; + p1 = 0; + } + } + assert( p1>=0 && p2>=0 ); + if( p0type!=SQLITE_BLOB ){ + while( *z && p1 ){ + SQLITE_SKIP_UTF8(z); + p1--; + } + for(z2=z; *z2 && p2; p2--){ + SQLITE_SKIP_UTF8(z2); + } + sqlite3_result_text64(context, (char*)z, z2-z, SQLITE_TRANSIENT, + SQLITE_UTF8); + }else{ + if( p1+p2>len ){ + p2 = len-p1; + if( p2<0 ) p2 = 0; + } + sqlite3_result_blob64(context, (char*)&z[p1], (u64)p2, SQLITE_TRANSIENT); + } +} + +/* +** Implementation of the round() function +*/ +#ifndef SQLITE_OMIT_FLOATING_POINT +static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ + int n = 0; + double r; + char *zBuf; + 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( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + r = sqlite3_value_double(argv[0]); + /* If Y==0 and X will fit in a 64-bit int, + ** handle the rounding directly, + ** otherwise use printf. + */ + if( n==0 && r>=0 && r0 ); + testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH] ); + testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH]+1 ); + if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + sqlite3_result_error_toobig(context); + z = 0; + }else{ + z = sqlite3Malloc(nByte); + if( !z ){ + sqlite3_result_error_nomem(context); + } + } + return z; +} + +/* +** Implementation of the upper() and lower() SQL functions. +*/ +static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ + char *z1; + const char *z2; + int i, n; + UNUSED_PARAMETER(argc); + z2 = (char*)sqlite3_value_text(argv[0]); + n = sqlite3_value_bytes(argv[0]); + /* Verify that the call to _bytes() does not invalidate the _text() pointer */ + assert( z2==(char*)sqlite3_value_text(argv[0]) ); + if( z2 ){ + z1 = contextMalloc(context, ((i64)n)+1); + if( z1 ){ + for(i=0; imatchOne; /* "?" or "_" */ + u32 matchAll = pInfo->matchAll; /* "*" or "%" */ + u32 matchOther; /* "[" or the escape character */ + u8 noCase = pInfo->noCase; /* True if uppercase==lowercase */ + const u8 *zEscaped = 0; /* One past the last escaped input char */ + + /* The GLOB operator does not have an ESCAPE clause. And LIKE does not + ** have the matchSet operator. So we either have to look for one or + ** the other, never both. Hence the single variable matchOther is used + ** to store the one we have to look for. + */ + matchOther = esc ? esc : pInfo->matchSet; + + while( (c = sqlite3Utf8Read(&zPattern))!=0 ){ + if( c==matchAll ){ /* Match "*" */ + /* Skip over multiple "*" characters in the pattern. If there + ** are also "?" characters, skip those as well, but consume a + ** single character of the input string for each "?" skipped */ + while( (c=sqlite3Utf8Read(&zPattern)) == matchAll + || c == matchOne ){ + if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){ + return 0; + } + } + if( c==0 ){ + return 1; /* "*" at the end of the pattern matches */ + }else if( c==matchOther ){ + if( esc ){ + c = sqlite3Utf8Read(&zPattern); + if( c==0 ) return 0; + }else{ + /* "[...]" immediately follows the "*". We have to do a slow + ** recursive search in this case, but it is an unusual case. */ + assert( matchOther<0x80 ); /* '[' is a single-byte character */ + while( *zString + && patternCompare(&zPattern[-1],zString,pInfo,esc)==0 ){ + SQLITE_SKIP_UTF8(zString); + } + return *zString!=0; + } + } + + /* At this point variable c contains the first character of the + ** pattern string past the "*". Search in the input string for the + ** first matching character and recursively contine the match from + ** that point. + ** + ** For a case-insensitive search, set variable cx to be the same as + ** c but in the other case and search the input string for either + ** c or cx. + */ + if( c<=0x80 ){ + u32 cx; + if( noCase ){ + cx = sqlite3Toupper(c); + c = sqlite3Tolower(c); + }else{ + cx = c; + } + while( (c2 = *(zString++))!=0 ){ + if( c2!=c && c2!=cx ) continue; + if( patternCompare(zPattern,zString,pInfo,esc) ) return 1; + } + }else{ + while( (c2 = sqlite3Utf8Read(&zString))!=0 ){ + if( c2!=c ) continue; + if( patternCompare(zPattern,zString,pInfo,esc) ) return 1; + } + } + return 0; + } + if( c==matchOther ){ + if( esc ){ + c = sqlite3Utf8Read(&zPattern); + if( c==0 ) return 0; + zEscaped = zPattern; + }else{ + u32 prior_c = 0; + int seen = 0; + int invert = 0; + c = sqlite3Utf8Read(&zString); + if( c==0 ) return 0; + c2 = sqlite3Utf8Read(&zPattern); + if( c2=='^' ){ + invert = 1; + c2 = sqlite3Utf8Read(&zPattern); + } + if( c2==']' ){ + if( c==']' ) seen = 1; + c2 = sqlite3Utf8Read(&zPattern); + } + while( c2 && c2!=']' ){ + if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){ + c2 = sqlite3Utf8Read(&zPattern); + if( c>=prior_c && c<=c2 ) seen = 1; + prior_c = 0; + }else{ + if( c==c2 ){ + seen = 1; + } + prior_c = c2; + } + c2 = sqlite3Utf8Read(&zPattern); + } + if( c2==0 || (seen ^ invert)==0 ){ + return 0; + } + continue; + } + } + c2 = sqlite3Utf8Read(&zString); + if( c==c2 ) continue; + if( noCase && c<0x80 && c2<0x80 && sqlite3Tolower(c)==sqlite3Tolower(c2) ){ + continue; + } + if( c==matchOne && zPattern!=zEscaped && c2!=0 ) continue; + return 0; + } + return *zString==0; +} + +/* +** The sqlite3_strglob() interface. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlobPattern, const char *zString){ + return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, 0)==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 +SQLITE_API 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, *zB; + u32 escape = 0; + int nPat; + sqlite3 *db = sqlite3_context_db_handle(context); + + zB = sqlite3_value_text(argv[0]); + zA = sqlite3_value_text(argv[1]); + + /* Limit the length of the LIKE or GLOB pattern to avoid problems + ** of deep recursion and N*N behavior in patternCompare(). + */ + nPat = sqlite3_value_bytes(argv[0]); + testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ); + testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]+1 ); + if( nPat > db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ){ + sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1); + return; + } + assert( zB==sqlite3_value_text(argv[0]) ); /* Encoding did not change */ + + 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( zEsc==0 ) return; + if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){ + sqlite3_result_error(context, + "ESCAPE expression must be a single character", -1); + return; + } + escape = sqlite3Utf8Read(&zEsc); + } + if( zA && zB ){ + struct compareInfo *pInfo = sqlite3_user_data(context); +#ifdef SQLITE_TEST + sqlite3_like_count++; +#endif + + sqlite3_result_int(context, patternCompare(zB, zA, 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. +*/ +static void nullifFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + CollSeq *pColl = sqlite3GetFuncCollSeq(context); + UNUSED_PARAMETER(NotUsed); + if( sqlite3MemCompare(argv[0], argv[1], pColl)!=0 ){ + sqlite3_result_value(context, argv[0]); + } +} + +/* +** Implementation of the sqlite_version() function. The result is the version +** of the SQLite library that is running. +*/ +static void versionFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **NotUsed2 +){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + /* IMP: R-48699-48617 This function is an SQL wrapper around the + ** sqlite3_libversion() C-interface. */ + sqlite3_result_text(context, sqlite3_libversion(), -1, SQLITE_STATIC); +} + +/* +** Implementation of the sqlite_source_id() function. The result is a string +** that identifies the particular version of the source code used to build +** SQLite. +*/ +static void sourceidFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **NotUsed2 +){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + /* IMP: R-24470-31136 This function is an SQL wrapper around the + ** sqlite3_sourceid() C interface. */ + sqlite3_result_text(context, sqlite3_sourceid(), -1, SQLITE_STATIC); +} + +/* +** Implementation of the sqlite_log() function. This is a wrapper around +** sqlite3_log(). The return value is NULL. The function exists purely for +** its side-effects. +*/ +static void errlogFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(context); + sqlite3_log(sqlite3_value_int(argv[0]), "%s", sqlite3_value_text(argv[1])); +} + +/* +** Implementation of the sqlite_compileoption_used() function. +** The result is an integer that identifies if the compiler option +** was used to build SQLite. +*/ +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS +static void compileoptionusedFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zOptName; + assert( argc==1 ); + UNUSED_PARAMETER(argc); + /* IMP: R-39564-36305 The sqlite_compileoption_used() SQL + ** function is a wrapper around the sqlite3_compileoption_used() C/C++ + ** function. + */ + if( (zOptName = (const char*)sqlite3_value_text(argv[0]))!=0 ){ + sqlite3_result_int(context, sqlite3_compileoption_used(zOptName)); + } +} +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ + +/* +** Implementation of the sqlite_compileoption_get() function. +** The result is a string that identifies the compiler options +** used to build SQLite. +*/ +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS +static void compileoptiongetFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int n; + assert( argc==1 ); + UNUSED_PARAMETER(argc); + /* IMP: R-04922-24076 The sqlite_compileoption_get() SQL function + ** is a wrapper around the sqlite3_compileoption_get() C/C++ function. + */ + n = sqlite3_value_int(argv[0]); + sqlite3_result_text(context, sqlite3_compileoption_get(n), -1, SQLITE_STATIC); +} +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ + +/* Array for converting from half-bytes (nybbles) into ASCII hex +** digits. */ +static const char hexdigits[] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' +}; + +/* +** Implementation of the QUOTE() function. This function takes a single +** argument. If the argument is numeric, the return value is the same as +** the argument. If the argument is NULL, the return value is the string +** "NULL". Otherwise, the argument is enclosed in single quotes with +** single-quote escapes. +*/ +static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ + assert( argc==1 ); + UNUSED_PARAMETER(argc); + switch( sqlite3_value_type(argv[0]) ){ + case SQLITE_FLOAT: { + double r1, r2; + char zBuf[50]; + r1 = sqlite3_value_double(argv[0]); + sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1); + sqlite3AtoF(zBuf, &r2, 20, SQLITE_UTF8); + if( r1!=r2 ){ + sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.20e", r1); + } + sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); + break; + } + case SQLITE_INTEGER: { + sqlite3_result_value(context, argv[0]); + break; + } + case SQLITE_BLOB: { + char *zText = 0; + char const *zBlob = sqlite3_value_blob(argv[0]); + int nBlob = sqlite3_value_bytes(argv[0]); + assert( zBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ + zText = (char *)contextMalloc(context, (2*(i64)nBlob)+4); + if( zText ){ + int i; + for(i=0; i>4)&0x0F]; + zText[(i*2)+3] = hexdigits[(zBlob[i])&0x0F]; + } + zText[(nBlob*2)+2] = '\''; + zText[(nBlob*2)+3] = '\0'; + zText[0] = 'X'; + zText[1] = '\''; + sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT); + sqlite3_free(zText); + } + break; + } + case SQLITE_TEXT: { + int i,j; + u64 n; + const unsigned char *zArg = sqlite3_value_text(argv[0]); + char *z; + + if( zArg==0 ) return; + for(i=0, n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; } + z = contextMalloc(context, ((i64)i)+((i64)n)+3); + if( z ){ + z[0] = '\''; + for(i=0, j=1; zArg[i]; i++){ + z[j++] = zArg[i]; + if( zArg[i]=='\'' ){ + z[j++] = '\''; + } + } + z[j++] = '\''; + z[j] = 0; + sqlite3_result_text(context, z, j, sqlite3_free); + } + break; + } + default: { + assert( sqlite3_value_type(argv[0])==SQLITE_NULL ); + sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC); + break; + } + } +} + +/* +** The unicode() function. Return the integer unicode code-point value +** for the first character of the input string. +*/ +static void unicodeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *z = sqlite3_value_text(argv[0]); + (void)argc; + if( z && z[0] ) sqlite3_result_int(context, sqlite3Utf8Read(&z)); +} + +/* +** The char() function takes zero or more arguments, each of which is +** an integer. It constructs a string where each character of the string +** is the unicode character for the corresponding integer argument. +*/ +static void charFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + unsigned char *z, *zOut; + int i; + zOut = z = sqlite3_malloc64( argc*4+1 ); + if( z==0 ){ + sqlite3_result_error_nomem(context); + return; + } + for(i=0; i0x10ffff ) x = 0xfffd; + c = (unsigned)(x & 0x1fffff); + if( c<0x00080 ){ + *zOut++ = (u8)(c&0xFF); + }else if( c<0x00800 ){ + *zOut++ = 0xC0 + (u8)((c>>6)&0x1F); + *zOut++ = 0x80 + (u8)(c & 0x3F); + }else if( c<0x10000 ){ + *zOut++ = 0xE0 + (u8)((c>>12)&0x0F); + *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); + *zOut++ = 0x80 + (u8)(c & 0x3F); + }else{ + *zOut++ = 0xF0 + (u8)((c>>18) & 0x07); + *zOut++ = 0x80 + (u8)((c>>12) & 0x3F); + *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); + *zOut++ = 0x80 + (u8)(c & 0x3F); + } \ + } + sqlite3_result_text64(context, (char*)z, zOut-z, sqlite3_free, SQLITE_UTF8); +} + +/* +** The hex() function. Interpret the argument as a blob. Return +** a hexadecimal rendering as text. +*/ +static void hexFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int i, n; + const unsigned char *pBlob; + char *zHex, *z; + assert( argc==1 ); + UNUSED_PARAMETER(argc); + pBlob = sqlite3_value_blob(argv[0]); + n = sqlite3_value_bytes(argv[0]); + assert( pBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ + z = zHex = contextMalloc(context, ((i64)n)*2 + 1); + if( zHex ){ + for(i=0; i>4)&0xf]; + *(z++) = hexdigits[c&0xf]; + } + *z = 0; + sqlite3_result_text(context, zHex, n*2, sqlite3_free); + } +} + +/* +** The zeroblob(N) function returns a zero-filled blob of size N bytes. +*/ +static void zeroblobFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + i64 n; + sqlite3 *db = sqlite3_context_db_handle(context); + assert( argc==1 ); + UNUSED_PARAMETER(argc); + n = sqlite3_value_int64(argv[0]); + testcase( n==db->aLimit[SQLITE_LIMIT_LENGTH] ); + testcase( n==db->aLimit[SQLITE_LIMIT_LENGTH]+1 ); + if( n>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + sqlite3_result_error_toobig(context); + }else{ + sqlite3_result_zeroblob(context, (int)n); /* IMP: R-00293-64994 */ + } +} + +/* +** The replace() function. Three arguments are all strings: call +** them A, B, and C. The result is also a string which is derived +** from A by replacing every occurrence of B with C. The match +** must be exact. Collating sequences are not used. +*/ +static void replaceFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *zStr; /* The input string A */ + const unsigned char *zPattern; /* The pattern string B */ + const unsigned char *zRep; /* The replacement string C */ + unsigned char *zOut; /* The output */ + int nStr; /* Size of zStr */ + int nPattern; /* Size of zPattern */ + int nRep; /* Size of zRep */ + i64 nOut; /* Maximum size of zOut */ + int loopLimit; /* Last zStr[] that might match zPattern[] */ + int i, j; /* Loop counters */ + + assert( argc==3 ); + UNUSED_PARAMETER(argc); + zStr = sqlite3_value_text(argv[0]); + if( zStr==0 ) return; + nStr = sqlite3_value_bytes(argv[0]); + assert( zStr==sqlite3_value_text(argv[0]) ); /* No encoding change */ + zPattern = sqlite3_value_text(argv[1]); + if( zPattern==0 ){ + assert( sqlite3_value_type(argv[1])==SQLITE_NULL + || sqlite3_context_db_handle(context)->mallocFailed ); + return; + } + if( zPattern[0]==0 ){ + assert( sqlite3_value_type(argv[1])!=SQLITE_NULL ); + sqlite3_result_value(context, argv[0]); + return; + } + nPattern = sqlite3_value_bytes(argv[1]); + assert( zPattern==sqlite3_value_text(argv[1]) ); /* No encoding change */ + zRep = sqlite3_value_text(argv[2]); + if( zRep==0 ) return; + nRep = sqlite3_value_bytes(argv[2]); + assert( zRep==sqlite3_value_text(argv[2]) ); + nOut = nStr + 1; + assert( nOutaLimit[SQLITE_LIMIT_LENGTH] ); + testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] ); + if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + sqlite3_result_error_toobig(context); + sqlite3_free(zOut); + return; + } + zOld = zOut; + zOut = sqlite3_realloc64(zOut, (int)nOut); + if( zOut==0 ){ + sqlite3_result_error_nomem(context); + sqlite3_free(zOld); + return; + } + memcpy(&zOut[j], zRep, nRep); + j += nRep; + i += nPattern-1; + } + } + assert( j+nStr-i+1==nOut ); + memcpy(&zOut[j], &zStr[i], nStr-i); + j += nStr - i; + assert( j<=nOut ); + zOut[j] = 0; + sqlite3_result_text(context, (char*)zOut, j, sqlite3_free); +} + +/* +** Implementation of the TRIM(), LTRIM(), and RTRIM() functions. +** The userdata is 0x1 for left trim, 0x2 for right trim, 0x3 for both. +*/ +static void trimFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *zIn; /* Input string */ + const unsigned char *zCharSet; /* Set of characters to trim */ + int nIn; /* Number of bytes in input */ + int flags; /* 1: trimleft 2: trimright 3: trim */ + int i; /* Loop counter */ + unsigned char *aLen = 0; /* Length of each character in zCharSet */ + unsigned char **azChar = 0; /* Individual characters in zCharSet */ + int nChar; /* Number of characters in zCharSet */ + + if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ + return; + } + zIn = sqlite3_value_text(argv[0]); + if( zIn==0 ) return; + nIn = sqlite3_value_bytes(argv[0]); + assert( zIn==sqlite3_value_text(argv[0]) ); + if( argc==1 ){ + static const unsigned char lenOne[] = { 1 }; + static unsigned char * const azOne[] = { (u8*)" " }; + nChar = 1; + aLen = (u8*)lenOne; + azChar = (unsigned char **)azOne; + zCharSet = 0; + }else if( (zCharSet = sqlite3_value_text(argv[1]))==0 ){ + return; + }else{ + const unsigned char *z; + for(z=zCharSet, nChar=0; *z; nChar++){ + SQLITE_SKIP_UTF8(z); + } + if( nChar>0 ){ + azChar = contextMalloc(context, ((i64)nChar)*(sizeof(char*)+1)); + if( azChar==0 ){ + return; + } + aLen = (unsigned char*)&azChar[nChar]; + for(z=zCharSet, nChar=0; *z; nChar++){ + azChar[nChar] = (unsigned char *)z; + SQLITE_SKIP_UTF8(z); + aLen[nChar] = (u8)(z - azChar[nChar]); + } + } + } + if( nChar>0 ){ + flags = SQLITE_PTR_TO_INT(sqlite3_user_data(context)); + if( flags & 1 ){ + while( nIn>0 ){ + int len = 0; + for(i=0; i=nChar ) break; + zIn += len; + nIn -= len; + } + } + if( flags & 2 ){ + while( nIn>0 ){ + int len = 0; + for(i=0; i=nChar ) break; + nIn -= len; + } + } + if( zCharSet ){ + sqlite3_free(azChar); + } + } + sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT); +} + + +/* IMP: R-25361-16150 This function is omitted from SQLite by default. It +** is only available if the SQLITE_SOUNDEX compile-time option is used +** when SQLite is built. +*/ +#ifdef SQLITE_SOUNDEX +/* +** Compute the soundex encoding of a word. +** +** IMP: R-59782-00072 The soundex(X) function returns a string that is the +** soundex encoding of the string X. +*/ +static void soundexFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + char zResult[8]; + const u8 *zIn; + int i, j; + static const unsigned char iCode[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0, + 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0, + 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0, + }; + assert( argc==1 ); + zIn = (u8*)sqlite3_value_text(argv[0]); + if( zIn==0 ) zIn = (u8*)""; + for(i=0; zIn[i] && !sqlite3Isalpha(zIn[i]); i++){} + if( zIn[i] ){ + u8 prevcode = iCode[zIn[i]&0x7f]; + zResult[0] = sqlite3Toupper(zIn[i]); + for(j=1; j<4 && zIn[i]; i++){ + int code = iCode[zIn[i]&0x7f]; + if( code>0 ){ + if( code!=prevcode ){ + prevcode = code; + zResult[j++] = code + '0'; + } + }else{ + prevcode = 0; + } + } + while( j<4 ){ + zResult[j++] = '0'; + } + zResult[j] = 0; + sqlite3_result_text(context, zResult, 4, SQLITE_TRANSIENT); + }else{ + /* IMP: R-64894-50321 The string "?000" is returned if the argument + ** is NULL or contains no ASCII alphabetic characters. */ + sqlite3_result_text(context, "?000", 4, SQLITE_STATIC); + } +} +#endif /* SQLITE_SOUNDEX */ + +#ifndef SQLITE_OMIT_LOAD_EXTENSION +/* +** A function that loads a shared-library extension then returns NULL. +*/ +static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){ + const char *zFile = (const char *)sqlite3_value_text(argv[0]); + const char *zProc; + sqlite3 *db = sqlite3_context_db_handle(context); + char *zErrMsg = 0; + + if( argc==2 ){ + zProc = (const char *)sqlite3_value_text(argv[1]); + }else{ + zProc = 0; + } + if( zFile && sqlite3_load_extension(db, zFile, zProc, &zErrMsg) ){ + sqlite3_result_error(context, zErrMsg, -1); + sqlite3_free(zErrMsg); + } +} +#endif + + +/* +** An instance of the following structure holds the context of a +** sum() or avg() aggregate computation. +*/ +typedef struct SumCtx SumCtx; +struct SumCtx { + double rSum; /* Floating point sum */ + i64 iSum; /* Integer sum */ + i64 cnt; /* Number of elements summed */ + u8 overflow; /* True if integer overflow seen */ + u8 approx; /* True if non-integer value was input to the sum */ +}; + +/* +** 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. TOTAL never fails, but SUM might through an exception if +** it overflows an integer. +*/ +static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ + SumCtx *p; + int type; + assert( argc==1 ); + UNUSED_PARAMETER(argc); + p = sqlite3_aggregate_context(context, sizeof(*p)); + type = sqlite3_value_numeric_type(argv[0]); + if( p && type!=SQLITE_NULL ){ + p->cnt++; + if( type==SQLITE_INTEGER ){ + i64 v = sqlite3_value_int64(argv[0]); + p->rSum += v; + if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, v) ){ + p->overflow = 1; + } + }else{ + p->rSum += sqlite3_value_double(argv[0]); + p->approx = 1; + } + } +} +static void sumFinalize(sqlite3_context *context){ + SumCtx *p; + p = sqlite3_aggregate_context(context, 0); + if( p && p->cnt>0 ){ + if( p->overflow ){ + sqlite3_result_error(context,"integer overflow",-1); + }else if( p->approx ){ + sqlite3_result_double(context, p->rSum); + }else{ + sqlite3_result_int64(context, p->iSum); + } + } +} +static void avgFinalize(sqlite3_context *context){ + SumCtx *p; + p = sqlite3_aggregate_context(context, 0); + if( p && p->cnt>0 ){ + sqlite3_result_double(context, p->rSum/(double)p->cnt); + } +} +static void totalFinalize(sqlite3_context *context){ + SumCtx *p; + p = sqlite3_aggregate_context(context, 0); + /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ + sqlite3_result_double(context, p ? p->rSum : (double)0); +} + +/* +** The following structure keeps track of state information for the +** count() aggregate function. +*/ +typedef struct CountCtx CountCtx; +struct CountCtx { + i64 n; +}; + +/* +** Routines to implement the count() aggregate function. +*/ +static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){ + CountCtx *p; + p = sqlite3_aggregate_context(context, sizeof(*p)); + if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && p ){ + p->n++; + } + +#ifndef SQLITE_OMIT_DEPRECATED + /* The sqlite3_aggregate_count() function is deprecated. But just to make + ** sure it still operates correctly, verify that its count agrees with our + ** internal count when using count(*) and when the total count can be + ** expressed as a 32-bit integer. */ + assert( argc==1 || p==0 || p->n>0x7fffffff + || p->n==sqlite3_aggregate_count(context) ); +#endif +} +static void countFinalize(sqlite3_context *context){ + CountCtx *p; + p = sqlite3_aggregate_context(context, 0); + sqlite3_result_int64(context, p ? p->n : 0); +} + +/* +** Routines to implement min() and max() aggregate functions. +*/ +static void minmaxStep( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + Mem *pArg = (Mem *)argv[0]; + Mem *pBest; + UNUSED_PARAMETER(NotUsed); + + pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest)); + if( !pBest ) return; + + if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ + if( pBest->flags ) sqlite3SkipAccumulatorLoad(context); + }else if( pBest->flags ){ + int max; + int cmp; + CollSeq *pColl = sqlite3GetFuncCollSeq(context); + /* This step function is used for both the min() and max() aggregates, + ** the only difference between the two being that the sense of the + ** comparison is inverted. For the max() aggregate, the + ** sqlite3_user_data() function returns (void *)-1. For min() it + ** returns (void *)db, where db is the sqlite3* database pointer. + ** Therefore the next statement sets variable 'max' to 1 for the max() + ** aggregate, or 0 for min(). + */ + max = sqlite3_user_data(context)!=0; + cmp = sqlite3MemCompare(pBest, pArg, pColl); + if( (max && cmp<0) || (!max && cmp>0) ){ + sqlite3VdbeMemCopy(pBest, pArg); + }else{ + sqlite3SkipAccumulatorLoad(context); + } + }else{ + pBest->db = sqlite3_context_db_handle(context); + 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); + } +} + +/* +** group_concat(EXPR, ?SEPARATOR?) +*/ +static void groupConcatStep( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zVal; + StrAccum *pAccum; + const char *zSep; + int nVal, nSep; + assert( argc==1 || argc==2 ); + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum)); + + if( pAccum ){ + sqlite3 *db = sqlite3_context_db_handle(context); + int firstTerm = pAccum->mxAlloc==0; + pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH]; + if( !firstTerm ){ + if( argc==2 ){ + zSep = (char*)sqlite3_value_text(argv[1]); + nSep = sqlite3_value_bytes(argv[1]); + }else{ + zSep = ","; + nSep = 1; + } + if( nSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep); + } + zVal = (char*)sqlite3_value_text(argv[0]); + nVal = sqlite3_value_bytes(argv[0]); + if( zVal ) sqlite3StrAccumAppend(pAccum, zVal, nVal); + } +} +static void groupConcatFinalize(sqlite3_context *context){ + StrAccum *pAccum; + pAccum = sqlite3_aggregate_context(context, 0); + if( pAccum ){ + if( pAccum->accError==STRACCUM_TOOBIG ){ + sqlite3_result_error_toobig(context); + }else if( pAccum->accError==STRACCUM_NOMEM ){ + sqlite3_result_error_nomem(context); + }else{ + sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, + sqlite3_free); + } + } +} + +/* +** This routine does per-connection function registration. Most +** of the built-in functions above are part of the global function set. +** This routine only deals with those that are not global. +*/ +SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ + int rc = sqlite3_overload_function(db, "MATCH", 2); + assert( rc==SQLITE_NOMEM || rc==SQLITE_OK ); + if( rc==SQLITE_NOMEM ){ + db->mallocFailed = 1; + } +} + +/* +** Set the LIKEOPT flag on the 2-argument function with the given name. +*/ +static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){ + FuncDef *pDef; + pDef = sqlite3FindFunction(db, zName, sqlite3Strlen30(zName), + 2, SQLITE_UTF8, 0); + if( ALWAYS(pDef) ){ + pDef->funcFlags |= 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. +*/ +SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){ + struct compareInfo *pInfo; + if( caseSensitive ){ + pInfo = (struct compareInfo*)&likeInfoAlt; + }else{ + pInfo = (struct compareInfo*)&likeInfoNorm; + } + sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0); + sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0); + sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8, + (struct compareInfo*)&globInfo, likeFunc, 0, 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. +** +** *pIsNocase is set to true if uppercase and lowercase are equivalent for +** the function (default for LIKE). If the function makes the distinction +** between uppercase and lowercase (as does GLOB) then *pIsNocase is set to +** false. +*/ +SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){ + FuncDef *pDef; + if( pExpr->op!=TK_FUNCTION + || !pExpr->x.pList + || pExpr->x.pList->nExpr!=2 + ){ + return 0; + } + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + pDef = sqlite3FindFunction(db, pExpr->u.zToken, + sqlite3Strlen30(pExpr->u.zToken), + 2, SQLITE_UTF8, 0); + if( NEVER(pDef==0) || (pDef->funcFlags & 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->funcFlags & SQLITE_FUNC_CASE)==0; + return 1; +} + +/* +** All of the FuncDef structures in the aBuiltinFunc[] array above +** to the global function hash table. This occurs at start-time (as +** a consequence of calling sqlite3_initialize()). +** +** After this routine runs +*/ +SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){ + /* + ** The following array holds FuncDef structures for all of the functions + ** defined in this file. + ** + ** The array cannot be constant since changes are made to the + ** FuncDef.pHash elements at start-time. The elements of this array + ** are read-only after initialization is complete. + */ + static SQLITE_WSD FuncDef aBuiltinFunc[] = { + FUNCTION(ltrim, 1, 1, 0, trimFunc ), + FUNCTION(ltrim, 2, 1, 0, trimFunc ), + FUNCTION(rtrim, 1, 2, 0, trimFunc ), + FUNCTION(rtrim, 2, 2, 0, trimFunc ), + FUNCTION(trim, 1, 3, 0, trimFunc ), + FUNCTION(trim, 2, 3, 0, trimFunc ), + FUNCTION(min, -1, 0, 1, minmaxFunc ), + FUNCTION(min, 0, 0, 1, 0 ), + AGGREGATE2(min, 1, 0, 1, minmaxStep, minMaxFinalize, + SQLITE_FUNC_MINMAX ), + FUNCTION(max, -1, 1, 1, minmaxFunc ), + FUNCTION(max, 0, 1, 1, 0 ), + AGGREGATE2(max, 1, 1, 1, minmaxStep, minMaxFinalize, + SQLITE_FUNC_MINMAX ), + FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF), + FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH), + FUNCTION(instr, 2, 0, 0, instrFunc ), + FUNCTION(substr, 2, 0, 0, substrFunc ), + FUNCTION(substr, 3, 0, 0, substrFunc ), + FUNCTION(printf, -1, 0, 0, printfFunc ), + FUNCTION(unicode, 1, 0, 0, unicodeFunc ), + FUNCTION(char, -1, 0, 0, charFunc ), + FUNCTION(abs, 1, 0, 0, absFunc ), +#ifndef SQLITE_OMIT_FLOATING_POINT + FUNCTION(round, 1, 0, 0, roundFunc ), + FUNCTION(round, 2, 0, 0, roundFunc ), +#endif + FUNCTION(upper, 1, 0, 0, upperFunc ), + FUNCTION(lower, 1, 0, 0, lowerFunc ), + FUNCTION(coalesce, 1, 0, 0, 0 ), + FUNCTION(coalesce, 0, 0, 0, 0 ), + FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQLITE_FUNC_COALESCE), + FUNCTION(hex, 1, 0, 0, hexFunc ), + FUNCTION2(ifnull, 2, 0, 0, noopFunc, SQLITE_FUNC_COALESCE), + FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), + FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), + FUNCTION2(likely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), + VFUNCTION(random, 0, 0, 0, randomFunc ), + VFUNCTION(randomblob, 1, 0, 0, randomBlob ), + FUNCTION(nullif, 2, 0, 1, nullifFunc ), + FUNCTION(sqlite_version, 0, 0, 0, versionFunc ), + FUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ), + FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ), +#if SQLITE_USER_AUTHENTICATION + FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ), +#endif +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS + FUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ), + FUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ), +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ + FUNCTION(quote, 1, 0, 0, quoteFunc ), + VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid), + VFUNCTION(changes, 0, 0, 0, changes ), + VFUNCTION(total_changes, 0, 0, 0, total_changes ), + FUNCTION(replace, 3, 0, 0, replaceFunc ), + FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ), + #ifdef SQLITE_SOUNDEX + FUNCTION(soundex, 1, 0, 0, soundexFunc ), + #endif + #ifndef SQLITE_OMIT_LOAD_EXTENSION + FUNCTION(load_extension, 1, 0, 0, loadExt ), + FUNCTION(load_extension, 2, 0, 0, loadExt ), + #endif + AGGREGATE(sum, 1, 0, 0, sumStep, sumFinalize ), + AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ), + AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ), + AGGREGATE2(count, 0, 0, 0, countStep, countFinalize, + SQLITE_FUNC_COUNT ), + AGGREGATE(count, 1, 0, 0, countStep, countFinalize ), + AGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize), + AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize), + + LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), + #ifdef SQLITE_CASE_SENSITIVE_LIKE + LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), + LIKEFUNC(like, 3, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), + #else + LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE), + LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE), + #endif + }; + + int i; + FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions); + FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aBuiltinFunc); + + for(i=0; idb->mallocFailed flag is set. +*/ +SQLITE_PRIVATE int sqlite3FkLocateIndex( + Parse *pParse, /* Parse context to store any error in */ + Table *pParent, /* Parent table of FK constraint pFKey */ + FKey *pFKey, /* Foreign key to find index for */ + Index **ppIdx, /* OUT: Unique index on parent table */ + int **paiCol /* OUT: Map of index columns in pFKey */ +){ + Index *pIdx = 0; /* Value to return via *ppIdx */ + int *aiCol = 0; /* Value to return via *paiCol */ + int nCol = pFKey->nCol; /* Number of columns in parent key */ + char *zKey = pFKey->aCol[0].zCol; /* Name of left-most parent key column */ + + /* The caller is responsible for zeroing output parameters. */ + assert( ppIdx && *ppIdx==0 ); + assert( !paiCol || *paiCol==0 ); + assert( pParse ); + + /* If this is a non-composite (single column) foreign key, check if it + ** maps to the INTEGER PRIMARY KEY of table pParent. If so, leave *ppIdx + ** and *paiCol set to zero and return early. + ** + ** Otherwise, for a composite foreign key (more than one column), allocate + ** space for the aiCol array (returned via output parameter *paiCol). + ** Non-composite foreign keys do not require the aiCol array. + */ + if( nCol==1 ){ + /* The FK maps to the IPK if any of the following are true: + ** + ** 1) There is an INTEGER PRIMARY KEY column and the FK is implicitly + ** mapped to the primary key of table pParent, or + ** 2) The FK is explicitly mapped to a column declared as INTEGER + ** PRIMARY KEY. + */ + if( pParent->iPKey>=0 ){ + if( !zKey ) return 0; + if( !sqlite3StrICmp(pParent->aCol[pParent->iPKey].zName, zKey) ) return 0; + } + }else if( paiCol ){ + assert( nCol>1 ); + aiCol = (int *)sqlite3DbMallocRaw(pParse->db, nCol*sizeof(int)); + if( !aiCol ) return 1; + *paiCol = aiCol; + } + + for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->nKeyCol==nCol && IsUniqueIndex(pIdx) ){ + /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number + ** of columns. If each indexed column corresponds to a foreign key + ** column of pFKey, then this index is a winner. */ + + if( zKey==0 ){ + /* If zKey is NULL, then this foreign key is implicitly mapped to + ** the PRIMARY KEY of table pParent. The PRIMARY KEY index may be + ** identified by the test. */ + if( IsPrimaryKeyIndex(pIdx) ){ + if( aiCol ){ + int i; + for(i=0; iaCol[i].iFrom; + } + break; + } + }else{ + /* If zKey is non-NULL, then this foreign key was declared to + ** map to an explicit list of columns in table pParent. Check if this + ** index matches those columns. Also, check that the index uses + ** the default collation sequences for each column. */ + int i, j; + for(i=0; iaiColumn[i]; /* Index of column in parent tbl */ + char *zDfltColl; /* Def. collation for column */ + char *zIdxCol; /* Name of indexed column */ + + /* If the index uses a collation sequence that is different from + ** the default collation sequence for the column, this index is + ** unusable. Bail out early in this case. */ + zDfltColl = pParent->aCol[iCol].zColl; + if( !zDfltColl ){ + zDfltColl = "BINARY"; + } + if( sqlite3StrICmp(pIdx->azColl[i], zDfltColl) ) break; + + zIdxCol = pParent->aCol[iCol].zName; + for(j=0; jaCol[j].zCol, zIdxCol)==0 ){ + if( aiCol ) aiCol[i] = pFKey->aCol[j].iFrom; + break; + } + } + if( j==nCol ) break; + } + if( i==nCol ) break; /* pIdx is usable */ + } + } + } + + if( !pIdx ){ + if( !pParse->disableTriggers ){ + sqlite3ErrorMsg(pParse, + "foreign key mismatch - \"%w\" referencing \"%w\"", + pFKey->pFrom->zName, pFKey->zTo); + } + sqlite3DbFree(pParse->db, aiCol); + return 1; + } + + *ppIdx = pIdx; + return 0; +} + +/* +** This function is called when a row is inserted into or deleted from the +** child table of foreign key constraint pFKey. If an SQL UPDATE is executed +** on the child table of pFKey, this function is invoked twice for each row +** affected - once to "delete" the old row, and then again to "insert" the +** new row. +** +** Each time it is called, this function generates VDBE code to locate the +** row in the parent table that corresponds to the row being inserted into +** or deleted from the child table. If the parent row can be found, no +** special action is taken. Otherwise, if the parent row can *not* be +** found in the parent table: +** +** Operation | FK type | Action taken +** -------------------------------------------------------------------------- +** INSERT immediate Increment the "immediate constraint counter". +** +** DELETE immediate Decrement the "immediate constraint counter". +** +** INSERT deferred Increment the "deferred constraint counter". +** +** DELETE deferred Decrement the "deferred constraint counter". +** +** These operations are identified in the comment at the top of this file +** (fkey.c) as "I.1" and "D.1". +*/ +static void fkLookupParent( + Parse *pParse, /* Parse context */ + int iDb, /* Index of database housing pTab */ + Table *pTab, /* Parent table of FK pFKey */ + Index *pIdx, /* Unique index on parent key columns in pTab */ + FKey *pFKey, /* Foreign key constraint */ + int *aiCol, /* Map from parent key columns to child table columns */ + int regData, /* Address of array containing child table row */ + int nIncr, /* Increment constraint counter by this */ + int isIgnore /* If true, pretend pTab contains all NULL values */ +){ + int i; /* Iterator variable */ + Vdbe *v = sqlite3GetVdbe(pParse); /* Vdbe to add code to */ + int iCur = pParse->nTab - 1; /* Cursor number to use */ + int iOk = sqlite3VdbeMakeLabel(v); /* jump here if parent key found */ + + /* If nIncr is less than zero, then check at runtime if there are any + ** outstanding constraints to resolve. If there are not, there is no need + ** to check if deleting this row resolves any outstanding violations. + ** + ** Check if any of the key columns in the child table row are NULL. If + ** any are, then the constraint is considered satisfied. No need to + ** search for a matching row in the parent table. */ + if( nIncr<0 ){ + sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk); + VdbeCoverage(v); + } + for(i=0; inCol; i++){ + int iReg = aiCol[i] + regData + 1; + sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk); VdbeCoverage(v); + } + + if( isIgnore==0 ){ + if( pIdx==0 ){ + /* If pIdx is NULL, then the parent key is the INTEGER PRIMARY KEY + ** column of the parent table (table pTab). */ + int iMustBeInt; /* Address of MustBeInt instruction */ + int regTemp = sqlite3GetTempReg(pParse); + + /* Invoke MustBeInt to coerce the child key value to an integer (i.e. + ** apply the affinity of the parent key). If this fails, then there + ** is no matching parent key. Before using MustBeInt, make a copy of + ** the value. Otherwise, the value inserted into the child key column + ** will have INTEGER affinity applied to it, which may not be correct. */ + sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[0]+1+regData, regTemp); + iMustBeInt = sqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0); + VdbeCoverage(v); + + /* If the parent table is the same as the child table, and we are about + ** to increment the constraint-counter (i.e. this is an INSERT operation), + ** then check if the row being inserted matches itself. If so, do not + ** increment the constraint-counter. */ + if( pTab==pFKey->pFrom && nIncr==1 ){ + sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + } + + sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead); + sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk); + sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); + sqlite3VdbeJumpHere(v, iMustBeInt); + sqlite3ReleaseTempReg(pParse, regTemp); + }else{ + int nCol = pFKey->nCol; + int regTemp = sqlite3GetTempRange(pParse, nCol); + int regRec = sqlite3GetTempReg(pParse); + + sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); + for(i=0; ipFrom && nIncr==1 ){ + int iJump = sqlite3VdbeCurrentAddr(v) + nCol + 1; + for(i=0; iaiColumn[i]+1+regData; + assert( aiCol[i]!=pTab->iPKey ); + if( pIdx->aiColumn[i]==pTab->iPKey ){ + /* The parent key is a composite key that includes the IPK column */ + iParent = regData; + } + sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL); + } + sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk); + } + + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol, regRec, + sqlite3IndexAffinityStr(v,pIdx), nCol); + sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); VdbeCoverage(v); + + sqlite3ReleaseTempReg(pParse, regRec); + sqlite3ReleaseTempRange(pParse, regTemp, nCol); + } + } + + if( !pFKey->isDeferred && !(pParse->db->flags & SQLITE_DeferFKs) + && !pParse->pToplevel + && !pParse->isMultiWrite + ){ + /* Special case: If this is an INSERT statement that will insert exactly + ** one row into the table, raise a constraint immediately instead of + ** incrementing a counter. This is necessary as the VM code is being + ** generated for will not open a statement transaction. */ + assert( nIncr==1 ); + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY, + OE_Abort, 0, P4_STATIC, P5_ConstraintFK); + }else{ + if( nIncr>0 && pFKey->isDeferred==0 ){ + sqlite3MayAbort(pParse); + } + sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr); + } + + sqlite3VdbeResolveLabel(v, iOk); + sqlite3VdbeAddOp1(v, OP_Close, iCur); +} + + +/* +** Return an Expr object that refers to a memory register corresponding +** to column iCol of table pTab. +** +** regBase is the first of an array of register that contains the data +** for pTab. regBase itself holds the rowid. regBase+1 holds the first +** column. regBase+2 holds the second column, and so forth. +*/ +static Expr *exprTableRegister( + Parse *pParse, /* Parsing and code generating context */ + Table *pTab, /* The table whose content is at r[regBase]... */ + int regBase, /* Contents of table pTab */ + i16 iCol /* Which column of pTab is desired */ +){ + Expr *pExpr; + Column *pCol; + const char *zColl; + sqlite3 *db = pParse->db; + + pExpr = sqlite3Expr(db, TK_REGISTER, 0); + if( pExpr ){ + if( iCol>=0 && iCol!=pTab->iPKey ){ + pCol = &pTab->aCol[iCol]; + pExpr->iTable = regBase + iCol + 1; + pExpr->affinity = pCol->affinity; + zColl = pCol->zColl; + if( zColl==0 ) zColl = db->pDfltColl->zName; + pExpr = sqlite3ExprAddCollateString(pParse, pExpr, zColl); + }else{ + pExpr->iTable = regBase; + pExpr->affinity = SQLITE_AFF_INTEGER; + } + } + return pExpr; +} + +/* +** Return an Expr object that refers to column iCol of table pTab which +** has cursor iCur. +*/ +static Expr *exprTableColumn( + sqlite3 *db, /* The database connection */ + Table *pTab, /* The table whose column is desired */ + int iCursor, /* The open cursor on the table */ + i16 iCol /* The column that is wanted */ +){ + Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0); + if( pExpr ){ + pExpr->pTab = pTab; + pExpr->iTable = iCursor; + pExpr->iColumn = iCol; + } + return pExpr; +} + +/* +** This function is called to generate code executed when a row is deleted +** from the parent table of foreign key constraint pFKey and, if pFKey is +** deferred, when a row is inserted into the same table. When generating +** code for an SQL UPDATE operation, this function may be called twice - +** once to "delete" the old row and once to "insert" the new row. +** +** Parameter nIncr is passed -1 when inserting a row (as this may decrease +** the number of FK violations in the db) or +1 when deleting one (as this +** may increase the number of FK constraint problems). +** +** The code generated by this function scans through the rows in the child +** table that correspond to the parent table row being deleted or inserted. +** For each child row found, one of the following actions is taken: +** +** Operation | FK type | Action taken +** -------------------------------------------------------------------------- +** DELETE immediate Increment the "immediate constraint counter". +** Or, if the ON (UPDATE|DELETE) action is RESTRICT, +** throw a "FOREIGN KEY constraint failed" exception. +** +** INSERT immediate Decrement the "immediate constraint counter". +** +** DELETE deferred Increment the "deferred constraint counter". +** Or, if the ON (UPDATE|DELETE) action is RESTRICT, +** throw a "FOREIGN KEY constraint failed" exception. +** +** INSERT deferred Decrement the "deferred constraint counter". +** +** These operations are identified in the comment at the top of this file +** (fkey.c) as "I.2" and "D.2". +*/ +static void fkScanChildren( + Parse *pParse, /* Parse context */ + SrcList *pSrc, /* The child table to be scanned */ + Table *pTab, /* The parent table */ + Index *pIdx, /* Index on parent covering the foreign key */ + FKey *pFKey, /* The foreign key linking pSrc to pTab */ + int *aiCol, /* Map from pIdx cols to child table cols */ + int regData, /* Parent row data starts here */ + int nIncr /* Amount to increment deferred counter by */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + int i; /* Iterator variable */ + Expr *pWhere = 0; /* WHERE clause to scan with */ + NameContext sNameContext; /* Context used to resolve WHERE clause */ + WhereInfo *pWInfo; /* Context used by sqlite3WhereXXX() */ + int iFkIfZero = 0; /* Address of OP_FkIfZero */ + Vdbe *v = sqlite3GetVdbe(pParse); + + assert( pIdx==0 || pIdx->pTable==pTab ); + assert( pIdx==0 || pIdx->nKeyCol==pFKey->nCol ); + assert( pIdx!=0 || pFKey->nCol==1 ); + assert( pIdx!=0 || HasRowid(pTab) ); + + if( nIncr<0 ){ + iFkIfZero = sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0); + VdbeCoverage(v); + } + + /* Create an Expr object representing an SQL expression like: + ** + ** = AND = ... + ** + ** The collation sequence used for the comparison should be that of + ** the parent key columns. The affinity of the parent key column should + ** be applied to each child key value before the comparison takes place. + */ + for(i=0; inCol; i++){ + Expr *pLeft; /* Value from parent table row */ + Expr *pRight; /* Column ref to child table */ + Expr *pEq; /* Expression (pLeft = pRight) */ + i16 iCol; /* Index of column in child table */ + const char *zCol; /* Name of column in child table */ + + iCol = pIdx ? pIdx->aiColumn[i] : -1; + pLeft = exprTableRegister(pParse, pTab, regData, iCol); + iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; + assert( iCol>=0 ); + zCol = pFKey->pFrom->aCol[iCol].zName; + pRight = sqlite3Expr(db, TK_ID, zCol); + pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0); + pWhere = sqlite3ExprAnd(db, pWhere, pEq); + } + + /* If the child table is the same as the parent table, then add terms + ** to the WHERE clause that prevent this entry from being scanned. + ** The added WHERE clause terms are like this: + ** + ** $current_rowid!=rowid + ** NOT( $current_a==a AND $current_b==b AND ... ) + ** + ** The first form is used for rowid tables. The second form is used + ** for WITHOUT ROWID tables. In the second form, the primary key is + ** (a,b,...) + */ + if( pTab==pFKey->pFrom && nIncr>0 ){ + Expr *pNe; /* Expression (pLeft != pRight) */ + Expr *pLeft; /* Value from parent table row */ + Expr *pRight; /* Column ref to child table */ + if( HasRowid(pTab) ){ + pLeft = exprTableRegister(pParse, pTab, regData, -1); + pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, -1); + pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight, 0); + }else{ + Expr *pEq, *pAll = 0; + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pIdx!=0 ); + for(i=0; inKeyCol; i++){ + i16 iCol = pIdx->aiColumn[i]; + pLeft = exprTableRegister(pParse, pTab, regData, iCol); + pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol); + pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0); + pAll = sqlite3ExprAnd(db, pAll, pEq); + } + pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0, 0); + } + pWhere = sqlite3ExprAnd(db, pWhere, pNe); + } + + /* Resolve the references in the WHERE clause. */ + memset(&sNameContext, 0, sizeof(NameContext)); + sNameContext.pSrcList = pSrc; + sNameContext.pParse = pParse; + sqlite3ResolveExprNames(&sNameContext, pWhere); + + /* Create VDBE to loop through the entries in pSrc that match the WHERE + ** clause. For each row found, increment either the deferred or immediate + ** foreign key constraint counter. */ + pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0); + sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr); + if( pWInfo ){ + sqlite3WhereEnd(pWInfo); + } + + /* Clean up the WHERE clause constructed above. */ + sqlite3ExprDelete(db, pWhere); + if( iFkIfZero ){ + sqlite3VdbeJumpHere(v, iFkIfZero); + } +} + +/* +** This function returns a linked list of FKey objects (connected by +** FKey.pNextTo) holding all children of table pTab. For example, +** given the following schema: +** +** CREATE TABLE t1(a PRIMARY KEY); +** CREATE TABLE t2(b REFERENCES t1(a); +** +** Calling this function with table "t1" as an argument returns a pointer +** to the FKey structure representing the foreign key constraint on table +** "t2". Calling this function with "t2" as the argument would return a +** NULL pointer (as there are no FK constraints for which t2 is the parent +** table). +*/ +SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *pTab){ + return (FKey *)sqlite3HashFind(&pTab->pSchema->fkeyHash, pTab->zName); +} + +/* +** The second argument is a Trigger structure allocated by the +** fkActionTrigger() routine. This function deletes the Trigger structure +** and all of its sub-components. +** +** The Trigger structure or any of its sub-components may be allocated from +** the lookaside buffer belonging to database handle dbMem. +*/ +static void fkTriggerDelete(sqlite3 *dbMem, Trigger *p){ + if( p ){ + TriggerStep *pStep = p->step_list; + sqlite3ExprDelete(dbMem, pStep->pWhere); + sqlite3ExprListDelete(dbMem, pStep->pExprList); + sqlite3SelectDelete(dbMem, pStep->pSelect); + sqlite3ExprDelete(dbMem, p->pWhen); + sqlite3DbFree(dbMem, p); + } +} + +/* +** This function is called to generate code that runs when table pTab is +** being dropped from the database. The SrcList passed as the second argument +** to this function contains a single entry guaranteed to resolve to +** table pTab. +** +** Normally, no code is required. However, if either +** +** (a) The table is the parent table of a FK constraint, or +** (b) The table is the child table of a deferred FK constraint and it is +** determined at runtime that there are outstanding deferred FK +** constraint violations in the database, +** +** then the equivalent of "DELETE FROM " is executed before dropping +** the table from the database. Triggers are disabled while running this +** DELETE, but foreign key actions are not. +*/ +SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){ + sqlite3 *db = pParse->db; + if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) && !pTab->pSelect ){ + int iSkip = 0; + Vdbe *v = sqlite3GetVdbe(pParse); + + assert( v ); /* VDBE has already been allocated */ + if( sqlite3FkReferences(pTab)==0 ){ + /* Search for a deferred foreign key constraint for which this table + ** is the child table. If one cannot be found, return without + ** generating any VDBE code. If one can be found, then jump over + ** the entire DELETE if there are no outstanding deferred constraints + ** when this statement is run. */ + FKey *p; + for(p=pTab->pFKey; p; p=p->pNextFrom){ + if( p->isDeferred || (db->flags & SQLITE_DeferFKs) ) break; + } + if( !p ) return; + iSkip = sqlite3VdbeMakeLabel(v); + sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); VdbeCoverage(v); + } + + pParse->disableTriggers = 1; + sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0); + pParse->disableTriggers = 0; + + /* If the DELETE has generated immediate foreign key constraint + ** violations, halt the VDBE and return an error at this point, before + ** any modifications to the schema are made. This is because statement + ** transactions are not able to rollback schema changes. + ** + ** If the SQLITE_DeferFKs flag is set, then this is not required, as + ** the statement transaction will not be rolled back even if FK + ** constraints are violated. + */ + if( (db->flags & SQLITE_DeferFKs)==0 ){ + sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY, + OE_Abort, 0, P4_STATIC, P5_ConstraintFK); + } + + if( iSkip ){ + sqlite3VdbeResolveLabel(v, iSkip); + } + } +} + + +/* +** The second argument points to an FKey object representing a foreign key +** for which pTab is the child table. An UPDATE statement against pTab +** is currently being processed. For each column of the table that is +** actually updated, the corresponding element in the aChange[] array +** is zero or greater (if a column is unmodified the corresponding element +** is set to -1). If the rowid column is modified by the UPDATE statement +** the bChngRowid argument is non-zero. +** +** This function returns true if any of the columns that are part of the +** child key for FK constraint *p are modified. +*/ +static int fkChildIsModified( + Table *pTab, /* Table being updated */ + FKey *p, /* Foreign key for which pTab is the child */ + int *aChange, /* Array indicating modified columns */ + int bChngRowid /* True if rowid is modified by this update */ +){ + int i; + for(i=0; inCol; i++){ + int iChildKey = p->aCol[i].iFrom; + if( aChange[iChildKey]>=0 ) return 1; + if( iChildKey==pTab->iPKey && bChngRowid ) return 1; + } + return 0; +} + +/* +** The second argument points to an FKey object representing a foreign key +** for which pTab is the parent table. An UPDATE statement against pTab +** is currently being processed. For each column of the table that is +** actually updated, the corresponding element in the aChange[] array +** is zero or greater (if a column is unmodified the corresponding element +** is set to -1). If the rowid column is modified by the UPDATE statement +** the bChngRowid argument is non-zero. +** +** This function returns true if any of the columns that are part of the +** parent key for FK constraint *p are modified. +*/ +static int fkParentIsModified( + Table *pTab, + FKey *p, + int *aChange, + int bChngRowid +){ + int i; + for(i=0; inCol; i++){ + char *zKey = p->aCol[i].zCol; + int iKey; + for(iKey=0; iKeynCol; iKey++){ + if( aChange[iKey]>=0 || (iKey==pTab->iPKey && bChngRowid) ){ + Column *pCol = &pTab->aCol[iKey]; + if( zKey ){ + if( 0==sqlite3StrICmp(pCol->zName, zKey) ) return 1; + }else if( pCol->colFlags & COLFLAG_PRIMKEY ){ + return 1; + } + } + } + } + return 0; +} + +/* +** Return true if the parser passed as the first argument is being +** used to code a trigger that is really a "SET NULL" action belonging +** to trigger pFKey. +*/ +static int isSetNullAction(Parse *pParse, FKey *pFKey){ + Parse *pTop = sqlite3ParseToplevel(pParse); + if( pTop->pTriggerPrg ){ + Trigger *p = pTop->pTriggerPrg->pTrigger; + if( (p==pFKey->apTrigger[0] && pFKey->aAction[0]==OE_SetNull) + || (p==pFKey->apTrigger[1] && pFKey->aAction[1]==OE_SetNull) + ){ + return 1; + } + } + return 0; +} + +/* +** This function is called when inserting, deleting or updating a row of +** table pTab to generate VDBE code to perform foreign key constraint +** processing for the operation. +** +** For a DELETE operation, parameter regOld is passed the index of the +** first register in an array of (pTab->nCol+1) registers containing the +** rowid of the row being deleted, followed by each of the column values +** of the row being deleted, from left to right. Parameter regNew is passed +** zero in this case. +** +** For an INSERT operation, regOld is passed zero and regNew is passed the +** first register of an array of (pTab->nCol+1) registers containing the new +** row data. +** +** For an UPDATE operation, this function is called twice. Once before +** the original record is deleted from the table using the calling convention +** described for DELETE. Then again after the original record is deleted +** but before the new record is inserted using the INSERT convention. +*/ +SQLITE_PRIVATE void sqlite3FkCheck( + Parse *pParse, /* Parse context */ + Table *pTab, /* Row is being deleted from this table */ + int regOld, /* Previous row data is stored here */ + int regNew, /* New row data is stored here */ + int *aChange, /* Array indicating UPDATEd columns (or 0) */ + int bChngRowid /* True if rowid is UPDATEd */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + FKey *pFKey; /* Used to iterate through FKs */ + int iDb; /* Index of database containing pTab */ + const char *zDb; /* Name of database containing pTab */ + int isIgnoreErrors = pParse->disableTriggers; + + /* Exactly one of regOld and regNew should be non-zero. */ + assert( (regOld==0)!=(regNew==0) ); + + /* If foreign-keys are disabled, this function is a no-op. */ + if( (db->flags&SQLITE_ForeignKeys)==0 ) return; + + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + zDb = db->aDb[iDb].zName; + + /* Loop through all the foreign key constraints for which pTab is the + ** child table (the table that the foreign key definition is part of). */ + for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){ + Table *pTo; /* Parent table of foreign key pFKey */ + Index *pIdx = 0; /* Index on key columns in pTo */ + int *aiFree = 0; + int *aiCol; + int iCol; + int i; + int bIgnore = 0; + + if( aChange + && sqlite3_stricmp(pTab->zName, pFKey->zTo)!=0 + && fkChildIsModified(pTab, pFKey, aChange, bChngRowid)==0 + ){ + continue; + } + + /* Find the parent table of this foreign key. Also find a unique index + ** on the parent key columns in the parent table. If either of these + ** schema items cannot be located, set an error in pParse and return + ** early. */ + if( pParse->disableTriggers ){ + pTo = sqlite3FindTable(db, pFKey->zTo, zDb); + }else{ + pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb); + } + if( !pTo || sqlite3FkLocateIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){ + assert( isIgnoreErrors==0 || (regOld!=0 && regNew==0) ); + if( !isIgnoreErrors || db->mallocFailed ) return; + if( pTo==0 ){ + /* If isIgnoreErrors is true, then a table is being dropped. In this + ** case SQLite runs a "DELETE FROM xxx" on the table being dropped + ** before actually dropping it in order to check FK constraints. + ** If the parent table of an FK constraint on the current table is + ** missing, behave as if it is empty. i.e. decrement the relevant + ** FK counter for each row of the current table with non-NULL keys. + */ + Vdbe *v = sqlite3GetVdbe(pParse); + int iJump = sqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1; + for(i=0; inCol; i++){ + int iReg = pFKey->aCol[i].iFrom + regOld + 1; + sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iJump); VdbeCoverage(v); + } + sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, -1); + } + continue; + } + assert( pFKey->nCol==1 || (aiFree && pIdx) ); + + if( aiFree ){ + aiCol = aiFree; + }else{ + iCol = pFKey->aCol[0].iFrom; + aiCol = &iCol; + } + for(i=0; inCol; i++){ + if( aiCol[i]==pTab->iPKey ){ + aiCol[i] = -1; + } +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Request permission to read the parent key columns. If the + ** authorization callback returns SQLITE_IGNORE, behave as if any + ** values read from the parent table are NULL. */ + if( db->xAuth ){ + int rcauth; + char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zName; + rcauth = sqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb); + bIgnore = (rcauth==SQLITE_IGNORE); + } +#endif + } + + /* Take a shared-cache advisory read-lock on the parent table. Allocate + ** a cursor to use to search the unique index on the parent key columns + ** in the parent table. */ + sqlite3TableLock(pParse, iDb, pTo->tnum, 0, pTo->zName); + pParse->nTab++; + + if( regOld!=0 ){ + /* A row is being removed from the child table. Search for the parent. + ** If the parent does not exist, removing the child row resolves an + ** outstanding foreign key constraint violation. */ + fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1, bIgnore); + } + if( regNew!=0 && !isSetNullAction(pParse, pFKey) ){ + /* A row is being added to the child table. If a parent row cannot + ** be found, adding the child row has violated the FK constraint. + ** + ** If this operation is being performed as part of a trigger program + ** that is actually a "SET NULL" action belonging to this very + ** foreign key, then omit this scan altogether. As all child key + ** values are guaranteed to be NULL, it is not possible for adding + ** this row to cause an FK violation. */ + fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1, bIgnore); + } + + sqlite3DbFree(db, aiFree); + } + + /* Loop through all the foreign key constraints that refer to this table. + ** (the "child" constraints) */ + for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){ + Index *pIdx = 0; /* Foreign key index for pFKey */ + SrcList *pSrc; + int *aiCol = 0; + + if( aChange && fkParentIsModified(pTab, pFKey, aChange, bChngRowid)==0 ){ + continue; + } + + if( !pFKey->isDeferred && !(db->flags & SQLITE_DeferFKs) + && !pParse->pToplevel && !pParse->isMultiWrite + ){ + assert( regOld==0 && regNew!=0 ); + /* Inserting a single row into a parent table cannot cause (or fix) + ** an immediate foreign key violation. So do nothing in this case. */ + continue; + } + + if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){ + if( !isIgnoreErrors || db->mallocFailed ) return; + continue; + } + assert( aiCol || pFKey->nCol==1 ); + + /* Create a SrcList structure containing the child table. We need the + ** child table as a SrcList for sqlite3WhereBegin() */ + pSrc = sqlite3SrcListAppend(db, 0, 0, 0); + if( pSrc ){ + struct SrcList_item *pItem = pSrc->a; + pItem->pTab = pFKey->pFrom; + pItem->zName = pFKey->pFrom->zName; + pItem->pTab->nRef++; + pItem->iCursor = pParse->nTab++; + + if( regNew!=0 ){ + fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1); + } + if( regOld!=0 ){ + int eAction = pFKey->aAction[aChange!=0]; + fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1); + /* If this is a deferred FK constraint, or a CASCADE or SET NULL + ** action applies, then any foreign key violations caused by + ** removing the parent key will be rectified by the action trigger. + ** So do not set the "may-abort" flag in this case. + ** + ** Note 1: If the FK is declared "ON UPDATE CASCADE", then the + ** may-abort flag will eventually be set on this statement anyway + ** (when this function is called as part of processing the UPDATE + ** within the action trigger). + ** + ** Note 2: At first glance it may seem like SQLite could simply omit + ** all OP_FkCounter related scans when either CASCADE or SET NULL + ** applies. The trouble starts if the CASCADE or SET NULL action + ** trigger causes other triggers or action rules attached to the + ** child table to fire. In these cases the fk constraint counters + ** might be set incorrectly if any OP_FkCounter related scans are + ** omitted. */ + if( !pFKey->isDeferred && eAction!=OE_Cascade && eAction!=OE_SetNull ){ + sqlite3MayAbort(pParse); + } + } + pItem->zName = 0; + sqlite3SrcListDelete(db, pSrc); + } + sqlite3DbFree(db, aiCol); + } +} + +#define COLUMN_MASK(x) (((x)>31) ? 0xffffffff : ((u32)1<<(x))) + +/* +** This function is called before generating code to update or delete a +** row contained in table pTab. +*/ +SQLITE_PRIVATE u32 sqlite3FkOldmask( + Parse *pParse, /* Parse context */ + Table *pTab /* Table being modified */ +){ + u32 mask = 0; + if( pParse->db->flags&SQLITE_ForeignKeys ){ + FKey *p; + int i; + for(p=pTab->pFKey; p; p=p->pNextFrom){ + for(i=0; inCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom); + } + for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ + Index *pIdx = 0; + sqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0); + if( pIdx ){ + for(i=0; inKeyCol; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]); + } + } + } + return mask; +} + + +/* +** This function is called before generating code to update or delete a +** row contained in table pTab. If the operation is a DELETE, then +** parameter aChange is passed a NULL value. For an UPDATE, aChange points +** to an array of size N, where N is the number of columns in table pTab. +** If the i'th column is not modified by the UPDATE, then the corresponding +** entry in the aChange[] array is set to -1. If the column is modified, +** the value is 0 or greater. Parameter chngRowid is set to true if the +** UPDATE statement modifies the rowid fields of the table. +** +** If any foreign key processing will be required, this function returns +** true. If there is no foreign key related processing, this function +** returns false. +*/ +SQLITE_PRIVATE int sqlite3FkRequired( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being modified */ + int *aChange, /* Non-NULL for UPDATE operations */ + int chngRowid /* True for UPDATE that affects rowid */ +){ + if( pParse->db->flags&SQLITE_ForeignKeys ){ + if( !aChange ){ + /* A DELETE operation. Foreign key processing is required if the + ** table in question is either the child or parent table for any + ** foreign key constraint. */ + return (sqlite3FkReferences(pTab) || pTab->pFKey); + }else{ + /* This is an UPDATE. Foreign key processing is only required if the + ** operation modifies one or more child or parent key columns. */ + FKey *p; + + /* Check if any child key columns are being modified. */ + for(p=pTab->pFKey; p; p=p->pNextFrom){ + if( fkChildIsModified(pTab, p, aChange, chngRowid) ) return 1; + } + + /* Check if any parent key columns are being modified. */ + for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ + if( fkParentIsModified(pTab, p, aChange, chngRowid) ) return 1; + } + } + } + return 0; +} + +/* +** This function is called when an UPDATE or DELETE operation is being +** compiled on table pTab, which is the parent table of foreign-key pFKey. +** If the current operation is an UPDATE, then the pChanges parameter is +** passed a pointer to the list of columns being modified. If it is a +** DELETE, pChanges is passed a NULL pointer. +** +** It returns a pointer to a Trigger structure containing a trigger +** equivalent to the ON UPDATE or ON DELETE action specified by pFKey. +** If the action is "NO ACTION" or "RESTRICT", then a NULL pointer is +** returned (these actions require no special handling by the triggers +** sub-system, code for them is created by fkScanChildren()). +** +** For example, if pFKey is the foreign key and pTab is table "p" in +** the following schema: +** +** CREATE TABLE p(pk PRIMARY KEY); +** CREATE TABLE c(ck REFERENCES p ON DELETE CASCADE); +** +** then the returned trigger structure is equivalent to: +** +** CREATE TRIGGER ... DELETE ON p BEGIN +** DELETE FROM c WHERE ck = old.pk; +** END; +** +** The returned pointer is cached as part of the foreign key object. It +** is eventually freed along with the rest of the foreign key object by +** sqlite3FkDelete(). +*/ +static Trigger *fkActionTrigger( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being updated or deleted from */ + FKey *pFKey, /* Foreign key to get action for */ + ExprList *pChanges /* Change-list for UPDATE, NULL for DELETE */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + int action; /* One of OE_None, OE_Cascade etc. */ + Trigger *pTrigger; /* Trigger definition to return */ + int iAction = (pChanges!=0); /* 1 for UPDATE, 0 for DELETE */ + + action = pFKey->aAction[iAction]; + pTrigger = pFKey->apTrigger[iAction]; + + if( action!=OE_None && !pTrigger ){ + u8 enableLookaside; /* Copy of db->lookaside.bEnabled */ + char const *zFrom; /* Name of child table */ + int nFrom; /* Length in bytes of zFrom */ + Index *pIdx = 0; /* Parent key index for this FK */ + int *aiCol = 0; /* child table cols -> parent key cols */ + TriggerStep *pStep = 0; /* First (only) step of trigger program */ + Expr *pWhere = 0; /* WHERE clause of trigger step */ + ExprList *pList = 0; /* Changes list if ON UPDATE CASCADE */ + Select *pSelect = 0; /* If RESTRICT, "SELECT RAISE(...)" */ + int i; /* Iterator variable */ + Expr *pWhen = 0; /* WHEN clause for the trigger */ + + if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0; + assert( aiCol || pFKey->nCol==1 ); + + for(i=0; inCol; i++){ + Token tOld = { "old", 3 }; /* Literal "old" token */ + Token tNew = { "new", 3 }; /* Literal "new" token */ + Token tFromCol; /* Name of column in child table */ + Token tToCol; /* Name of column in parent table */ + int iFromCol; /* Idx of column in child table */ + Expr *pEq; /* tFromCol = OLD.tToCol */ + + iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; + assert( iFromCol>=0 ); + assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKeynCol) ); + tToCol.z = pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName; + tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName; + + tToCol.n = sqlite3Strlen30(tToCol.z); + tFromCol.n = sqlite3Strlen30(tFromCol.z); + + /* Create the expression "OLD.zToCol = zFromCol". It is important + ** that the "OLD.zToCol" term is on the LHS of the = operator, so + ** that the affinity and collation sequence associated with the + ** parent table are used for the comparison. */ + pEq = sqlite3PExpr(pParse, TK_EQ, + sqlite3PExpr(pParse, TK_DOT, + sqlite3ExprAlloc(db, TK_ID, &tOld, 0), + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0) + , 0), + sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0) + , 0); + pWhere = sqlite3ExprAnd(db, pWhere, pEq); + + /* For ON UPDATE, construct the next term of the WHEN clause. + ** The final WHEN clause will be like this: + ** + ** WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN) + */ + if( pChanges ){ + pEq = sqlite3PExpr(pParse, TK_IS, + sqlite3PExpr(pParse, TK_DOT, + sqlite3ExprAlloc(db, TK_ID, &tOld, 0), + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0), + 0), + sqlite3PExpr(pParse, TK_DOT, + sqlite3ExprAlloc(db, TK_ID, &tNew, 0), + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0), + 0), + 0); + pWhen = sqlite3ExprAnd(db, pWhen, pEq); + } + + if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){ + Expr *pNew; + if( action==OE_Cascade ){ + pNew = sqlite3PExpr(pParse, TK_DOT, + sqlite3ExprAlloc(db, TK_ID, &tNew, 0), + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0) + , 0); + }else if( action==OE_SetDflt ){ + Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt; + if( pDflt ){ + pNew = sqlite3ExprDup(db, pDflt, 0); + }else{ + pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0); + } + }else{ + pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0); + } + pList = sqlite3ExprListAppend(pParse, pList, pNew); + sqlite3ExprListSetName(pParse, pList, &tFromCol, 0); + } + } + sqlite3DbFree(db, aiCol); + + zFrom = pFKey->pFrom->zName; + nFrom = sqlite3Strlen30(zFrom); + + if( action==OE_Restrict ){ + Token tFrom; + Expr *pRaise; + + tFrom.z = zFrom; + tFrom.n = nFrom; + pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed"); + if( pRaise ){ + pRaise->affinity = OE_Abort; + } + pSelect = sqlite3SelectNew(pParse, + sqlite3ExprListAppend(pParse, 0, pRaise), + sqlite3SrcListAppend(db, 0, &tFrom, 0), + pWhere, + 0, 0, 0, 0, 0, 0 + ); + pWhere = 0; + } + + /* Disable lookaside memory allocation */ + enableLookaside = db->lookaside.bEnabled; + db->lookaside.bEnabled = 0; + + pTrigger = (Trigger *)sqlite3DbMallocZero(db, + sizeof(Trigger) + /* struct Trigger */ + sizeof(TriggerStep) + /* Single step in trigger program */ + nFrom + 1 /* Space for pStep->zTarget */ + ); + if( pTrigger ){ + pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1]; + pStep->zTarget = (char *)&pStep[1]; + memcpy((char *)pStep->zTarget, zFrom, nFrom); + + pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE); + pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + if( pWhen ){ + pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0, 0); + pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); + } + } + + /* Re-enable the lookaside buffer, if it was disabled earlier. */ + db->lookaside.bEnabled = enableLookaside; + + sqlite3ExprDelete(db, pWhere); + sqlite3ExprDelete(db, pWhen); + sqlite3ExprListDelete(db, pList); + sqlite3SelectDelete(db, pSelect); + if( db->mallocFailed==1 ){ + fkTriggerDelete(db, pTrigger); + return 0; + } + assert( pStep!=0 ); + + switch( action ){ + case OE_Restrict: + pStep->op = TK_SELECT; + break; + case OE_Cascade: + if( !pChanges ){ + pStep->op = TK_DELETE; + break; + } + default: + pStep->op = TK_UPDATE; + } + pStep->pTrig = pTrigger; + pTrigger->pSchema = pTab->pSchema; + pTrigger->pTabSchema = pTab->pSchema; + pFKey->apTrigger[iAction] = pTrigger; + pTrigger->op = (pChanges ? TK_UPDATE : TK_DELETE); + } + + return pTrigger; +} + +/* +** This function is called when deleting or updating a row to implement +** any required CASCADE, SET NULL or SET DEFAULT actions. +*/ +SQLITE_PRIVATE void sqlite3FkActions( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being updated or deleted from */ + ExprList *pChanges, /* Change-list for UPDATE, NULL for DELETE */ + int regOld, /* Address of array containing old row */ + int *aChange, /* Array indicating UPDATEd columns (or 0) */ + int bChngRowid /* True if rowid is UPDATEd */ +){ + /* If foreign-key support is enabled, iterate through all FKs that + ** refer to table pTab. If there is an action associated with the FK + ** for this operation (either update or delete), invoke the associated + ** trigger sub-program. */ + if( pParse->db->flags&SQLITE_ForeignKeys ){ + FKey *pFKey; /* Iterator variable */ + for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){ + if( aChange==0 || fkParentIsModified(pTab, pFKey, aChange, bChngRowid) ){ + Trigger *pAct = fkActionTrigger(pParse, pTab, pFKey, pChanges); + if( pAct ){ + sqlite3CodeRowTriggerDirect(pParse, pAct, pTab, regOld, OE_Abort, 0); + } + } + } + } +} + +#endif /* ifndef SQLITE_OMIT_TRIGGER */ + +/* +** Free all memory associated with foreign key definitions attached to +** table pTab. Remove the deleted foreign keys from the Schema.fkeyHash +** hash table. +*/ +SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *db, Table *pTab){ + FKey *pFKey; /* Iterator variable */ + FKey *pNext; /* Copy of pFKey->pNextFrom */ + + assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) ); + for(pFKey=pTab->pFKey; pFKey; pFKey=pNext){ + + /* Remove the FK from the fkeyHash hash table. */ + if( !db || db->pnBytesFreed==0 ){ + if( pFKey->pPrevTo ){ + pFKey->pPrevTo->pNextTo = pFKey->pNextTo; + }else{ + void *p = (void *)pFKey->pNextTo; + const char *z = (p ? pFKey->pNextTo->zTo : pFKey->zTo); + sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, p); + } + if( pFKey->pNextTo ){ + pFKey->pNextTo->pPrevTo = pFKey->pPrevTo; + } + } + + /* EV: R-30323-21917 Each foreign key constraint in SQLite is + ** classified as either immediate or deferred. + */ + assert( pFKey->isDeferred==0 || pFKey->isDeferred==1 ); + + /* Delete any triggers created to implement actions for this FK. */ +#ifndef SQLITE_OMIT_TRIGGER + fkTriggerDelete(db, pFKey->apTrigger[0]); + fkTriggerDelete(db, pFKey->apTrigger[1]); +#endif + + pNext = pFKey->pNextFrom; + sqlite3DbFree(db, pFKey); + } +} +#endif /* ifndef SQLITE_OMIT_FOREIGN_KEY */ + +/************** End of fkey.c ************************************************/ +/************** Begin file insert.c ******************************************/ +/* +** 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. +** +************************************************************************* +** This file contains C code routines that are called by the parser +** to handle INSERT statements in SQLite. +*/ + +/* +** Generate code that will +** +** (1) acquire a lock for table pTab then +** (2) open pTab as cursor iCur. +** +** If pTab is a WITHOUT ROWID table, then it is the PRIMARY KEY index +** for that table that is actually opened. +*/ +SQLITE_PRIVATE void sqlite3OpenTable( + Parse *pParse, /* 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; + assert( !IsVirtual(pTab) ); + v = sqlite3GetVdbe(pParse); + assert( opcode==OP_OpenWrite || opcode==OP_OpenRead ); + sqlite3TableLock(pParse, iDb, pTab->tnum, + (opcode==OP_OpenWrite)?1:0, pTab->zName); + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nCol); + VdbeComment((v, "%s", pTab->zName)); + }else{ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pPk!=0 ); + assert( pPk->tnum=pTab->tnum ); + sqlite3VdbeAddOp3(v, opcode, iCur, pPk->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pPk); + VdbeComment((v, "%s", pTab->zName)); + } +} + +/* +** Return a pointer to the column affinity string associated with 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' NONE +** 'B' TEXT +** 'C' NUMERIC +** 'D' INTEGER +** 'F' REAL +** +** An extra 'D' is appended to the end of the string to cover the +** rowid that appears as the last column in every index. +** +** Memory for the buffer containing the column index affinity string +** is managed along with the rest of the Index structure. It will be +** released when sqlite3DeleteIndex() is called. +*/ +SQLITE_PRIVATE const char *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. + ** + ** The column affinity string will eventually be deleted by + ** sqliteDeleteIndex() when the Index structure itself is cleaned + ** up. + */ + int n; + Table *pTab = pIdx->pTable; + sqlite3 *db = sqlite3VdbeDb(v); + pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1); + if( !pIdx->zColAff ){ + db->mallocFailed = 1; + return 0; + } + for(n=0; nnColumn; n++){ + i16 x = pIdx->aiColumn[n]; + pIdx->zColAff[n] = x<0 ? SQLITE_AFF_INTEGER : pTab->aCol[x].affinity; + } + pIdx->zColAff[n] = 0; + } + + return pIdx->zColAff; +} + +/* +** Compute the affinity string for table pTab, if it has not already been +** computed. As an optimization, omit trailing SQLITE_AFF_NONE affinities. +** +** If the affinity exists (if it is no entirely SQLITE_AFF_NONE values) and +** if iReg>0 then code an OP_Affinity opcode that will set the affinities +** for register iReg and following. Or if affinities exists and iReg==0, +** then just set the P4 operand of the previous opcode (which should be +** an OP_MakeRecord) to the affinity string. +** +** A column affinity string has one character per column: +** +** Character Column affinity +** ------------------------------ +** 'A' NONE +** 'B' TEXT +** 'C' NUMERIC +** 'D' INTEGER +** 'E' REAL +*/ +SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ + int i; + char *zColAff = pTab->zColAff; + if( zColAff==0 ){ + sqlite3 *db = sqlite3VdbeDb(v); + zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1); + if( !zColAff ){ + db->mallocFailed = 1; + return; + } + + for(i=0; inCol; i++){ + zColAff[i] = pTab->aCol[i].affinity; + } + do{ + zColAff[i--] = 0; + }while( i>=0 && zColAff[i]==SQLITE_AFF_NONE ); + pTab->zColAff = zColAff; + } + i = sqlite3Strlen30(zColAff); + if( i ){ + if( iReg ){ + sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i); + }else{ + sqlite3VdbeChangeP4(v, -1, zColAff, i); + } + } +} + +/* +** Return non-zero if the table pTab in database iDb or any of its indices +** have been opened at any point in the VDBE program. This is used to see if +** a statement of the form "INSERT INTO SELECT ..." can +** run without using a temporary table for the results of the SELECT. +*/ +static int readsTable(Parse *p, int iDb, Table *pTab){ + Vdbe *v = sqlite3GetVdbe(p); + int i; + int iEnd = sqlite3VdbeCurrentAddr(v); +#ifndef SQLITE_OMIT_VIRTUALTABLE + VTable *pVTab = IsVirtual(pTab) ? sqlite3GetVTable(p->db, pTab) : 0; +#endif + + for(i=1; iopcode==OP_OpenRead && pOp->p3==iDb ){ + Index *pIndex; + int tnum = pOp->p2; + if( tnum==pTab->tnum ){ + return 1; + } + for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){ + if( tnum==pIndex->tnum ){ + return 1; + } + } + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( pOp->opcode==OP_VOpen && pOp->p4.pVtab==pVTab ){ + assert( pOp->p4.pVtab!=0 ); + assert( pOp->p4type==P4_VTAB ); + return 1; + } +#endif + } + return 0; +} + +#ifndef SQLITE_OMIT_AUTOINCREMENT +/* +** Locate or create an AutoincInfo structure associated with table pTab +** which is in database iDb. Return the register number for the register +** that holds the maximum rowid. +** +** There is at most one AutoincInfo structure per table even if the +** same table is autoincremented multiple times due to inserts within +** triggers. A new AutoincInfo structure is created if this is the +** first use of table pTab. On 2nd and subsequent uses, the original +** AutoincInfo structure is used. +** +** Three memory locations are allocated: +** +** (1) Register to hold the name of the pTab table. +** (2) Register to hold the maximum ROWID of pTab. +** (3) Register to hold the rowid in sqlite_sequence of pTab +** +** The 2nd register is the one that is returned. That is all the +** insert routine needs to know about. +*/ +static int autoIncBegin( + Parse *pParse, /* Parsing context */ + int iDb, /* Index of the database holding pTab */ + Table *pTab /* The table we are writing to */ +){ + int memId = 0; /* Register holding maximum rowid */ + if( pTab->tabFlags & TF_Autoincrement ){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + AutoincInfo *pInfo; + + pInfo = pToplevel->pAinc; + while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; } + if( pInfo==0 ){ + pInfo = sqlite3DbMallocRaw(pParse->db, sizeof(*pInfo)); + if( pInfo==0 ) return 0; + pInfo->pNext = pToplevel->pAinc; + pToplevel->pAinc = pInfo; + pInfo->pTab = pTab; + pInfo->iDb = iDb; + pToplevel->nMem++; /* Register to hold name of table */ + pInfo->regCtr = ++pToplevel->nMem; /* Max rowid register */ + pToplevel->nMem++; /* Rowid in sqlite_sequence */ + } + memId = pInfo->regCtr; + } + return memId; +} + +/* +** This routine generates code that will initialize all of the +** register used by the autoincrement tracker. +*/ +SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){ + AutoincInfo *p; /* Information about an AUTOINCREMENT */ + sqlite3 *db = pParse->db; /* The database connection */ + Db *pDb; /* Database only autoinc table */ + int memId; /* Register holding max rowid */ + int addr; /* A VDBE address */ + Vdbe *v = pParse->pVdbe; /* VDBE under construction */ + + /* This routine is never called during trigger-generation. It is + ** only called from the top-level */ + assert( pParse->pTriggerTab==0 ); + assert( pParse==sqlite3ParseToplevel(pParse) ); + + assert( v ); /* We failed long ago if this is not so */ + for(p = pParse->pAinc; p; p = p->pNext){ + pDb = &db->aDb[p->iDb]; + memId = p->regCtr; + assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); + sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead); + sqlite3VdbeAddOp3(v, OP_Null, 0, memId, memId+1); + addr = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, p->pTab->zName, 0); + sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_Column, 0, 0, memId); + sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL); + sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1); + sqlite3VdbeAddOp3(v, OP_Column, 0, 1, memId); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+9); + sqlite3VdbeAddOp2(v, OP_Next, 0, addr+2); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Integer, 0, memId); + sqlite3VdbeAddOp0(v, OP_Close); + } +} + +/* +** Update the maximum rowid for an autoincrement calculation. +** +** This routine should be called when the top of the stack holds a +** new rowid that is about to be inserted. If that new rowid is +** larger than the maximum rowid in the memId memory cell, then the +** memory cell is updated. The stack is unchanged. +*/ +static void autoIncStep(Parse *pParse, int memId, int regRowid){ + if( memId>0 ){ + sqlite3VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, regRowid); + } +} + +/* +** This routine generates the code needed to write autoincrement +** maximum rowid values back into the sqlite_sequence register. +** Every statement that might do an INSERT into an autoincrement +** table (either directly or through triggers) needs to call this +** routine just before the "exit" code. +*/ +SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){ + AutoincInfo *p; + Vdbe *v = pParse->pVdbe; + sqlite3 *db = pParse->db; + + assert( v ); + for(p = pParse->pAinc; p; p = p->pNext){ + Db *pDb = &db->aDb[p->iDb]; + int j1; + int iRec; + int memId = p->regCtr; + + iRec = sqlite3GetTempReg(pParse); + assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); + sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); + j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_NewRowid, 0, memId+1); + sqlite3VdbeJumpHere(v, j1); + sqlite3VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, iRec); + sqlite3VdbeAddOp3(v, OP_Insert, 0, iRec, memId+1); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3VdbeAddOp0(v, OP_Close); + sqlite3ReleaseTempReg(pParse, iRec); + } +} +#else +/* +** If SQLITE_OMIT_AUTOINCREMENT is defined, then the three routines +** above are all no-ops +*/ +# define autoIncBegin(A,B,C) (0) +# define autoIncStep(A,B,C) +#endif /* SQLITE_OMIT_AUTOINCREMENT */ + + +/* Forward declaration */ +static int xferOptimization( + Parse *pParse, /* Parser context */ + Table *pDest, /* The table we are inserting into */ + Select *pSelect, /* A SELECT statement to use as the data source */ + int onError, /* How to handle constraint errors */ + int iDbDest /* The database of pDest */ +); + +/* +** This routine is called to handle SQL of the following forms: +** +** insert into TABLE (IDLIST) values(EXPRLIST),(EXPRLIST),... +** insert into TABLE (IDLIST) select +** insert into TABLE (IDLIST) default values +** +** The IDLIST following the table name is always optional. If omitted, +** then a list of all (non-hidden) columns for the table is substituted. +** The IDLIST appears in the pColumn parameter. pColumn is NULL if IDLIST +** is omitted. +** +** For the pSelect parameter holds the values to be inserted for the +** first two forms shown above. A VALUES clause is really just short-hand +** for a SELECT statement that omits the FROM clause and everything else +** that follows. If the pSelect parameter is NULL, that means that the +** DEFAULT VALUES form of the INSERT statement is intended. +** +** The code generated follows one of four templates. For a simple +** insert with data coming from a single-row VALUES clause, the code executes +** once straight down through. Pseudo-code follows (we call this +** the "1st template"): +** +** open write cursor to
    and its indices +** put VALUES clause expressions into registers +** write the resulting record into
    +** cleanup +** +** The three remaining templates assume the statement is of the form +** +** INSERT INTO
    SELECT ... +** +** If the SELECT clause is of the restricted form "SELECT * FROM " - +** in other words if the SELECT pulls all columns from a single table +** and there is no WHERE or LIMIT or GROUP BY or ORDER BY clauses, and +** if and are distinct tables but have identical +** schemas, including all the same indices, then a special optimization +** is invoked that copies raw records from over to . +** See the xferOptimization() function for the implementation of this +** template. This is the 2nd template. +** +** open a write cursor to
    +** open read cursor on +** transfer all records in over to
    +** close cursors +** foreach index on
    +** open a write cursor on the
    index +** open a read cursor on the corresponding index +** transfer all records from the read to the write cursors +** close cursors +** end foreach +** +** The 3rd template is for when the second template does not apply +** and the SELECT clause does not read from
    at any time. +** The generated code follows this template: +** +** X <- A +** goto B +** A: setup for the SELECT +** loop over the rows in the SELECT +** load values into registers R..R+n +** yield X +** end loop +** cleanup after the SELECT +** end-coroutine X +** B: open write cursor to
    and its indices +** C: yield X, at EOF goto D +** insert the select result into
    from R..R+n +** goto C +** D: cleanup +** +** The 4th template is used if the insert statement takes its +** values from a SELECT but the data is being inserted into a table +** that is also read as part of the SELECT. In the third form, +** we have to use an intermediate table to store the results of +** the select. The template is like this: +** +** X <- A +** goto B +** A: setup for the SELECT +** loop over the tables in the SELECT +** load value into register R..R+n +** yield X +** end loop +** cleanup after the SELECT +** end co-routine R +** B: open temp table +** L: yield X, at EOF goto M +** insert row from R..R+n into temp table +** goto L +** M: open write cursor to
    and its indices +** rewind temp table +** C: loop over rows of intermediate table +** transfer values form intermediate table into
    +** end loop +** D: cleanup +*/ +SQLITE_PRIVATE void sqlite3Insert( + Parse *pParse, /* Parser context */ + SrcList *pTabList, /* Name of table into which we are inserting */ + Select *pSelect, /* A SELECT statement to use as the data source */ + IdList *pColumn, /* Column names corresponding to IDLIST. */ + int onError /* How to handle constraint errors */ +){ + sqlite3 *db; /* The main database structure */ + Table *pTab; /* The table to insert into. aka TABLE */ + char *zTab; /* Name of the table into which we are inserting */ + const char *zDb; /* Name of the database holding this table */ + int i, j, idx; /* Loop counters */ + Vdbe *v; /* Generate code into this virtual machine */ + Index *pIdx; /* For looping over indices of the table */ + int nColumn; /* Number of columns in the data */ + int nHidden = 0; /* Number of hidden columns if TABLE is virtual */ + int iDataCur = 0; /* VDBE cursor that is the main data repository */ + int iIdxCur = 0; /* First index cursor */ + int ipkColumn = -1; /* Column that is the INTEGER PRIMARY KEY */ + int endOfLoop; /* Label for the end of the insertion loop */ + int srcTab = 0; /* Data comes from this temporary cursor if >=0 */ + int addrInsTop = 0; /* Jump to label "D" */ + int addrCont = 0; /* Top of insert loop. Label "C" in templates 3 and 4 */ + SelectDest dest; /* Destination for SELECT on rhs of INSERT */ + int iDb; /* Index of database holding TABLE */ + Db *pDb; /* The database containing table being inserted into */ + u8 useTempTable = 0; /* Store SELECT results in intermediate table */ + u8 appendFlag = 0; /* True if the insert is likely to be an append */ + u8 withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */ + u8 bIdListInOrder; /* True if IDLIST is in table order */ + ExprList *pList = 0; /* List of VALUES() to be inserted */ + + /* Register allocations */ + int regFromSelect = 0;/* Base register for data coming from SELECT */ + int regAutoinc = 0; /* Register holding the AUTOINCREMENT counter */ + int regRowCount = 0; /* Memory cell used for the row counter */ + int regIns; /* Block of regs holding rowid+data being inserted */ + int regRowid; /* registers holding insert rowid */ + int regData; /* register holding first column to insert */ + int *aRegIdx = 0; /* One register allocated to each index */ + +#ifndef SQLITE_OMIT_TRIGGER + int isView; /* True if attempting to insert into a view */ + Trigger *pTrigger; /* List of triggers on pTab, if required */ + int tmask; /* Mask of trigger times */ +#endif + + db = pParse->db; + memset(&dest, 0, sizeof(dest)); + if( pParse->nErr || db->mallocFailed ){ + goto insert_cleanup; + } + + /* If the Select object is really just a simple VALUES() list with a + ** single row (the common case) then keep that one row of values + ** and discard the other (unused) parts of the pSelect object + */ + if( pSelect && (pSelect->selFlags & SF_Values)!=0 && pSelect->pPrior==0 ){ + pList = pSelect->pEList; + pSelect->pEList = 0; + sqlite3SelectDelete(db, pSelect); + pSelect = 0; + } + + /* Locate the table into which we will be inserting new information. + */ + assert( pTabList->nSrc==1 ); + zTab = pTabList->a[0].zName; + if( NEVER(zTab==0) ) goto insert_cleanup; + pTab = sqlite3SrcListLookup(pParse, pTabList); + if( pTab==0 ){ + goto insert_cleanup; + } + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDbnDb ); + pDb = &db->aDb[iDb]; + zDb = pDb->zName; + if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){ + goto insert_cleanup; + } + withoutRowid = !HasRowid(pTab); + + /* Figure out if we have any triggers and if the table being + ** inserted into is a view + */ +#ifndef SQLITE_OMIT_TRIGGER + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_INSERT, 0, &tmask); + isView = pTab->pSelect!=0; +#else +# define pTrigger 0 +# define tmask 0 +# define isView 0 +#endif +#ifdef SQLITE_OMIT_VIEW +# undef isView +# define isView 0 +#endif + assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) ); + + /* If pTab is really a view, make sure it has been initialized. + ** ViewGetColumnNames() is a no-op if pTab is not a view. + */ + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto insert_cleanup; + } + + /* Cannot insert into a read-only table. + */ + if( sqlite3IsReadOnly(pParse, pTab, tmask) ){ + goto insert_cleanup; + } + + /* Allocate a VDBE + */ + v = sqlite3GetVdbe(pParse); + if( v==0 ) goto insert_cleanup; + if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); + sqlite3BeginWriteOperation(pParse, pSelect || pTrigger, iDb); + +#ifndef SQLITE_OMIT_XFER_OPT + /* If the statement is of the form + ** + ** INSERT INTO SELECT * FROM ; + ** + ** Then special optimizations can be applied that make the transfer + ** very fast and which reduce fragmentation of indices. + ** + ** This is the 2nd template. + */ + if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){ + assert( !pTrigger ); + assert( pList==0 ); + goto insert_end; + } +#endif /* SQLITE_OMIT_XFER_OPT */ + + /* If this is an AUTOINCREMENT table, look up the sequence number in the + ** sqlite_sequence table and store it in memory cell regAutoinc. + */ + regAutoinc = autoIncBegin(pParse, iDb, pTab); + + /* Allocate registers for holding the rowid of the new row, + ** the content of the new row, and the assembled row record. + */ + regRowid = regIns = pParse->nMem+1; + pParse->nMem += pTab->nCol + 1; + if( IsVirtual(pTab) ){ + regRowid++; + pParse->nMem++; + } + regData = regRowid+1; + + /* If the INSERT statement included an IDLIST term, then make sure + ** all elements of the IDLIST really are columns of the table and + ** remember the column indices. + ** + ** If the table has an INTEGER PRIMARY KEY column and that column + ** is named in the IDLIST, then record in the ipkColumn variable + ** the index into IDLIST of the primary key column. ipkColumn is + ** the index of the primary key as it appears in IDLIST, not as + ** is appears in the original table. (The index of the INTEGER + ** PRIMARY KEY in the original table is pTab->iPKey.) + */ + bIdListInOrder = (pTab->tabFlags & TF_OOOHidden)==0; + if( pColumn ){ + for(i=0; inId; i++){ + pColumn->a[i].idx = -1; + } + for(i=0; inId; i++){ + for(j=0; jnCol; j++){ + if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){ + pColumn->a[i].idx = j; + if( i!=j ) bIdListInOrder = 0; + if( j==pTab->iPKey ){ + ipkColumn = i; assert( !withoutRowid ); + } + break; + } + } + if( j>=pTab->nCol ){ + if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){ + ipkColumn = i; + bIdListInOrder = 0; + }else{ + sqlite3ErrorMsg(pParse, "table %S has no column named %s", + pTabList, 0, pColumn->a[i].zName); + pParse->checkSchema = 1; + goto insert_cleanup; + } + } + } + } + + /* Figure out how many columns of data are supplied. If the data + ** is coming from a SELECT statement, then generate a co-routine that + ** produces a single row of the SELECT on each invocation. The + ** co-routine is the common header to the 3rd and 4th templates. + */ + if( pSelect ){ + /* Data is coming from a SELECT or from a multi-row VALUES clause. + ** Generate a co-routine to run the SELECT. */ + int regYield; /* Register holding co-routine entry-point */ + int addrTop; /* Top of the co-routine */ + int rc; /* Result code */ + + regYield = ++pParse->nMem; + addrTop = sqlite3VdbeCurrentAddr(v) + 1; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); + sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); + dest.iSdst = bIdListInOrder ? regData : 0; + dest.nSdst = pTab->nCol; + rc = sqlite3Select(pParse, pSelect, &dest); + regFromSelect = dest.iSdst; + if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup; + sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield); + sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */ + 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 (template 4). Set to + ** FALSE if each output row of the SELECT can be written directly into + ** the destination table (template 3). + ** + ** 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( pTrigger || readsTable(pParse, iDb, pTab) ){ + useTempTable = 1; + } + + if( useTempTable ){ + /* Invoke the coroutine to extract information from the SELECT + ** and add it to a transient table srcTab. The code generated + ** here is from the 4th template: + ** + ** B: open temp table + ** L: yield X, goto M at EOF + ** insert row from R..R+n into temp table + ** goto L + ** M: ... + */ + int regRec; /* Register to hold packed record */ + int regTempRowid; /* Register to hold temp table ROWID */ + int addrL; /* Label "L" */ + + srcTab = pParse->nTab++; + regRec = sqlite3GetTempReg(pParse); + regTempRowid = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn); + addrL = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec); + sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid); + sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrL); + sqlite3VdbeJumpHere(v, addrL); + sqlite3ReleaseTempReg(pParse, regRec); + sqlite3ReleaseTempReg(pParse, regTempRowid); + } + }else{ + /* This is the case if the data for the INSERT is coming from a + ** single-row VALUES clause + */ + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + srcTab = -1; + assert( useTempTable==0 ); + nColumn = pList ? pList->nExpr : 0; + for(i=0; ia[i].pExpr) ){ + goto insert_cleanup; + } + } + } + + /* If there is no IDLIST term but the table has an integer primary + ** key, the set the ipkColumn variable to the integer primary key + ** column index in the original table definition. + */ + if( pColumn==0 && nColumn>0 ){ + ipkColumn = pTab->iPKey; + } + + /* Make sure the number of columns in the source data matches the number + ** of columns to be inserted into the table. + */ + if( IsVirtual(pTab) ){ + for(i=0; inCol; i++){ + nHidden += (IsHiddenColumn(&pTab->aCol[i]) ? 1 : 0); + } + } + if( pColumn==0 && nColumn && nColumn!=(pTab->nCol-nHidden) ){ + sqlite3ErrorMsg(pParse, + "table %S has %d columns but %d values were supplied", + pTabList, 0, pTab->nCol-nHidden, nColumn); + goto insert_cleanup; + } + if( pColumn!=0 && nColumn!=pColumn->nId ){ + sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId); + goto insert_cleanup; + } + + /* Initialize the count of rows to be inserted + */ + if( db->flags & SQLITE_CountRows ){ + regRowCount = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); + } + + /* If this is not a view, open the table and and all indices */ + if( !isView ){ + int nIdx; + nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, -1, 0, + &iDataCur, &iIdxCur); + aRegIdx = sqlite3DbMallocRaw(db, sizeof(int)*(nIdx+1)); + if( aRegIdx==0 ){ + goto insert_cleanup; + } + for(i=0; inMem; + } + } + + /* This is the top of the main insertion loop */ + if( useTempTable ){ + /* This block codes the top of loop only. The complete loop is the + ** following pseudocode (template 4): + ** + ** rewind temp table, if empty goto D + ** C: loop over rows of intermediate table + ** transfer values form intermediate table into
    + ** end loop + ** D: ... + */ + addrInsTop = sqlite3VdbeAddOp1(v, OP_Rewind, srcTab); VdbeCoverage(v); + addrCont = sqlite3VdbeCurrentAddr(v); + }else if( pSelect ){ + /* This block codes the top of loop only. The complete loop is the + ** following pseudocode (template 3): + ** + ** C: yield X, at EOF goto D + ** insert the select result into
    from R..R+n + ** goto C + ** D: ... + */ + addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); + VdbeCoverage(v); + } + + /* Run the BEFORE and INSTEAD OF triggers, if there are any + */ + endOfLoop = sqlite3VdbeMakeLabel(v); + if( tmask & TRIGGER_BEFORE ){ + int regCols = sqlite3GetTempRange(pParse, pTab->nCol+1); + + /* build the NEW.* reference row. Note that if there is an INTEGER + ** PRIMARY KEY into which a NULL is being inserted, that NULL will be + ** translated into a unique ID for the row. But on a BEFORE trigger, + ** we do not know what the unique ID will be (because the insert has + ** not happened yet) so we substitute a rowid of -1 + */ + if( ipkColumn<0 ){ + sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols); + }else{ + int j1; + assert( !withoutRowid ); + if( useTempTable ){ + sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regCols); + }else{ + assert( pSelect==0 ); /* Otherwise useTempTable is true */ + sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regCols); + } + j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols); + sqlite3VdbeJumpHere(v, j1); + sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v); + } + + /* Cannot have triggers on a virtual table. If it were possible, + ** this block would have to account for hidden column. + */ + assert( !IsVirtual(pTab) ); + + /* Create the new column data + */ + for(i=0; inCol; i++){ + if( pColumn==0 ){ + j = i; + }else{ + for(j=0; jnId; j++){ + if( pColumn->a[j].idx==i ) break; + } + } + if( (!useTempTable && !pList) || (pColumn && j>=pColumn->nId) ){ + sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regCols+i+1); + }else if( useTempTable ){ + sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, regCols+i+1); + }else{ + assert( pSelect==0 ); /* Otherwise useTempTable is true */ + sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr, regCols+i+1); + } + } + + /* If this is an INSERT on a view with an INSTEAD OF INSERT trigger, + ** 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 ){ + sqlite3TableAffinity(v, pTab, regCols+1); + } + + /* Fire BEFORE or INSTEAD OF triggers */ + sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, + pTab, regCols-pTab->nCol-1, onError, endOfLoop); + + sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol+1); + } + + /* Compute the content of the next row to insert into a range of + ** registers beginning at regIns. + */ + if( !isView ){ + if( IsVirtual(pTab) ){ + /* The row that the VUpdate opcode will delete: none */ + sqlite3VdbeAddOp2(v, OP_Null, 0, regIns); + } + if( ipkColumn>=0 ){ + if( useTempTable ){ + sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regRowid); + }else if( pSelect ){ + sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid); + }else{ + VdbeOp *pOp; + sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid); + pOp = sqlite3VdbeGetOp(v, -1); + if( ALWAYS(pOp) && pOp->opcode==OP_Null && !IsVirtual(pTab) ){ + appendFlag = 1; + pOp->opcode = OP_NewRowid; + pOp->p1 = iDataCur; + pOp->p2 = regRowid; + pOp->p3 = regAutoinc; + } + } + /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid + ** to generate a unique primary key value. + */ + if( !appendFlag ){ + int j1; + if( !IsVirtual(pTab) ){ + j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc); + sqlite3VdbeJumpHere(v, j1); + }else{ + j1 = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, j1+2); VdbeCoverage(v); + } + sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid); VdbeCoverage(v); + } + }else if( IsVirtual(pTab) || withoutRowid ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid); + }else{ + sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc); + appendFlag = 1; + } + autoIncStep(pParse, regAutoinc, regRowid); + + /* Compute data for all columns of the new entry, beginning + ** with the first column. + */ + nHidden = 0; + for(i=0; inCol; i++){ + int iRegStore = regRowid+1+i; + if( i==pTab->iPKey ){ + /* The value of the INTEGER PRIMARY KEY column is always a NULL. + ** Whenever this column is read, the rowid will be substituted + ** in its place. Hence, fill this column with a NULL to avoid + ** taking up data space with information that will never be used. + ** As there may be shallow copies of this value, make it a soft-NULL */ + sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore); + continue; + } + if( pColumn==0 ){ + if( IsHiddenColumn(&pTab->aCol[i]) ){ + assert( IsVirtual(pTab) ); + j = -1; + nHidden++; + }else{ + j = i - nHidden; + } + }else{ + for(j=0; jnId; j++){ + if( pColumn->a[j].idx==i ) break; + } + } + if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){ + sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore); + }else if( useTempTable ){ + sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, iRegStore); + }else if( pSelect ){ + if( regFromSelect!=regData ){ + sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+j, iRegStore); + } + }else{ + sqlite3ExprCode(pParse, pList->a[j].pExpr, iRegStore); + } + } + + /* Generate code to check constraints and generate index keys and + ** do the insertion. + */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); + sqlite3VtabMakeWritable(pParse, pTab); + sqlite3VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, regIns, pVTab, P4_VTAB); + sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError); + sqlite3MayAbort(pParse); + }else +#endif + { + int isReplace; /* Set to true if constraints may cause a replace */ + sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, + regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace + ); + sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0); + sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur, + regIns, aRegIdx, 0, appendFlag, isReplace==0); + } + } + + /* Update the count of rows that are inserted + */ + if( (db->flags & SQLITE_CountRows)!=0 ){ + sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); + } + + if( pTrigger ){ + /* Code AFTER triggers */ + sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER, + pTab, regData-2-pTab->nCol, onError, endOfLoop); + } + + /* The bottom of the main insertion loop, if the data source + ** is a SELECT statement. + */ + sqlite3VdbeResolveLabel(v, endOfLoop); + if( useTempTable ){ + sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addrInsTop); + sqlite3VdbeAddOp1(v, OP_Close, srcTab); + }else if( pSelect ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrCont); + sqlite3VdbeJumpHere(v, addrInsTop); + } + + if( !IsVirtual(pTab) && !isView ){ + /* Close all tables opened */ + if( iDataCurpIndex; pIdx; pIdx=pIdx->pNext, idx++){ + sqlite3VdbeAddOp1(v, OP_Close, idx+iIdxCur); + } + } + +insert_end: + /* Update the sqlite_sequence table by storing the content of the + ** maximum rowid counter values recorded while inserting into + ** autoincrement tables. + */ + if( pParse->nested==0 && pParse->pTriggerTab==0 ){ + sqlite3AutoincrementEnd(pParse); + } + + /* + ** 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 && !pParse->pTriggerTab ){ + sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC); + } + +insert_cleanup: + sqlite3SrcListDelete(db, pTabList); + sqlite3ExprListDelete(db, pList); + sqlite3SelectDelete(db, pSelect); + sqlite3IdListDelete(db, pColumn); + sqlite3DbFree(db, aRegIdx); +} + +/* Make sure "isView" and other macros defined above are undefined. Otherwise +** they may interfere with compilation of other functions in this file +** (or in another file, if this file becomes part of the amalgamation). */ +#ifdef isView + #undef isView +#endif +#ifdef pTrigger + #undef pTrigger +#endif +#ifdef tmask + #undef tmask +#endif + +/* +** Generate code to do constraint checks prior to an INSERT or an UPDATE +** on table pTab. +** +** The regNewData parameter is the first register in a range that contains +** the data to be inserted or the data after the update. There will be +** pTab->nCol+1 registers in this range. The first register (the one +** that regNewData points to) will contain the new rowid, or NULL in the +** case of a WITHOUT ROWID table. The second register in the range will +** contain the content of the first table column. The third register will +** contain the content of the second table column. And so forth. +** +** The regOldData parameter is similar to regNewData except that it contains +** the data prior to an UPDATE rather than afterwards. regOldData is zero +** for an INSERT. This routine can distinguish between UPDATE and INSERT by +** checking regOldData for zero. +** +** For an UPDATE, the pkChng boolean is true if the true primary key (the +** rowid for a normal table or the PRIMARY KEY for a WITHOUT ROWID table) +** might be modified by the UPDATE. If pkChng is false, then the key of +** the iDataCur content table is guaranteed to be unchanged by the UPDATE. +** +** For an INSERT, the pkChng boolean indicates whether or not the rowid +** was explicitly specified as part of the INSERT statement. If pkChng +** is zero, it means that the either rowid is computed automatically or +** that the table is a WITHOUT ROWID table and has no rowid. On an INSERT, +** pkChng will only be true if the INSERT statement provides an integer +** value for either the rowid column or its INTEGER PRIMARY KEY alias. +** +** The code generated by this routine will store new index entries into +** registers identified by aRegIdx[]. No index entry is created for +** indices where aRegIdx[i]==0. The order of indices in aRegIdx[] is +** the same as the order of indices on the linked list of indices +** at pTab->pIndex. +** +** The caller must have already opened writeable cursors on the main +** table and all applicable indices (that is to say, all indices for which +** aRegIdx[] is not zero). iDataCur is the cursor for the main table when +** inserting or updating a rowid table, or the cursor for the PRIMARY KEY +** index when operating on a WITHOUT ROWID table. iIdxCur is the cursor +** for the first index in the pTab->pIndex list. Cursors for other indices +** are at iIdxCur+N for the N-th element of the pTab->pIndex list. +** +** This routine also generates code to check constraints. NOT NULL, +** CHECK, and UNIQUE constraints are all checked. If a constraint fails, +** then the appropriate action is performed. There are five possible +** actions: ROLLBACK, ABORT, FAIL, REPLACE, and IGNORE. +** +** Constraint type Action What Happens +** --------------- ---------- ---------------------------------------- +** any ROLLBACK The current transaction is rolled back and +** sqlite3_step() returns immediately with a +** return code of SQLITE_CONSTRAINT. +** +** any ABORT Back out changes from the current command +** only (do not do a complete rollback) then +** cause sqlite3_step() to return immediately +** with SQLITE_CONSTRAINT. +** +** any FAIL Sqlite3_step() returns immediately with a +** return code of SQLITE_CONSTRAINT. The +** transaction is not rolled back and any +** changes to prior rows are retained. +** +** any IGNORE The attempt in insert or update the current +** row is skipped, without throwing an error. +** Processing continues with the next row. +** (There is an immediate jump to ignoreDest.) +** +** NOT NULL REPLACE The NULL value is replace by the default +** value for that column. If the default value +** is NULL, the action is the same as ABORT. +** +** UNIQUE REPLACE The other row that conflicts with the row +** being inserted is removed. +** +** CHECK REPLACE Illegal. The results in an exception. +** +** Which action to take is determined by the overrideError parameter. +** Or if overrideError==OE_Default, then the pParse->onError parameter +** is used. Or if pParse->onError==OE_Default then the onError value +** for the constraint is used. +*/ +SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( + Parse *pParse, /* The parser context */ + Table *pTab, /* The table being inserted or updated */ + int *aRegIdx, /* Use register aRegIdx[i] for index i. 0 for unused */ + int iDataCur, /* Canonical data cursor (main table or PK index) */ + int iIdxCur, /* First index cursor */ + int regNewData, /* First register in a range holding values to insert */ + int regOldData, /* Previous content. 0 for INSERTs */ + u8 pkChng, /* Non-zero if the rowid or PRIMARY KEY changed */ + u8 overrideError, /* Override onError to this if not OE_Default */ + int ignoreDest, /* Jump to this label on an OE_Ignore resolution */ + int *pbMayReplace /* OUT: Set to true if constraint may cause a replace */ +){ + Vdbe *v; /* VDBE under constrution */ + Index *pIdx; /* Pointer to one of the indices */ + Index *pPk = 0; /* The PRIMARY KEY index */ + sqlite3 *db; /* Database connection */ + int i; /* loop counter */ + int ix; /* Index loop counter */ + int nCol; /* Number of columns */ + int onError; /* Conflict resolution strategy */ + int j1; /* Address of jump instruction */ + int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */ + int nPkField; /* Number of fields in PRIMARY KEY. 1 for ROWID tables */ + int ipkTop = 0; /* Top of the rowid change constraint check */ + int ipkBottom = 0; /* Bottom of the rowid change constraint check */ + u8 isUpdate; /* True if this is an UPDATE operation */ + u8 bAffinityDone = 0; /* True if the OP_Affinity operation has been run */ + int regRowid = -1; /* Register holding ROWID value */ + + isUpdate = regOldData!=0; + db = pParse->db; + v = sqlite3GetVdbe(pParse); + assert( v!=0 ); + assert( pTab->pSelect==0 ); /* This table is not a VIEW */ + nCol = pTab->nCol; + + /* pPk is the PRIMARY KEY index for WITHOUT ROWID tables and NULL for + ** normal rowid tables. nPkField is the number of key fields in the + ** pPk index or 1 for a rowid table. In other words, nPkField is the + ** number of fields in the true primary key of the table. */ + if( HasRowid(pTab) ){ + pPk = 0; + nPkField = 1; + }else{ + pPk = sqlite3PrimaryKeyIndex(pTab); + nPkField = pPk->nKeyCol; + } + + /* Record that this module has started */ + VdbeModuleComment((v, "BEGIN: GenCnstCks(%d,%d,%d,%d,%d)", + iDataCur, iIdxCur, regNewData, regOldData, pkChng)); + + /* Test all NOT NULL constraints. + */ + for(i=0; iiPKey ){ + continue; + } + onError = pTab->aCol[i].notNull; + if( onError==OE_None ) continue; + if( overrideError!=OE_Default ){ + onError = overrideError; + }else if( onError==OE_Default ){ + onError = OE_Abort; + } + if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){ + onError = OE_Abort; + } + assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail + || onError==OE_Ignore || onError==OE_Replace ); + switch( onError ){ + case OE_Abort: + sqlite3MayAbort(pParse); + /* Fall through */ + case OE_Rollback: + case OE_Fail: { + char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName, + pTab->aCol[i].zName); + sqlite3VdbeAddOp4(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError, + regNewData+1+i, zMsg, P4_DYNAMIC); + sqlite3VdbeChangeP5(v, P5_ConstraintNotNull); + VdbeCoverage(v); + break; + } + case OE_Ignore: { + sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest); + VdbeCoverage(v); + break; + } + default: { + assert( onError==OE_Replace ); + j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i); VdbeCoverage(v); + sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i); + sqlite3VdbeJumpHere(v, j1); + break; + } + } + } + + /* Test all CHECK constraints + */ +#ifndef SQLITE_OMIT_CHECK + if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){ + ExprList *pCheck = pTab->pCheck; + pParse->ckBase = regNewData+1; + onError = overrideError!=OE_Default ? overrideError : OE_Abort; + for(i=0; inExpr; i++){ + int allOk = sqlite3VdbeMakeLabel(v); + sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL); + if( onError==OE_Ignore ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest); + }else{ + char *zName = pCheck->a[i].zName; + if( zName==0 ) zName = pTab->zName; + if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */ + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK, + onError, zName, P4_TRANSIENT, + P5_ConstraintCheck); + } + sqlite3VdbeResolveLabel(v, allOk); + } + } +#endif /* !defined(SQLITE_OMIT_CHECK) */ + + /* If rowid is changing, make sure the new rowid does not previously + ** exist in the table. + */ + if( pkChng && pPk==0 ){ + int addrRowidOk = sqlite3VdbeMakeLabel(v); + + /* Figure out what action to take in case of a rowid collision */ + onError = pTab->keyConf; + if( overrideError!=OE_Default ){ + onError = overrideError; + }else if( onError==OE_Default ){ + onError = OE_Abort; + } + + if( isUpdate ){ + /* pkChng!=0 does not mean that the rowid has change, only that + ** it might have changed. Skip the conflict logic below if the rowid + ** is unchanged. */ + sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + VdbeCoverage(v); + } + + /* If the response to a rowid conflict is REPLACE but the response + ** to some other UNIQUE constraint is FAIL or IGNORE, then we need + ** to defer the running of the rowid conflict checking until after + ** the UNIQUE constraints have run. + */ + if( onError==OE_Replace && overrideError!=OE_Replace ){ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->onError==OE_Ignore || pIdx->onError==OE_Fail ){ + ipkTop = sqlite3VdbeAddOp0(v, OP_Goto); + break; + } + } + } + + /* Check to see if the new rowid already exists in the table. Skip + ** the following conflict logic if it does not. */ + sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData); + VdbeCoverage(v); + + /* Generate code that deals with a rowid collision */ + switch( onError ){ + default: { + onError = OE_Abort; + /* Fall thru into the next case */ + } + case OE_Rollback: + case OE_Abort: + case OE_Fail: { + sqlite3RowidConstraint(pParse, onError, pTab); + break; + } + case OE_Replace: { + /* If there are DELETE triggers on this table and the + ** recursive-triggers flag is set, call GenerateRowDelete() to + ** remove the conflicting row from the table. This will fire + ** the triggers and remove both the table and index b-tree entries. + ** + ** Otherwise, if there are no triggers or the recursive-triggers + ** flag is not set, but the table has one or more indexes, call + ** GenerateRowIndexDelete(). This removes the index b-tree entries + ** only. The table b-tree entry will be replaced by the new entry + ** when it is inserted. + ** + ** If either GenerateRowDelete() or GenerateRowIndexDelete() is called, + ** also invoke MultiWrite() to indicate that this VDBE may require + ** statement rollback (if the statement is aborted after the delete + ** takes place). Earlier versions called sqlite3MultiWrite() regardless, + ** but being more selective here allows statements like: + ** + ** REPLACE INTO t(rowid) VALUES($newrowid) + ** + ** to run without a statement journal if there are no indexes on the + ** table. + */ + Trigger *pTrigger = 0; + if( db->flags&SQLITE_RecTriggers ){ + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); + } + if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){ + sqlite3MultiWrite(pParse); + sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, + regNewData, 1, 0, OE_Replace, 1); + }else if( pTab->pIndex ){ + sqlite3MultiWrite(pParse); + sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, 0); + } + seenReplace = 1; + break; + } + case OE_Ignore: { + /*assert( seenReplace==0 );*/ + sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest); + break; + } + } + sqlite3VdbeResolveLabel(v, addrRowidOk); + if( ipkTop ){ + ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto); + sqlite3VdbeJumpHere(v, ipkTop); + } + } + + /* Test all UNIQUE constraints by creating entries for each UNIQUE + ** index and making sure that duplicate entries do not already exist. + ** Compute the revised record entries for indices as we go. + ** + ** This loop also handles the case of the PRIMARY KEY index for a + ** WITHOUT ROWID table. + */ + for(ix=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, ix++){ + int regIdx; /* Range of registers hold conent for pIdx */ + int regR; /* Range of registers holding conflicting PK */ + int iThisCur; /* Cursor for this UNIQUE index */ + int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */ + + if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */ + if( bAffinityDone==0 ){ + sqlite3TableAffinity(v, pTab, regNewData+1); + bAffinityDone = 1; + } + iThisCur = iIdxCur+ix; + addrUniqueOk = sqlite3VdbeMakeLabel(v); + + /* Skip partial indices for which the WHERE clause is not true */ + if( pIdx->pPartIdxWhere ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[ix]); + pParse->ckBase = regNewData+1; + sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, addrUniqueOk, + SQLITE_JUMPIFNULL); + pParse->ckBase = 0; + } + + /* Create a record for this index entry as it should appear after + ** the insert or update. Store that record in the aRegIdx[ix] register + */ + regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn); + for(i=0; inColumn; i++){ + int iField = pIdx->aiColumn[i]; + int x; + if( iField<0 || iField==pTab->iPKey ){ + if( regRowid==regIdx+i ) continue; /* ROWID already in regIdx+i */ + x = regNewData; + regRowid = pIdx->pPartIdxWhere ? -1 : regIdx+i; + }else{ + x = iField + regNewData + 1; + } + sqlite3VdbeAddOp2(v, OP_SCopy, x, regIdx+i); + VdbeComment((v, "%s", iField<0 ? "rowid" : pTab->aCol[iField].zName)); + } + sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]); + VdbeComment((v, "for %s", pIdx->zName)); + sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn); + + /* In an UPDATE operation, if this index is the PRIMARY KEY index + ** of a WITHOUT ROWID table and there has been no change the + ** primary key, then no collision is possible. The collision detection + ** logic below can all be skipped. */ + if( isUpdate && pPk==pIdx && pkChng==0 ){ + sqlite3VdbeResolveLabel(v, addrUniqueOk); + continue; + } + + /* Find out what action to take in case there is a uniqueness conflict */ + onError = pIdx->onError; + if( onError==OE_None ){ + sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn); + sqlite3VdbeResolveLabel(v, addrUniqueOk); + continue; /* pIdx is not a UNIQUE index */ + } + if( overrideError!=OE_Default ){ + onError = overrideError; + }else if( onError==OE_Default ){ + onError = OE_Abort; + } + + /* Check to see if the new index entry will be unique */ + sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk, + regIdx, pIdx->nKeyCol); VdbeCoverage(v); + + /* Generate code to handle collisions */ + regR = (pIdx==pPk) ? regIdx : sqlite3GetTempRange(pParse, nPkField); + if( isUpdate || onError==OE_Replace ){ + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR); + /* Conflict only if the rowid of the existing index entry + ** is different from old-rowid */ + if( isUpdate ){ + sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + VdbeCoverage(v); + } + }else{ + int x; + /* Extract the PRIMARY KEY from the end of the index entry and + ** store it in registers regR..regR+nPk-1 */ + if( pIdx!=pPk ){ + for(i=0; inKeyCol; i++){ + x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]); + sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i); + VdbeComment((v, "%s.%s", pTab->zName, + pTab->aCol[pPk->aiColumn[i]].zName)); + } + } + if( isUpdate ){ + /* If currently processing the PRIMARY KEY of a WITHOUT ROWID + ** table, only conflict if the new PRIMARY KEY values are actually + ** different from the old. + ** + ** For a UNIQUE index, only conflict if the PRIMARY KEY values + ** of the matched index row are different from the original PRIMARY + ** KEY values of this row before the update. */ + int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol; + int op = OP_Ne; + int regCmp = (IsPrimaryKeyIndex(pIdx) ? regIdx : regR); + + for(i=0; inKeyCol; i++){ + char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]); + x = pPk->aiColumn[i]; + if( i==(pPk->nKeyCol-1) ){ + addrJump = addrUniqueOk; + op = OP_Eq; + } + sqlite3VdbeAddOp4(v, op, + regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ + ); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + VdbeCoverageIf(v, op==OP_Eq); + VdbeCoverageIf(v, op==OP_Ne); + } + } + } + } + + /* 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: + case OE_Abort: + case OE_Fail: { + sqlite3UniqueConstraint(pParse, onError, pIdx); + break; + } + case OE_Ignore: { + sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest); + break; + } + default: { + Trigger *pTrigger = 0; + assert( onError==OE_Replace ); + sqlite3MultiWrite(pParse); + if( db->flags&SQLITE_RecTriggers ){ + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); + } + sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, + regR, nPkField, 0, OE_Replace, pIdx==pPk); + seenReplace = 1; + break; + } + } + sqlite3VdbeResolveLabel(v, addrUniqueOk); + sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn); + if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField); + } + if( ipkTop ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, ipkTop+1); + sqlite3VdbeJumpHere(v, ipkBottom); + } + + *pbMayReplace = seenReplace; + VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace)); +} + +/* +** This routine generates code to finish the INSERT or UPDATE operation +** that was started by a prior call to sqlite3GenerateConstraintChecks. +** A consecutive range of registers starting at regNewData contains the +** rowid and the content to be inserted. +** +** The arguments to this routine should be the same as the first six +** arguments to sqlite3GenerateConstraintChecks. +*/ +SQLITE_PRIVATE void sqlite3CompleteInsertion( + Parse *pParse, /* The parser context */ + Table *pTab, /* the table into which we are inserting */ + int iDataCur, /* Cursor of the canonical data source */ + int iIdxCur, /* First index cursor */ + int regNewData, /* Range of content */ + int *aRegIdx, /* Register used by each index. 0 for unused indices */ + int isUpdate, /* True for UPDATE, False for INSERT */ + int appendBias, /* True if this is likely to be an append */ + int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */ +){ + Vdbe *v; /* Prepared statements under construction */ + Index *pIdx; /* An index being inserted or updated */ + u8 pik_flags; /* flag values passed to the btree insert */ + int regData; /* Content registers (after the rowid) */ + int regRec; /* Register holding assembled record for the table */ + int i; /* Loop counter */ + u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */ + + v = sqlite3GetVdbe(pParse); + assert( v!=0 ); + assert( pTab->pSelect==0 ); /* This table is not a VIEW */ + for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ + if( aRegIdx[i]==0 ) continue; + bAffinityDone = 1; + if( pIdx->pPartIdxWhere ){ + sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + } + sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]); + pik_flags = 0; + if( useSeekResult ) pik_flags = OPFLAG_USESEEKRESULT; + if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ + assert( pParse->nested==0 ); + pik_flags |= OPFLAG_NCHANGE; + } + if( pik_flags ) sqlite3VdbeChangeP5(v, pik_flags); + } + if( !HasRowid(pTab) ) return; + regData = regNewData + 1; + regRec = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec); + if( !bAffinityDone ) sqlite3TableAffinity(v, pTab, 0); + sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol); + if( pParse->nested ){ + pik_flags = 0; + }else{ + pik_flags = OPFLAG_NCHANGE; + pik_flags |= (isUpdate?OPFLAG_ISUPDATE:OPFLAG_LASTROWID); + } + if( appendBias ){ + pik_flags |= OPFLAG_APPEND; + } + if( useSeekResult ){ + pik_flags |= OPFLAG_USESEEKRESULT; + } + sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, regRec, regNewData); + if( !pParse->nested ){ + sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT); + } + sqlite3VdbeChangeP5(v, pik_flags); +} + +/* +** Allocate cursors for the pTab table and all its indices and generate +** code to open and initialized those cursors. +** +** The cursor for the object that contains the complete data (normally +** the table itself, but the PRIMARY KEY index in the case of a WITHOUT +** ROWID table) is returned in *piDataCur. The first index cursor is +** returned in *piIdxCur. The number of indices is returned. +** +** Use iBase as the first cursor (either the *piDataCur for rowid tables +** or the first index for WITHOUT ROWID tables) if it is non-negative. +** If iBase is negative, then allocate the next available cursor. +** +** For a rowid table, *piDataCur will be exactly one less than *piIdxCur. +** For a WITHOUT ROWID table, *piDataCur will be somewhere in the range +** of *piIdxCurs, depending on where the PRIMARY KEY index appears on the +** pTab->pIndex list. +** +** If pTab is a virtual table, then this routine is a no-op and the +** *piDataCur and *piIdxCur values are left uninitialized. +*/ +SQLITE_PRIVATE int sqlite3OpenTableAndIndices( + Parse *pParse, /* Parsing context */ + Table *pTab, /* Table to be opened */ + int op, /* OP_OpenRead or OP_OpenWrite */ + int iBase, /* Use this for the table cursor, if there is one */ + u8 *aToOpen, /* If not NULL: boolean for each table and index */ + int *piDataCur, /* Write the database source cursor number here */ + int *piIdxCur /* Write the first index cursor number here */ +){ + int i; + int iDb; + int iDataCur; + Index *pIdx; + Vdbe *v; + + assert( op==OP_OpenRead || op==OP_OpenWrite ); + if( IsVirtual(pTab) ){ + /* This routine is a no-op for virtual tables. Leave the output + ** variables *piDataCur and *piIdxCur uninitialized so that valgrind + ** can detect if they are used by mistake in the caller. */ + return 0; + } + iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + v = sqlite3GetVdbe(pParse); + assert( v!=0 ); + if( iBase<0 ) iBase = pParse->nTab; + iDataCur = iBase++; + if( piDataCur ) *piDataCur = iDataCur; + if( HasRowid(pTab) && (aToOpen==0 || aToOpen[0]) ){ + sqlite3OpenTable(pParse, iDataCur, iDb, pTab, op); + }else{ + sqlite3TableLock(pParse, iDb, pTab->tnum, op==OP_OpenWrite, pTab->zName); + } + if( piIdxCur ) *piIdxCur = iBase; + for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ + int iIdxCur = iBase++; + assert( pIdx->pSchema==pTab->pSchema ); + if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) && piDataCur ){ + *piDataCur = iIdxCur; + } + if( aToOpen==0 || aToOpen[i+1] ){ + sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); + VdbeComment((v, "%s", pIdx->zName)); + } + } + if( iBase>pParse->nTab ) pParse->nTab = iBase; + return i; +} + + +#ifdef SQLITE_TEST +/* +** The following global variable is incremented whenever the +** transfer optimization is used. This is used for testing +** purposes only - to make sure the transfer optimization really +** is happening when it is supposed to. +*/ +SQLITE_API int sqlite3_xferopt_count; +#endif /* SQLITE_TEST */ + + +#ifndef SQLITE_OMIT_XFER_OPT +/* +** Check to collation names to see if they are compatible. +*/ +static int xferCompatibleCollation(const char *z1, const char *z2){ + if( z1==0 ){ + return z2==0; + } + if( z2==0 ){ + return 0; + } + return sqlite3StrICmp(z1, z2)==0; +} + + +/* +** Check to see if index pSrc is compatible as a source of data +** for index pDest in an insert transfer optimization. The rules +** for a compatible index: +** +** * The index is over the same set of columns +** * The same DESC and ASC markings occurs on all columns +** * The same onError processing (OE_Abort, OE_Ignore, etc) +** * The same collating sequence on each column +** * The index has the exact same WHERE clause +*/ +static int xferCompatibleIndex(Index *pDest, Index *pSrc){ + int i; + assert( pDest && pSrc ); + assert( pDest->pTable!=pSrc->pTable ); + if( pDest->nKeyCol!=pSrc->nKeyCol ){ + return 0; /* Different number of columns */ + } + if( pDest->onError!=pSrc->onError ){ + return 0; /* Different conflict resolution strategies */ + } + for(i=0; inKeyCol; i++){ + if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){ + return 0; /* Different columns indexed */ + } + if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){ + return 0; /* Different sort orders */ + } + if( !xferCompatibleCollation(pSrc->azColl[i],pDest->azColl[i]) ){ + return 0; /* Different collating sequences */ + } + } + if( sqlite3ExprCompare(pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){ + return 0; /* Different WHERE clauses */ + } + + /* If no test above fails then the indices must be compatible */ + return 1; +} + +/* +** Attempt the transfer optimization on INSERTs of the form +** +** INSERT INTO tab1 SELECT * FROM tab2; +** +** The xfer optimization transfers raw records from tab2 over to tab1. +** Columns are not decoded and reassembled, which greatly improves +** performance. Raw index records are transferred in the same way. +** +** The xfer optimization is only attempted if tab1 and tab2 are compatible. +** There are lots of rules for determining compatibility - see comments +** embedded in the code for details. +** +** This routine returns TRUE if the optimization is guaranteed to be used. +** Sometimes the xfer optimization will only work if the destination table +** is empty - a factor that can only be determined at run-time. In that +** case, this routine generates code for the xfer optimization but also +** does a test to see if the destination table is empty and jumps over the +** xfer optimization code if the test fails. In that case, this routine +** returns FALSE so that the caller will know to go ahead and generate +** an unoptimized transfer. This routine also returns FALSE if there +** is no chance that the xfer optimization can be applied. +** +** This optimization is particularly useful at making VACUUM run faster. +*/ +static int xferOptimization( + Parse *pParse, /* Parser context */ + Table *pDest, /* The table we are inserting into */ + Select *pSelect, /* A SELECT statement to use as the data source */ + int onError, /* How to handle constraint errors */ + int iDbDest /* The database of pDest */ +){ + sqlite3 *db = pParse->db; + ExprList *pEList; /* The result set of the SELECT */ + Table *pSrc; /* The table in the FROM clause of SELECT */ + Index *pSrcIdx, *pDestIdx; /* Source and destination indices */ + struct SrcList_item *pItem; /* An element of pSelect->pSrc */ + int i; /* Loop counter */ + int iDbSrc; /* The database of pSrc */ + int iSrc, iDest; /* Cursors from source and destination */ + int addr1, addr2; /* Loop addresses */ + int emptyDestTest = 0; /* Address of test for empty pDest */ + int emptySrcTest = 0; /* Address of test for empty pSrc */ + Vdbe *v; /* The VDBE we are building */ + int regAutoinc; /* Memory register used by AUTOINC */ + int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */ + int regData, regRowid; /* Registers holding data and rowid */ + + if( pSelect==0 ){ + return 0; /* Must be of the form INSERT INTO ... SELECT ... */ + } + if( pParse->pWith || pSelect->pWith ){ + /* Do not attempt to process this query if there are an WITH clauses + ** attached to it. Proceeding may generate a false "no such table: xxx" + ** error if pSelect reads from a CTE named "xxx". */ + return 0; + } + if( sqlite3TriggerList(pParse, pDest) ){ + return 0; /* tab1 must not have triggers */ + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( pDest->tabFlags & TF_Virtual ){ + return 0; /* tab1 must not be a virtual table */ + } +#endif + if( onError==OE_Default ){ + if( pDest->iPKey>=0 ) onError = pDest->keyConf; + if( onError==OE_Default ) onError = OE_Abort; + } + assert(pSelect->pSrc); /* allocated even if there is no FROM clause */ + if( pSelect->pSrc->nSrc!=1 ){ + return 0; /* FROM clause must have exactly one term */ + } + if( pSelect->pSrc->a[0].pSelect ){ + return 0; /* FROM clause cannot contain a subquery */ + } + if( pSelect->pWhere ){ + return 0; /* SELECT may not have a WHERE clause */ + } + if( pSelect->pOrderBy ){ + return 0; /* SELECT may not have an ORDER BY clause */ + } + /* Do not need to test for a HAVING clause. If HAVING is present but + ** there is no ORDER BY, we will get an error. */ + if( pSelect->pGroupBy ){ + return 0; /* SELECT may not have a GROUP BY clause */ + } + if( pSelect->pLimit ){ + return 0; /* SELECT may not have a LIMIT clause */ + } + assert( pSelect->pOffset==0 ); /* Must be so if pLimit==0 */ + if( pSelect->pPrior ){ + return 0; /* SELECT may not be a compound query */ + } + if( pSelect->selFlags & SF_Distinct ){ + return 0; /* SELECT may not be DISTINCT */ + } + pEList = pSelect->pEList; + assert( pEList!=0 ); + if( pEList->nExpr!=1 ){ + return 0; /* The result set must have exactly one column */ + } + assert( pEList->a[0].pExpr ); + if( pEList->a[0].pExpr->op!=TK_ALL ){ + return 0; /* The result set must be the special operator "*" */ + } + + /* At this point we have established that the statement is of the + ** correct syntactic form to participate in this optimization. Now + ** we have to check the semantics. + */ + pItem = pSelect->pSrc->a; + pSrc = sqlite3LocateTableItem(pParse, 0, pItem); + if( pSrc==0 ){ + return 0; /* FROM clause does not contain a real table */ + } + if( pSrc==pDest ){ + return 0; /* tab1 and tab2 may not be the same table */ + } + if( HasRowid(pDest)!=HasRowid(pSrc) ){ + return 0; /* source and destination must both be WITHOUT ROWID or not */ + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( pSrc->tabFlags & TF_Virtual ){ + return 0; /* tab2 must not be a virtual table */ + } +#endif + if( pSrc->pSelect ){ + return 0; /* tab2 may not be a view */ + } + if( pDest->nCol!=pSrc->nCol ){ + return 0; /* Number of columns must be the same in tab1 and tab2 */ + } + if( pDest->iPKey!=pSrc->iPKey ){ + return 0; /* Both tables must have the same INTEGER PRIMARY KEY */ + } + for(i=0; inCol; i++){ + Column *pDestCol = &pDest->aCol[i]; + Column *pSrcCol = &pSrc->aCol[i]; + if( pDestCol->affinity!=pSrcCol->affinity ){ + return 0; /* Affinity must be the same on all columns */ + } + if( !xferCompatibleCollation(pDestCol->zColl, pSrcCol->zColl) ){ + return 0; /* Collating sequence must be the same on all columns */ + } + if( pDestCol->notNull && !pSrcCol->notNull ){ + return 0; /* tab2 must be NOT NULL if tab1 is */ + } + /* Default values for second and subsequent columns need to match. */ + if( i>0 + && ((pDestCol->zDflt==0)!=(pSrcCol->zDflt==0) + || (pDestCol->zDflt && strcmp(pDestCol->zDflt, pSrcCol->zDflt)!=0)) + ){ + return 0; /* Default values must be the same for all columns */ + } + } + for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ + if( IsUniqueIndex(pDestIdx) ){ + destHasUniqueIdx = 1; + } + for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){ + if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; + } + if( pSrcIdx==0 ){ + return 0; /* pDestIdx has no corresponding index in pSrc */ + } + } +#ifndef SQLITE_OMIT_CHECK + if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){ + return 0; /* Tables have different CHECK constraints. Ticket #2252 */ + } +#endif +#ifndef SQLITE_OMIT_FOREIGN_KEY + /* Disallow the transfer optimization if the destination table constains + ** any foreign key constraints. This is more restrictive than necessary. + ** But the main beneficiary of the transfer optimization is the VACUUM + ** command, and the VACUUM command disables foreign key constraints. So + ** the extra complication to make this rule less restrictive is probably + ** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e] + */ + if( (db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){ + return 0; + } +#endif + if( (db->flags & SQLITE_CountRows)!=0 ){ + return 0; /* xfer opt does not play well with PRAGMA count_changes */ + } + + /* If we get this far, it means that the xfer optimization is at + ** least a possibility, though it might only work if the destination + ** table (tab1) is initially empty. + */ +#ifdef SQLITE_TEST + sqlite3_xferopt_count++; +#endif + iDbSrc = sqlite3SchemaToIndex(db, pSrc->pSchema); + v = sqlite3GetVdbe(pParse); + sqlite3CodeVerifySchema(pParse, iDbSrc); + iSrc = pParse->nTab++; + iDest = pParse->nTab++; + regAutoinc = autoIncBegin(pParse, iDbDest, pDest); + regData = sqlite3GetTempReg(pParse); + regRowid = sqlite3GetTempReg(pParse); + sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite); + assert( HasRowid(pDest) || destHasUniqueIdx ); + if( (db->flags & SQLITE_Vacuum)==0 && ( + (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */ + || destHasUniqueIdx /* (2) */ + || (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */ + )){ + /* In some circumstances, we are able to run the xfer optimization + ** only if the destination table is initially empty. Unless the + ** SQLITE_Vacuum flag is set, this block generates code to make + ** that determination. If SQLITE_Vacuum is set, then the destination + ** table is always empty. + ** + ** Conditions under which the destination must be empty: + ** + ** (1) There is no INTEGER PRIMARY KEY but there are indices. + ** (If the destination is not initially empty, the rowid fields + ** of index entries might need to change.) + ** + ** (2) The destination has a unique index. (The xfer optimization + ** is unable to test uniqueness.) + ** + ** (3) onError is something other than OE_Abort and OE_Rollback. + */ + addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0); VdbeCoverage(v); + emptyDestTest = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); + sqlite3VdbeJumpHere(v, addr1); + } + if( HasRowid(pSrc) ){ + sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead); + emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); + if( pDest->iPKey>=0 ){ + addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); + addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid); + VdbeCoverage(v); + sqlite3RowidConstraint(pParse, onError, pDest); + sqlite3VdbeJumpHere(v, addr2); + autoIncStep(pParse, regAutoinc, regRowid); + }else if( pDest->pIndex==0 ){ + addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid); + }else{ + addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); + assert( (pDest->tabFlags & TF_Autoincrement)==0 ); + } + sqlite3VdbeAddOp2(v, OP_RowData, iSrc, regData); + sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid); + sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND); + sqlite3VdbeChangeP4(v, -1, pDest->zName, 0); + sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); + sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); + }else{ + sqlite3TableLock(pParse, iDbDest, pDest->tnum, 1, pDest->zName); + sqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName); + } + for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ + u8 useSeekResult = 0; + for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){ + if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; + } + assert( pSrcIdx ); + sqlite3VdbeAddOp3(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc); + sqlite3VdbeSetP4KeyInfo(pParse, pSrcIdx); + VdbeComment((v, "%s", pSrcIdx->zName)); + sqlite3VdbeAddOp3(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest); + sqlite3VdbeSetP4KeyInfo(pParse, pDestIdx); + sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR); + VdbeComment((v, "%s", pDestIdx->zName)); + addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData); + if( db->flags & SQLITE_Vacuum ){ + /* This INSERT command is part of a VACUUM operation, which guarantees + ** that the destination table is empty. If all indexed columns use + ** collation sequence BINARY, then it can also be assumed that the + ** index will be populated by inserting keys in strictly sorted + ** order. In this case, instead of seeking within the b-tree as part + ** of every OP_IdxInsert opcode, an OP_Last is added before the + ** OP_IdxInsert to seek to the point within the b-tree where each key + ** should be inserted. This is faster. + ** + ** If any of the indexed columns use a collation sequence other than + ** BINARY, this optimization is disabled. This is because the user + ** might change the definition of a collation sequence and then run + ** a VACUUM command. In that case keys may not be written in strictly + ** sorted order. */ + for(i=0; inColumn; i++){ + char *zColl = pSrcIdx->azColl[i]; + assert( zColl!=0 ); + if( sqlite3_stricmp("BINARY", zColl) ) break; + } + if( i==pSrcIdx->nColumn ){ + useSeekResult = OPFLAG_USESEEKRESULT; + sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1); + } + } + sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1); + sqlite3VdbeChangeP5(v, useSeekResult); + sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr1); + sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); + sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); + } + if( emptySrcTest ) sqlite3VdbeJumpHere(v, emptySrcTest); + sqlite3ReleaseTempReg(pParse, regRowid); + sqlite3ReleaseTempReg(pParse, regData); + if( emptyDestTest ){ + sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0); + sqlite3VdbeJumpHere(v, emptyDestTest); + sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); + return 0; + }else{ + return 1; + } +} +#endif /* SQLITE_OMIT_XFER_OPT */ + +/************** End of insert.c **********************************************/ +/************** Begin file legacy.c ******************************************/ +/* +** 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. +** +************************************************************************* +** 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. +*/ + + +/* +** Execute SQL code. Return one of the SQLITE_ success/failure +** codes. Also write an error message into memory obtained from +** malloc() and make *pzErrMsg point to that message. +** +** If the SQL is a query, then for each row in the query result +** the xCallback() function is called. pArg becomes the first +** argument to xCallback(). If xCallback=NULL then no callback +** is invoked, even for queries. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_exec( + sqlite3 *db, /* The database on which the SQL executes */ + const char *zSql, /* The SQL to be executed */ + sqlite3_callback xCallback, /* Invoke this callback routine */ + void *pArg, /* First argument to xCallback() */ + char **pzErrMsg /* Write error messages here */ +){ + int rc = SQLITE_OK; /* Return code */ + const char *zLeftover; /* Tail of unprocessed SQL */ + sqlite3_stmt *pStmt = 0; /* The current SQL statement */ + char **azCols = 0; /* Names of result columns */ + int callbackIsInit; /* True if callback data is initialized */ + + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; + if( zSql==0 ) zSql = ""; + + sqlite3_mutex_enter(db->mutex); + sqlite3Error(db, SQLITE_OK); + while( rc==SQLITE_OK && zSql[0] ){ + int nCol; + char **azVals = 0; + + pStmt = 0; + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); + assert( rc==SQLITE_OK || pStmt==0 ); + if( rc!=SQLITE_OK ){ + continue; + } + if( !pStmt ){ + /* this happens for a comment or white-space */ + zSql = zLeftover; + continue; + } + + callbackIsInit = 0; + nCol = sqlite3_column_count(pStmt); + + while( 1 ){ + int i; + rc = sqlite3_step(pStmt); + + /* Invoke the callback function if required */ + if( xCallback && (SQLITE_ROW==rc || + (SQLITE_DONE==rc && !callbackIsInit + && db->flags&SQLITE_NullCallback)) ){ + if( !callbackIsInit ){ + azCols = sqlite3DbMallocZero(db, 2*nCol*sizeof(const char*) + 1); + if( azCols==0 ){ + goto exec_out; + } + for(i=0; imallocFailed = 1; + goto exec_out; + } + } + } + if( xCallback(pArg, nCol, azVals, azCols) ){ + /* EVIDENCE-OF: R-38229-40159 If the callback function to + ** sqlite3_exec() returns non-zero, then sqlite3_exec() will + ** return SQLITE_ABORT. */ + rc = SQLITE_ABORT; + sqlite3VdbeFinalize((Vdbe *)pStmt); + pStmt = 0; + sqlite3Error(db, SQLITE_ABORT); + goto exec_out; + } + } + + if( rc!=SQLITE_ROW ){ + rc = sqlite3VdbeFinalize((Vdbe *)pStmt); + pStmt = 0; + zSql = zLeftover; + while( sqlite3Isspace(zSql[0]) ) zSql++; + break; + } + } + + sqlite3DbFree(db, azCols); + azCols = 0; + } + +exec_out: + if( pStmt ) sqlite3VdbeFinalize((Vdbe *)pStmt); + sqlite3DbFree(db, azCols); + + rc = sqlite3ApiExit(db, rc); + if( rc!=SQLITE_OK && pzErrMsg ){ + int nErrMsg = 1 + sqlite3Strlen30(sqlite3_errmsg(db)); + *pzErrMsg = sqlite3Malloc(nErrMsg); + if( *pzErrMsg ){ + memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg); + }else{ + rc = SQLITE_NOMEM; + sqlite3Error(db, SQLITE_NOMEM); + } + }else if( pzErrMsg ){ + *pzErrMsg = 0; + } + + assert( (rc&db->errMask)==rc ); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/************** End of legacy.c **********************************************/ +/************** Begin file loadext.c *****************************************/ +/* +** 2006 June 7 +** +** 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 dynamically load extensions into +** the SQLite library. +*/ + +#ifndef SQLITE_CORE + #define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */ +#endif +/************** Include sqlite3ext.h in the middle of loadext.c **************/ +/************** Begin file sqlite3ext.h **************************************/ +/* +** 2006 June 7 +** +** 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 the SQLite interface for use by +** shared libraries that want to be imported as extensions into +** an SQLite instance. Shared libraries that intend to be loaded +** as extensions by SQLite should #include this file instead of +** sqlite3.h. +*/ +#ifndef _SQLITE3EXT_H_ +#define _SQLITE3EXT_H_ + +typedef struct sqlite3_api_routines sqlite3_api_routines; + +/* +** The following structure holds pointers to all of the SQLite API +** routines. +** +** WARNING: In order to maintain backwards compatibility, add new +** interfaces to the end of this structure only. If you insert new +** interfaces in the middle of this structure, then older different +** versions of SQLite will not be able to load each other's shared +** libraries! +*/ +struct sqlite3_api_routines { + void * (*aggregate_context)(sqlite3_context*,int nBytes); + int (*aggregate_count)(sqlite3_context*); + int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*)); + int (*bind_double)(sqlite3_stmt*,int,double); + int (*bind_int)(sqlite3_stmt*,int,int); + int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64); + int (*bind_null)(sqlite3_stmt*,int); + int (*bind_parameter_count)(sqlite3_stmt*); + int (*bind_parameter_index)(sqlite3_stmt*,const char*zName); + const char * (*bind_parameter_name)(sqlite3_stmt*,int); + int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*)); + int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*)); + int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*); + int (*busy_handler)(sqlite3*,int(*)(void*,int),void*); + int (*busy_timeout)(sqlite3*,int ms); + int (*changes)(sqlite3*); + int (*close)(sqlite3*); + int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*, + int eTextRep,const char*)); + int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*, + int eTextRep,const void*)); + const void * (*column_blob)(sqlite3_stmt*,int iCol); + int (*column_bytes)(sqlite3_stmt*,int iCol); + int (*column_bytes16)(sqlite3_stmt*,int iCol); + int (*column_count)(sqlite3_stmt*pStmt); + const char * (*column_database_name)(sqlite3_stmt*,int); + const void * (*column_database_name16)(sqlite3_stmt*,int); + const char * (*column_decltype)(sqlite3_stmt*,int i); + const void * (*column_decltype16)(sqlite3_stmt*,int); + double (*column_double)(sqlite3_stmt*,int iCol); + int (*column_int)(sqlite3_stmt*,int iCol); + sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol); + const char * (*column_name)(sqlite3_stmt*,int); + const void * (*column_name16)(sqlite3_stmt*,int); + const char * (*column_origin_name)(sqlite3_stmt*,int); + const void * (*column_origin_name16)(sqlite3_stmt*,int); + const char * (*column_table_name)(sqlite3_stmt*,int); + const void * (*column_table_name16)(sqlite3_stmt*,int); + const unsigned char * (*column_text)(sqlite3_stmt*,int iCol); + const void * (*column_text16)(sqlite3_stmt*,int iCol); + int (*column_type)(sqlite3_stmt*,int iCol); + sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol); + void * (*commit_hook)(sqlite3*,int(*)(void*),void*); + int (*complete)(const char*sql); + int (*complete16)(const void*sql); + int (*create_collation)(sqlite3*,const char*,int,void*, + int(*)(void*,int,const void*,int,const void*)); + int (*create_collation16)(sqlite3*,const void*,int,void*, + int(*)(void*,int,const void*,int,const void*)); + int (*create_function)(sqlite3*,const char*,int,int,void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*)); + int (*create_function16)(sqlite3*,const void*,int,int,void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*)); + int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*); + int (*data_count)(sqlite3_stmt*pStmt); + sqlite3 * (*db_handle)(sqlite3_stmt*); + int (*declare_vtab)(sqlite3*,const char*); + int (*enable_shared_cache)(int); + int (*errcode)(sqlite3*db); + const char * (*errmsg)(sqlite3*); + const void * (*errmsg16)(sqlite3*); + int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**); + int (*expired)(sqlite3_stmt*); + int (*finalize)(sqlite3_stmt*pStmt); + void (*free)(void*); + void (*free_table)(char**result); + int (*get_autocommit)(sqlite3*); + void * (*get_auxdata)(sqlite3_context*,int); + int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**); + int (*global_recover)(void); + void (*interruptx)(sqlite3*); + sqlite_int64 (*last_insert_rowid)(sqlite3*); + const char * (*libversion)(void); + int (*libversion_number)(void); + void *(*malloc)(int); + char * (*mprintf)(const char*,...); + int (*open)(const char*,sqlite3**); + int (*open16)(const void*,sqlite3**); + int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); + int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); + void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*); + void (*progress_handler)(sqlite3*,int,int(*)(void*),void*); + void *(*realloc)(void*,int); + int (*reset)(sqlite3_stmt*pStmt); + void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_double)(sqlite3_context*,double); + void (*result_error)(sqlite3_context*,const char*,int); + void (*result_error16)(sqlite3_context*,const void*,int); + void (*result_int)(sqlite3_context*,int); + void (*result_int64)(sqlite3_context*,sqlite_int64); + void (*result_null)(sqlite3_context*); + void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*)); + void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_value)(sqlite3_context*,sqlite3_value*); + void * (*rollback_hook)(sqlite3*,void(*)(void*),void*); + int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*, + const char*,const char*),void*); + void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*)); + char * (*snprintf)(int,char*,const char*,...); + int (*step)(sqlite3_stmt*); + int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*, + char const**,char const**,int*,int*,int*); + void (*thread_cleanup)(void); + int (*total_changes)(sqlite3*); + void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*); + int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*); + void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*, + sqlite_int64),void*); + void * (*user_data)(sqlite3_context*); + const void * (*value_blob)(sqlite3_value*); + int (*value_bytes)(sqlite3_value*); + int (*value_bytes16)(sqlite3_value*); + double (*value_double)(sqlite3_value*); + int (*value_int)(sqlite3_value*); + sqlite_int64 (*value_int64)(sqlite3_value*); + int (*value_numeric_type)(sqlite3_value*); + const unsigned char * (*value_text)(sqlite3_value*); + const void * (*value_text16)(sqlite3_value*); + const void * (*value_text16be)(sqlite3_value*); + const void * (*value_text16le)(sqlite3_value*); + int (*value_type)(sqlite3_value*); + char *(*vmprintf)(const char*,va_list); + /* Added ??? */ + int (*overload_function)(sqlite3*, const char *zFuncName, int nArg); + /* Added by 3.3.13 */ + int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); + int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); + int (*clear_bindings)(sqlite3_stmt*); + /* Added by 3.4.1 */ + int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*, + void (*xDestroy)(void *)); + /* Added by 3.5.0 */ + int (*bind_zeroblob)(sqlite3_stmt*,int,int); + int (*blob_bytes)(sqlite3_blob*); + int (*blob_close)(sqlite3_blob*); + int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64, + int,sqlite3_blob**); + int (*blob_read)(sqlite3_blob*,void*,int,int); + int (*blob_write)(sqlite3_blob*,const void*,int,int); + int (*create_collation_v2)(sqlite3*,const char*,int,void*, + int(*)(void*,int,const void*,int,const void*), + void(*)(void*)); + int (*file_control)(sqlite3*,const char*,int,void*); + sqlite3_int64 (*memory_highwater)(int); + sqlite3_int64 (*memory_used)(void); + sqlite3_mutex *(*mutex_alloc)(int); + void (*mutex_enter)(sqlite3_mutex*); + void (*mutex_free)(sqlite3_mutex*); + void (*mutex_leave)(sqlite3_mutex*); + int (*mutex_try)(sqlite3_mutex*); + int (*open_v2)(const char*,sqlite3**,int,const char*); + int (*release_memory)(int); + void (*result_error_nomem)(sqlite3_context*); + void (*result_error_toobig)(sqlite3_context*); + int (*sleep)(int); + void (*soft_heap_limit)(int); + sqlite3_vfs *(*vfs_find)(const char*); + int (*vfs_register)(sqlite3_vfs*,int); + int (*vfs_unregister)(sqlite3_vfs*); + int (*xthreadsafe)(void); + void (*result_zeroblob)(sqlite3_context*,int); + void (*result_error_code)(sqlite3_context*,int); + int (*test_control)(int, ...); + void (*randomness)(int,void*); + sqlite3 *(*context_db_handle)(sqlite3_context*); + int (*extended_result_codes)(sqlite3*,int); + int (*limit)(sqlite3*,int,int); + sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*); + const char *(*sql)(sqlite3_stmt*); + int (*status)(int,int*,int*,int); + int (*backup_finish)(sqlite3_backup*); + sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*); + int (*backup_pagecount)(sqlite3_backup*); + int (*backup_remaining)(sqlite3_backup*); + int (*backup_step)(sqlite3_backup*,int); + const char *(*compileoption_get)(int); + int (*compileoption_used)(const char*); + int (*create_function_v2)(sqlite3*,const char*,int,int,void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void(*xDestroy)(void*)); + int (*db_config)(sqlite3*,int,...); + sqlite3_mutex *(*db_mutex)(sqlite3*); + int (*db_status)(sqlite3*,int,int*,int*,int); + int (*extended_errcode)(sqlite3*); + void (*log)(int,const char*,...); + sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64); + const char *(*sourceid)(void); + int (*stmt_status)(sqlite3_stmt*,int,int); + int (*strnicmp)(const char*,const char*,int); + int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*); + int (*wal_autocheckpoint)(sqlite3*,int); + int (*wal_checkpoint)(sqlite3*,const char*); + void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*); + int (*blob_reopen)(sqlite3_blob*,sqlite3_int64); + int (*vtab_config)(sqlite3*,int op,...); + int (*vtab_on_conflict)(sqlite3*); + /* Version 3.7.16 and later */ + int (*close_v2)(sqlite3*); + const char *(*db_filename)(sqlite3*,const char*); + int (*db_readonly)(sqlite3*,const char*); + int (*db_release_memory)(sqlite3*); + const char *(*errstr)(int); + int (*stmt_busy)(sqlite3_stmt*); + int (*stmt_readonly)(sqlite3_stmt*); + int (*stricmp)(const char*,const char*); + int (*uri_boolean)(const char*,const char*,int); + sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64); + const char *(*uri_parameter)(const char*,const char*); + char *(*vsnprintf)(int,char*,const char*,va_list); + int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*); + /* Version 3.8.7 and later */ + int (*auto_extension)(void(*)(void)); + int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64, + void(*)(void*)); + int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64, + void(*)(void*),unsigned char); + int (*cancel_auto_extension)(void(*)(void)); + int (*load_extension)(sqlite3*,const char*,const char*,char**); + void *(*malloc64)(sqlite3_uint64); + sqlite3_uint64 (*msize)(void*); + void *(*realloc64)(void*,sqlite3_uint64); + void (*reset_auto_extension)(void); + void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64, + void(*)(void*)); + void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64, + void(*)(void*), unsigned char); + int (*strglob)(const char*,const char*); +}; + +/* +** The following macros redefine the API routines so that they are +** redirected through the global sqlite3_api structure. +** +** This header file is also used by the loadext.c source file +** (part of the main SQLite library - not an extension) so that +** it can get access to the sqlite3_api_routines structure +** definition. But the main library does not want to redefine +** the API. So the redefinition macros are only valid if the +** SQLITE_CORE macros is undefined. +*/ +#ifndef SQLITE_CORE +#define sqlite3_aggregate_context sqlite3_api->aggregate_context +#ifndef SQLITE_OMIT_DEPRECATED +#define sqlite3_aggregate_count sqlite3_api->aggregate_count +#endif +#define sqlite3_bind_blob sqlite3_api->bind_blob +#define sqlite3_bind_double sqlite3_api->bind_double +#define sqlite3_bind_int sqlite3_api->bind_int +#define sqlite3_bind_int64 sqlite3_api->bind_int64 +#define sqlite3_bind_null sqlite3_api->bind_null +#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count +#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index +#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name +#define sqlite3_bind_text sqlite3_api->bind_text +#define sqlite3_bind_text16 sqlite3_api->bind_text16 +#define sqlite3_bind_value sqlite3_api->bind_value +#define sqlite3_busy_handler sqlite3_api->busy_handler +#define sqlite3_busy_timeout sqlite3_api->busy_timeout +#define sqlite3_changes sqlite3_api->changes +#define sqlite3_close sqlite3_api->close +#define sqlite3_collation_needed sqlite3_api->collation_needed +#define sqlite3_collation_needed16 sqlite3_api->collation_needed16 +#define sqlite3_column_blob sqlite3_api->column_blob +#define sqlite3_column_bytes sqlite3_api->column_bytes +#define sqlite3_column_bytes16 sqlite3_api->column_bytes16 +#define sqlite3_column_count sqlite3_api->column_count +#define sqlite3_column_database_name sqlite3_api->column_database_name +#define sqlite3_column_database_name16 sqlite3_api->column_database_name16 +#define sqlite3_column_decltype sqlite3_api->column_decltype +#define sqlite3_column_decltype16 sqlite3_api->column_decltype16 +#define sqlite3_column_double sqlite3_api->column_double +#define sqlite3_column_int sqlite3_api->column_int +#define sqlite3_column_int64 sqlite3_api->column_int64 +#define sqlite3_column_name sqlite3_api->column_name +#define sqlite3_column_name16 sqlite3_api->column_name16 +#define sqlite3_column_origin_name sqlite3_api->column_origin_name +#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16 +#define sqlite3_column_table_name sqlite3_api->column_table_name +#define sqlite3_column_table_name16 sqlite3_api->column_table_name16 +#define sqlite3_column_text sqlite3_api->column_text +#define sqlite3_column_text16 sqlite3_api->column_text16 +#define sqlite3_column_type sqlite3_api->column_type +#define sqlite3_column_value sqlite3_api->column_value +#define sqlite3_commit_hook sqlite3_api->commit_hook +#define sqlite3_complete sqlite3_api->complete +#define sqlite3_complete16 sqlite3_api->complete16 +#define sqlite3_create_collation sqlite3_api->create_collation +#define sqlite3_create_collation16 sqlite3_api->create_collation16 +#define sqlite3_create_function sqlite3_api->create_function +#define sqlite3_create_function16 sqlite3_api->create_function16 +#define sqlite3_create_module sqlite3_api->create_module +#define sqlite3_create_module_v2 sqlite3_api->create_module_v2 +#define sqlite3_data_count sqlite3_api->data_count +#define sqlite3_db_handle sqlite3_api->db_handle +#define sqlite3_declare_vtab sqlite3_api->declare_vtab +#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache +#define sqlite3_errcode sqlite3_api->errcode +#define sqlite3_errmsg sqlite3_api->errmsg +#define sqlite3_errmsg16 sqlite3_api->errmsg16 +#define sqlite3_exec sqlite3_api->exec +#ifndef SQLITE_OMIT_DEPRECATED +#define sqlite3_expired sqlite3_api->expired +#endif +#define sqlite3_finalize sqlite3_api->finalize +#define sqlite3_free sqlite3_api->free +#define sqlite3_free_table sqlite3_api->free_table +#define sqlite3_get_autocommit sqlite3_api->get_autocommit +#define sqlite3_get_auxdata sqlite3_api->get_auxdata +#define sqlite3_get_table sqlite3_api->get_table +#ifndef SQLITE_OMIT_DEPRECATED +#define sqlite3_global_recover sqlite3_api->global_recover +#endif +#define sqlite3_interrupt sqlite3_api->interruptx +#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid +#define sqlite3_libversion sqlite3_api->libversion +#define sqlite3_libversion_number sqlite3_api->libversion_number +#define sqlite3_malloc sqlite3_api->malloc +#define sqlite3_mprintf sqlite3_api->mprintf +#define sqlite3_open sqlite3_api->open +#define sqlite3_open16 sqlite3_api->open16 +#define sqlite3_prepare sqlite3_api->prepare +#define sqlite3_prepare16 sqlite3_api->prepare16 +#define sqlite3_prepare_v2 sqlite3_api->prepare_v2 +#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 +#define sqlite3_profile sqlite3_api->profile +#define sqlite3_progress_handler sqlite3_api->progress_handler +#define sqlite3_realloc sqlite3_api->realloc +#define sqlite3_reset sqlite3_api->reset +#define sqlite3_result_blob sqlite3_api->result_blob +#define sqlite3_result_double sqlite3_api->result_double +#define sqlite3_result_error sqlite3_api->result_error +#define sqlite3_result_error16 sqlite3_api->result_error16 +#define sqlite3_result_int sqlite3_api->result_int +#define sqlite3_result_int64 sqlite3_api->result_int64 +#define sqlite3_result_null sqlite3_api->result_null +#define sqlite3_result_text sqlite3_api->result_text +#define sqlite3_result_text16 sqlite3_api->result_text16 +#define sqlite3_result_text16be sqlite3_api->result_text16be +#define sqlite3_result_text16le sqlite3_api->result_text16le +#define sqlite3_result_value sqlite3_api->result_value +#define sqlite3_rollback_hook sqlite3_api->rollback_hook +#define sqlite3_set_authorizer sqlite3_api->set_authorizer +#define sqlite3_set_auxdata sqlite3_api->set_auxdata +#define sqlite3_snprintf sqlite3_api->snprintf +#define sqlite3_step sqlite3_api->step +#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata +#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup +#define sqlite3_total_changes sqlite3_api->total_changes +#define sqlite3_trace sqlite3_api->trace +#ifndef SQLITE_OMIT_DEPRECATED +#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings +#endif +#define sqlite3_update_hook sqlite3_api->update_hook +#define sqlite3_user_data sqlite3_api->user_data +#define sqlite3_value_blob sqlite3_api->value_blob +#define sqlite3_value_bytes sqlite3_api->value_bytes +#define sqlite3_value_bytes16 sqlite3_api->value_bytes16 +#define sqlite3_value_double sqlite3_api->value_double +#define sqlite3_value_int sqlite3_api->value_int +#define sqlite3_value_int64 sqlite3_api->value_int64 +#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type +#define sqlite3_value_text sqlite3_api->value_text +#define sqlite3_value_text16 sqlite3_api->value_text16 +#define sqlite3_value_text16be sqlite3_api->value_text16be +#define sqlite3_value_text16le sqlite3_api->value_text16le +#define sqlite3_value_type sqlite3_api->value_type +#define sqlite3_vmprintf sqlite3_api->vmprintf +#define sqlite3_overload_function sqlite3_api->overload_function +#define sqlite3_prepare_v2 sqlite3_api->prepare_v2 +#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 +#define sqlite3_clear_bindings sqlite3_api->clear_bindings +#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob +#define sqlite3_blob_bytes sqlite3_api->blob_bytes +#define sqlite3_blob_close sqlite3_api->blob_close +#define sqlite3_blob_open sqlite3_api->blob_open +#define sqlite3_blob_read sqlite3_api->blob_read +#define sqlite3_blob_write sqlite3_api->blob_write +#define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2 +#define sqlite3_file_control sqlite3_api->file_control +#define sqlite3_memory_highwater sqlite3_api->memory_highwater +#define sqlite3_memory_used sqlite3_api->memory_used +#define sqlite3_mutex_alloc sqlite3_api->mutex_alloc +#define sqlite3_mutex_enter sqlite3_api->mutex_enter +#define sqlite3_mutex_free sqlite3_api->mutex_free +#define sqlite3_mutex_leave sqlite3_api->mutex_leave +#define sqlite3_mutex_try sqlite3_api->mutex_try +#define sqlite3_open_v2 sqlite3_api->open_v2 +#define sqlite3_release_memory sqlite3_api->release_memory +#define sqlite3_result_error_nomem sqlite3_api->result_error_nomem +#define sqlite3_result_error_toobig sqlite3_api->result_error_toobig +#define sqlite3_sleep sqlite3_api->sleep +#define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit +#define sqlite3_vfs_find sqlite3_api->vfs_find +#define sqlite3_vfs_register sqlite3_api->vfs_register +#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister +#define sqlite3_threadsafe sqlite3_api->xthreadsafe +#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob +#define sqlite3_result_error_code sqlite3_api->result_error_code +#define sqlite3_test_control sqlite3_api->test_control +#define sqlite3_randomness sqlite3_api->randomness +#define sqlite3_context_db_handle sqlite3_api->context_db_handle +#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes +#define sqlite3_limit sqlite3_api->limit +#define sqlite3_next_stmt sqlite3_api->next_stmt +#define sqlite3_sql sqlite3_api->sql +#define sqlite3_status sqlite3_api->status +#define sqlite3_backup_finish sqlite3_api->backup_finish +#define sqlite3_backup_init sqlite3_api->backup_init +#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount +#define sqlite3_backup_remaining sqlite3_api->backup_remaining +#define sqlite3_backup_step sqlite3_api->backup_step +#define sqlite3_compileoption_get sqlite3_api->compileoption_get +#define sqlite3_compileoption_used sqlite3_api->compileoption_used +#define sqlite3_create_function_v2 sqlite3_api->create_function_v2 +#define sqlite3_db_config sqlite3_api->db_config +#define sqlite3_db_mutex sqlite3_api->db_mutex +#define sqlite3_db_status sqlite3_api->db_status +#define sqlite3_extended_errcode sqlite3_api->extended_errcode +#define sqlite3_log sqlite3_api->log +#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64 +#define sqlite3_sourceid sqlite3_api->sourceid +#define sqlite3_stmt_status sqlite3_api->stmt_status +#define sqlite3_strnicmp sqlite3_api->strnicmp +#define sqlite3_unlock_notify sqlite3_api->unlock_notify +#define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint +#define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint +#define sqlite3_wal_hook sqlite3_api->wal_hook +#define sqlite3_blob_reopen sqlite3_api->blob_reopen +#define sqlite3_vtab_config sqlite3_api->vtab_config +#define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict +/* Version 3.7.16 and later */ +#define sqlite3_close_v2 sqlite3_api->close_v2 +#define sqlite3_db_filename sqlite3_api->db_filename +#define sqlite3_db_readonly sqlite3_api->db_readonly +#define sqlite3_db_release_memory sqlite3_api->db_release_memory +#define sqlite3_errstr sqlite3_api->errstr +#define sqlite3_stmt_busy sqlite3_api->stmt_busy +#define sqlite3_stmt_readonly sqlite3_api->stmt_readonly +#define sqlite3_stricmp sqlite3_api->stricmp +#define sqlite3_uri_boolean sqlite3_api->uri_boolean +#define sqlite3_uri_int64 sqlite3_api->uri_int64 +#define sqlite3_uri_parameter sqlite3_api->uri_parameter +#define sqlite3_uri_vsnprintf sqlite3_api->vsnprintf +#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2 +/* Version 3.8.7 and later */ +#define sqlite3_auto_extension sqlite3_api->auto_extension +#define sqlite3_bind_blob64 sqlite3_api->bind_blob64 +#define sqlite3_bind_text64 sqlite3_api->bind_text64 +#define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension +#define sqlite3_load_extension sqlite3_api->load_extension +#define sqlite3_malloc64 sqlite3_api->malloc64 +#define sqlite3_msize sqlite3_api->msize +#define sqlite3_realloc64 sqlite3_api->realloc64 +#define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension +#define sqlite3_result_blob64 sqlite3_api->result_blob64 +#define sqlite3_result_text64 sqlite3_api->result_text64 +#define sqlite3_strglob sqlite3_api->strglob +#endif /* SQLITE_CORE */ + +#ifndef SQLITE_CORE + /* This case when the file really is being compiled as a loadable + ** extension */ +# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; +# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; +# define SQLITE_EXTENSION_INIT3 \ + extern const sqlite3_api_routines *sqlite3_api; +#else + /* This case when the file is being statically linked into the + ** application */ +# define SQLITE_EXTENSION_INIT1 /*no-op*/ +# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */ +# define SQLITE_EXTENSION_INIT3 /*no-op*/ +#endif + +#endif /* _SQLITE3EXT_H_ */ + +/************** End of sqlite3ext.h ******************************************/ +/************** Continuing where we left off in loadext.c ********************/ +/* #include */ + +#ifndef SQLITE_OMIT_LOAD_EXTENSION + +/* +** Some API routines are omitted when various features are +** excluded from a build of SQLite. Substitute a NULL pointer +** for any missing APIs. +*/ +#ifndef SQLITE_ENABLE_COLUMN_METADATA +# define sqlite3_column_database_name 0 +# define sqlite3_column_database_name16 0 +# define sqlite3_column_table_name 0 +# define sqlite3_column_table_name16 0 +# define sqlite3_column_origin_name 0 +# define sqlite3_column_origin_name16 0 +#endif + +#ifdef SQLITE_OMIT_AUTHORIZATION +# define sqlite3_set_authorizer 0 +#endif + +#ifdef SQLITE_OMIT_UTF16 +# define sqlite3_bind_text16 0 +# define sqlite3_collation_needed16 0 +# define sqlite3_column_decltype16 0 +# define sqlite3_column_name16 0 +# define sqlite3_column_text16 0 +# define sqlite3_complete16 0 +# define sqlite3_create_collation16 0 +# define sqlite3_create_function16 0 +# define sqlite3_errmsg16 0 +# define sqlite3_open16 0 +# define sqlite3_prepare16 0 +# define sqlite3_prepare16_v2 0 +# define sqlite3_result_error16 0 +# define sqlite3_result_text16 0 +# define sqlite3_result_text16be 0 +# define sqlite3_result_text16le 0 +# define sqlite3_value_text16 0 +# define sqlite3_value_text16be 0 +# define sqlite3_value_text16le 0 +# define sqlite3_column_database_name16 0 +# define sqlite3_column_table_name16 0 +# define sqlite3_column_origin_name16 0 +#endif + +#ifdef SQLITE_OMIT_COMPLETE +# define sqlite3_complete 0 +# define sqlite3_complete16 0 +#endif + +#ifdef SQLITE_OMIT_DECLTYPE +# define sqlite3_column_decltype16 0 +# define sqlite3_column_decltype 0 +#endif + +#ifdef SQLITE_OMIT_PROGRESS_CALLBACK +# define sqlite3_progress_handler 0 +#endif + +#ifdef SQLITE_OMIT_VIRTUALTABLE +# define sqlite3_create_module 0 +# define sqlite3_create_module_v2 0 +# define sqlite3_declare_vtab 0 +# define sqlite3_vtab_config 0 +# define sqlite3_vtab_on_conflict 0 +#endif + +#ifdef SQLITE_OMIT_SHARED_CACHE +# define sqlite3_enable_shared_cache 0 +#endif + +#ifdef SQLITE_OMIT_TRACE +# define sqlite3_profile 0 +# define sqlite3_trace 0 +#endif + +#ifdef SQLITE_OMIT_GET_TABLE +# define sqlite3_free_table 0 +# define sqlite3_get_table 0 +#endif + +#ifdef SQLITE_OMIT_INCRBLOB +#define sqlite3_bind_zeroblob 0 +#define sqlite3_blob_bytes 0 +#define sqlite3_blob_close 0 +#define sqlite3_blob_open 0 +#define sqlite3_blob_read 0 +#define sqlite3_blob_write 0 +#define sqlite3_blob_reopen 0 +#endif + +/* +** The following structure contains pointers to all SQLite API routines. +** A pointer to this structure is passed into extensions when they are +** loaded so that the extension can make calls back into the SQLite +** library. +** +** When adding new APIs, add them to the bottom of this structure +** in order to preserve backwards compatibility. +** +** Extensions that use newer APIs should first call the +** sqlite3_libversion_number() to make sure that the API they +** intend to use is supported by the library. Extensions should +** also check to make sure that the pointer to the function is +** not NULL before calling it. +*/ +static const sqlite3_api_routines sqlite3Apis = { + sqlite3_aggregate_context, +#ifndef SQLITE_OMIT_DEPRECATED + sqlite3_aggregate_count, +#else + 0, +#endif + sqlite3_bind_blob, + sqlite3_bind_double, + sqlite3_bind_int, + sqlite3_bind_int64, + sqlite3_bind_null, + sqlite3_bind_parameter_count, + sqlite3_bind_parameter_index, + sqlite3_bind_parameter_name, + sqlite3_bind_text, + sqlite3_bind_text16, + sqlite3_bind_value, + sqlite3_busy_handler, + sqlite3_busy_timeout, + sqlite3_changes, + sqlite3_close, + sqlite3_collation_needed, + sqlite3_collation_needed16, + sqlite3_column_blob, + sqlite3_column_bytes, + sqlite3_column_bytes16, + sqlite3_column_count, + sqlite3_column_database_name, + sqlite3_column_database_name16, + sqlite3_column_decltype, + sqlite3_column_decltype16, + sqlite3_column_double, + sqlite3_column_int, + sqlite3_column_int64, + sqlite3_column_name, + sqlite3_column_name16, + sqlite3_column_origin_name, + sqlite3_column_origin_name16, + sqlite3_column_table_name, + sqlite3_column_table_name16, + sqlite3_column_text, + sqlite3_column_text16, + sqlite3_column_type, + sqlite3_column_value, + sqlite3_commit_hook, + sqlite3_complete, + sqlite3_complete16, + sqlite3_create_collation, + sqlite3_create_collation16, + sqlite3_create_function, + sqlite3_create_function16, + sqlite3_create_module, + sqlite3_data_count, + sqlite3_db_handle, + sqlite3_declare_vtab, + sqlite3_enable_shared_cache, + sqlite3_errcode, + sqlite3_errmsg, + sqlite3_errmsg16, + sqlite3_exec, +#ifndef SQLITE_OMIT_DEPRECATED + sqlite3_expired, +#else + 0, +#endif + sqlite3_finalize, + sqlite3_free, + sqlite3_free_table, + sqlite3_get_autocommit, + sqlite3_get_auxdata, + sqlite3_get_table, + 0, /* Was sqlite3_global_recover(), but that function is deprecated */ + sqlite3_interrupt, + sqlite3_last_insert_rowid, + sqlite3_libversion, + sqlite3_libversion_number, + sqlite3_malloc, + sqlite3_mprintf, + sqlite3_open, + sqlite3_open16, + sqlite3_prepare, + sqlite3_prepare16, + sqlite3_profile, + sqlite3_progress_handler, + sqlite3_realloc, + 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_table_column_metadata, +#ifndef SQLITE_OMIT_DEPRECATED + sqlite3_thread_cleanup, +#else + 0, +#endif + sqlite3_total_changes, + sqlite3_trace, +#ifndef SQLITE_OMIT_DEPRECATED + sqlite3_transfer_bindings, +#else + 0, +#endif + 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_numeric_type, + sqlite3_value_text, + sqlite3_value_text16, + sqlite3_value_text16be, + sqlite3_value_text16le, + sqlite3_value_type, + sqlite3_vmprintf, + /* + ** The original API set ends here. All extensions can call any + ** of the APIs above provided that the pointer is not NULL. But + ** before calling APIs that follow, extension should check the + ** sqlite3_libversion_number() to make sure they are dealing with + ** a library that is new enough to support that API. + ************************************************************************* + */ + sqlite3_overload_function, + + /* + ** Added after 3.3.13 + */ + sqlite3_prepare_v2, + sqlite3_prepare16_v2, + sqlite3_clear_bindings, + + /* + ** Added for 3.4.1 + */ + sqlite3_create_module_v2, + + /* + ** Added for 3.5.0 + */ + sqlite3_bind_zeroblob, + sqlite3_blob_bytes, + sqlite3_blob_close, + sqlite3_blob_open, + sqlite3_blob_read, + sqlite3_blob_write, + sqlite3_create_collation_v2, + sqlite3_file_control, + sqlite3_memory_highwater, + sqlite3_memory_used, +#ifdef SQLITE_MUTEX_OMIT + 0, + 0, + 0, + 0, + 0, +#else + sqlite3_mutex_alloc, + sqlite3_mutex_enter, + sqlite3_mutex_free, + sqlite3_mutex_leave, + sqlite3_mutex_try, +#endif + sqlite3_open_v2, + sqlite3_release_memory, + sqlite3_result_error_nomem, + sqlite3_result_error_toobig, + sqlite3_sleep, + sqlite3_soft_heap_limit, + sqlite3_vfs_find, + sqlite3_vfs_register, + sqlite3_vfs_unregister, + + /* + ** Added for 3.5.8 + */ + sqlite3_threadsafe, + sqlite3_result_zeroblob, + sqlite3_result_error_code, + sqlite3_test_control, + sqlite3_randomness, + sqlite3_context_db_handle, + + /* + ** Added for 3.6.0 + */ + sqlite3_extended_result_codes, + sqlite3_limit, + sqlite3_next_stmt, + sqlite3_sql, + sqlite3_status, + + /* + ** Added for 3.7.4 + */ + sqlite3_backup_finish, + sqlite3_backup_init, + sqlite3_backup_pagecount, + sqlite3_backup_remaining, + sqlite3_backup_step, +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS + sqlite3_compileoption_get, + sqlite3_compileoption_used, +#else + 0, + 0, +#endif + sqlite3_create_function_v2, + sqlite3_db_config, + sqlite3_db_mutex, + sqlite3_db_status, + sqlite3_extended_errcode, + sqlite3_log, + sqlite3_soft_heap_limit64, + sqlite3_sourceid, + sqlite3_stmt_status, + sqlite3_strnicmp, +#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY + sqlite3_unlock_notify, +#else + 0, +#endif +#ifndef SQLITE_OMIT_WAL + sqlite3_wal_autocheckpoint, + sqlite3_wal_checkpoint, + sqlite3_wal_hook, +#else + 0, + 0, + 0, +#endif + sqlite3_blob_reopen, + sqlite3_vtab_config, + sqlite3_vtab_on_conflict, + sqlite3_close_v2, + sqlite3_db_filename, + sqlite3_db_readonly, + sqlite3_db_release_memory, + sqlite3_errstr, + sqlite3_stmt_busy, + sqlite3_stmt_readonly, + sqlite3_stricmp, + sqlite3_uri_boolean, + sqlite3_uri_int64, + sqlite3_uri_parameter, + sqlite3_vsnprintf, + sqlite3_wal_checkpoint_v2, + /* Version 3.8.7 and later */ + sqlite3_auto_extension, + sqlite3_bind_blob64, + sqlite3_bind_text64, + sqlite3_cancel_auto_extension, + sqlite3_load_extension, + sqlite3_malloc64, + sqlite3_msize, + sqlite3_realloc64, + sqlite3_reset_auto_extension, + sqlite3_result_blob64, + sqlite3_result_text64, + sqlite3_strglob +}; + +/* +** Attempt to load an SQLite extension library contained in the file +** zFile. The entry point is zProc. zProc may be 0 in which case a +** default entry point name (sqlite3_extension_init) is used. Use +** of the default name is recommended. +** +** Return SQLITE_OK on success and SQLITE_ERROR if something goes wrong. +** +** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with +** error message text. The calling function should free this memory +** by calling sqlite3DbFree(db, ). +*/ +static int sqlite3LoadExtension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +){ + sqlite3_vfs *pVfs = db->pVfs; + void *handle; + int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*); + char *zErrmsg = 0; + const char *zEntry; + char *zAltEntry = 0; + void **aHandle; + u64 nMsg = 300 + sqlite3Strlen30(zFile); + int ii; + + /* Shared library endings to try if zFile cannot be loaded as written */ + static const char *azEndings[] = { +#if SQLITE_OS_WIN + "dll" +#elif defined(__APPLE__) + "dylib" +#else + "so" +#endif + }; + + + if( pzErrMsg ) *pzErrMsg = 0; + + /* Ticket #1863. To avoid a creating security problems for older + ** applications that relink against newer versions of SQLite, the + ** ability to run load_extension is turned off by default. One + ** must call sqlite3_enable_load_extension() to turn on extension + ** loading. Otherwise you get the following error. + */ + if( (db->flags & SQLITE_LoadExtension)==0 ){ + if( pzErrMsg ){ + *pzErrMsg = sqlite3_mprintf("not authorized"); + } + return SQLITE_ERROR; + } + + zEntry = zProc ? zProc : "sqlite3_extension_init"; + + handle = sqlite3OsDlOpen(pVfs, zFile); +#if SQLITE_OS_UNIX || SQLITE_OS_WIN + for(ii=0; ii sqlite3_example_init + ** C:/lib/mathfuncs.dll ==> sqlite3_mathfuncs_init + */ + if( xInit==0 && zProc==0 ){ + int iFile, iEntry, c; + int ncFile = sqlite3Strlen30(zFile); + zAltEntry = sqlite3_malloc64(ncFile+30); + if( zAltEntry==0 ){ + sqlite3OsDlClose(pVfs, handle); + return SQLITE_NOMEM; + } + memcpy(zAltEntry, "sqlite3_", 8); + for(iFile=ncFile-1; iFile>=0 && zFile[iFile]!='/'; iFile--){} + iFile++; + if( sqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3; + for(iEntry=8; (c = zFile[iFile])!=0 && c!='.'; iFile++){ + if( sqlite3Isalpha(c) ){ + zAltEntry[iEntry++] = (char)sqlite3UpperToLower[(unsigned)c]; + } + } + memcpy(zAltEntry+iEntry, "_init", 6); + zEntry = zAltEntry; + xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*)) + sqlite3OsDlSym(pVfs, handle, zEntry); + } + if( xInit==0 ){ + if( pzErrMsg ){ + nMsg += sqlite3Strlen30(zEntry); + *pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg); + if( zErrmsg ){ + sqlite3_snprintf(nMsg, zErrmsg, + "no entry point [%s] in shared library [%s]", zEntry, zFile); + sqlite3OsDlError(pVfs, nMsg-1, zErrmsg); + } + } + sqlite3OsDlClose(pVfs, handle); + sqlite3_free(zAltEntry); + return SQLITE_ERROR; + } + sqlite3_free(zAltEntry); + if( xInit(db, &zErrmsg, &sqlite3Apis) ){ + if( pzErrMsg ){ + *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg); + } + sqlite3_free(zErrmsg); + sqlite3OsDlClose(pVfs, handle); + return SQLITE_ERROR; + } + + /* Append the new shared library handle to the db->aExtension array. */ + aHandle = sqlite3DbMallocZero(db, sizeof(handle)*(db->nExtension+1)); + if( aHandle==0 ){ + return SQLITE_NOMEM; + } + if( db->nExtension>0 ){ + memcpy(aHandle, db->aExtension, sizeof(handle)*db->nExtension); + } + sqlite3DbFree(db, db->aExtension); + db->aExtension = aHandle; + + db->aExtension[db->nExtension++] = handle; + return SQLITE_OK; +} +SQLITE_API int SQLITE_STDCALL sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +){ + int rc; + sqlite3_mutex_enter(db->mutex); + rc = sqlite3LoadExtension(db, zFile, zProc, pzErrMsg); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Call this routine when the database connection is closing in order +** to clean up loaded extensions +*/ +SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3 *db){ + int i; + assert( sqlite3_mutex_held(db->mutex) ); + for(i=0; inExtension; i++){ + sqlite3OsDlClose(db->pVfs, db->aExtension[i]); + } + sqlite3DbFree(db, db->aExtension); +} + +/* +** Enable or disable extension loading. Extension loading is disabled by +** default so as not to open security holes in older applications. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff){ + sqlite3_mutex_enter(db->mutex); + if( onoff ){ + db->flags |= SQLITE_LoadExtension; + }else{ + db->flags &= ~SQLITE_LoadExtension; + } + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +#endif /* SQLITE_OMIT_LOAD_EXTENSION */ + +/* +** The auto-extension code added regardless of whether or not extension +** loading is supported. We need a dummy sqlite3Apis pointer for that +** code if regular extension loading is not available. This is that +** dummy pointer. +*/ +#ifdef SQLITE_OMIT_LOAD_EXTENSION +static const sqlite3_api_routines sqlite3Apis = { 0 }; +#endif + + +/* +** The following object holds the list of automatically loaded +** extensions. +** +** This list is shared across threads. The SQLITE_MUTEX_STATIC_MASTER +** mutex must be held while accessing this list. +*/ +typedef struct sqlite3AutoExtList sqlite3AutoExtList; +static SQLITE_WSD struct sqlite3AutoExtList { + u32 nExt; /* Number of entries in aExt[] */ + void (**aExt)(void); /* Pointers to the extension init functions */ +} sqlite3Autoext = { 0, 0 }; + +/* The "wsdAutoext" macro will resolve to the autoextension +** state vector. If writable static data is unsupported on the target, +** we have to locate the state vector at run-time. In the more common +** case where writable static data is supported, wsdStat can refer directly +** to the "sqlite3Autoext" state vector declared above. +*/ +#ifdef SQLITE_OMIT_WSD +# define wsdAutoextInit \ + sqlite3AutoExtList *x = &GLOBAL(sqlite3AutoExtList,sqlite3Autoext) +# define wsdAutoext x[0] +#else +# define wsdAutoextInit +# define wsdAutoext sqlite3Autoext +#endif + + +/* +** Register a statically linked extension that is automatically +** loaded by every new database connection. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xInit)(void)){ + int rc = SQLITE_OK; +#ifndef SQLITE_OMIT_AUTOINIT + rc = sqlite3_initialize(); + if( rc ){ + return rc; + }else +#endif + { + u32 i; +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); +#endif + wsdAutoextInit; + sqlite3_mutex_enter(mutex); + for(i=0; i=0; i--){ + if( wsdAutoext.aExt[i]==xInit ){ + wsdAutoext.nExt--; + wsdAutoext.aExt[i] = wsdAutoext.aExt[wsdAutoext.nExt]; + n++; + break; + } + } + sqlite3_mutex_leave(mutex); + return n; +} + +/* +** Reset the automatic extension loading mechanism. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void){ +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize()==SQLITE_OK ) +#endif + { +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); +#endif + wsdAutoextInit; + sqlite3_mutex_enter(mutex); + sqlite3_free(wsdAutoext.aExt); + wsdAutoext.aExt = 0; + wsdAutoext.nExt = 0; + sqlite3_mutex_leave(mutex); + } +} + +/* +** Load all automatic extensions. +** +** If anything goes wrong, set an error in the database connection. +*/ +SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){ + u32 i; + int go = 1; + int rc; + int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*); + + wsdAutoextInit; + if( wsdAutoext.nExt==0 ){ + /* Common case: early out without every having to acquire a mutex */ + return; + } + for(i=0; go; i++){ + char *zErrmsg; +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); +#endif + sqlite3_mutex_enter(mutex); + if( i>=wsdAutoext.nExt ){ + xInit = 0; + go = 0; + }else{ + xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*)) + wsdAutoext.aExt[i]; + } + sqlite3_mutex_leave(mutex); + zErrmsg = 0; + if( xInit && (rc = xInit(db, &zErrmsg, &sqlite3Apis))!=0 ){ + sqlite3ErrorWithMsg(db, rc, + "automatic extension loading failed: %s", zErrmsg); + go = 0; + } + sqlite3_free(zErrmsg); + } +} + +/************** End of loadext.c *********************************************/ +/************** Begin file pragma.c ******************************************/ +/* +** 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. +*/ + +#if !defined(SQLITE_ENABLE_LOCKING_STYLE) +# if defined(__APPLE__) +# define SQLITE_ENABLE_LOCKING_STYLE 1 +# else +# define SQLITE_ENABLE_LOCKING_STYLE 0 +# endif +#endif + +/*************************************************************************** +** The "pragma.h" include file is an automatically generated file that +** that includes the PragType_XXXX macro definitions and the aPragmaName[] +** object. This ensures that the aPragmaName[] table is arranged in +** lexicographical order to facility a binary search of the pragma name. +** Do not edit pragma.h directly. Edit and rerun the script in at +** ../tool/mkpragmatab.tcl. */ +/************** Include pragma.h in the middle of pragma.c *******************/ +/************** Begin file pragma.h ******************************************/ +/* DO NOT EDIT! +** This file is automatically generated by the script at +** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit +** that script and rerun it. +*/ +#define PragTyp_HEADER_VALUE 0 +#define PragTyp_AUTO_VACUUM 1 +#define PragTyp_FLAG 2 +#define PragTyp_BUSY_TIMEOUT 3 +#define PragTyp_CACHE_SIZE 4 +#define PragTyp_CASE_SENSITIVE_LIKE 5 +#define PragTyp_COLLATION_LIST 6 +#define PragTyp_COMPILE_OPTIONS 7 +#define PragTyp_DATA_STORE_DIRECTORY 8 +#define PragTyp_DATABASE_LIST 9 +#define PragTyp_DEFAULT_CACHE_SIZE 10 +#define PragTyp_ENCODING 11 +#define PragTyp_FOREIGN_KEY_CHECK 12 +#define PragTyp_FOREIGN_KEY_LIST 13 +#define PragTyp_INCREMENTAL_VACUUM 14 +#define PragTyp_INDEX_INFO 15 +#define PragTyp_INDEX_LIST 16 +#define PragTyp_INTEGRITY_CHECK 17 +#define PragTyp_JOURNAL_MODE 18 +#define PragTyp_JOURNAL_SIZE_LIMIT 19 +#define PragTyp_LOCK_PROXY_FILE 20 +#define PragTyp_LOCKING_MODE 21 +#define PragTyp_PAGE_COUNT 22 +#define PragTyp_MMAP_SIZE 23 +#define PragTyp_PAGE_SIZE 24 +#define PragTyp_SECURE_DELETE 25 +#define PragTyp_SHRINK_MEMORY 26 +#define PragTyp_SOFT_HEAP_LIMIT 27 +#define PragTyp_STATS 28 +#define PragTyp_SYNCHRONOUS 29 +#define PragTyp_TABLE_INFO 30 +#define PragTyp_TEMP_STORE 31 +#define PragTyp_TEMP_STORE_DIRECTORY 32 +#define PragTyp_THREADS 33 +#define PragTyp_WAL_AUTOCHECKPOINT 34 +#define PragTyp_WAL_CHECKPOINT 35 +#define PragTyp_ACTIVATE_EXTENSIONS 36 +#define PragTyp_HEXKEY 37 +#define PragTyp_KEY 38 +#define PragTyp_REKEY 39 +#define PragTyp_LOCK_STATUS 40 +#define PragTyp_PARSER_TRACE 41 +#define PragFlag_NeedSchema 0x01 +#define PragFlag_ReadOnly 0x02 +static const struct sPragmaNames { + const char *const zName; /* Name of pragma */ + u8 ePragTyp; /* PragTyp_XXX value */ + u8 mPragFlag; /* Zero or more PragFlag_XXX values */ + u32 iArg; /* Extra argument */ +} aPragmaNames[] = { +#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) + { /* zName: */ "activate_extensions", + /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + { /* zName: */ "application_id", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlag: */ 0, + /* iArg: */ BTREE_APPLICATION_ID }, +#endif +#if !defined(SQLITE_OMIT_AUTOVACUUM) + { /* zName: */ "auto_vacuum", + /* ePragTyp: */ PragTyp_AUTO_VACUUM, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) +#if !defined(SQLITE_OMIT_AUTOMATIC_INDEX) + { /* zName: */ "automatic_index", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_AutoIndex }, +#endif +#endif + { /* zName: */ "busy_timeout", + /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + { /* zName: */ "cache_size", + /* ePragTyp: */ PragTyp_CACHE_SIZE, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + { /* zName: */ "cache_spill", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_CacheSpill }, +#endif + { /* zName: */ "case_sensitive_like", + /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + { /* zName: */ "checkpoint_fullfsync", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_CkptFullFSync }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + { /* zName: */ "collation_list", + /* ePragTyp: */ PragTyp_COLLATION_LIST, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) + { /* zName: */ "compile_options", + /* ePragTyp: */ PragTyp_COMPILE_OPTIONS, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + { /* zName: */ "count_changes", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_CountRows }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN + { /* zName: */ "data_store_directory", + /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + { /* zName: */ "data_version", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlag: */ PragFlag_ReadOnly, + /* iArg: */ BTREE_DATA_VERSION }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + { /* zName: */ "database_list", + /* ePragTyp: */ PragTyp_DATABASE_LIST, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) + { /* zName: */ "default_cache_size", + /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + { /* zName: */ "defer_foreign_keys", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_DeferFKs }, +#endif +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + { /* zName: */ "empty_result_callbacks", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_NullCallback }, +#endif +#if !defined(SQLITE_OMIT_UTF16) + { /* zName: */ "encoding", + /* ePragTyp: */ PragTyp_ENCODING, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + { /* zName: */ "foreign_key_check", + /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FOREIGN_KEY) + { /* zName: */ "foreign_key_list", + /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + { /* zName: */ "foreign_keys", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_ForeignKeys }, +#endif +#endif +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + { /* zName: */ "freelist_count", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlag: */ PragFlag_ReadOnly, + /* iArg: */ BTREE_FREE_PAGE_COUNT }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + { /* zName: */ "full_column_names", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_FullColNames }, + { /* zName: */ "fullfsync", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_FullFSync }, +#endif +#if defined(SQLITE_HAS_CODEC) + { /* zName: */ "hexkey", + /* ePragTyp: */ PragTyp_HEXKEY, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, + { /* zName: */ "hexrekey", + /* ePragTyp: */ PragTyp_HEXKEY, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) +#if !defined(SQLITE_OMIT_CHECK) + { /* zName: */ "ignore_check_constraints", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_IgnoreChecks }, +#endif +#endif +#if !defined(SQLITE_OMIT_AUTOVACUUM) + { /* zName: */ "incremental_vacuum", + /* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + { /* zName: */ "index_info", + /* ePragTyp: */ PragTyp_INDEX_INFO, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, + { /* zName: */ "index_list", + /* ePragTyp: */ PragTyp_INDEX_LIST, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, + { /* zName: */ "index_xinfo", + /* ePragTyp: */ PragTyp_INDEX_INFO, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 1 }, +#endif +#if !defined(SQLITE_OMIT_INTEGRITY_CHECK) + { /* zName: */ "integrity_check", + /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + { /* zName: */ "journal_mode", + /* ePragTyp: */ PragTyp_JOURNAL_MODE, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, + { /* zName: */ "journal_size_limit", + /* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, +#endif +#if defined(SQLITE_HAS_CODEC) + { /* zName: */ "key", + /* ePragTyp: */ PragTyp_KEY, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + { /* zName: */ "legacy_file_format", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_LegacyFileFmt }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE + { /* zName: */ "lock_proxy_file", + /* ePragTyp: */ PragTyp_LOCK_PROXY_FILE, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, +#endif +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + { /* zName: */ "lock_status", + /* ePragTyp: */ PragTyp_LOCK_STATUS, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + { /* zName: */ "locking_mode", + /* ePragTyp: */ PragTyp_LOCKING_MODE, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, + { /* zName: */ "max_page_count", + /* ePragTyp: */ PragTyp_PAGE_COUNT, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, + { /* zName: */ "mmap_size", + /* ePragTyp: */ PragTyp_MMAP_SIZE, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, + { /* zName: */ "page_count", + /* ePragTyp: */ PragTyp_PAGE_COUNT, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, + { /* zName: */ "page_size", + /* ePragTyp: */ PragTyp_PAGE_SIZE, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, +#endif +#if defined(SQLITE_DEBUG) + { /* zName: */ "parser_trace", + /* ePragTyp: */ PragTyp_PARSER_TRACE, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + { /* zName: */ "query_only", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_QueryOnly }, +#endif +#if !defined(SQLITE_OMIT_INTEGRITY_CHECK) + { /* zName: */ "quick_check", + /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + { /* zName: */ "read_uncommitted", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_ReadUncommitted }, + { /* zName: */ "recursive_triggers", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_RecTriggers }, +#endif +#if defined(SQLITE_HAS_CODEC) + { /* zName: */ "rekey", + /* ePragTyp: */ PragTyp_REKEY, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + { /* zName: */ "reverse_unordered_selects", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_ReverseOrder }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + { /* zName: */ "schema_version", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlag: */ 0, + /* iArg: */ BTREE_SCHEMA_VERSION }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + { /* zName: */ "secure_delete", + /* ePragTyp: */ PragTyp_SECURE_DELETE, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + { /* zName: */ "short_column_names", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_ShortColNames }, +#endif + { /* zName: */ "shrink_memory", + /* ePragTyp: */ PragTyp_SHRINK_MEMORY, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, + { /* zName: */ "soft_heap_limit", + /* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) +#if defined(SQLITE_DEBUG) + { /* zName: */ "sql_trace", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_SqlTrace }, +#endif +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + { /* zName: */ "stats", + /* ePragTyp: */ PragTyp_STATS, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + { /* zName: */ "synchronous", + /* ePragTyp: */ PragTyp_SYNCHRONOUS, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + { /* zName: */ "table_info", + /* ePragTyp: */ PragTyp_TABLE_INFO, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + { /* zName: */ "temp_store", + /* ePragTyp: */ PragTyp_TEMP_STORE, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, + { /* zName: */ "temp_store_directory", + /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, +#endif + { /* zName: */ "threads", + /* ePragTyp: */ PragTyp_THREADS, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + { /* zName: */ "user_version", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlag: */ 0, + /* iArg: */ BTREE_USER_VERSION }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) +#if defined(SQLITE_DEBUG) + { /* zName: */ "vdbe_addoptrace", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_VdbeAddopTrace }, + { /* zName: */ "vdbe_debug", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace }, + { /* zName: */ "vdbe_eqp", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_VdbeEQP }, + { /* zName: */ "vdbe_listing", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_VdbeListing }, + { /* zName: */ "vdbe_trace", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_VdbeTrace }, +#endif +#endif +#if !defined(SQLITE_OMIT_WAL) + { /* zName: */ "wal_autocheckpoint", + /* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, + { /* zName: */ "wal_checkpoint", + /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + { /* zName: */ "writable_schema", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode }, +#endif +}; +/* Number of pragmas: 59 on by default, 72 total. */ + +/************** End of pragma.h **********************************************/ +/************** Continuing where we left off in pragma.c *********************/ + +/* +** 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. The FULL option is disallowed +** if the omitFull parameter it 1. +** +** 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 u8 getSafetyLevel(const char *z, int omitFull, u8 dflt){ + /* 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( sqlite3Isdigit(*z) ){ + return (u8)sqlite3Atoi(z); + } + n = sqlite3Strlen30(z); + for(i=0; i=0&&i<=2)?i:0); +} +#endif /* ifndef SQLITE_OMIT_AUTOVACUUM */ + +#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->autoCommit || sqlite3BtreeIsInReadTrans(db->aDb[1].pBt) ){ + sqlite3ErrorMsg(pParse, "temporary storage cannot be changed " + "from within a transaction"); + return SQLITE_ERROR; + } + sqlite3BtreeClose(db->aDb[1].pBt); + db->aDb[1].pBt = 0; + sqlite3ResetAllSchemasOfConnection(db); + } + 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 SQLITE_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 = (u8)ts; + return SQLITE_OK; +} +#endif /* SQLITE_PAGER_PRAGMAS */ + +/* +** Generate code to return a single integer value. +*/ +static void returnSingleInt(Parse *pParse, const char *zLabel, i64 value){ + Vdbe *v = sqlite3GetVdbe(pParse); + int nMem = ++pParse->nMem; + i64 *pI64 = sqlite3DbMallocRaw(pParse->db, sizeof(value)); + if( pI64 ){ + memcpy(pI64, &value, sizeof(value)); + } + sqlite3VdbeAddOp4(v, OP_Int64, 0, nMem, 0, (char*)pI64, P4_INT64); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC); + sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1); +} + + +/* +** Set the safety_level and pager flags for pager iDb. Or if iDb<0 +** set these values for all pagers. +*/ +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +static void setAllPagerFlags(sqlite3 *db){ + if( db->autoCommit ){ + Db *pDb = db->aDb; + int n = db->nDb; + assert( SQLITE_FullFSync==PAGER_FULLFSYNC ); + assert( SQLITE_CkptFullFSync==PAGER_CKPT_FULLFSYNC ); + assert( SQLITE_CacheSpill==PAGER_CACHESPILL ); + assert( (PAGER_FULLFSYNC | PAGER_CKPT_FULLFSYNC | PAGER_CACHESPILL) + == PAGER_FLAGS_MASK ); + assert( (pDb->safety_level & PAGER_SYNCHRONOUS_MASK)==pDb->safety_level ); + while( (n--) > 0 ){ + if( pDb->pBt ){ + sqlite3BtreeSetPagerFlags(pDb->pBt, + pDb->safety_level | (db->flags & PAGER_FLAGS_MASK) ); + } + pDb++; + } + } +} +#else +# define setAllPagerFlags(X) /* no-op */ +#endif + + +/* +** Return a human-readable name for a constraint resolution action. +*/ +#ifndef SQLITE_OMIT_FOREIGN_KEY +static const char *actionName(u8 action){ + const char *zName; + switch( action ){ + case OE_SetNull: zName = "SET NULL"; break; + case OE_SetDflt: zName = "SET DEFAULT"; break; + case OE_Cascade: zName = "CASCADE"; break; + case OE_Restrict: zName = "RESTRICT"; break; + default: zName = "NO ACTION"; + assert( action==OE_None ); break; + } + return zName; +} +#endif + + +/* +** Parameter eMode must be one of the PAGER_JOURNALMODE_XXX constants +** defined in pager.h. This function returns the associated lowercase +** journal-mode name. +*/ +SQLITE_PRIVATE const char *sqlite3JournalModename(int eMode){ + static char * const azModeName[] = { + "delete", "persist", "off", "truncate", "memory" +#ifndef SQLITE_OMIT_WAL + , "wal" +#endif + }; + assert( PAGER_JOURNALMODE_DELETE==0 ); + assert( PAGER_JOURNALMODE_PERSIST==1 ); + assert( PAGER_JOURNALMODE_OFF==2 ); + assert( PAGER_JOURNALMODE_TRUNCATE==3 ); + assert( PAGER_JOURNALMODE_MEMORY==4 ); + assert( PAGER_JOURNALMODE_WAL==5 ); + assert( eMode>=0 && eMode<=ArraySize(azModeName) ); + + if( eMode==ArraySize(azModeName) ) return 0; + return azModeName[eMode]; +} + +/* +** Process a pragma statement. +** +** Pragmas are of this form: +** +** PRAGMA [database.]id [= value] +** +** The identifier might also be a string. The value is a string, and +** identifier, or a number. If minusFlag is true, then the value is +** a number that was preceded by a minus sign. +** +** If the left side is "database.id" then pId1 is the database name +** and pId2 is the id. If the left side is just "id" then pId1 is the +** id and pId2 is any empty string. +*/ +SQLITE_PRIVATE void sqlite3Pragma( + Parse *pParse, + Token *pId1, /* First part of [database.]id field */ + Token *pId2, /* Second part of [database.]id field, or NULL */ + Token *pValue, /* Token for , or NULL */ + int minusFlag /* True if a '-' sign preceded */ +){ + char *zLeft = 0; /* Nul-terminated UTF-8 string */ + char *zRight = 0; /* Nul-terminated UTF-8 string , or NULL */ + const char *zDb = 0; /* The database name */ + Token *pId; /* Pointer to token */ + char *aFcntl[4]; /* Argument to SQLITE_FCNTL_PRAGMA */ + int iDb; /* Database index for */ + int lwr, upr, mid = 0; /* Binary search bounds */ + int rc; /* return value form SQLITE_FCNTL_PRAGMA */ + sqlite3 *db = pParse->db; /* The database connection */ + Db *pDb; /* The specific database being pragmaed */ + Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */ + const struct sPragmaNames *pPragma; + + if( v==0 ) return; + sqlite3VdbeRunOnlyOnce(v); + pParse->nMem = 2; + + /* Interpret the [database.] part of the pragma statement. iDb is the + ** index of the database this pragma is being applied to in db.aDb[]. */ + iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId); + if( iDb<0 ) return; + pDb = &db->aDb[iDb]; + + /* If the temp database has been explicitly named as part of the + ** pragma, make sure it is open. + */ + if( iDb==1 && sqlite3OpenTempDatabase(pParse) ){ + return; + } + + zLeft = sqlite3NameFromToken(db, pId); + if( !zLeft ) return; + if( minusFlag ){ + zRight = sqlite3MPrintf(db, "-%T", pValue); + }else{ + zRight = sqlite3NameFromToken(db, pValue); + } + + assert( pId2 ); + zDb = pId2->n>0 ? pDb->zName : 0; + if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){ + goto pragma_out; + } + + /* Send an SQLITE_FCNTL_PRAGMA file-control to the underlying VFS + ** connection. If it returns SQLITE_OK, then assume that the VFS + ** handled the pragma and generate a no-op prepared statement. + ** + ** IMPLEMENTATION-OF: R-12238-55120 Whenever a PRAGMA statement is parsed, + ** an SQLITE_FCNTL_PRAGMA file control is sent to the open sqlite3_file + ** object corresponding to the database file to which the pragma + ** statement refers. + ** + ** IMPLEMENTATION-OF: R-29875-31678 The argument to the SQLITE_FCNTL_PRAGMA + ** file control is an array of pointers to strings (char**) in which the + ** second element of the array is the name of the pragma and the third + ** element is the argument to the pragma or NULL if the pragma has no + ** argument. + */ + aFcntl[0] = 0; + aFcntl[1] = zLeft; + aFcntl[2] = zRight; + aFcntl[3] = 0; + db->busyHandler.nBusy = 0; + rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl); + if( rc==SQLITE_OK ){ + if( aFcntl[0] ){ + int nMem = ++pParse->nMem; + sqlite3VdbeAddOp4(v, OP_String8, 0, nMem, 0, aFcntl[0], 0); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "result", SQLITE_STATIC); + sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1); + sqlite3_free(aFcntl[0]); + } + goto pragma_out; + } + if( rc!=SQLITE_NOTFOUND ){ + if( aFcntl[0] ){ + sqlite3ErrorMsg(pParse, "%s", aFcntl[0]); + sqlite3_free(aFcntl[0]); + } + pParse->nErr++; + pParse->rc = rc; + goto pragma_out; + } + + /* Locate the pragma in the lookup table */ + lwr = 0; + upr = ArraySize(aPragmaNames)-1; + while( lwr<=upr ){ + mid = (lwr+upr)/2; + rc = sqlite3_stricmp(zLeft, aPragmaNames[mid].zName); + if( rc==0 ) break; + if( rc<0 ){ + upr = mid - 1; + }else{ + lwr = mid + 1; + } + } + if( lwr>upr ) goto pragma_out; + pPragma = &aPragmaNames[mid]; + + /* Make sure the database schema is loaded if the pragma requires that */ + if( (pPragma->mPragFlag & PragFlag_NeedSchema)!=0 ){ + if( sqlite3ReadSchema(pParse) ) goto pragma_out; + } + + /* Jump to the appropriate pragma handler */ + switch( pPragma->ePragTyp ){ + +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) + /* + ** PRAGMA [database.]default_cache_size + ** PRAGMA [database.]default_cache_size=N + ** + ** The first form reports the current persistent setting for the + ** page cache size. The value returned is the maximum number of + ** pages in the page cache. The second form sets both the current + ** page cache size value and the persistent page cache size value + ** stored in the database file. + ** + ** Older versions of SQLite would set the default cache size to a + ** negative number to indicate synchronous=OFF. These days, synchronous + ** is always on by default regardless of the sign of the default cache + ** size. But continue to take the absolute value of the default cache + ** size of historical compatibility. + */ + case PragTyp_DEFAULT_CACHE_SIZE: { + static const int iLn = VDBE_OFFSET_LINENO(2); + static const VdbeOpList getCacheSize[] = { + { OP_Transaction, 0, 0, 0}, /* 0 */ + { OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 1 */ + { OP_IfPos, 1, 8, 0}, + { OP_Integer, 0, 2, 0}, + { OP_Subtract, 1, 2, 1}, + { OP_IfPos, 1, 8, 0}, + { OP_Integer, 0, 1, 0}, /* 6 */ + { OP_Noop, 0, 0, 0}, + { OP_ResultRow, 1, 1, 0}, + }; + int addr; + sqlite3VdbeUsesBtree(v, iDb); + if( !zRight ){ + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", SQLITE_STATIC); + pParse->nMem += 2; + addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize,iLn); + sqlite3VdbeChangeP1(v, addr, iDb); + sqlite3VdbeChangeP1(v, addr+1, iDb); + sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE); + }else{ + int size = sqlite3AbsInt32(sqlite3Atoi(zRight)); + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3VdbeAddOp2(v, OP_Integer, size, 1); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, 1); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pDb->pSchema->cache_size = size; + sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); + } + break; + } +#endif /* !SQLITE_OMIT_PAGER_PRAGMAS && !SQLITE_OMIT_DEPRECATED */ + +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + /* + ** PRAGMA [database.]page_size + ** PRAGMA [database.]page_size=N + ** + ** The first form reports the current setting for the + ** database page size in bytes. The second form sets the + ** database page size value. The value can only be set if + ** the database has not yet been created. + */ + case PragTyp_PAGE_SIZE: { + Btree *pBt = pDb->pBt; + assert( pBt!=0 ); + if( !zRight ){ + int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0; + returnSingleInt(pParse, "page_size", size); + }else{ + /* Malloc may fail when setting the page-size, as there is an internal + ** buffer that the pager module resizes using sqlite3_realloc(). + */ + db->nextPagesize = sqlite3Atoi(zRight); + if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,-1,0) ){ + db->mallocFailed = 1; + } + } + break; + } + + /* + ** PRAGMA [database.]secure_delete + ** PRAGMA [database.]secure_delete=ON/OFF + ** + ** The first form reports the current setting for the + ** secure_delete flag. The second form changes the secure_delete + ** flag setting and reports thenew value. + */ + case PragTyp_SECURE_DELETE: { + Btree *pBt = pDb->pBt; + int b = -1; + assert( pBt!=0 ); + if( zRight ){ + b = sqlite3GetBoolean(zRight, 0); + } + if( pId2->n==0 && b>=0 ){ + int ii; + for(ii=0; iinDb; ii++){ + sqlite3BtreeSecureDelete(db->aDb[ii].pBt, b); + } + } + b = sqlite3BtreeSecureDelete(pBt, b); + returnSingleInt(pParse, "secure_delete", b); + break; + } + + /* + ** PRAGMA [database.]max_page_count + ** PRAGMA [database.]max_page_count=N + ** + ** The first form reports the current setting for the + ** maximum number of pages in the database file. The + ** second form attempts to change this setting. Both + ** forms return the current setting. + ** + ** The absolute value of N is used. This is undocumented and might + ** change. The only purpose is to provide an easy way to test + ** the sqlite3AbsInt32() function. + ** + ** PRAGMA [database.]page_count + ** + ** Return the number of pages in the specified database. + */ + case PragTyp_PAGE_COUNT: { + int iReg; + sqlite3CodeVerifySchema(pParse, iDb); + iReg = ++pParse->nMem; + if( sqlite3Tolower(zLeft[0])=='p' ){ + sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg); + }else{ + sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, + sqlite3AbsInt32(sqlite3Atoi(zRight))); + } + sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT); + break; + } + + /* + ** PRAGMA [database.]locking_mode + ** PRAGMA [database.]locking_mode = (normal|exclusive) + */ + case PragTyp_LOCKING_MODE: { + const char *zRet = "normal"; + int eMode = getLockingMode(zRight); + + if( pId2->n==0 && eMode==PAGER_LOCKINGMODE_QUERY ){ + /* Simple "PRAGMA locking_mode;" statement. This is a query for + ** the current default locking mode (which may be different to + ** the locking-mode of the main database). + */ + eMode = db->dfltLockMode; + }else{ + Pager *pPager; + if( pId2->n==0 ){ + /* This indicates that no database name was specified as part + ** of the PRAGMA command. In this case the locking-mode must be + ** set on all attached databases, as well as the main db file. + ** + ** Also, the sqlite3.dfltLockMode variable is set so that + ** any subsequently attached databases also use the specified + ** locking mode. + */ + int ii; + assert(pDb==&db->aDb[0]); + for(ii=2; iinDb; ii++){ + pPager = sqlite3BtreePager(db->aDb[ii].pBt); + sqlite3PagerLockingMode(pPager, eMode); + } + db->dfltLockMode = (u8)eMode; + } + pPager = sqlite3BtreePager(pDb->pBt); + eMode = sqlite3PagerLockingMode(pPager, eMode); + } + + assert( eMode==PAGER_LOCKINGMODE_NORMAL + || eMode==PAGER_LOCKINGMODE_EXCLUSIVE ); + if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){ + zRet = "exclusive"; + } + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "locking_mode", SQLITE_STATIC); + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zRet, 0); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + break; + } + + /* + ** PRAGMA [database.]journal_mode + ** PRAGMA [database.]journal_mode = + ** (delete|persist|off|truncate|memory|wal|off) + */ + case PragTyp_JOURNAL_MODE: { + int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */ + int ii; /* Loop counter */ + + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", SQLITE_STATIC); + + if( zRight==0 ){ + /* If there is no "=MODE" part of the pragma, do a query for the + ** current mode */ + eMode = PAGER_JOURNALMODE_QUERY; + }else{ + const char *zMode; + int n = sqlite3Strlen30(zRight); + for(eMode=0; (zMode = sqlite3JournalModename(eMode))!=0; eMode++){ + if( sqlite3StrNICmp(zRight, zMode, n)==0 ) break; + } + if( !zMode ){ + /* If the "=MODE" part does not match any known journal mode, + ** then do a query */ + eMode = PAGER_JOURNALMODE_QUERY; + } + } + if( eMode==PAGER_JOURNALMODE_QUERY && pId2->n==0 ){ + /* Convert "PRAGMA journal_mode" into "PRAGMA main.journal_mode" */ + iDb = 0; + pId2->n = 1; + } + for(ii=db->nDb-1; ii>=0; ii--){ + if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ + sqlite3VdbeUsesBtree(v, ii); + sqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode); + } + } + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + break; + } + + /* + ** PRAGMA [database.]journal_size_limit + ** PRAGMA [database.]journal_size_limit=N + ** + ** Get or set the size limit on rollback journal files. + */ + case PragTyp_JOURNAL_SIZE_LIMIT: { + Pager *pPager = sqlite3BtreePager(pDb->pBt); + i64 iLimit = -2; + if( zRight ){ + sqlite3DecOrHexToI64(zRight, &iLimit); + if( iLimit<-1 ) iLimit = -1; + } + iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); + returnSingleInt(pParse, "journal_size_limit", iLimit); + break; + } + +#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ + + /* + ** PRAGMA [database.]auto_vacuum + ** PRAGMA [database.]auto_vacuum=N + ** + ** Get or set the value of the database 'auto-vacuum' parameter. + ** The value is one of: 0 NONE 1 FULL 2 INCREMENTAL + */ +#ifndef SQLITE_OMIT_AUTOVACUUM + case PragTyp_AUTO_VACUUM: { + Btree *pBt = pDb->pBt; + assert( pBt!=0 ); + if( !zRight ){ + returnSingleInt(pParse, "auto_vacuum", sqlite3BtreeGetAutoVacuum(pBt)); + }else{ + int eAuto = getAutoVacuum(zRight); + assert( eAuto>=0 && eAuto<=2 ); + db->nextAutovac = (u8)eAuto; + /* Call SetAutoVacuum() to set initialize the internal auto and + ** incr-vacuum flags. This is required in case this connection + ** creates the database file. It is important that it is created + ** as an auto-vacuum capable db. + */ + rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto); + if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){ + /* When setting the auto_vacuum mode to either "full" or + ** "incremental", write the value of meta[6] in the database + ** file. Before writing to meta[6], check that meta[3] indicates + ** that this really is an auto-vacuum capable database. + */ + static const int iLn = VDBE_OFFSET_LINENO(2); + static const VdbeOpList setMeta6[] = { + { OP_Transaction, 0, 1, 0}, /* 0 */ + { OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE}, + { OP_If, 1, 0, 0}, /* 2 */ + { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */ + { OP_Integer, 0, 1, 0}, /* 4 */ + { OP_SetCookie, 0, BTREE_INCR_VACUUM, 1}, /* 5 */ + }; + int iAddr; + iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6, iLn); + sqlite3VdbeChangeP1(v, iAddr, iDb); + sqlite3VdbeChangeP1(v, iAddr+1, iDb); + sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4); + sqlite3VdbeChangeP1(v, iAddr+4, eAuto-1); + sqlite3VdbeChangeP1(v, iAddr+5, iDb); + sqlite3VdbeUsesBtree(v, iDb); + } + } + break; + } +#endif + + /* + ** PRAGMA [database.]incremental_vacuum(N) + ** + ** Do N steps of incremental vacuuming on a database. + */ +#ifndef SQLITE_OMIT_AUTOVACUUM + case PragTyp_INCREMENTAL_VACUUM: { + int iLimit, addr; + if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){ + iLimit = 0x7fffffff; + } + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1); + addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb); VdbeCoverage(v); + sqlite3VdbeAddOp1(v, OP_ResultRow, 1); + sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); + sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr); + break; + } +#endif + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS + /* + ** PRAGMA [database.]cache_size + ** PRAGMA [database.]cache_size=N + ** + ** The first form reports the current local setting for the + ** page cache size. The second form sets the local + ** page cache size value. If N is positive then that is the + ** number of pages in the cache. If N is negative, then the + ** number of pages is adjusted so that the cache uses -N kibibytes + ** of memory. + */ + case PragTyp_CACHE_SIZE: { + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + if( !zRight ){ + returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size); + }else{ + int size = sqlite3Atoi(zRight); + pDb->pSchema->cache_size = size; + sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); + } + break; + } + + /* + ** PRAGMA [database.]mmap_size(N) + ** + ** Used to set mapping size limit. The mapping size limit is + ** used to limit the aggregate size of all memory mapped regions of the + ** database file. If this parameter is set to zero, then memory mapping + ** is not used at all. If N is negative, then the default memory map + ** limit determined by sqlite3_config(SQLITE_CONFIG_MMAP_SIZE) is set. + ** The parameter N is measured in bytes. + ** + ** This value is advisory. The underlying VFS is free to memory map + ** as little or as much as it wants. Except, if N is set to 0 then the + ** upper layers will never invoke the xFetch interfaces to the VFS. + */ + case PragTyp_MMAP_SIZE: { + sqlite3_int64 sz; +#if SQLITE_MAX_MMAP_SIZE>0 + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + if( zRight ){ + int ii; + sqlite3DecOrHexToI64(zRight, &sz); + if( sz<0 ) sz = sqlite3GlobalConfig.szMmap; + if( pId2->n==0 ) db->szMmap = sz; + for(ii=db->nDb-1; ii>=0; ii--){ + if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ + sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz); + } + } + } + sz = -1; + rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_MMAP_SIZE, &sz); +#else + sz = 0; + rc = SQLITE_OK; +#endif + if( rc==SQLITE_OK ){ + returnSingleInt(pParse, "mmap_size", sz); + }else if( rc!=SQLITE_NOTFOUND ){ + pParse->nErr++; + pParse->rc = rc; + } + break; + } + + /* + ** PRAGMA temp_store + ** PRAGMA temp_store = "default"|"memory"|"file" + ** + ** Return or set the local value of the temp_store flag. Changing + ** the local value does not make changes to the disk file and the default + ** value will be restored the next time the database is opened. + ** + ** Note that it is possible for the library compile-time options to + ** override this setting + */ + case PragTyp_TEMP_STORE: { + if( !zRight ){ + returnSingleInt(pParse, "temp_store", db->temp_store); + }else{ + changeTempStorage(pParse, zRight); + } + break; + } + + /* + ** PRAGMA temp_store_directory + ** PRAGMA temp_store_directory = ""|"directory_name" + ** + ** Return or set the local value of the temp_store_directory flag. Changing + ** the value sets a specific directory to be used for temporary files. + ** Setting to a null string reverts to the default temporary directory search. + ** If temporary directory is changed, then invalidateTempStorage. + ** + */ + case PragTyp_TEMP_STORE_DIRECTORY: { + if( !zRight ){ + if( sqlite3_temp_directory ){ + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, + "temp_store_directory", SQLITE_STATIC); + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_temp_directory, 0); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + } + }else{ +#ifndef SQLITE_OMIT_WSD + if( zRight[0] ){ + int res; + rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); + if( rc!=SQLITE_OK || res==0 ){ + sqlite3ErrorMsg(pParse, "not a writable directory"); + goto pragma_out; + } + } + if( SQLITE_TEMP_STORE==0 + || (SQLITE_TEMP_STORE==1 && db->temp_store<=1) + || (SQLITE_TEMP_STORE==2 && db->temp_store==1) + ){ + invalidateTempStorage(pParse); + } + sqlite3_free(sqlite3_temp_directory); + if( zRight[0] ){ + sqlite3_temp_directory = sqlite3_mprintf("%s", zRight); + }else{ + sqlite3_temp_directory = 0; + } +#endif /* SQLITE_OMIT_WSD */ + } + break; + } + +#if SQLITE_OS_WIN + /* + ** PRAGMA data_store_directory + ** PRAGMA data_store_directory = ""|"directory_name" + ** + ** Return or set the local value of the data_store_directory flag. Changing + ** the value sets a specific directory to be used for database files that + ** were specified with a relative pathname. Setting to a null string reverts + ** to the default database directory, which for database files specified with + ** a relative path will probably be based on the current directory for the + ** process. Database file specified with an absolute path are not impacted + ** by this setting, regardless of its value. + ** + */ + case PragTyp_DATA_STORE_DIRECTORY: { + if( !zRight ){ + if( sqlite3_data_directory ){ + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, + "data_store_directory", SQLITE_STATIC); + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_data_directory, 0); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + } + }else{ +#ifndef SQLITE_OMIT_WSD + if( zRight[0] ){ + int res; + rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); + if( rc!=SQLITE_OK || res==0 ){ + sqlite3ErrorMsg(pParse, "not a writable directory"); + goto pragma_out; + } + } + sqlite3_free(sqlite3_data_directory); + if( zRight[0] ){ + sqlite3_data_directory = sqlite3_mprintf("%s", zRight); + }else{ + sqlite3_data_directory = 0; + } +#endif /* SQLITE_OMIT_WSD */ + } + break; + } +#endif + +#if SQLITE_ENABLE_LOCKING_STYLE + /* + ** PRAGMA [database.]lock_proxy_file + ** PRAGMA [database.]lock_proxy_file = ":auto:"|"lock_file_path" + ** + ** Return or set the value of the lock_proxy_file flag. Changing + ** the value sets a specific file to be used for database access locks. + ** + */ + case PragTyp_LOCK_PROXY_FILE: { + if( !zRight ){ + Pager *pPager = sqlite3BtreePager(pDb->pBt); + char *proxy_file_path = NULL; + sqlite3_file *pFile = sqlite3PagerFile(pPager); + sqlite3OsFileControlHint(pFile, SQLITE_GET_LOCKPROXYFILE, + &proxy_file_path); + + if( proxy_file_path ){ + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, + "lock_proxy_file", SQLITE_STATIC); + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, proxy_file_path, 0); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + } + }else{ + Pager *pPager = sqlite3BtreePager(pDb->pBt); + sqlite3_file *pFile = sqlite3PagerFile(pPager); + int res; + if( zRight[0] ){ + res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE, + zRight); + } else { + res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE, + NULL); + } + if( res!=SQLITE_OK ){ + sqlite3ErrorMsg(pParse, "failed to set lock proxy file"); + goto pragma_out; + } + } + break; + } +#endif /* SQLITE_ENABLE_LOCKING_STYLE */ + + /* + ** PRAGMA [database.]synchronous + ** PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL + ** + ** Return or set the local value of the synchronous flag. Changing + ** the local value does not make changes to the disk file and the + ** default value will be restored the next time the database is + ** opened. + */ + case PragTyp_SYNCHRONOUS: { + if( !zRight ){ + returnSingleInt(pParse, "synchronous", pDb->safety_level-1); + }else{ + if( !db->autoCommit ){ + sqlite3ErrorMsg(pParse, + "Safety level may not be changed inside a transaction"); + }else{ + int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK; + if( iLevel==0 ) iLevel = 1; + pDb->safety_level = iLevel; + setAllPagerFlags(db); + } + } + break; + } +#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ + +#ifndef SQLITE_OMIT_FLAG_PRAGMAS + case PragTyp_FLAG: { + if( zRight==0 ){ + returnSingleInt(pParse, pPragma->zName, (db->flags & pPragma->iArg)!=0 ); + }else{ + int mask = pPragma->iArg; /* Mask of bits to set or clear. */ + if( db->autoCommit==0 ){ + /* Foreign key support may not be enabled or disabled while not + ** in auto-commit mode. */ + mask &= ~(SQLITE_ForeignKeys); + } +#if SQLITE_USER_AUTHENTICATION + if( db->auth.authLevel==UAUTH_User ){ + /* Do not allow non-admin users to modify the schema arbitrarily */ + mask &= ~(SQLITE_WriteSchema); + } +#endif + + if( sqlite3GetBoolean(zRight, 0) ){ + db->flags |= mask; + }else{ + db->flags &= ~mask; + if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0; + } + + /* Many of the flag-pragmas modify the code generated by the SQL + ** compiler (eg. count_changes). So add an opcode to expire all + ** compiled SQL statements after modifying a pragma value. + */ + sqlite3VdbeAddOp2(v, OP_Expire, 0, 0); + setAllPagerFlags(db); + } + break; + } +#endif /* SQLITE_OMIT_FLAG_PRAGMAS */ + +#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS + /* + ** PRAGMA table_info(
    ) + ** + ** Return a single row for each column of the named table. The columns of + ** the returned data set are: + ** + ** cid: Column id (numbered from left to right, starting at 0) + ** name: Column name + ** type: Column declaration type. + ** notnull: True if 'NOT NULL' is part of column declaration + ** dflt_value: The default value for the column, if any. + */ + case PragTyp_TABLE_INFO: if( zRight ){ + Table *pTab; + pTab = sqlite3FindTable(db, zRight, zDb); + if( pTab ){ + int i, k; + int nHidden = 0; + Column *pCol; + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + sqlite3VdbeSetNumCols(v, 6); + pParse->nMem = 6; + sqlite3CodeVerifySchema(pParse, iDb); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "notnull", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "dflt_value", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "pk", SQLITE_STATIC); + sqlite3ViewGetColumnNames(pParse, pTab); + for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ + if( IsHiddenColumn(pCol) ){ + nHidden++; + continue; + } + sqlite3VdbeAddOp2(v, OP_Integer, i-nHidden, 1); + sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pCol->zName, 0); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, + pCol->zType ? pCol->zType : "", 0); + sqlite3VdbeAddOp2(v, OP_Integer, (pCol->notNull ? 1 : 0), 4); + if( pCol->zDflt ){ + sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)pCol->zDflt, 0); + }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, 5); + } + if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){ + k = 0; + }else if( pPk==0 ){ + k = 1; + }else{ + for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){} + } + sqlite3VdbeAddOp2(v, OP_Integer, k, 6); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6); + } + } + } + break; + + case PragTyp_STATS: { + Index *pIdx; + HashElem *i; + v = sqlite3GetVdbe(pParse); + sqlite3VdbeSetNumCols(v, 4); + pParse->nMem = 4; + sqlite3CodeVerifySchema(pParse, iDb); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "table", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "index", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "width", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "height", SQLITE_STATIC); + for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){ + Table *pTab = sqliteHashData(i); + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, pTab->zName, 0); + sqlite3VdbeAddOp2(v, OP_Null, 0, 2); + sqlite3VdbeAddOp2(v, OP_Integer, + (int)sqlite3LogEstToInt(pTab->szTabRow), 3); + sqlite3VdbeAddOp2(v, OP_Integer, + (int)sqlite3LogEstToInt(pTab->nRowLogEst), 4); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4); + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0); + sqlite3VdbeAddOp2(v, OP_Integer, + (int)sqlite3LogEstToInt(pIdx->szIdxRow), 3); + sqlite3VdbeAddOp2(v, OP_Integer, + (int)sqlite3LogEstToInt(pIdx->aiRowLogEst[0]), 4); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4); + } + } + } + break; + + case PragTyp_INDEX_INFO: if( zRight ){ + Index *pIdx; + Table *pTab; + pIdx = sqlite3FindIndex(db, zRight, zDb); + if( pIdx ){ + int i; + int mx; + if( pPragma->iArg ){ + /* PRAGMA index_xinfo (newer version with more rows and columns) */ + mx = pIdx->nColumn; + pParse->nMem = 6; + }else{ + /* PRAGMA index_info (legacy version) */ + mx = pIdx->nKeyCol; + pParse->nMem = 3; + } + pTab = pIdx->pTable; + sqlite3VdbeSetNumCols(v, pParse->nMem); + sqlite3CodeVerifySchema(pParse, iDb); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", SQLITE_STATIC); + if( pPragma->iArg ){ + sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "desc", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "coll", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "key", SQLITE_STATIC); + } + for(i=0; iaiColumn[i]; + sqlite3VdbeAddOp2(v, OP_Integer, i, 1); + sqlite3VdbeAddOp2(v, OP_Integer, cnum, 2); + if( cnum<0 ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, 3); + }else{ + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pTab->aCol[cnum].zName, 0); + } + if( pPragma->iArg ){ + sqlite3VdbeAddOp2(v, OP_Integer, pIdx->aSortOrder[i], 4); + sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, pIdx->azColl[i], 0); + sqlite3VdbeAddOp2(v, OP_Integer, inKeyCol, 6); + } + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, pParse->nMem); + } + } + } + break; + + case PragTyp_INDEX_LIST: if( zRight ){ + Index *pIdx; + Table *pTab; + int i; + pTab = sqlite3FindTable(db, zRight, zDb); + if( pTab ){ + v = sqlite3GetVdbe(pParse); + sqlite3VdbeSetNumCols(v, 5); + pParse->nMem = 5; + sqlite3CodeVerifySchema(pParse, iDb); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "origin", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "partial", SQLITE_STATIC); + for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){ + const char *azOrigin[] = { "c", "u", "pk" }; + sqlite3VdbeAddOp2(v, OP_Integer, i, 1); + sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0); + sqlite3VdbeAddOp2(v, OP_Integer, IsUniqueIndex(pIdx), 3); + sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, azOrigin[pIdx->idxType], 0); + sqlite3VdbeAddOp2(v, OP_Integer, pIdx->pPartIdxWhere!=0, 5); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5); + } + } + } + break; + + case PragTyp_DATABASE_LIST: { + int i; + sqlite3VdbeSetNumCols(v, 3); + pParse->nMem = 3; + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "file", SQLITE_STATIC); + for(i=0; inDb; i++){ + if( db->aDb[i].pBt==0 ) continue; + assert( db->aDb[i].zName!=0 ); + sqlite3VdbeAddOp2(v, OP_Integer, i, 1); + sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, db->aDb[i].zName, 0); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, + sqlite3BtreeGetFilename(db->aDb[i].pBt), 0); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); + } + } + break; + + case PragTyp_COLLATION_LIST: { + int i = 0; + HashElem *p; + sqlite3VdbeSetNumCols(v, 2); + pParse->nMem = 2; + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC); + for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){ + CollSeq *pColl = (CollSeq *)sqliteHashData(p); + sqlite3VdbeAddOp2(v, OP_Integer, i++, 1); + sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pColl->zName, 0); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); + } + } + break; +#endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */ + +#ifndef SQLITE_OMIT_FOREIGN_KEY + case PragTyp_FOREIGN_KEY_LIST: if( zRight ){ + FKey *pFK; + Table *pTab; + pTab = sqlite3FindTable(db, zRight, zDb); + if( pTab ){ + v = sqlite3GetVdbe(pParse); + pFK = pTab->pFKey; + if( pFK ){ + int i = 0; + sqlite3VdbeSetNumCols(v, 8); + pParse->nMem = 8; + sqlite3CodeVerifySchema(pParse, iDb); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "id", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "seq", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "table", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "from", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "to", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "on_update", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 6, COLNAME_NAME, "on_delete", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 7, COLNAME_NAME, "match", SQLITE_STATIC); + while(pFK){ + int j; + for(j=0; jnCol; j++){ + char *zCol = pFK->aCol[j].zCol; + char *zOnDelete = (char *)actionName(pFK->aAction[0]); + char *zOnUpdate = (char *)actionName(pFK->aAction[1]); + sqlite3VdbeAddOp2(v, OP_Integer, i, 1); + sqlite3VdbeAddOp2(v, OP_Integer, j, 2); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pFK->zTo, 0); + sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, + pTab->aCol[pFK->aCol[j].iFrom].zName, 0); + sqlite3VdbeAddOp4(v, zCol ? OP_String8 : OP_Null, 0, 5, 0, zCol, 0); + sqlite3VdbeAddOp4(v, OP_String8, 0, 6, 0, zOnUpdate, 0); + sqlite3VdbeAddOp4(v, OP_String8, 0, 7, 0, zOnDelete, 0); + sqlite3VdbeAddOp4(v, OP_String8, 0, 8, 0, "NONE", 0); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 8); + } + ++i; + pFK = pFK->pNextFrom; + } + } + } + } + break; +#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ + +#ifndef SQLITE_OMIT_FOREIGN_KEY +#ifndef SQLITE_OMIT_TRIGGER + case PragTyp_FOREIGN_KEY_CHECK: { + FKey *pFK; /* A foreign key constraint */ + Table *pTab; /* Child table contain "REFERENCES" keyword */ + Table *pParent; /* Parent table that child points to */ + Index *pIdx; /* Index in the parent table */ + int i; /* Loop counter: Foreign key number for pTab */ + int j; /* Loop counter: Field of the foreign key */ + HashElem *k; /* Loop counter: Next table in schema */ + int x; /* result variable */ + int regResult; /* 3 registers to hold a result row */ + int regKey; /* Register to hold key for checking the FK */ + int regRow; /* Registers to hold a row from pTab */ + int addrTop; /* Top of a loop checking foreign keys */ + int addrOk; /* Jump here if the key is OK */ + int *aiCols; /* child to parent column mapping */ + + regResult = pParse->nMem+1; + pParse->nMem += 4; + regKey = ++pParse->nMem; + regRow = ++pParse->nMem; + v = sqlite3GetVdbe(pParse); + sqlite3VdbeSetNumCols(v, 4); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "table", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "rowid", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "parent", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "fkid", SQLITE_STATIC); + sqlite3CodeVerifySchema(pParse, iDb); + k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash); + while( k ){ + if( zRight ){ + pTab = sqlite3LocateTable(pParse, 0, zRight, zDb); + k = 0; + }else{ + pTab = (Table*)sqliteHashData(k); + k = sqliteHashNext(k); + } + if( pTab==0 || pTab->pFKey==0 ) continue; + sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow; + sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead); + sqlite3VdbeAddOp4(v, OP_String8, 0, regResult, 0, pTab->zName, + P4_TRANSIENT); + for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){ + pParent = sqlite3FindTable(db, pFK->zTo, zDb); + if( pParent==0 ) continue; + pIdx = 0; + sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName); + x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0); + if( x==0 ){ + if( pIdx==0 ){ + sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead); + }else{ + sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); + } + }else{ + k = 0; + break; + } + } + assert( pParse->nErr>0 || pFK==0 ); + if( pFK ) break; + if( pParse->nTabnTab = i; + addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); VdbeCoverage(v); + for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){ + pParent = sqlite3FindTable(db, pFK->zTo, zDb); + pIdx = 0; + aiCols = 0; + if( pParent ){ + x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols); + assert( x==0 ); + } + addrOk = sqlite3VdbeMakeLabel(v); + if( pParent && pIdx==0 ){ + int iKey = pFK->aCol[0].iFrom; + assert( iKey>=0 && iKeynCol ); + if( iKey!=pTab->iPKey ){ + sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow); + sqlite3ColumnDefault(v, pTab, iKey, regRow); + sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_MustBeInt, regRow, + sqlite3VdbeCurrentAddr(v)+3); VdbeCoverage(v); + }else{ + sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow); + } + sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrOk); + sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); + }else{ + for(j=0; jnCol; j++){ + sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, + aiCols ? aiCols[j] : pFK->aCol[j].iFrom, regRow+j); + sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v); + } + if( pParent ){ + sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey, + sqlite3IndexAffinityStr(v,pIdx), pFK->nCol); + sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0); + VdbeCoverage(v); + } + } + sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1); + sqlite3VdbeAddOp4(v, OP_String8, 0, regResult+2, 0, + pFK->zTo, P4_TRANSIENT); + sqlite3VdbeAddOp2(v, OP_Integer, i-1, regResult+3); + sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4); + sqlite3VdbeResolveLabel(v, addrOk); + sqlite3DbFree(db, aiCols); + } + sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addrTop); + } + } + break; +#endif /* !defined(SQLITE_OMIT_TRIGGER) */ +#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ + +#ifndef NDEBUG + case PragTyp_PARSER_TRACE: { + if( zRight ){ + if( sqlite3GetBoolean(zRight, 0) ){ + sqlite3ParserTrace(stderr, "parser: "); + }else{ + sqlite3ParserTrace(0, 0); + } + } + } + break; +#endif + + /* Reinstall the LIKE and GLOB functions. The variant of LIKE + ** used will be case sensitive or not depending on the RHS. + */ + case PragTyp_CASE_SENSITIVE_LIKE: { + if( zRight ){ + sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight, 0)); + } + } + break; + +#ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX +# define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100 +#endif + +#ifndef SQLITE_OMIT_INTEGRITY_CHECK + /* Pragma "quick_check" is reduced version of + ** integrity_check designed to detect most database corruption + ** without most of the overhead of a full integrity-check. + */ + case PragTyp_INTEGRITY_CHECK: { + int i, j, addr, mxErr; + + /* 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 int iLn = VDBE_OFFSET_LINENO(2); + static const VdbeOpList endCode[] = { + { OP_IfNeg, 1, 0, 0}, /* 0 */ + { OP_String8, 0, 3, 0}, /* 1 */ + { OP_ResultRow, 3, 1, 0}, + }; + + int isQuick = (sqlite3Tolower(zLeft[0])=='q'); + + /* If the PRAGMA command was of the form "PRAGMA .integrity_check", + ** then iDb is set to the index of the database identified by . + ** In this case, the integrity of database iDb only is verified by + ** the VDBE created below. + ** + ** Otherwise, if the command was simply "PRAGMA integrity_check" (or + ** "PRAGMA quick_check"), then iDb is set to 0. In this case, set iDb + ** to -1 here, to indicate that the VDBE should verify the integrity + ** of all attached databases. */ + assert( iDb>=0 ); + assert( iDb==0 || pId2->z ); + if( pId2->z==0 ) iDb = -1; + + /* Initialize the VDBE program */ + pParse->nMem = 6; + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", SQLITE_STATIC); + + /* Set the maximum error count */ + mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; + if( zRight ){ + sqlite3GetInt32(zRight, &mxErr); + if( mxErr<=0 ){ + mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; + } + } + sqlite3VdbeAddOp2(v, OP_Integer, mxErr, 1); /* reg[1] holds errors left */ + + /* Do an integrity check on each database file */ + for(i=0; inDb; i++){ + HashElem *x; + Hash *pTbls; + int cnt = 0; + + if( OMIT_TEMPDB && i==1 ) continue; + if( iDb>=0 && i!=iDb ) continue; + + sqlite3CodeVerifySchema(pParse, i); + addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */ + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); + sqlite3VdbeJumpHere(v, addr); + + /* Do an integrity check of the B-Tree + ** + ** Begin by filling registers 2, 3, ... with the root pages numbers + ** for all tables and indices in the database. + */ + assert( sqlite3SchemaMutexHeld(db, i, 0) ); + pTbls = &db->aDb[i].pSchema->tblHash; + for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ + Table *pTab = sqliteHashData(x); + Index *pIdx; + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 2+cnt); + VdbeComment((v, "%s", pTab->zName)); + cnt++; + } + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + sqlite3VdbeAddOp2(v, OP_Integer, pIdx->tnum, 2+cnt); + VdbeComment((v, "%s", pIdx->zName)); + cnt++; + } + } + + /* Make sure sufficient number of registers have been allocated */ + pParse->nMem = MAX( pParse->nMem, cnt+8 ); + + /* Do the b-tree integrity checks */ + sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1); + sqlite3VdbeChangeP5(v, (u8)i); + addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, + sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName), + P4_DYNAMIC); + sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1); + sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2); + sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1); + sqlite3VdbeJumpHere(v, addr); + + /* Make sure all the indices are constructed correctly. + */ + for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){ + Table *pTab = sqliteHashData(x); + Index *pIdx, *pPk; + Index *pPrior = 0; + int loopTop; + int iDataCur, iIdxCur; + int r1 = -1; + + if( pTab->pIndex==0 ) continue; + pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); + addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */ + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); + sqlite3VdbeJumpHere(v, addr); + sqlite3ExprCacheClear(pParse); + sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, + 1, 0, &iDataCur, &iIdxCur); + sqlite3VdbeAddOp2(v, OP_Integer, 0, 7); + for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ + sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */ + } + pParse->nMem = MAX(pParse->nMem, 8+j); + sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v); + loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); + /* Verify that all NOT NULL columns really are NOT NULL */ + for(j=0; jnCol; j++){ + char *zErr; + int jmp2, jmp3; + if( j==pTab->iPKey ) continue; + if( pTab->aCol[j].notNull==0 ) continue; + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); + sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); + jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ + zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, + pTab->aCol[j].zName); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); + sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); + jmp3 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v); + sqlite3VdbeAddOp0(v, OP_Halt); + sqlite3VdbeJumpHere(v, jmp2); + sqlite3VdbeJumpHere(v, jmp3); + } + /* Validate index entries for the current row */ + for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ + int jmp2, jmp3, jmp4, jmp5; + int ckUniq = sqlite3VdbeMakeLabel(v); + if( pPk==pIdx ) continue; + r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3, + pPrior, r1); + pPrior = pIdx; + sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1); /* increment entry count */ + /* Verify that an index entry exists for the current table row */ + jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1, + pIdx->nColumn); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, "row ", P4_STATIC); + sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); + sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, + " missing from index ", P4_STATIC); + sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); + jmp5 = sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, + pIdx->zName, P4_TRANSIENT); + sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); + sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); + jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v); + sqlite3VdbeAddOp0(v, OP_Halt); + sqlite3VdbeJumpHere(v, jmp2); + /* For UNIQUE indexes, verify that only one entry exists with the + ** current key. The entry is unique if (1) any column is NULL + ** or (2) the next entry has a different key */ + if( IsUniqueIndex(pIdx) ){ + int uniqOk = sqlite3VdbeMakeLabel(v); + int jmp6; + int kk; + for(kk=0; kknKeyCol; kk++){ + int iCol = pIdx->aiColumn[kk]; + assert( iCol>=0 && iColnCol ); + if( pTab->aCol[iCol].notNull ) continue; + sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk); + VdbeCoverage(v); + } + jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Goto, 0, uniqOk); + sqlite3VdbeJumpHere(v, jmp6); + sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1, + pIdx->nKeyCol); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, + "non-unique entry in index ", P4_STATIC); + sqlite3VdbeAddOp2(v, OP_Goto, 0, jmp5); + sqlite3VdbeResolveLabel(v, uniqOk); + } + sqlite3VdbeJumpHere(v, jmp4); + sqlite3ResolvePartIdxLabel(pParse, jmp3); + } + sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, loopTop-1); +#ifndef SQLITE_OMIT_BTREECOUNT + sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, + "wrong # of entries in index ", P4_STATIC); + for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ + if( pPk==pIdx ) continue; + addr = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); + sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3); + sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pIdx->zName, P4_TRANSIENT); + sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7); + sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1); + } +#endif /* SQLITE_OMIT_BTREECOUNT */ + } + } + addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn); + sqlite3VdbeChangeP3(v, addr, -mxErr); + sqlite3VdbeJumpHere(v, addr); + sqlite3VdbeChangeP4(v, addr+1, "ok", P4_STATIC); + } + break; +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +#ifndef SQLITE_OMIT_UTF16 + /* + ** PRAGMA encoding + ** PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be" + ** + ** In its first form, this pragma returns the encoding of the main + ** database. If the database is not initialized, it is initialized now. + ** + ** The second form of this pragma is a no-op if the main database file + ** has not already been initialized. In this case it sets the default + ** encoding that will be used for the main database file if a new file + ** is created. If an existing main database file is opened, then the + ** default text encoding for the existing database is used. + ** + ** In all cases new databases created using the ATTACH command are + ** created to use the same default text encoding as the main database. If + ** the main database has not been initialized and/or created when ATTACH + ** is executed, this is done before the ATTACH operation. + ** + ** In the second form this pragma sets the text encoding to be used in + ** new database files created using this database handle. It is only + ** useful if invoked immediately after the main database i + */ + case PragTyp_ENCODING: { + static const struct EncName { + char *zName; + u8 enc; + } encnames[] = { + { "UTF8", SQLITE_UTF8 }, + { "UTF-8", SQLITE_UTF8 }, /* Must be element [1] */ + { "UTF-16le", SQLITE_UTF16LE }, /* Must be element [2] */ + { "UTF-16be", SQLITE_UTF16BE }, /* Must be element [3] */ + { "UTF16le", SQLITE_UTF16LE }, + { "UTF16be", SQLITE_UTF16BE }, + { "UTF-16", 0 }, /* SQLITE_UTF16NATIVE */ + { "UTF16", 0 }, /* SQLITE_UTF16NATIVE */ + { 0, 0 } + }; + const struct EncName *pEnc; + if( !zRight ){ /* "PRAGMA encoding" */ + if( sqlite3ReadSchema(pParse) ) goto pragma_out; + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "encoding", SQLITE_STATIC); + sqlite3VdbeAddOp2(v, OP_String8, 0, 1); + assert( encnames[SQLITE_UTF8].enc==SQLITE_UTF8 ); + assert( encnames[SQLITE_UTF16LE].enc==SQLITE_UTF16LE ); + assert( encnames[SQLITE_UTF16BE].enc==SQLITE_UTF16BE ); + sqlite3VdbeChangeP4(v, -1, encnames[ENC(pParse->db)].zName, P4_STATIC); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + }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) ){ + SCHEMA_ENC(db) = ENC(db) = + pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE; + break; + } + } + if( !pEnc->zName ){ + sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight); + } + } + } + } + break; +#endif /* SQLITE_OMIT_UTF16 */ + +#ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS + /* + ** PRAGMA [database.]schema_version + ** PRAGMA [database.]schema_version = + ** + ** PRAGMA [database.]user_version + ** PRAGMA [database.]user_version = + ** + ** PRAGMA [database.]freelist_count = + ** + ** PRAGMA [database.]application_id + ** PRAGMA [database.]application_id = + ** + ** The pragma's schema_version and user_version are used to set or get + ** the value of the schema-version and user-version, respectively. Both + ** the schema-version and the user-version are 32-bit signed integers + ** stored in the database header. + ** + ** The schema-cookie is usually only manipulated internally by SQLite. It + ** is incremented by SQLite whenever the database schema is modified (by + ** creating or dropping a table or index). The schema version is used by + ** SQLite each time a query is executed to ensure that the internal cache + ** of the schema used when compiling the SQL query matches the schema of + ** the database against which the compiled query is actually executed. + ** Subverting this mechanism by using "PRAGMA schema_version" to modify + ** the schema-version is potentially dangerous and may lead to program + ** crashes or database corruption. Use with caution! + ** + ** The user-version is not used internally by SQLite. It may be used by + ** applications for any purpose. + */ + case PragTyp_HEADER_VALUE: { + int iCookie = pPragma->iArg; /* Which cookie to read or write */ + sqlite3VdbeUsesBtree(v, iDb); + if( zRight && (pPragma->mPragFlag & PragFlag_ReadOnly)==0 ){ + /* Write the specified cookie value */ + static const VdbeOpList setCookie[] = { + { OP_Transaction, 0, 1, 0}, /* 0 */ + { OP_Integer, 0, 1, 0}, /* 1 */ + { OP_SetCookie, 0, 0, 1}, /* 2 */ + }; + int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0); + sqlite3VdbeChangeP1(v, addr, iDb); + sqlite3VdbeChangeP1(v, addr+1, sqlite3Atoi(zRight)); + sqlite3VdbeChangeP1(v, addr+2, iDb); + sqlite3VdbeChangeP2(v, addr+2, iCookie); + }else{ + /* Read the specified cookie value */ + static const VdbeOpList readCookie[] = { + { OP_Transaction, 0, 0, 0}, /* 0 */ + { OP_ReadCookie, 0, 1, 0}, /* 1 */ + { OP_ResultRow, 1, 1, 0} + }; + int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie, 0); + sqlite3VdbeChangeP1(v, addr, iDb); + sqlite3VdbeChangeP1(v, addr+1, iDb); + sqlite3VdbeChangeP3(v, addr+1, iCookie); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT); + } + } + break; +#endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */ + +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS + /* + ** PRAGMA compile_options + ** + ** Return the names of all compile-time options used in this build, + ** one option per row. + */ + case PragTyp_COMPILE_OPTIONS: { + int i = 0; + const char *zOpt; + sqlite3VdbeSetNumCols(v, 1); + pParse->nMem = 1; + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "compile_option", SQLITE_STATIC); + while( (zOpt = sqlite3_compileoption_get(i++))!=0 ){ + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zOpt, 0); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + } + } + break; +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ + +#ifndef SQLITE_OMIT_WAL + /* + ** PRAGMA [database.]wal_checkpoint = passive|full|restart|truncate + ** + ** Checkpoint the database. + */ + case PragTyp_WAL_CHECKPOINT: { + int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED); + int eMode = SQLITE_CHECKPOINT_PASSIVE; + if( zRight ){ + if( sqlite3StrICmp(zRight, "full")==0 ){ + eMode = SQLITE_CHECKPOINT_FULL; + }else if( sqlite3StrICmp(zRight, "restart")==0 ){ + eMode = SQLITE_CHECKPOINT_RESTART; + }else if( sqlite3StrICmp(zRight, "truncate")==0 ){ + eMode = SQLITE_CHECKPOINT_TRUNCATE; + } + } + sqlite3VdbeSetNumCols(v, 3); + pParse->nMem = 3; + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "busy", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "log", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "checkpointed", SQLITE_STATIC); + + sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); + } + break; + + /* + ** PRAGMA wal_autocheckpoint + ** PRAGMA wal_autocheckpoint = N + ** + ** Configure a database connection to automatically checkpoint a database + ** after accumulating N frames in the log. Or query for the current value + ** of N. + */ + case PragTyp_WAL_AUTOCHECKPOINT: { + if( zRight ){ + sqlite3_wal_autocheckpoint(db, sqlite3Atoi(zRight)); + } + returnSingleInt(pParse, "wal_autocheckpoint", + db->xWalCallback==sqlite3WalDefaultHook ? + SQLITE_PTR_TO_INT(db->pWalArg) : 0); + } + break; +#endif + + /* + ** PRAGMA shrink_memory + ** + ** IMPLEMENTATION-OF: R-23445-46109 This pragma causes the database + ** connection on which it is invoked to free up as much memory as it + ** can, by calling sqlite3_db_release_memory(). + */ + case PragTyp_SHRINK_MEMORY: { + sqlite3_db_release_memory(db); + break; + } + + /* + ** PRAGMA busy_timeout + ** PRAGMA busy_timeout = N + ** + ** Call sqlite3_busy_timeout(db, N). Return the current timeout value + ** if one is set. If no busy handler or a different busy handler is set + ** then 0 is returned. Setting the busy_timeout to 0 or negative + ** disables the timeout. + */ + /*case PragTyp_BUSY_TIMEOUT*/ default: { + assert( pPragma->ePragTyp==PragTyp_BUSY_TIMEOUT ); + if( zRight ){ + sqlite3_busy_timeout(db, sqlite3Atoi(zRight)); + } + returnSingleInt(pParse, "timeout", db->busyTimeout); + break; + } + + /* + ** PRAGMA soft_heap_limit + ** PRAGMA soft_heap_limit = N + ** + ** IMPLEMENTATION-OF: R-26343-45930 This pragma invokes the + ** sqlite3_soft_heap_limit64() interface with the argument N, if N is + ** specified and is a non-negative integer. + ** IMPLEMENTATION-OF: R-64451-07163 The soft_heap_limit pragma always + ** returns the same integer that would be returned by the + ** sqlite3_soft_heap_limit64(-1) C-language function. + */ + case PragTyp_SOFT_HEAP_LIMIT: { + sqlite3_int64 N; + if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){ + sqlite3_soft_heap_limit64(N); + } + returnSingleInt(pParse, "soft_heap_limit", sqlite3_soft_heap_limit64(-1)); + break; + } + + /* + ** PRAGMA threads + ** PRAGMA threads = N + ** + ** Configure the maximum number of worker threads. Return the new + ** maximum, which might be less than requested. + */ + case PragTyp_THREADS: { + sqlite3_int64 N; + if( zRight + && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK + && N>=0 + ){ + sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff)); + } + returnSingleInt(pParse, "threads", + sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1)); + break; + } + +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + /* + ** Report the current state of file logs for all databases + */ + case PragTyp_LOCK_STATUS: { + static const char *const azLockName[] = { + "unlocked", "shared", "reserved", "pending", "exclusive" + }; + int i; + sqlite3VdbeSetNumCols(v, 2); + pParse->nMem = 2; + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "database", SQLITE_STATIC); + sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "status", SQLITE_STATIC); + for(i=0; inDb; i++){ + Btree *pBt; + const char *zState = "unknown"; + int j; + if( db->aDb[i].zName==0 ) continue; + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, db->aDb[i].zName, P4_STATIC); + pBt = db->aDb[i].pBt; + if( pBt==0 || sqlite3BtreePager(pBt)==0 ){ + zState = "closed"; + }else if( sqlite3_file_control(db, i ? db->aDb[i].zName : 0, + SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){ + zState = azLockName[j]; + } + sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, zState, P4_STATIC); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); + } + break; + } +#endif + +#ifdef SQLITE_HAS_CODEC + case PragTyp_KEY: { + if( zRight ) sqlite3_key_v2(db, zDb, zRight, sqlite3Strlen30(zRight)); + break; + } + case PragTyp_REKEY: { + if( zRight ) sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight)); + break; + } + case PragTyp_HEXKEY: { + if( zRight ){ + u8 iByte; + int i; + char zKey[40]; + for(i=0, iByte=0; idb; + if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){ + if( zObj==0 ) zObj = "?"; + sqlite3SetString(pData->pzErrMsg, db, + "malformed database schema (%s)", zObj); + if( zExtra ){ + *pData->pzErrMsg = sqlite3MAppendf(db, *pData->pzErrMsg, + "%s - %s", *pData->pzErrMsg, zExtra); + } + } + pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT; +} + +/* +** 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. 0 for trigger or view. +** argv[2] = SQL text for the CREATE statement. +** +*/ +SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ + InitData *pData = (InitData*)pInit; + sqlite3 *db = pData->db; + int iDb = pData->iDb; + + assert( argc==3 ); + UNUSED_PARAMETER2(NotUsed, argc); + assert( sqlite3_mutex_held(db->mutex) ); + DbClearProperty(db, iDb, DB_Empty); + if( db->mallocFailed ){ + corruptSchema(pData, argv[0], 0); + return 1; + } + + assert( iDb>=0 && iDbnDb ); + if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ + if( argv[1]==0 ){ + corruptSchema(pData, argv[0], 0); + }else if( sqlite3_strnicmp(argv[2],"create ",7)==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. + */ + int rc; + sqlite3_stmt *pStmt; + TESTONLY(int rcp); /* Return code from sqlite3_prepare() */ + + assert( db->init.busy ); + db->init.iDb = iDb; + db->init.newTnum = sqlite3Atoi(argv[1]); + db->init.orphanTrigger = 0; + TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0); + rc = db->errCode; + assert( (rc&0xFF)==(rcp&0xFF) ); + db->init.iDb = 0; + if( SQLITE_OK!=rc ){ + if( db->init.orphanTrigger ){ + assert( iDb==1 ); + }else{ + pData->rc = rc; + if( rc==SQLITE_NOMEM ){ + db->mallocFailed = 1; + }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ + corruptSchema(pData, argv[0], sqlite3_errmsg(db)); + } + } + } + sqlite3_finalize(pStmt); + }else if( argv[0]==0 || (argv[2]!=0 && argv[2][0]!=0) ){ + corruptSchema(pData, argv[0], 0); + }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 ){ + /* 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 if( sqlite3GetInt32(argv[1], &pIndex->tnum)==0 ){ + corruptSchema(pData, argv[0], "invalid rootpage"); + } + } + 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; + int i; +#ifndef SQLITE_OMIT_DEPRECATED + int size; +#endif + Table *pTab; + Db *pDb; + char const *azArg[4]; + int meta[5]; + InitData initData; + char const *zMasterSchema; + char const *zMasterName; + int openedTransaction = 0; + + /* + ** 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 && iDbnDb ); + assert( db->aDb[iDb].pSchema ); + assert( sqlite3_mutex_held(db->mutex) ); + assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); + + /* zMasterSchema and zInitScript are set to point at the master schema + ** and initialisation script appropriate for the database being + ** initialized. 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. */ + azArg[0] = zMasterName; + azArg[1] = "1"; + azArg[2] = zMasterSchema; + azArg[3] = 0; + initData.db = db; + initData.iDb = iDb; + initData.rc = SQLITE_OK; + initData.pzErrMsg = pzErrMsg; + sqlite3InitCallback(&initData, 3, (char **)azArg, 0); + if( initData.rc ){ + rc = initData.rc; + goto error_out; + } + pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName); + if( ALWAYS(pTab) ){ + pTab->tabFlags |= TF_Readonly; + } + + /* Create a cursor to hold the database open + */ + pDb = &db->aDb[iDb]; + if( pDb->pBt==0 ){ + if( !OMIT_TEMPDB && ALWAYS(iDb==1) ){ + DbSetProperty(db, 1, DB_SchemaLoaded); + } + return SQLITE_OK; + } + + /* If there is not already a read-only (or read-write) transaction opened + ** on the b-tree database, open one now. If a transaction is opened, it + ** will be closed before this function returns. */ + sqlite3BtreeEnter(pDb->pBt); + if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){ + rc = sqlite3BtreeBeginTrans(pDb->pBt, 0); + if( rc!=SQLITE_OK ){ + sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc)); + goto initone_error_out; + } + openedTransaction = 1; + } + + /* 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] Largest rootpage (auto/incr_vacuum mode) + ** meta[4] Db text encoding. 1:UTF-8 2:UTF-16LE 3:UTF-16BE + ** meta[5] User version + ** meta[6] Incremental vacuum mode + ** meta[7] unused + ** meta[8] unused + ** meta[9] unused + ** + ** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to + ** the possible values of meta[4]. + */ + for(i=0; ipBt, i+1, (u32 *)&meta[i]); + } + pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1]; + + /* 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[BTREE_TEXT_ENCODING-1] ){ /* text encoding */ + if( iDb==0 ){ +#ifndef SQLITE_OMIT_UTF16 + u8 encoding; + /* If opening the main database, set ENC(db). */ + encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3; + if( encoding==0 ) encoding = SQLITE_UTF8; + ENC(db) = encoding; +#else + ENC(db) = SQLITE_UTF8; +#endif + }else{ + /* If opening an attached database, the encoding much match ENC(db) */ + if( meta[BTREE_TEXT_ENCODING-1]!=ENC(db) ){ + sqlite3SetString(pzErrMsg, db, "attached databases must use the same" + " text encoding as main database"); + rc = SQLITE_ERROR; + goto initone_error_out; + } + } + }else{ + DbSetProperty(db, iDb, DB_Empty); + } + pDb->pSchema->enc = ENC(db); + + if( pDb->pSchema->cache_size==0 ){ +#ifndef SQLITE_OMIT_DEPRECATED + size = sqlite3AbsInt32(meta[BTREE_DEFAULT_CACHE_SIZE-1]); + if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; } + pDb->pSchema->cache_size = size; +#else + pDb->pSchema->cache_size = SQLITE_DEFAULT_CACHE_SIZE; +#endif + 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 = (u8)meta[BTREE_FILE_FORMAT-1]; + if( pDb->pSchema->file_format==0 ){ + pDb->pSchema->file_format = 1; + } + if( pDb->pSchema->file_format>SQLITE_MAX_FILE_FORMAT ){ + sqlite3SetString(pzErrMsg, db, "unsupported file format"); + rc = SQLITE_ERROR; + goto initone_error_out; + } + + /* Ticket #2804: When we open a database in the newer file format, + ** clear the legacy_file_format pragma flag so that a VACUUM will + ** not downgrade the database and thus invalidate any descending + ** indices that the user might have created. + */ + if( iDb==0 && meta[BTREE_FILE_FORMAT-1]>=4 ){ + db->flags &= ~SQLITE_LegacyFileFmt; + } + + /* Read the schema information out of the schema tables + */ + assert( db->init.busy ); + { + char *zSql; + zSql = sqlite3MPrintf(db, + "SELECT name, rootpage, sql FROM '%q'.%s ORDER BY rowid", + db->aDb[iDb].zName, zMasterName); +#ifndef SQLITE_OMIT_AUTHORIZATION + { + sqlite3_xauth xAuth; + xAuth = db->xAuth; + db->xAuth = 0; +#endif + rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; + } +#endif + if( rc==SQLITE_OK ) rc = initData.rc; + sqlite3DbFree(db, zSql); +#ifndef SQLITE_OMIT_ANALYZE + if( rc==SQLITE_OK ){ + sqlite3AnalysisLoad(db, iDb); + } +#endif + } + if( db->mallocFailed ){ + rc = SQLITE_NOMEM; + sqlite3ResetAllSchemasOfConnection(db); + } + if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){ + /* Black magic: If the SQLITE_RecoveryMode flag is set, then consider + ** the schema loaded, even if errors occurred. In this situation the + ** current sqlite3_prepare() operation will fail, but the following one + ** will attempt to compile the supplied statement against whatever subset + ** of the schema was loaded before the error occurred. The primary + ** purpose of this is to allow access to the sqlite_master table + ** even when its contents have been corrupted. + */ + DbSetProperty(db, iDb, DB_SchemaLoaded); + rc = SQLITE_OK; + } + + /* Jump here for an error that occurs after successfully allocating + ** curMain and calling sqlite3BtreeEnter(). For an error that occurs + ** before that point, jump to error_out. + */ +initone_error_out: + if( openedTransaction ){ + sqlite3BtreeCommit(pDb->pBt); + } + sqlite3BtreeLeave(pDb->pBt); + +error_out: + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ + db->mallocFailed = 1; + } + 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. +*/ +SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){ + int i, rc; + int commit_internal = !(db->flags&SQLITE_InternChanges); + + assert( sqlite3_mutex_held(db->mutex) ); + assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) ); + assert( db->init.busy==0 ); + rc = SQLITE_OK; + db->init.busy = 1; + ENC(db) = SCHEMA_ENC(db); + for(i=0; rc==SQLITE_OK && inDb; i++){ + if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue; + rc = sqlite3InitOne(db, i, pzErrMsg); + if( rc ){ + sqlite3ResetOneSchema(db, i); + } + } + + /* Once all the other databases have been initialized, 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 + assert( db->nDb>1 ); + if( rc==SQLITE_OK && !DbHasProperty(db, 1, DB_SchemaLoaded) ){ + rc = sqlite3InitOne(db, 1, pzErrMsg); + if( rc ){ + sqlite3ResetOneSchema(db, 1); + } + } +#endif + + db->init.busy = 0; + if( rc==SQLITE_OK && commit_internal ){ + sqlite3CommitInternalChanges(db); + } + + return rc; +} + +/* +** This routine is a no-op if the database schema is already initialized. +** Otherwise, the schema is loaded. An error code is returned. +*/ +SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse){ + int rc = SQLITE_OK; + sqlite3 *db = pParse->db; + assert( sqlite3_mutex_held(db->mutex) ); + 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 set pParse->rc to SQLITE_SCHEMA. If all schema cookies +** make no changes to pParse->rc. +*/ +static void schemaIsValid(Parse *pParse){ + sqlite3 *db = pParse->db; + int iDb; + int rc; + int cookie; + + assert( pParse->checkSchema ); + assert( sqlite3_mutex_held(db->mutex) ); + for(iDb=0; iDbnDb; iDb++){ + int openedTransaction = 0; /* True if a transaction is opened */ + Btree *pBt = db->aDb[iDb].pBt; /* Btree database to read cookie from */ + if( pBt==0 ) continue; + + /* If there is not already a read-only (or read-write) transaction opened + ** on the b-tree database, open one now. If a transaction is opened, it + ** will be closed immediately after reading the meta-value. */ + if( !sqlite3BtreeIsInReadTrans(pBt) ){ + rc = sqlite3BtreeBeginTrans(pBt, 0); + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ + db->mallocFailed = 1; + } + if( rc!=SQLITE_OK ) return; + openedTransaction = 1; + } + + /* Read the schema cookie from the database. If it does not match the + ** value stored as part of the in-memory schema representation, + ** set Parse.rc to SQLITE_SCHEMA. */ + sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){ + sqlite3ResetOneSchema(db, iDb); + pParse->rc = SQLITE_SCHEMA; + } + + /* Close the transaction, if one was opened. */ + if( openedTransaction ){ + sqlite3BtreeCommit(pBt); + } + } +} + +/* +** Convert a schema pointer into the iDb index that indicates +** which database file in db->aDb[] the schema refers to. +** +** If the same database is attached more than once, the first +** attached database is returned. +*/ +SQLITE_PRIVATE 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 the incorrect 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). + */ + assert( sqlite3_mutex_held(db->mutex) ); + if( pSchema ){ + for(i=0; ALWAYS(inDb); i++){ + if( db->aDb[i].pSchema==pSchema ){ + break; + } + } + assert( i>=0 && inDb ); + } + return i; +} + +/* +** Free all memory allocations in the pParse object +*/ +SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){ + if( pParse ){ + sqlite3 *db = pParse->db; + sqlite3DbFree(db, pParse->aLabel); + sqlite3ExprListDelete(db, pParse->pConstExpr); + } +} + +/* +** Compile the UTF-8 encoded SQL statement zSql into a statement handle. +*/ +static int sqlite3Prepare( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */ + Vdbe *pReprepare, /* VM being reprepared */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const char **pzTail /* OUT: End of parsed string */ +){ + Parse *pParse; /* Parsing context */ + char *zErrMsg = 0; /* Error message */ + int rc = SQLITE_OK; /* Result code */ + int i; /* Loop counter */ + + /* Allocate the parsing context */ + pParse = sqlite3StackAllocZero(db, sizeof(*pParse)); + if( pParse==0 ){ + rc = SQLITE_NOMEM; + goto end_prepare; + } + pParse->pReprepare = pReprepare; + assert( ppStmt && *ppStmt==0 ); + assert( !db->mallocFailed ); + assert( sqlite3_mutex_held(db->mutex) ); + + /* Check to verify that it is possible to get a read lock on all + ** database schemas. The inability to get a read lock indicates that + ** some other database connection is holding a write-lock, which in + ** turn means that the other connection has made uncommitted changes + ** to the schema. + ** + ** Were we to proceed and prepare the statement against the uncommitted + ** schema changes and if those schema changes are subsequently rolled + ** back and different changes are made in their place, then when this + ** prepared statement goes to run the schema cookie would fail to detect + ** the schema change. Disaster would follow. + ** + ** This thread is currently holding mutexes on all Btrees (because + ** of the sqlite3BtreeEnterAll() in sqlite3LockAndPrepare()) so it + ** is not possible for another thread to start a new schema change + ** while this routine is running. Hence, we do not need to hold + ** locks on the schema, we just need to make sure nobody else is + ** holding them. + ** + ** Note that setting READ_UNCOMMITTED overrides most lock detection, + ** but it does *not* override schema lock detection, so this all still + ** works even if READ_UNCOMMITTED is set. + */ + for(i=0; inDb; i++) { + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + assert( sqlite3BtreeHoldsMutex(pBt) ); + rc = sqlite3BtreeSchemaLocked(pBt); + if( rc ){ + const char *zDb = db->aDb[i].zName; + sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb); + testcase( db->flags & SQLITE_ReadUncommitted ); + goto end_prepare; + } + } + } + + sqlite3VtabUnlockList(db); + + pParse->db = db; + pParse->nQueryLoop = 0; /* Logarithmic, so 0 really means 1 */ + if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){ + char *zSqlCopy; + int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; + testcase( nBytes==mxLen ); + testcase( nBytes==mxLen+1 ); + if( nBytes>mxLen ){ + sqlite3ErrorWithMsg(db, SQLITE_TOOBIG, "statement too long"); + rc = sqlite3ApiExit(db, SQLITE_TOOBIG); + goto end_prepare; + } + zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes); + if( zSqlCopy ){ + sqlite3RunParser(pParse, zSqlCopy, &zErrMsg); + sqlite3DbFree(db, zSqlCopy); + pParse->zTail = &zSql[pParse->zTail-zSqlCopy]; + }else{ + pParse->zTail = &zSql[nBytes]; + } + }else{ + sqlite3RunParser(pParse, zSql, &zErrMsg); + } + assert( 0==pParse->nQueryLoop ); + + if( db->mallocFailed ){ + pParse->rc = SQLITE_NOMEM; + } + if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK; + if( pParse->checkSchema ){ + schemaIsValid(pParse); + } + if( db->mallocFailed ){ + pParse->rc = SQLITE_NOMEM; + } + if( pzTail ){ + *pzTail = pParse->zTail; + } + rc = pParse->rc; + +#ifndef SQLITE_OMIT_EXPLAIN + if( rc==SQLITE_OK && pParse->pVdbe && pParse->explain ){ + static const char * const azColName[] = { + "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", + "selectid", "order", "from", "detail" + }; + int iFirst, mx; + if( pParse->explain==2 ){ + sqlite3VdbeSetNumCols(pParse->pVdbe, 4); + iFirst = 8; + mx = 12; + }else{ + sqlite3VdbeSetNumCols(pParse->pVdbe, 8); + iFirst = 0; + mx = 8; + } + for(i=iFirst; ipVdbe, i-iFirst, COLNAME_NAME, + azColName[i], SQLITE_STATIC); + } + } +#endif + + if( db->init.busy==0 ){ + Vdbe *pVdbe = pParse->pVdbe; + sqlite3VdbeSetSql(pVdbe, zSql, (int)(pParse->zTail-zSql), saveSqlFlag); + } + if( pParse->pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){ + sqlite3VdbeFinalize(pParse->pVdbe); + assert(!(*ppStmt)); + }else{ + *ppStmt = (sqlite3_stmt*)pParse->pVdbe; + } + + if( zErrMsg ){ + sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg); + sqlite3DbFree(db, zErrMsg); + }else{ + sqlite3Error(db, rc); + } + + /* Delete any TriggerPrg structures allocated while parsing this statement. */ + while( pParse->pTriggerPrg ){ + TriggerPrg *pT = pParse->pTriggerPrg; + pParse->pTriggerPrg = pT->pNext; + sqlite3DbFree(db, pT); + } + +end_prepare: + + sqlite3ParserReset(pParse); + sqlite3StackFree(db, pParse); + rc = sqlite3ApiExit(db, rc); + assert( (rc&db->errMask)==rc ); + return rc; +} +static int sqlite3LockAndPrepare( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */ + Vdbe *pOld, /* VM being reprepared */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const char **pzTail /* OUT: End of parsed string */ +){ + int rc; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( ppStmt==0 ) return SQLITE_MISUSE_BKPT; +#endif + *ppStmt = 0; + if( !sqlite3SafetyCheckOk(db)||zSql==0 ){ + return SQLITE_MISUSE_BKPT; + } + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); + rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail); + if( rc==SQLITE_SCHEMA ){ + sqlite3_finalize(*ppStmt); + rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail); + } + sqlite3BtreeLeaveAll(db); + sqlite3_mutex_leave(db->mutex); + assert( rc==SQLITE_OK || *ppStmt==0 ); + return rc; +} + +/* +** Rerun the compilation of a statement after a schema change. +** +** If the statement is successfully recompiled, return SQLITE_OK. Otherwise, +** if the statement cannot be recompiled because another connection has +** locked the sqlite3_master table, return SQLITE_LOCKED. If any other error +** occurs, return SQLITE_SCHEMA. +*/ +SQLITE_PRIVATE int sqlite3Reprepare(Vdbe *p){ + int rc; + sqlite3_stmt *pNew; + const char *zSql; + sqlite3 *db; + + assert( sqlite3_mutex_held(sqlite3VdbeDb(p)->mutex) ); + zSql = sqlite3_sql((sqlite3_stmt *)p); + assert( zSql!=0 ); /* Reprepare only called for prepare_v2() statements */ + db = sqlite3VdbeDb(p); + assert( sqlite3_mutex_held(db->mutex) ); + rc = sqlite3LockAndPrepare(db, zSql, -1, 0, p, &pNew, 0); + if( rc ){ + if( rc==SQLITE_NOMEM ){ + db->mallocFailed = 1; + } + assert( pNew==0 ); + return rc; + }else{ + assert( pNew!=0 ); + } + sqlite3VdbeSwap((Vdbe*)pNew, p); + sqlite3TransferBindings(pNew, (sqlite3_stmt*)p); + sqlite3VdbeResetStepResult((Vdbe*)pNew); + sqlite3VdbeFinalize((Vdbe*)pNew); + return SQLITE_OK; +} + + +/* +** Two versions of the official API. Legacy and new use. In the legacy +** version, the original SQL text is not saved in the prepared statement +** and so if a schema change occurs, SQLITE_SCHEMA is returned by +** sqlite3_step(). In the new version, the original SQL text is retained +** and the statement is automatically recompiled if an schema change +** occurs. +*/ +SQLITE_API int SQLITE_STDCALL 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 */ +){ + int rc; + rc = sqlite3LockAndPrepare(db,zSql,nBytes,0,0,ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ + return rc; +} +SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2( + 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 */ +){ + int rc; + rc = sqlite3LockAndPrepare(db,zSql,nBytes,1,0,ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ + return rc; +} + + +#ifndef SQLITE_OMIT_UTF16 +/* +** Compile the UTF-16 encoded SQL statement zSql into a statement handle. +*/ +static int sqlite3Prepare16( + sqlite3 *db, /* Database handle. */ + const void *zSql, /* UTF-16 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + int saveSqlFlag, /* True to save SQL text into the sqlite3_stmt */ + 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; + const char *zTail8 = 0; + int rc = SQLITE_OK; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( ppStmt==0 ) return SQLITE_MISUSE_BKPT; +#endif + *ppStmt = 0; + if( !sqlite3SafetyCheckOk(db)||zSql==0 ){ + return SQLITE_MISUSE_BKPT; + } + if( nBytes>=0 ){ + int sz; + const char *z = (const char*)zSql; + for(sz=0; szmutex); + zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE); + if( zSql8 ){ + rc = sqlite3LockAndPrepare(db, zSql8, -1, saveSqlFlag, 0, 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, (int)(zTail8-zSql8)); + *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed); + } + sqlite3DbFree(db, zSql8); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Two versions of the official API. Legacy and new use. In the legacy +** version, the original SQL text is not saved in the prepared statement +** and so if a schema change occurs, SQLITE_SCHEMA is returned by +** sqlite3_step(). In the new version, the original SQL text is retained +** and the statement is automatically recompiled if an schema change +** occurs. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_prepare16( + sqlite3 *db, /* Database handle. */ + const void *zSql, /* UTF-16 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 */ +){ + int rc; + rc = sqlite3Prepare16(db,zSql,nBytes,0,ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ + return rc; +} +SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle. */ + const void *zSql, /* UTF-16 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 */ +){ + int rc; + rc = sqlite3Prepare16(db,zSql,nBytes,1,ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ + return rc; +} + +#endif /* SQLITE_OMIT_UTF16 */ + +/************** End of prepare.c *********************************************/ +/************** Begin file select.c ******************************************/ +/* +** 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. +** +************************************************************************* +** This file contains C code routines that are called by the parser +** to handle SELECT statements in SQLite. +*/ + +/* +** Trace output macros +*/ +#if SELECTTRACE_ENABLED +/***/ int sqlite3SelectTrace = 0; +# define SELECTTRACE(K,P,S,X) \ + if(sqlite3SelectTrace&(K)) \ + sqlite3DebugPrintf("%*s%s.%p: ",(P)->nSelectIndent*2-2,"",(S)->zSelName,(S)),\ + sqlite3DebugPrintf X +#else +# define SELECTTRACE(K,P,S,X) +#endif + + +/* +** An instance of the following object is used to record information about +** how to process the DISTINCT keyword, to simplify passing that information +** into the selectInnerLoop() routine. +*/ +typedef struct DistinctCtx DistinctCtx; +struct DistinctCtx { + u8 isTnct; /* True if the DISTINCT keyword is present */ + u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */ + int tabTnct; /* Ephemeral table used for DISTINCT processing */ + int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */ +}; + +/* +** An instance of the following object is used to record information about +** the ORDER BY (or GROUP BY) clause of query is being coded. +*/ +typedef struct SortCtx SortCtx; +struct SortCtx { + ExprList *pOrderBy; /* The ORDER BY (or GROUP BY clause) */ + int nOBSat; /* Number of ORDER BY terms satisfied by indices */ + int iECursor; /* Cursor number for the sorter */ + int regReturn; /* Register holding block-output return address */ + int labelBkOut; /* Start label for the block-output subroutine */ + int addrSortIndex; /* Address of the OP_SorterOpen or OP_OpenEphemeral */ + u8 sortFlags; /* Zero or more SORTFLAG_* bits */ +}; +#define SORTFLAG_UseSorter 0x01 /* Use SorterOpen instead of OpenEphemeral */ + +/* +** Delete all the content of a Select structure. Deallocate the structure +** itself only if bFree is true. +*/ +static void clearSelect(sqlite3 *db, Select *p, int bFree){ + while( p ){ + Select *pPrior = p->pPrior; + sqlite3ExprListDelete(db, p->pEList); + sqlite3SrcListDelete(db, p->pSrc); + sqlite3ExprDelete(db, p->pWhere); + sqlite3ExprListDelete(db, p->pGroupBy); + sqlite3ExprDelete(db, p->pHaving); + sqlite3ExprListDelete(db, p->pOrderBy); + sqlite3ExprDelete(db, p->pLimit); + sqlite3ExprDelete(db, p->pOffset); + sqlite3WithDelete(db, p->pWith); + if( bFree ) sqlite3DbFree(db, p); + p = pPrior; + bFree = 1; + } +} + +/* +** Initialize a SelectDest structure. +*/ +SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){ + pDest->eDest = (u8)eDest; + pDest->iSDParm = iParm; + pDest->affSdst = 0; + pDest->iSdst = 0; + pDest->nSdst = 0; +} + + +/* +** Allocate a new Select structure and return a pointer to that +** structure. +*/ +SQLITE_PRIVATE Select *sqlite3SelectNew( + Parse *pParse, /* Parsing context */ + ExprList *pEList, /* which columns to include in the result */ + SrcList *pSrc, /* the FROM clause -- which tables to scan */ + Expr *pWhere, /* the WHERE clause */ + ExprList *pGroupBy, /* the GROUP BY clause */ + Expr *pHaving, /* the HAVING clause */ + ExprList *pOrderBy, /* the ORDER BY clause */ + u16 selFlags, /* Flag parameters, such as SF_Distinct */ + Expr *pLimit, /* LIMIT value. NULL means not used */ + Expr *pOffset /* OFFSET value. NULL means no offset */ +){ + Select *pNew; + Select standin; + sqlite3 *db = pParse->db; + pNew = sqlite3DbMallocZero(db, sizeof(*pNew) ); + if( pNew==0 ){ + assert( db->mallocFailed ); + pNew = &standin; + memset(pNew, 0, sizeof(*pNew)); + } + if( pEList==0 ){ + pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0)); + } + pNew->pEList = pEList; + if( pSrc==0 ) pSrc = sqlite3DbMallocZero(db, sizeof(*pSrc)); + pNew->pSrc = pSrc; + pNew->pWhere = pWhere; + pNew->pGroupBy = pGroupBy; + pNew->pHaving = pHaving; + pNew->pOrderBy = pOrderBy; + pNew->selFlags = selFlags; + pNew->op = TK_SELECT; + pNew->pLimit = pLimit; + pNew->pOffset = pOffset; + assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 ); + pNew->addrOpenEphm[0] = -1; + pNew->addrOpenEphm[1] = -1; + if( db->mallocFailed ) { + clearSelect(db, pNew, pNew!=&standin); + pNew = 0; + }else{ + assert( pNew->pSrc!=0 || pParse->nErr>0 ); + } + assert( pNew!=&standin ); + return pNew; +} + +#if SELECTTRACE_ENABLED +/* +** Set the name of a Select object +*/ +SQLITE_PRIVATE void sqlite3SelectSetName(Select *p, const char *zName){ + if( p && zName ){ + sqlite3_snprintf(sizeof(p->zSelName), p->zSelName, "%s", zName); + } +} +#endif + + +/* +** Delete the given Select structure and all of its substructures. +*/ +SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){ + clearSelect(db, p, 1); +} + +/* +** Return a pointer to the right-most SELECT statement in a compound. +*/ +static Select *findRightmost(Select *p){ + while( p->pNext ) p = p->pNext; + return p; +} + +/* +** Given 1 to 3 identifiers preceding 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. +*/ +SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){ + int jointype = 0; + Token *apAll[3]; + Token *p; + /* 0123456789 123456789 123456789 123 */ + static const char zKeyText[] = "naturaleftouterightfullinnercross"; + static const struct { + u8 i; /* Beginning of keyword text in zKeyText[] */ + u8 nChar; /* Length of the keyword in characters */ + u8 code; /* Join type mask */ + } aKeyword[] = { + /* natural */ { 0, 7, JT_NATURAL }, + /* left */ { 6, 4, JT_LEFT|JT_OUTER }, + /* outer */ { 10, 5, JT_OUTER }, + /* right */ { 14, 5, JT_RIGHT|JT_OUTER }, + /* full */ { 19, 4, JT_LEFT|JT_RIGHT|JT_OUTER }, + /* inner */ { 23, 5, JT_INNER }, + /* cross */ { 28, 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; jn==aKeyword[j].nChar + && sqlite3StrNICmp((char*)p->z, &zKeyText[aKeyword[j].i], p->n)==0 ){ + jointype |= aKeyword[j].code; + break; + } + } + testcase( j==0 || j==1 || j==2 || j==3 || j==4 || j==5 || j==6 ); + if( j>=ArraySize(aKeyword) ){ + jointype |= JT_ERROR; + break; + } + } + if( + (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) || + (jointype & JT_ERROR)!=0 + ){ + const char *zSp = " "; + assert( pB!=0 ); + if( pC==0 ){ zSp++; } + sqlite3ErrorMsg(pParse, "unknown or unsupported join type: " + "%T %T%s%T", pA, pB, zSp, pC); + jointype = JT_INNER; + }else if( (jointype & JT_OUTER)!=0 + && (jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ){ + sqlite3ErrorMsg(pParse, + "RIGHT and FULL OUTER JOINs are not currently supported"); + jointype = JT_INNER; + } + return jointype; +} + +/* +** Return the index of a column in a table. Return -1 if the column +** is not contained in the table. +*/ +static int columnIndex(Table *pTab, const char *zCol){ + int i; + for(i=0; inCol; i++){ + if( sqlite3StrICmp(pTab->aCol[i].zName, zCol)==0 ) return i; + } + return -1; +} + +/* +** Search the first N tables in pSrc, from left to right, looking for a +** table that has a column named zCol. +** +** When found, set *piTab and *piCol to the table index and column index +** of the matching column and return TRUE. +** +** If not found, return FALSE. +*/ +static int tableAndColumnIndex( + SrcList *pSrc, /* Array of tables to search */ + int N, /* Number of tables in pSrc->a[] to search */ + const char *zCol, /* Name of the column we are looking for */ + int *piTab, /* Write index of pSrc->a[] here */ + int *piCol /* Write index of pSrc->a[*piTab].pTab->aCol[] here */ +){ + int i; /* For looping over tables in pSrc */ + int iCol; /* Index of column matching zCol */ + + assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ + for(i=0; ia[i].pTab, zCol); + if( iCol>=0 ){ + if( piTab ){ + *piTab = i; + *piCol = iCol; + } + return 1; + } + } + return 0; +} + +/* +** This function is used to add terms implied by JOIN syntax to the +** WHERE clause expression of a SELECT statement. The new term, which +** is ANDed with the existing WHERE clause, is of the form: +** +** (tab1.col1 = tab2.col2) +** +** where tab1 is the iSrc'th table in SrcList pSrc and tab2 is the +** (iSrc+1)'th. Column col1 is column iColLeft of tab1, and col2 is +** column iColRight of tab2. +*/ +static void addWhereTerm( + Parse *pParse, /* Parsing context */ + SrcList *pSrc, /* List of tables in FROM clause */ + int iLeft, /* Index of first table to join in pSrc */ + int iColLeft, /* Index of column in first table */ + int iRight, /* Index of second table in pSrc */ + int iColRight, /* Index of column in second table */ + int isOuterJoin, /* True if this is an OUTER join */ + Expr **ppWhere /* IN/OUT: The WHERE clause to add to */ +){ + sqlite3 *db = pParse->db; + Expr *pE1; + Expr *pE2; + Expr *pEq; + + assert( iLeftnSrc>iRight ); + assert( pSrc->a[iLeft].pTab ); + assert( pSrc->a[iRight].pTab ); + + pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iColLeft); + pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight); + + pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2, 0); + if( pEq && isOuterJoin ){ + ExprSetProperty(pEq, EP_FromJoin); + assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) ); + ExprSetVVAProperty(pEq, EP_NoReduce); + pEq->iRightJoinTable = (i16)pE2->iTable; + } + *ppWhere = sqlite3ExprAnd(db, *ppWhere, pEq); +} + +/* +** 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); + assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); + ExprSetVVAProperty(p, EP_NoReduce); + p->iRightJoinTable = (i16)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. +** NATURAL joins also create extra WHERE clause terms. +** +** The terms of a FROM clause are contained in the Select.pSrc structure. +** The left most table is the first entry in Select.pSrc. The right-most +** table is the last entry. The join operator is held in the entry to +** the left. Thus entry 0 contains the join operator for the join between +** entries 0 and 1. Any ON or USING clauses associated with the join are +** also attached to the left entry. +** +** This routine returns the number of errors encountered. +*/ +static int sqliteProcessJoin(Parse *pParse, Select *p){ + SrcList *pSrc; /* All tables in the FROM clause */ + int i, j; /* Loop counters */ + struct SrcList_item *pLeft; /* Left table being joined */ + struct SrcList_item *pRight; /* Right table being joined */ + + pSrc = p->pSrc; + pLeft = &pSrc->a[0]; + pRight = &pLeft[1]; + for(i=0; inSrc-1; i++, pRight++, pLeft++){ + Table *pLeftTab = pLeft->pTab; + Table *pRightTab = pRight->pTab; + int isOuter; + + if( NEVER(pLeftTab==0 || pRightTab==0) ) continue; + isOuter = (pRight->jointype & JT_OUTER)!=0; + + /* When the NATURAL keyword is present, add WHERE clause terms for + ** every column that the two tables have in common. + */ + if( pRight->jointype & JT_NATURAL ){ + if( pRight->pOn || pRight->pUsing ){ + sqlite3ErrorMsg(pParse, "a NATURAL join may not have " + "an ON or USING clause", 0); + return 1; + } + for(j=0; jnCol; j++){ + char *zName; /* Name of column in the right table */ + int iLeft; /* Matching left table */ + int iLeftCol; /* Matching column in the left table */ + + zName = pRightTab->aCol[j].zName; + if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol) ){ + addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, j, + isOuter, &p->pWhere); + } + } + } + + /* Disallow both ON and USING clauses in the same join + */ + if( pRight->pOn && pRight->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( pRight->pOn ){ + if( isOuter ) setJoinExpr(pRight->pOn, pRight->iCursor); + p->pWhere = sqlite3ExprAnd(pParse->db, p->pWhere, pRight->pOn); + pRight->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 + ** to the WHERE clause: A.X=B.X AND A.Y=B.Y AND A.Z=B.Z + ** Report an error if any column mentioned in the USING clause is + ** not contained in both tables to be joined. + */ + if( pRight->pUsing ){ + IdList *pList = pRight->pUsing; + for(j=0; jnId; j++){ + char *zName; /* Name of the term in the USING clause */ + int iLeft; /* Table on the left with matching column name */ + int iLeftCol; /* Column number of matching column on the left */ + int iRightCol; /* Column number of matching column on the right */ + + zName = pList->a[j].zName; + iRightCol = columnIndex(pRightTab, zName); + if( iRightCol<0 + || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol) + ){ + sqlite3ErrorMsg(pParse, "cannot join using column %s - column " + "not present in both tables", zName); + return 1; + } + addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, iRightCol, + isOuter, &p->pWhere); + } + } + } + return 0; +} + +/* Forward reference */ +static KeyInfo *keyInfoFromExprList( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* Form the KeyInfo object from this ExprList */ + int iStart, /* Begin with this column of pList */ + int nExtra /* Add this many extra columns to the end */ +); + +/* +** Generate code that will push the record in registers regData +** through regData+nData-1 onto the sorter. +*/ +static void pushOntoSorter( + Parse *pParse, /* Parser context */ + SortCtx *pSort, /* Information about the ORDER BY clause */ + Select *pSelect, /* The whole SELECT statement */ + int regData, /* First register holding data to be sorted */ + int nData, /* Number of elements in the data array */ + int nPrefixReg /* No. of reg prior to regData available for use */ +){ + Vdbe *v = pParse->pVdbe; /* Stmt under construction */ + int bSeq = ((pSort->sortFlags & SORTFLAG_UseSorter)==0); + int nExpr = pSort->pOrderBy->nExpr; /* No. of ORDER BY terms */ + int nBase = nExpr + bSeq + nData; /* Fields in sorter record */ + int regBase; /* Regs for sorter record */ + int regRecord = ++pParse->nMem; /* Assembled sorter record */ + int nOBSat = pSort->nOBSat; /* ORDER BY terms to skip */ + int op; /* Opcode to add sorter record to sorter */ + + assert( bSeq==0 || bSeq==1 ); + if( nPrefixReg ){ + assert( nPrefixReg==nExpr+bSeq ); + regBase = regData - nExpr - bSeq; + }else{ + regBase = pParse->nMem + 1; + pParse->nMem += nBase; + } + sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, SQLITE_ECEL_DUP); + if( bSeq ){ + sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr); + } + if( nPrefixReg==0 ){ + sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData); + } + + sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regRecord); + if( nOBSat>0 ){ + int regPrevKey; /* The first nOBSat columns of the previous row */ + int addrFirst; /* Address of the OP_IfNot opcode */ + int addrJmp; /* Address of the OP_Jump opcode */ + VdbeOp *pOp; /* Opcode that opens the sorter */ + int nKey; /* Number of sorting key columns, including OP_Sequence */ + KeyInfo *pKI; /* Original KeyInfo on the sorter table */ + + regPrevKey = pParse->nMem+1; + pParse->nMem += pSort->nOBSat; + nKey = nExpr - pSort->nOBSat + bSeq; + if( bSeq ){ + addrFirst = sqlite3VdbeAddOp1(v, OP_IfNot, regBase+nExpr); + }else{ + addrFirst = sqlite3VdbeAddOp1(v, OP_SequenceTest, pSort->iECursor); + } + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_Compare, regPrevKey, regBase, pSort->nOBSat); + pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex); + if( pParse->db->mallocFailed ) return; + pOp->p2 = nKey + nData; + pKI = pOp->p4.pKeyInfo; + memset(pKI->aSortOrder, 0, pKI->nField); /* Makes OP_Jump below testable */ + sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO); + testcase( pKI->nXField>2 ); + pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat, + pKI->nXField-1); + addrJmp = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v); + pSort->labelBkOut = sqlite3VdbeMakeLabel(v); + pSort->regReturn = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut); + sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor); + sqlite3VdbeJumpHere(v, addrFirst); + sqlite3ExprCodeMove(pParse, regBase, regPrevKey, pSort->nOBSat); + sqlite3VdbeJumpHere(v, addrJmp); + } + if( pSort->sortFlags & SORTFLAG_UseSorter ){ + op = OP_SorterInsert; + }else{ + op = OP_IdxInsert; + } + sqlite3VdbeAddOp2(v, op, pSort->iECursor, regRecord); + if( pSelect->iLimit ){ + int addr; + int iLimit; + if( pSelect->iOffset ){ + iLimit = pSelect->iOffset+1; + }else{ + iLimit = pSelect->iLimit; + } + addr = sqlite3VdbeAddOp3(v, OP_IfNotZero, iLimit, 0, -1); VdbeCoverage(v); + sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor); + sqlite3VdbeAddOp1(v, OP_Delete, pSort->iECursor); + sqlite3VdbeJumpHere(v, addr); + } +} + +/* +** Add code to implement the OFFSET +*/ +static void codeOffset( + Vdbe *v, /* Generate code into this VM */ + int iOffset, /* Register holding the offset counter */ + int iContinue /* Jump here to skip the current record */ +){ + if( iOffset>0 ){ + int addr; + addr = sqlite3VdbeAddOp3(v, OP_IfNeg, iOffset, 0, -1); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue); + VdbeComment((v, "skip OFFSET records")); + sqlite3VdbeJumpHere(v, addr); + } +} + +/* +** Add code that will check to make sure the N registers starting at iMem +** form a distinct entry. 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 N+1 values are popped from the +** stack if the top N elements are not distinct. +*/ +static void codeDistinct( + Parse *pParse, /* Parsing and code generating context */ + int iTab, /* A sorting index used to test for distinctness */ + int addrRepeat, /* Jump to here if not distinct */ + int N, /* Number of elements */ + int iMem /* First element */ +){ + Vdbe *v; + int r1; + + v = pParse->pVdbe; + r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iTab, r1); + sqlite3ReleaseTempReg(pParse, r1); +} + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Generate an error message when a SELECT is used within a subexpression +** (example: "a IN (SELECT * FROM table)") but it has more than 1 result +** column. We do this in a subroutine because the error used to occur +** in multiple places. (The error only occurs in one place now, but we +** retain the subroutine to minimize code disruption.) +*/ +static int checkForMultiColumnSelectError( + Parse *pParse, /* Parse context. */ + SelectDest *pDest, /* Destination of SELECT results */ + int nExpr /* Number of result columns returned by SELECT */ +){ + int eDest = pDest->eDest; + if( nExpr>1 && (eDest==SRT_Mem || eDest==SRT_Set) ){ + sqlite3ErrorMsg(pParse, "only a single result allowed for " + "a SELECT that is part of an expression"); + return 1; + }else{ + return 0; + } +} +#endif + +/* +** This routine generates the code for the inside of the inner loop +** of a SELECT. +** +** If srcTab is negative, then the pEList expressions +** are evaluated in order to get the data for this row. If srcTab is +** zero or more, then data is pulled from srcTab and pEList is used only +** to get number columns and the datatype for each column. +*/ +static void selectInnerLoop( + Parse *pParse, /* The parser context */ + Select *p, /* The complete select statement being coded */ + ExprList *pEList, /* List of values being extracted */ + int srcTab, /* Pull data from this table */ + SortCtx *pSort, /* If not NULL, info on how to process ORDER BY */ + DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */ + SelectDest *pDest, /* How to dispose of the results */ + int iContinue, /* Jump here to continue with next row */ + int iBreak /* Jump here to break out of the inner loop */ +){ + Vdbe *v = pParse->pVdbe; + int i; + int hasDistinct; /* True if the DISTINCT keyword is present */ + int regResult; /* Start of memory holding result set */ + int eDest = pDest->eDest; /* How to dispose of results */ + int iParm = pDest->iSDParm; /* First argument to disposal method */ + int nResultCol; /* Number of result columns */ + int nPrefixReg = 0; /* Number of extra registers before regResult */ + + assert( v ); + assert( pEList!=0 ); + hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP; + if( pSort && pSort->pOrderBy==0 ) pSort = 0; + if( pSort==0 && !hasDistinct ){ + assert( iContinue!=0 ); + codeOffset(v, p->iOffset, iContinue); + } + + /* Pull the requested columns. + */ + nResultCol = pEList->nExpr; + + if( pDest->iSdst==0 ){ + if( pSort ){ + nPrefixReg = pSort->pOrderBy->nExpr; + if( !(pSort->sortFlags & SORTFLAG_UseSorter) ) nPrefixReg++; + pParse->nMem += nPrefixReg; + } + pDest->iSdst = pParse->nMem+1; + pParse->nMem += nResultCol; + }else if( pDest->iSdst+nResultCol > pParse->nMem ){ + /* This is an error condition that can result, for example, when a SELECT + ** on the right-hand side of an INSERT contains more result columns than + ** there are columns in the table on the left. The error will be caught + ** and reported later. But we need to make sure enough memory is allocated + ** to avoid other spurious errors in the meantime. */ + pParse->nMem += nResultCol; + } + pDest->nSdst = nResultCol; + regResult = pDest->iSdst; + if( srcTab>=0 ){ + for(i=0; ia[i].zName)); + } + }else if( eDest!=SRT_Exists ){ + /* If the destination is an EXISTS(...) expression, the actual + ** values returned by the SELECT are not required. + */ + sqlite3ExprCodeExprList(pParse, pEList, regResult, + (eDest==SRT_Output||eDest==SRT_Coroutine)?SQLITE_ECEL_DUP:0); + } + + /* 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 ){ + switch( pDistinct->eTnctType ){ + case WHERE_DISTINCT_ORDERED: { + VdbeOp *pOp; /* No longer required OpenEphemeral instr. */ + int iJump; /* Jump destination */ + int regPrev; /* Previous row content */ + + /* Allocate space for the previous row */ + regPrev = pParse->nMem+1; + pParse->nMem += nResultCol; + + /* Change the OP_OpenEphemeral coded earlier to an OP_Null + ** sets the MEM_Cleared bit on the first register of the + ** previous value. This will cause the OP_Ne below to always + ** fail on the first iteration of the loop even if the first + ** row is all NULLs. + */ + sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct); + pOp = sqlite3VdbeGetOp(v, pDistinct->addrTnct); + pOp->opcode = OP_Null; + pOp->p1 = 1; + pOp->p2 = regPrev; + + iJump = sqlite3VdbeCurrentAddr(v) + nResultCol; + for(i=0; ia[i].pExpr); + if( idb->mallocFailed ); + sqlite3VdbeAddOp3(v, OP_Copy, regResult, regPrev, nResultCol-1); + break; + } + + case WHERE_DISTINCT_UNIQUE: { + sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct); + break; + } + + default: { + assert( pDistinct->eTnctType==WHERE_DISTINCT_UNORDERED ); + codeDistinct(pParse, pDistinct->tabTnct, iContinue, nResultCol, regResult); + break; + } + } + if( pSort==0 ){ + codeOffset(v, p->iOffset, iContinue); + } + } + + 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: { + int r1; + r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); + sqlite3ReleaseTempReg(pParse, r1); + 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: { + sqlite3VdbeAddOp3(v, OP_IdxDelete, iParm, regResult, nResultCol); + break; + } +#endif /* SQLITE_OMIT_COMPOUND_SELECT */ + + /* Store the result as data using a unique key. + */ + case SRT_Fifo: + case SRT_DistFifo: + case SRT_Table: + case SRT_EphemTab: { + int r1 = sqlite3GetTempRange(pParse, nPrefixReg+1); + testcase( eDest==SRT_Table ); + testcase( eDest==SRT_EphemTab ); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg); +#ifndef SQLITE_OMIT_CTE + if( eDest==SRT_DistFifo ){ + /* If the destination is DistFifo, then cursor (iParm+1) is open + ** on an ephemeral index. If the current row is already present + ** in the index, do not write it to the output. If not, add the + ** current row to the index and proceed with writing it to the + ** output table as well. */ + int addr = sqlite3VdbeCurrentAddr(v) + 4; + sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r1); + assert( pSort==0 ); + } +#endif + if( pSort ){ + pushOntoSorter(pParse, pSort, p, r1+nPrefixReg, 1, nPrefixReg); + }else{ + int r2 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2); + sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, r2); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3ReleaseTempReg(pParse, r2); + } + sqlite3ReleaseTempRange(pParse, r1, nPrefixReg+1); + 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: { + assert( nResultCol==1 ); + pDest->affSdst = + sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst); + if( pSort ){ + /* 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, pSort, p, regResult, 1, nPrefixReg); + }else{ + int r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult,1,r1, &pDest->affSdst, 1); + sqlite3ExprCacheAffinityChange(pParse, regResult, 1); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); + sqlite3ReleaseTempReg(pParse, r1); + } + break; + } + + /* If any row exist in the result set, record that fact and abort. + */ + case SRT_Exists: { + sqlite3VdbeAddOp2(v, OP_Integer, 1, iParm); + /* 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( nResultCol==1 ); + if( pSort ){ + pushOntoSorter(pParse, pSort, p, regResult, 1, nPrefixReg); + }else{ + assert( regResult==iParm ); + /* The LIMIT clause will jump out of the loop for us */ + } + break; + } +#endif /* #ifndef SQLITE_OMIT_SUBQUERY */ + + case SRT_Coroutine: /* Send data to a co-routine */ + case SRT_Output: { /* Return the results */ + testcase( eDest==SRT_Coroutine ); + testcase( eDest==SRT_Output ); + if( pSort ){ + pushOntoSorter(pParse, pSort, p, regResult, nResultCol, nPrefixReg); + }else if( eDest==SRT_Coroutine ){ + sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); + }else{ + sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nResultCol); + sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol); + } + break; + } + +#ifndef SQLITE_OMIT_CTE + /* Write the results into a priority queue that is order according to + ** pDest->pOrderBy (in pSO). pDest->iSDParm (in iParm) is the cursor for an + ** index with pSO->nExpr+2 columns. Build a key using pSO for the first + ** pSO->nExpr columns, then make sure all keys are unique by adding a + ** final OP_Sequence column. The last column is the record as a blob. + */ + case SRT_DistQueue: + case SRT_Queue: { + int nKey; + int r1, r2, r3; + int addrTest = 0; + ExprList *pSO; + pSO = pDest->pOrderBy; + assert( pSO ); + nKey = pSO->nExpr; + r1 = sqlite3GetTempReg(pParse); + r2 = sqlite3GetTempRange(pParse, nKey+2); + r3 = r2+nKey+1; + if( eDest==SRT_DistQueue ){ + /* If the destination is DistQueue, then cursor (iParm+1) is open + ** on a second ephemeral index that holds all values every previously + ** added to the queue. */ + addrTest = sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, 0, + regResult, nResultCol); + VdbeCoverage(v); + } + sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r3); + if( eDest==SRT_DistQueue ){ + sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r3); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + } + for(i=0; ia[i].u.x.iOrderByCol - 1, + r2+i); + } + sqlite3VdbeAddOp2(v, OP_Sequence, iParm, r2+nKey); + sqlite3VdbeAddOp3(v, OP_MakeRecord, r2, nKey+2, r1); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); + if( addrTest ) sqlite3VdbeJumpHere(v, addrTest); + sqlite3ReleaseTempReg(pParse, r1); + sqlite3ReleaseTempRange(pParse, r2, nKey+2); + break; + } +#endif /* SQLITE_OMIT_CTE */ + + + +#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 ); + break; + } +#endif + } + + /* Jump to the end of the loop if the LIMIT is reached. Except, if + ** there is a sorter, in which case the sorter has already limited + ** the output for us. + */ + if( pSort==0 && p->iLimit ){ + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v); + } +} + +/* +** Allocate a KeyInfo object sufficient for an index of N key columns and +** X extra columns. +*/ +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ + KeyInfo *p = sqlite3DbMallocZero(0, + sizeof(KeyInfo) + (N+X)*(sizeof(CollSeq*)+1)); + if( p ){ + p->aSortOrder = (u8*)&p->aColl[N+X]; + p->nField = (u16)N; + p->nXField = (u16)X; + p->enc = ENC(db); + p->db = db; + p->nRef = 1; + }else{ + db->mallocFailed = 1; + } + return p; +} + +/* +** Deallocate a KeyInfo object +*/ +SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo *p){ + if( p ){ + assert( p->nRef>0 ); + p->nRef--; + if( p->nRef==0 ) sqlite3DbFree(0, p); + } +} + +/* +** Make a new pointer to a KeyInfo object +*/ +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo *p){ + if( p ){ + assert( p->nRef>0 ); + p->nRef++; + } + return p; +} + +#ifdef SQLITE_DEBUG +/* +** Return TRUE if a KeyInfo object can be change. The KeyInfo object +** can only be changed if this is just a single reference to the object. +** +** This routine is used only inside of assert() statements. +*/ +SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo *p){ return p->nRef==1; } +#endif /* SQLITE_DEBUG */ + +/* +** 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 obtained from malloc. The calling +** function is responsible for seeing that this structure is eventually +** freed. +*/ +static KeyInfo *keyInfoFromExprList( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* Form the KeyInfo object from this ExprList */ + int iStart, /* Begin with this column of pList */ + int nExtra /* Add this many extra columns to the end */ +){ + int nExpr; + KeyInfo *pInfo; + struct ExprList_item *pItem; + sqlite3 *db = pParse->db; + int i; + + nExpr = pList->nExpr; + pInfo = sqlite3KeyInfoAlloc(db, nExpr-iStart, nExtra+1); + if( pInfo ){ + assert( sqlite3KeyInfoIsWriteable(pInfo) ); + for(i=iStart, pItem=pList->a+iStart; ipExpr); + if( !pColl ) pColl = db->pDfltColl; + pInfo->aColl[i-iStart] = pColl; + pInfo->aSortOrder[i-iStart] = pItem->sortOrder; + } + } + return pInfo; +} + +#ifndef SQLITE_OMIT_COMPOUND_SELECT +/* +** Name of the connection operator, used for error messages. +*/ +static const char *selectOpName(int id){ + char *z; + switch( id ){ + case TK_ALL: z = "UNION ALL"; break; + case TK_INTERSECT: z = "INTERSECT"; break; + case TK_EXCEPT: z = "EXCEPT"; break; + default: z = "UNION"; break; + } + return z; +} +#endif /* SQLITE_OMIT_COMPOUND_SELECT */ + +#ifndef SQLITE_OMIT_EXPLAIN +/* +** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function +** is a no-op. Otherwise, it adds a single row of output to the EQP result, +** where the caption is of the form: +** +** "USE TEMP B-TREE FOR xxx" +** +** where xxx is one of "DISTINCT", "ORDER BY" or "GROUP BY". Exactly which +** is determined by the zUsage argument. +*/ +static void explainTempTable(Parse *pParse, const char *zUsage){ + if( pParse->explain==2 ){ + Vdbe *v = pParse->pVdbe; + char *zMsg = sqlite3MPrintf(pParse->db, "USE TEMP B-TREE FOR %s", zUsage); + sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); + } +} + +/* +** Assign expression b to lvalue a. A second, no-op, version of this macro +** is provided when SQLITE_OMIT_EXPLAIN is defined. This allows the code +** in sqlite3Select() to assign values to structure member variables that +** only exist if SQLITE_OMIT_EXPLAIN is not defined without polluting the +** code with #ifndef directives. +*/ +# define explainSetInteger(a, b) a = b + +#else +/* No-op versions of the explainXXX() functions and macros. */ +# define explainTempTable(y,z) +# define explainSetInteger(y,z) +#endif + +#if !defined(SQLITE_OMIT_EXPLAIN) && !defined(SQLITE_OMIT_COMPOUND_SELECT) +/* +** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function +** is a no-op. Otherwise, it adds a single row of output to the EQP result, +** where the caption is of one of the two forms: +** +** "COMPOSITE SUBQUERIES iSub1 and iSub2 (op)" +** "COMPOSITE SUBQUERIES iSub1 and iSub2 USING TEMP B-TREE (op)" +** +** where iSub1 and iSub2 are the integers passed as the corresponding +** function parameters, and op is the text representation of the parameter +** of the same name. The parameter "op" must be one of TK_UNION, TK_EXCEPT, +** TK_INTERSECT or TK_ALL. The first form is used if argument bUseTmp is +** false, or the second form if it is true. +*/ +static void explainComposite( + Parse *pParse, /* Parse context */ + int op, /* One of TK_UNION, TK_EXCEPT etc. */ + int iSub1, /* Subquery id 1 */ + int iSub2, /* Subquery id 2 */ + int bUseTmp /* True if a temp table was used */ +){ + assert( op==TK_UNION || op==TK_EXCEPT || op==TK_INTERSECT || op==TK_ALL ); + if( pParse->explain==2 ){ + Vdbe *v = pParse->pVdbe; + char *zMsg = sqlite3MPrintf( + pParse->db, "COMPOUND SUBQUERIES %d AND %d %s(%s)", iSub1, iSub2, + bUseTmp?"USING TEMP B-TREE ":"", selectOpName(op) + ); + sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); + } +} +#else +/* No-op versions of the explainXXX() functions and macros. */ +# define explainComposite(v,w,x,y,z) +#endif + +/* +** 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, /* Parsing context */ + Select *p, /* The SELECT statement */ + SortCtx *pSort, /* Information on the ORDER BY clause */ + int nColumn, /* Number of columns of data */ + SelectDest *pDest /* Write the sorted results here */ +){ + Vdbe *v = pParse->pVdbe; /* The prepared statement */ + int addrBreak = sqlite3VdbeMakeLabel(v); /* Jump here to exit loop */ + int addrContinue = sqlite3VdbeMakeLabel(v); /* Jump here for next cycle */ + int addr; + int addrOnce = 0; + int iTab; + ExprList *pOrderBy = pSort->pOrderBy; + int eDest = pDest->eDest; + int iParm = pDest->iSDParm; + int regRow; + int regRowid; + int nKey; + int iSortTab; /* Sorter cursor to read from */ + int nSortData; /* Trailing values to read from sorter */ + int i; + int bSeq; /* True if sorter record includes seq. no. */ +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + struct ExprList_item *aOutEx = p->pEList->a; +#endif + + if( pSort->labelBkOut ){ + sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrBreak); + sqlite3VdbeResolveLabel(v, pSort->labelBkOut); + } + iTab = pSort->iECursor; + if( eDest==SRT_Output || eDest==SRT_Coroutine ){ + regRowid = 0; + regRow = pDest->iSdst; + nSortData = nColumn; + }else{ + regRowid = sqlite3GetTempReg(pParse); + regRow = sqlite3GetTempReg(pParse); + nSortData = 1; + } + nKey = pOrderBy->nExpr - pSort->nOBSat; + if( pSort->sortFlags & SORTFLAG_UseSorter ){ + int regSortOut = ++pParse->nMem; + iSortTab = pParse->nTab++; + if( pSort->labelBkOut ){ + addrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v); + } + sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData); + if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); + addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); + VdbeCoverage(v); + codeOffset(v, p->iOffset, addrContinue); + sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab); + bSeq = 0; + }else{ + addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v); + codeOffset(v, p->iOffset, addrContinue); + iSortTab = iTab; + bSeq = 1; + } + for(i=0; iaffSdst, 1); + sqlite3ExprCacheAffinityChange(pParse, regRow, 1); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid); + break; + } + case SRT_Mem: { + assert( nColumn==1 ); + sqlite3ExprCodeMove(pParse, regRow, iParm, 1); + /* The LIMIT clause will terminate the loop for us */ + break; + } +#endif + default: { + assert( eDest==SRT_Output || eDest==SRT_Coroutine ); + testcase( eDest==SRT_Output ); + testcase( eDest==SRT_Coroutine ); + if( eDest==SRT_Output ){ + sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn); + sqlite3ExprCacheAffinityChange(pParse, pDest->iSdst, nColumn); + }else{ + sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); + } + break; + } + } + if( regRowid ){ + sqlite3ReleaseTempReg(pParse, regRow); + sqlite3ReleaseTempReg(pParse, regRowid); + } + /* The bottom of the loop + */ + sqlite3VdbeResolveLabel(v, addrContinue); + if( pSort->sortFlags & SORTFLAG_UseSorter ){ + sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); VdbeCoverage(v); + }else{ + sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); VdbeCoverage(v); + } + if( pSort->regReturn ) sqlite3VdbeAddOp1(v, OP_Return, pSort->regReturn); + sqlite3VdbeResolveLabel(v, addrBreak); +} + +/* +** Return a pointer to a string containing the 'declaration type' of the +** expression pExpr. The string may be treated as static by the caller. +** +** Also try to estimate the size of the returned value and return that +** result in *pEstWidth. +** +** The declaration type is the exact datatype definition extracted from the +** original CREATE TABLE statement if the expression is a column. The +** declaration type for a ROWID field is INTEGER. Exactly when an expression +** is considered a column can be complex in the presence of subqueries. The +** result-set expression in all of the following SELECT statements is +** considered a column by this function. +** +** SELECT col FROM tbl; +** SELECT (SELECT col FROM tbl; +** SELECT (SELECT col FROM tbl); +** SELECT abc FROM (SELECT col AS abc FROM tbl); +** +** The declaration type for any expression other than a column is NULL. +** +** This routine has either 3 or 6 parameters depending on whether or not +** the SQLITE_ENABLE_COLUMN_METADATA compile-time option is used. +*/ +#ifdef SQLITE_ENABLE_COLUMN_METADATA +# define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,C,D,E,F) +static const char *columnTypeImpl( + NameContext *pNC, + Expr *pExpr, + const char **pzOrigDb, + const char **pzOrigTab, + const char **pzOrigCol, + u8 *pEstWidth +){ + char const *zOrigDb = 0; + char const *zOrigTab = 0; + char const *zOrigCol = 0; +#else /* if !defined(SQLITE_ENABLE_COLUMN_METADATA) */ +# define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,F) +static const char *columnTypeImpl( + NameContext *pNC, + Expr *pExpr, + u8 *pEstWidth +){ +#endif /* !defined(SQLITE_ENABLE_COLUMN_METADATA) */ + char const *zType = 0; + int j; + u8 estWidth = 1; + + if( NEVER(pExpr==0) || pNC->pSrcList==0 ) return 0; + switch( pExpr->op ){ + case TK_AGG_COLUMN: + case TK_COLUMN: { + /* The expression is a column. Locate the table the column is being + ** extracted from in NameContext.pSrcList. This table may be real + ** database table or a subquery. + */ + Table *pTab = 0; /* Table structure column is extracted from */ + Select *pS = 0; /* Select the column is extracted from */ + int iCol = pExpr->iColumn; /* Index of column in pTab */ + testcase( pExpr->op==TK_AGG_COLUMN ); + testcase( pExpr->op==TK_COLUMN ); + while( pNC && !pTab ){ + SrcList *pTabList = pNC->pSrcList; + for(j=0;jnSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++); + if( jnSrc ){ + pTab = pTabList->a[j].pTab; + pS = pTabList->a[j].pSelect; + }else{ + pNC = pNC->pNext; + } + } + + if( pTab==0 ){ + /* At one time, code such as "SELECT new.x" within a trigger would + ** cause this condition to run. Since then, we have restructured how + ** trigger code is generated and so this condition is no longer + ** possible. However, it can still be true for statements like + ** the following: + ** + ** CREATE TABLE t1(col INTEGER); + ** SELECT (SELECT t1.col) FROM FROM t1; + ** + ** when columnType() is called on the expression "t1.col" in the + ** sub-select. In this case, set the column type to NULL, even + ** though it should really be "INTEGER". + ** + ** This is not a problem, as the column type of "t1.col" is never + ** used. When columnType() is called on the expression + ** "(SELECT t1.col)", the correct type is returned (see the TK_SELECT + ** branch below. */ + break; + } + + assert( pTab && pExpr->pTab==pTab ); + if( pS ){ + /* The "table" is actually a sub-select or a view in the FROM clause + ** of the SELECT statement. Return the declaration type and origin + ** data for the result-set column of the sub-select. + */ + if( iCol>=0 && iColpEList->nExpr ){ + /* If iCol is less than zero, then the expression requests the + ** rowid of the sub-select or view. This expression is legal (see + ** test case misc2.2.2) - it always evaluates to NULL. + */ + NameContext sNC; + Expr *p = pS->pEList->a[iCol].pExpr; + sNC.pSrcList = pS->pSrc; + sNC.pNext = pNC; + sNC.pParse = pNC->pParse; + zType = columnType(&sNC, p,&zOrigDb,&zOrigTab,&zOrigCol, &estWidth); + } + }else if( pTab->pSchema ){ + /* A real table */ + assert( !pS ); + if( iCol<0 ) iCol = pTab->iPKey; + assert( iCol==-1 || (iCol>=0 && iColnCol) ); +#ifdef SQLITE_ENABLE_COLUMN_METADATA + if( iCol<0 ){ + zType = "INTEGER"; + zOrigCol = "rowid"; + }else{ + zType = pTab->aCol[iCol].zType; + zOrigCol = pTab->aCol[iCol].zName; + estWidth = pTab->aCol[iCol].szEst; + } + zOrigTab = pTab->zName; + if( pNC->pParse ){ + int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema); + zOrigDb = pNC->pParse->db->aDb[iDb].zName; + } +#else + if( iCol<0 ){ + zType = "INTEGER"; + }else{ + zType = pTab->aCol[iCol].zType; + estWidth = pTab->aCol[iCol].szEst; + } +#endif + } + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_SELECT: { + /* The expression is a sub-select. Return the declaration type and + ** origin info for the single column in the result set of the SELECT + ** statement. + */ + NameContext sNC; + Select *pS = pExpr->x.pSelect; + Expr *p = pS->pEList->a[0].pExpr; + assert( ExprHasProperty(pExpr, EP_xIsSelect) ); + sNC.pSrcList = pS->pSrc; + sNC.pNext = pNC; + sNC.pParse = pNC->pParse; + zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol, &estWidth); + break; + } +#endif + } + +#ifdef SQLITE_ENABLE_COLUMN_METADATA + if( pzOrigDb ){ + assert( pzOrigTab && pzOrigCol ); + *pzOrigDb = zOrigDb; + *pzOrigTab = zOrigTab; + *pzOrigCol = zOrigCol; + } +#endif + if( pEstWidth ) *pEstWidth = estWidth; + return zType; +} + +/* +** Generate code that will tell the VDBE the declaration types of columns +** in the result set. +*/ +static void generateColumnTypes( + Parse *pParse, /* Parser context */ + SrcList *pTabList, /* List of tables */ + ExprList *pEList /* Expressions defining the result set */ +){ +#ifndef SQLITE_OMIT_DECLTYPE + Vdbe *v = pParse->pVdbe; + int i; + NameContext sNC; + sNC.pSrcList = pTabList; + sNC.pParse = pParse; + for(i=0; inExpr; i++){ + Expr *p = pEList->a[i].pExpr; + const char *zType; +#ifdef SQLITE_ENABLE_COLUMN_METADATA + const char *zOrigDb = 0; + const char *zOrigTab = 0; + const char *zOrigCol = 0; + zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol, 0); + + /* The vdbe must make its own copy of the column-type and other + ** column specific strings, in case the schema is reset before this + ** virtual machine is deleted. + */ + sqlite3VdbeSetColName(v, i, COLNAME_DATABASE, zOrigDb, SQLITE_TRANSIENT); + sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, SQLITE_TRANSIENT); + sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, SQLITE_TRANSIENT); +#else + zType = columnType(&sNC, p, 0, 0, 0, 0); +#endif + sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT); + } +#endif /* !defined(SQLITE_OMIT_DECLTYPE) */ +} + +/* +** 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; + +#ifndef SQLITE_OMIT_EXPLAIN + /* If this is an EXPLAIN, skip this step */ + if( pParse->explain ){ + return; + } +#endif + + if( pParse->colNamesSet || NEVER(v==0) || db->mallocFailed ) return; + pParse->colNamesSet = 1; + fullNames = (db->flags & SQLITE_FullColNames)!=0; + shortNames = (db->flags & SQLITE_ShortColNames)!=0; + sqlite3VdbeSetNumCols(v, pEList->nExpr); + for(i=0; inExpr; i++){ + Expr *p; + p = pEList->a[i].pExpr; + if( NEVER(p==0) ) continue; + if( pEList->a[i].zName ){ + char *zName = pEList->a[i].zName; + sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT); + }else if( (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN) && pTabList ){ + Table *pTab; + char *zCol; + int iCol = p->iColumn; + for(j=0; ALWAYS(jnSrc); j++){ + if( pTabList->a[j].iCursor==p->iTable ) break; + } + assert( jnSrc ); + pTab = pTabList->a[j].pTab; + if( iCol<0 ) iCol = pTab->iPKey; + assert( iCol==-1 || (iCol>=0 && iColnCol) ); + if( iCol<0 ){ + zCol = "rowid"; + }else{ + zCol = pTab->aCol[iCol].zName; + } + if( !shortNames && !fullNames ){ + sqlite3VdbeSetColName(v, i, COLNAME_NAME, + sqlite3DbStrDup(db, pEList->a[i].zSpan), SQLITE_DYNAMIC); + }else if( fullNames ){ + char *zName = 0; + zName = sqlite3MPrintf(db, "%s.%s", pTab->zName, zCol); + sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_DYNAMIC); + }else{ + sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT); + } + }else{ + const char *z = pEList->a[i].zSpan; + z = z==0 ? sqlite3MPrintf(db, "column%d", i+1) : sqlite3DbStrDup(db, z); + sqlite3VdbeSetColName(v, i, COLNAME_NAME, z, SQLITE_DYNAMIC); + } + } + generateColumnTypes(pParse, pTabList, pEList); +} + +/* +** Given an expression list (which is really the list of expressions +** that form the result set of a SELECT statement) compute appropriate +** column names for a table that would hold the expression list. +** +** All column names will be unique. +** +** Only the column names are computed. Column.zType, Column.zColl, +** and other fields of Column are zeroed. +** +** Return SQLITE_OK on success. If a memory allocation error occurs, +** store NULL in *paCol and 0 in *pnCol and return SQLITE_NOMEM. +*/ +static int selectColumnsFromExprList( + Parse *pParse, /* Parsing context */ + ExprList *pEList, /* Expr list from which to derive column names */ + i16 *pnCol, /* Write the number of columns here */ + Column **paCol /* Write the new column list here */ +){ + sqlite3 *db = pParse->db; /* Database connection */ + int i, j; /* Loop counters */ + int cnt; /* Index added to make the name unique */ + Column *aCol, *pCol; /* For looping over result columns */ + int nCol; /* Number of columns in the result set */ + Expr *p; /* Expression for a single result column */ + char *zName; /* Column name */ + int nName; /* Size of name in zName[] */ + + if( pEList ){ + nCol = pEList->nExpr; + aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol); + testcase( aCol==0 ); + }else{ + nCol = 0; + aCol = 0; + } + *pnCol = nCol; + *paCol = aCol; + + for(i=0, pCol=aCol; ia[i].pExpr); + if( (zName = pEList->a[i].zName)!=0 ){ + /* If the column contains an "AS " phrase, use as the name */ + zName = sqlite3DbStrDup(db, zName); + }else{ + Expr *pColExpr = p; /* The expression that is the result column name */ + Table *pTab; /* Table associated with this expression */ + while( pColExpr->op==TK_DOT ){ + pColExpr = pColExpr->pRight; + assert( pColExpr!=0 ); + } + if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){ + /* For columns use the column name name */ + int iCol = pColExpr->iColumn; + pTab = pColExpr->pTab; + if( iCol<0 ) iCol = pTab->iPKey; + zName = sqlite3MPrintf(db, "%s", + iCol>=0 ? pTab->aCol[iCol].zName : "rowid"); + }else if( pColExpr->op==TK_ID ){ + assert( !ExprHasProperty(pColExpr, EP_IntValue) ); + zName = sqlite3MPrintf(db, "%s", pColExpr->u.zToken); + }else{ + /* Use the original text of the column expression as its name */ + zName = sqlite3MPrintf(db, "%s", pEList->a[i].zSpan); + } + } + if( db->mallocFailed ){ + sqlite3DbFree(db, zName); + break; + } + + /* Make sure the column name is unique. If the name is not unique, + ** append an integer to the name so that it becomes unique. + */ + nName = sqlite3Strlen30(zName); + for(j=cnt=0; j1 && sqlite3Isdigit(zName[k]); k--){} + if( k>=0 && zName[k]==':' ) nName = k; + zName[nName] = 0; + zNewName = sqlite3MPrintf(db, "%s:%d", zName, ++cnt); + sqlite3DbFree(db, zName); + zName = zNewName; + j = -1; + if( zName==0 ) break; + } + } + pCol->zName = zName; + } + if( db->mallocFailed ){ + for(j=0; jdb; + NameContext sNC; + Column *pCol; + CollSeq *pColl; + int i; + Expr *p; + struct ExprList_item *a; + u64 szAll = 0; + + assert( pSelect!=0 ); + assert( (pSelect->selFlags & SF_Resolved)!=0 ); + assert( pTab->nCol==pSelect->pEList->nExpr || db->mallocFailed ); + if( db->mallocFailed ) return; + memset(&sNC, 0, sizeof(sNC)); + sNC.pSrcList = pSelect->pSrc; + a = pSelect->pEList->a; + for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ + p = a[i].pExpr; + if( pCol->zType==0 ){ + pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p,0,0,0, &pCol->szEst)); + } + szAll += pCol->szEst; + pCol->affinity = sqlite3ExprAffinity(p); + if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_NONE; + pColl = sqlite3ExprCollSeq(pParse, p); + if( pColl && pCol->zColl==0 ){ + pCol->zColl = sqlite3DbStrDup(db, pColl->zName); + } + } + pTab->szTabRow = sqlite3LogEst(szAll*4); +} + +/* +** Given a SELECT statement, generate a Table structure that describes +** the result set of that SELECT. +*/ +SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){ + Table *pTab; + sqlite3 *db = pParse->db; + int savedFlags; + + savedFlags = db->flags; + db->flags &= ~SQLITE_FullColNames; + db->flags |= SQLITE_ShortColNames; + sqlite3SelectPrep(pParse, pSelect, 0); + if( pParse->nErr ) return 0; + while( pSelect->pPrior ) pSelect = pSelect->pPrior; + db->flags = savedFlags; + pTab = sqlite3DbMallocZero(db, sizeof(Table) ); + if( pTab==0 ){ + return 0; + } + /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside + ** is disabled */ + assert( db->lookaside.bEnabled==0 ); + pTab->nRef = 1; + pTab->zName = 0; + pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); + selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); + selectAddColumnTypeAndCollation(pParse, pTab, pSelect); + pTab->iPKey = -1; + if( db->mallocFailed ){ + sqlite3DeleteTable(db, pTab); + return 0; + } + return pTab; +} + +/* +** Get a VDBE for the given parser context. Create a new one if necessary. +** If an error occurs, return NULL and leave a message in pParse. +*/ +SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){ + Vdbe *v = pParse->pVdbe; + if( v==0 ){ + v = pParse->pVdbe = sqlite3VdbeCreate(pParse); + if( v ) sqlite3VdbeAddOp0(v, OP_Init); + if( pParse->pToplevel==0 + && OptimizationEnabled(pParse->db,SQLITE_FactorOutConst) + ){ + pParse->okConstFactor = 1; + } + + } + 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 (zero) +** prior to calling this routine. +** +** The iOffset register (if it exists) is initialized to the value +** of the OFFSET. The iLimit register is initialized to LIMIT. Register +** iOffset+1 is initialized to LIMIT+OFFSET. +** +** 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 = 0; + int iLimit = 0; + int iOffset; + int addr1, n; + if( p->iLimit ) return; + + /* + ** "LIMIT -1" always shows all rows. There is some + ** controversy about what the correct behavior should be. + ** The current implementation interprets "LIMIT 0" to mean + ** no rows. + */ + sqlite3ExprCacheClear(pParse); + assert( p->pOffset==0 || p->pLimit!=0 ); + if( p->pLimit ){ + p->iLimit = iLimit = ++pParse->nMem; + v = sqlite3GetVdbe(pParse); + assert( v!=0 ); + if( sqlite3ExprIsInteger(p->pLimit, &n) ){ + sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit); + VdbeComment((v, "LIMIT counter")); + if( n==0 ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak); + }else if( n>=0 && p->nSelectRow>(u64)n ){ + p->nSelectRow = n; + } + }else{ + sqlite3ExprCode(pParse, p->pLimit, iLimit); + sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v); + VdbeComment((v, "LIMIT counter")); + sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v); + } + if( p->pOffset ){ + p->iOffset = iOffset = ++pParse->nMem; + pParse->nMem++; /* Allocate an extra register for limit+offset */ + sqlite3ExprCode(pParse, p->pOffset, iOffset); + sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v); + VdbeComment((v, "OFFSET counter")); + addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Integer, 0, iOffset); + sqlite3VdbeJumpHere(v, addr1); + sqlite3VdbeAddOp3(v, OP_Add, iLimit, iOffset, iOffset+1); + VdbeComment((v, "LIMIT+OFFSET")); + addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Integer, -1, iOffset+1); + sqlite3VdbeJumpHere(v, addr1); + } + } +} + +#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. +** +** The collating sequence for the compound select is taken from the +** left-most term of the select that has a collating sequence. +*/ +static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){ + CollSeq *pRet; + if( p->pPrior ){ + pRet = multiSelectCollSeq(pParse, p->pPrior, iCol); + }else{ + pRet = 0; + } + assert( iCol>=0 ); + if( pRet==0 && iColpEList->nExpr ){ + pRet = sqlite3ExprCollSeq(pParse, p->pEList->a[iCol].pExpr); + } + return pRet; +} + +/* +** The select statement passed as the second parameter is a compound SELECT +** with an ORDER BY clause. This function allocates and returns a KeyInfo +** structure suitable for implementing the ORDER BY. +** +** Space to hold the KeyInfo structure is obtained from malloc. The calling +** function is responsible for ensuring that this structure is eventually +** freed. +*/ +static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){ + ExprList *pOrderBy = p->pOrderBy; + int nOrderBy = p->pOrderBy->nExpr; + sqlite3 *db = pParse->db; + KeyInfo *pRet = sqlite3KeyInfoAlloc(db, nOrderBy+nExtra, 1); + if( pRet ){ + int i; + for(i=0; ia[i]; + Expr *pTerm = pItem->pExpr; + CollSeq *pColl; + + if( pTerm->flags & EP_Collate ){ + pColl = sqlite3ExprCollSeq(pParse, pTerm); + }else{ + pColl = multiSelectCollSeq(pParse, p, pItem->u.x.iOrderByCol-1); + if( pColl==0 ) pColl = db->pDfltColl; + pOrderBy->a[i].pExpr = + sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName); + } + assert( sqlite3KeyInfoIsWriteable(pRet) ); + pRet->aColl[i] = pColl; + pRet->aSortOrder[i] = pOrderBy->a[i].sortOrder; + } + } + + return pRet; +} + +#ifndef SQLITE_OMIT_CTE +/* +** This routine generates VDBE code to compute the content of a WITH RECURSIVE +** query of the form: +** +** AS ( UNION [ALL] ) +** \___________/ \_______________/ +** p->pPrior p +** +** +** There is exactly one reference to the recursive-table in the FROM clause +** of recursive-query, marked with the SrcList->a[].isRecursive flag. +** +** The setup-query runs once to generate an initial set of rows that go +** into a Queue table. Rows are extracted from the Queue table one by +** one. Each row extracted from Queue is output to pDest. Then the single +** extracted row (now in the iCurrent table) becomes the content of the +** recursive-table for a recursive-query run. The output of the recursive-query +** is added back into the Queue table. Then another row is extracted from Queue +** and the iteration continues until the Queue table is empty. +** +** If the compound query operator is UNION then no duplicate rows are ever +** inserted into the Queue table. The iDistinct table keeps a copy of all rows +** that have ever been inserted into Queue and causes duplicates to be +** discarded. If the operator is UNION ALL, then duplicates are allowed. +** +** If the query has an ORDER BY, then entries in the Queue table are kept in +** ORDER BY order and the first entry is extracted for each cycle. Without +** an ORDER BY, the Queue table is just a FIFO. +** +** If a LIMIT clause is provided, then the iteration stops after LIMIT rows +** have been output to pDest. A LIMIT of zero means to output no rows and a +** negative LIMIT means to output all rows. If there is also an OFFSET clause +** with a positive value, then the first OFFSET outputs are discarded rather +** than being sent to pDest. The LIMIT count does not begin until after OFFSET +** rows have been skipped. +*/ +static void generateWithRecursiveQuery( + Parse *pParse, /* Parsing context */ + Select *p, /* The recursive SELECT to be coded */ + SelectDest *pDest /* What to do with query results */ +){ + SrcList *pSrc = p->pSrc; /* The FROM clause of the recursive query */ + int nCol = p->pEList->nExpr; /* Number of columns in the recursive table */ + Vdbe *v = pParse->pVdbe; /* The prepared statement under construction */ + Select *pSetup = p->pPrior; /* The setup query */ + int addrTop; /* Top of the loop */ + int addrCont, addrBreak; /* CONTINUE and BREAK addresses */ + int iCurrent = 0; /* The Current table */ + int regCurrent; /* Register holding Current table */ + int iQueue; /* The Queue table */ + int iDistinct = 0; /* To ensure unique results if UNION */ + int eDest = SRT_Fifo; /* How to write to Queue */ + SelectDest destQueue; /* SelectDest targetting the Queue table */ + int i; /* Loop counter */ + int rc; /* Result code */ + ExprList *pOrderBy; /* The ORDER BY clause */ + Expr *pLimit, *pOffset; /* Saved LIMIT and OFFSET */ + int regLimit, regOffset; /* Registers used by LIMIT and OFFSET */ + + /* Obtain authorization to do a recursive query */ + if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return; + + /* Process the LIMIT and OFFSET clauses, if they exist */ + addrBreak = sqlite3VdbeMakeLabel(v); + computeLimitRegisters(pParse, p, addrBreak); + pLimit = p->pLimit; + pOffset = p->pOffset; + regLimit = p->iLimit; + regOffset = p->iOffset; + p->pLimit = p->pOffset = 0; + p->iLimit = p->iOffset = 0; + pOrderBy = p->pOrderBy; + + /* Locate the cursor number of the Current table */ + for(i=0; ALWAYS(inSrc); i++){ + if( pSrc->a[i].isRecursive ){ + iCurrent = pSrc->a[i].iCursor; + break; + } + } + + /* Allocate cursors numbers for Queue and Distinct. The cursor number for + ** the Distinct table must be exactly one greater than Queue in order + ** for the SRT_DistFifo and SRT_DistQueue destinations to work. */ + iQueue = pParse->nTab++; + if( p->op==TK_UNION ){ + eDest = pOrderBy ? SRT_DistQueue : SRT_DistFifo; + iDistinct = pParse->nTab++; + }else{ + eDest = pOrderBy ? SRT_Queue : SRT_Fifo; + } + sqlite3SelectDestInit(&destQueue, eDest, iQueue); + + /* Allocate cursors for Current, Queue, and Distinct. */ + regCurrent = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_OpenPseudo, iCurrent, regCurrent, nCol); + if( pOrderBy ){ + KeyInfo *pKeyInfo = multiSelectOrderByKeyInfo(pParse, p, 1); + sqlite3VdbeAddOp4(v, OP_OpenEphemeral, iQueue, pOrderBy->nExpr+2, 0, + (char*)pKeyInfo, P4_KEYINFO); + destQueue.pOrderBy = pOrderBy; + }else{ + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iQueue, nCol); + } + VdbeComment((v, "Queue table")); + if( iDistinct ){ + p->addrOpenEphm[0] = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iDistinct, 0); + p->selFlags |= SF_UsesEphemeral; + } + + /* Detach the ORDER BY clause from the compound SELECT */ + p->pOrderBy = 0; + + /* Store the results of the setup-query in Queue. */ + pSetup->pNext = 0; + rc = sqlite3Select(pParse, pSetup, &destQueue); + pSetup->pNext = p; + if( rc ) goto end_of_recursive_query; + + /* Find the next row in the Queue and output that row */ + addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iQueue, addrBreak); VdbeCoverage(v); + + /* Transfer the next row in Queue over to Current */ + sqlite3VdbeAddOp1(v, OP_NullRow, iCurrent); /* To reset column cache */ + if( pOrderBy ){ + sqlite3VdbeAddOp3(v, OP_Column, iQueue, pOrderBy->nExpr+1, regCurrent); + }else{ + sqlite3VdbeAddOp2(v, OP_RowData, iQueue, regCurrent); + } + sqlite3VdbeAddOp1(v, OP_Delete, iQueue); + + /* Output the single row in Current */ + addrCont = sqlite3VdbeMakeLabel(v); + codeOffset(v, regOffset, addrCont); + selectInnerLoop(pParse, p, p->pEList, iCurrent, + 0, 0, pDest, addrCont, addrBreak); + if( regLimit ){ + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, regLimit, addrBreak); + VdbeCoverage(v); + } + sqlite3VdbeResolveLabel(v, addrCont); + + /* Execute the recursive SELECT taking the single row in Current as + ** the value for the recursive-table. Store the results in the Queue. + */ + p->pPrior = 0; + sqlite3Select(pParse, p, &destQueue); + assert( p->pPrior==0 ); + p->pPrior = pSetup; + + /* Keep running the loop until the Queue is empty */ + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop); + sqlite3VdbeResolveLabel(v, addrBreak); + +end_of_recursive_query: + sqlite3ExprListDelete(pParse->db, p->pOrderBy); + p->pOrderBy = pOrderBy; + p->pLimit = pLimit; + p->pOffset = pOffset; + return; +} +#endif /* SQLITE_OMIT_CTE */ + +/* Forward references */ +static int multiSelectOrderBy( + Parse *pParse, /* Parsing context */ + Select *p, /* The right-most of SELECTs to be coded */ + SelectDest *pDest /* What to do with query results */ +); + +/* +** Error message for when two or more terms of a compound select have different +** size result sets. +*/ +static void selectWrongNumTermsError(Parse *pParse, Select *p){ + if( p->selFlags & SF_Values ){ + sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms"); + }else{ + sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s" + " do not have the same number of result columns", selectOpName(p->op)); + } +} + +/* +** Handle the special case of a compound-select that originates from a +** VALUES clause. By handling this as a special case, we avoid deep +** recursion, and thus do not need to enforce the SQLITE_LIMIT_COMPOUND_SELECT +** on a VALUES clause. +** +** Because the Select object originates from a VALUES clause: +** (1) It has no LIMIT or OFFSET +** (2) All terms are UNION ALL +** (3) There is no ORDER BY clause +*/ +static int multiSelectValues( + Parse *pParse, /* Parsing context */ + Select *p, /* The right-most of SELECTs to be coded */ + SelectDest *pDest /* What to do with query results */ +){ + Select *pPrior; + int nExpr = p->pEList->nExpr; + int nRow = 1; + int rc = 0; + assert( p->selFlags & SF_MultiValue ); + do{ + assert( p->selFlags & SF_Values ); + assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) ); + assert( p->pLimit==0 ); + assert( p->pOffset==0 ); + if( p->pEList->nExpr!=nExpr ){ + selectWrongNumTermsError(pParse, p); + return 1; + } + if( p->pPrior==0 ) break; + assert( p->pPrior->pNext==p ); + p = p->pPrior; + nRow++; + }while(1); + while( p ){ + pPrior = p->pPrior; + p->pPrior = 0; + rc = sqlite3Select(pParse, p, pDest); + p->pPrior = pPrior; + if( rc ) break; + p->nSelectRow = nRow; + p = p->pNext; + } + return rc; +} + +/* +** This routine is called to process a compound query form from +** two or more separate queries using UNION, UNION ALL, EXCEPT, or +** INTERSECT +** +** "p" points to the right-most of the two queries. the query on the +** left is p->pPrior. The left query could also be a compound query +** in which case this routine will be called recursively. +** +** The results of the total query are to be written into a destination +** of type eDest with parameter iParm. +** +** Example 1: Consider a three-way compound SQL statement. +** +** SELECT a FROM t1 UNION SELECT b FROM t2 UNION SELECT c FROM t3 +** +** This statement is parsed up as follows: +** +** SELECT c FROM t3 +** | +** `-----> SELECT b FROM t2 +** | +** `------> SELECT a FROM t1 +** +** The arrows in the diagram above represent the Select.pPrior pointer. +** So if this routine is called with p equal to the t3 query, then +** pPrior will be the t2 query. p->op will be TK_UNION in this case. +** +** Notice that because of the way SQLite parses compound SELECTs, the +** individual selects always group from left to right. +*/ +static int multiSelect( + Parse *pParse, /* Parsing context */ + Select *p, /* The right-most of SELECTs to be coded */ + SelectDest *pDest /* What to do with query results */ +){ + int rc = SQLITE_OK; /* Success code from a subroutine */ + Select *pPrior; /* Another SELECT immediately to our left */ + Vdbe *v; /* Generate code to this VDBE */ + SelectDest dest; /* Alternative data destination */ + Select *pDelete = 0; /* Chain of simple selects to delete */ + sqlite3 *db; /* Database connection */ +#ifndef SQLITE_OMIT_EXPLAIN + int iSub1 = 0; /* EQP id of left-hand query */ + int iSub2 = 0; /* EQP id of right-hand query */ +#endif + + /* 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. + */ + assert( p && p->pPrior ); /* Calling function guarantees this much */ + assert( (p->selFlags & SF_Recursive)==0 || p->op==TK_ALL || p->op==TK_UNION ); + db = pParse->db; + pPrior = p->pPrior; + dest = *pDest; + 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; + } + + v = sqlite3GetVdbe(pParse); + assert( v!=0 ); /* The VDBE already created by calling function */ + + /* Create the destination temporary table if necessary + */ + if( dest.eDest==SRT_EphemTab ){ + assert( p->pEList ); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr); + sqlite3VdbeChangeP5(v, BTREE_UNORDERED); + dest.eDest = SRT_Table; + } + + /* Special handling for a compound-select that originates as a VALUES clause. + */ + if( p->selFlags & SF_MultiValue ){ + rc = multiSelectValues(pParse, p, &dest); + goto multi_select_end; + } + + /* Make sure all SELECTs in the statement have the same number of elements + ** in their result sets. + */ + assert( p->pEList && pPrior->pEList ); + if( p->pEList->nExpr!=pPrior->pEList->nExpr ){ + selectWrongNumTermsError(pParse, p); + rc = 1; + goto multi_select_end; + } + +#ifndef SQLITE_OMIT_CTE + if( p->selFlags & SF_Recursive ){ + generateWithRecursiveQuery(pParse, p, &dest); + }else +#endif + + /* Compound SELECTs that have an ORDER BY clause are handled separately. + */ + if( p->pOrderBy ){ + return multiSelectOrderBy(pParse, p, pDest); + }else + + /* Generate code for the left and right SELECT statements. + */ + switch( p->op ){ + case TK_ALL: { + int addr = 0; + int nLimit; + assert( !pPrior->pLimit ); + pPrior->iLimit = p->iLimit; + pPrior->iOffset = p->iOffset; + pPrior->pLimit = p->pLimit; + pPrior->pOffset = p->pOffset; + explainSetInteger(iSub1, pParse->iNextSelectId); + rc = sqlite3Select(pParse, pPrior, &dest); + 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 ){ + addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v); + VdbeComment((v, "Jump ahead if LIMIT reached")); + } + explainSetInteger(iSub2, pParse->iNextSelectId); + rc = sqlite3Select(pParse, p, &dest); + testcase( rc!=SQLITE_OK ); + pDelete = p->pPrior; + p->pPrior = pPrior; + p->nSelectRow += pPrior->nSelectRow; + if( pPrior->pLimit + && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit) + && nLimit>0 && p->nSelectRow > (u64)nLimit + ){ + p->nSelectRow = nLimit; + } + if( addr ){ + sqlite3VdbeJumpHere(v, addr); + } + break; + } + case TK_EXCEPT: + case TK_UNION: { + int unionTab; /* Cursor number of the temporary table holding result */ + u8 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; + SelectDest uniondest; + + testcase( p->op==TK_EXCEPT ); + testcase( p->op==TK_UNION ); + priorOp = SRT_Union; + if( dest.eDest==priorOp ){ + /* We can reuse a temporary table generated by a SELECT to our + ** right. + */ + assert( p->pLimit==0 ); /* Not allowed on leftward elements */ + assert( p->pOffset==0 ); /* Not allowed on leftward elements */ + unionTab = dest.iSDParm; + }else{ + /* We will need to create our own temporary table to hold the + ** intermediate results. + */ + unionTab = pParse->nTab++; + assert( p->pOrderBy==0 ); + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0); + assert( p->addrOpenEphm[0] == -1 ); + p->addrOpenEphm[0] = addr; + findRightmost(p)->selFlags |= SF_UsesEphemeral; + assert( p->pEList ); + } + + /* Code the SELECT statements to our left + */ + assert( !pPrior->pOrderBy ); + sqlite3SelectDestInit(&uniondest, priorOp, unionTab); + explainSetInteger(iSub1, pParse->iNextSelectId); + rc = sqlite3Select(pParse, pPrior, &uniondest); + if( rc ){ + goto multi_select_end; + } + + /* Code the current SELECT statement + */ + if( p->op==TK_EXCEPT ){ + op = SRT_Except; + }else{ + assert( p->op==TK_UNION ); + op = SRT_Union; + } + p->pPrior = 0; + pLimit = p->pLimit; + p->pLimit = 0; + pOffset = p->pOffset; + p->pOffset = 0; + uniondest.eDest = op; + explainSetInteger(iSub2, pParse->iNextSelectId); + rc = sqlite3Select(pParse, p, &uniondest); + testcase( rc!=SQLITE_OK ); + /* Query flattening in sqlite3Select() might refill p->pOrderBy. + ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */ + sqlite3ExprListDelete(db, p->pOrderBy); + pDelete = p->pPrior; + p->pPrior = pPrior; + p->pOrderBy = 0; + if( p->op==TK_UNION ) p->nSelectRow += pPrior->nSelectRow; + sqlite3ExprDelete(db, p->pLimit); + p->pLimit = pLimit; + p->pOffset = pOffset; + p->iLimit = 0; + p->iOffset = 0; + + /* Convert the data in the temporary table into whatever form + ** it is that we currently need. + */ + assert( unionTab==dest.iSDParm || dest.eDest!=priorOp ); + if( dest.eDest!=priorOp ){ + int iCont, iBreak, iStart; + assert( p->pEList ); + if( dest.eDest==SRT_Output ){ + Select *pFirst = p; + while( pFirst->pPrior ) pFirst = pFirst->pPrior; + generateColumnNames(pParse, 0, pFirst->pEList); + } + iBreak = sqlite3VdbeMakeLabel(v); + iCont = sqlite3VdbeMakeLabel(v); + computeLimitRegisters(pParse, p, iBreak); + sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v); + iStart = sqlite3VdbeCurrentAddr(v); + selectInnerLoop(pParse, p, p->pEList, unionTab, + 0, 0, &dest, iCont, iBreak); + sqlite3VdbeResolveLabel(v, iCont); + sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v); + sqlite3VdbeResolveLabel(v, iBreak); + sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0); + } + break; + } + default: assert( p->op==TK_INTERSECT ); { + int tab1, tab2; + int iCont, iBreak, iStart; + Expr *pLimit, *pOffset; + int addr; + SelectDest intersectdest; + int r1; + + /* 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++; + assert( p->pOrderBy==0 ); + + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0); + assert( p->addrOpenEphm[0] == -1 ); + p->addrOpenEphm[0] = addr; + findRightmost(p)->selFlags |= SF_UsesEphemeral; + assert( p->pEList ); + + /* Code the SELECTs to our left into temporary table "tab1". + */ + sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1); + explainSetInteger(iSub1, pParse->iNextSelectId); + rc = sqlite3Select(pParse, pPrior, &intersectdest); + if( rc ){ + goto multi_select_end; + } + + /* Code the current SELECT into temporary table "tab2" + */ + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0); + assert( p->addrOpenEphm[1] == -1 ); + p->addrOpenEphm[1] = addr; + p->pPrior = 0; + pLimit = p->pLimit; + p->pLimit = 0; + pOffset = p->pOffset; + p->pOffset = 0; + intersectdest.iSDParm = tab2; + explainSetInteger(iSub2, pParse->iNextSelectId); + rc = sqlite3Select(pParse, p, &intersectdest); + testcase( rc!=SQLITE_OK ); + pDelete = p->pPrior; + p->pPrior = pPrior; + if( p->nSelectRow>pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow; + sqlite3ExprDelete(db, p->pLimit); + p->pLimit = pLimit; + p->pOffset = pOffset; + + /* Generate code to take the intersection of the two temporary + ** tables. + */ + assert( p->pEList ); + if( dest.eDest==SRT_Output ){ + Select *pFirst = p; + while( pFirst->pPrior ) pFirst = pFirst->pPrior; + generateColumnNames(pParse, 0, pFirst->pEList); + } + iBreak = sqlite3VdbeMakeLabel(v); + iCont = sqlite3VdbeMakeLabel(v); + computeLimitRegisters(pParse, p, iBreak); + sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v); + r1 = sqlite3GetTempReg(pParse); + iStart = sqlite3VdbeAddOp2(v, OP_RowKey, tab1, r1); + sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); VdbeCoverage(v); + sqlite3ReleaseTempReg(pParse, r1); + selectInnerLoop(pParse, p, p->pEList, tab1, + 0, 0, &dest, iCont, iBreak); + sqlite3VdbeResolveLabel(v, iCont); + sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v); + sqlite3VdbeResolveLabel(v, iBreak); + sqlite3VdbeAddOp2(v, OP_Close, tab2, 0); + sqlite3VdbeAddOp2(v, OP_Close, tab1, 0); + break; + } + } + + explainComposite(pParse, p->op, iSub1, iSub2, p->op!=TK_ALL); + + /* Compute collating sequences used by + ** temporary tables needed to implement the compound select. + ** Attach the KeyInfo structure to all temporary tables. + ** + ** 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->selFlags & SF_UsesEphemeral ){ + int i; /* Loop counter */ + KeyInfo *pKeyInfo; /* Collating sequence for the result set */ + Select *pLoop; /* For looping through SELECT statements */ + CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */ + int nCol; /* Number of columns in result set */ + + assert( p->pNext==0 ); + nCol = p->pEList->nExpr; + pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1); + if( !pKeyInfo ){ + rc = SQLITE_NOMEM; + goto multi_select_end; + } + for(i=0, apColl=pKeyInfo->aColl; ipDfltColl; + } + } + + for(pLoop=p; pLoop; pLoop=pLoop->pPrior){ + for(i=0; i<2; i++){ + int addr = pLoop->addrOpenEphm[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->addrOpenEphm[1]<0 ); + break; + } + sqlite3VdbeChangeP2(v, addr, nCol); + sqlite3VdbeChangeP4(v, addr, (char*)sqlite3KeyInfoRef(pKeyInfo), + P4_KEYINFO); + pLoop->addrOpenEphm[i] = -1; + } + } + sqlite3KeyInfoUnref(pKeyInfo); + } + +multi_select_end: + pDest->iSdst = dest.iSdst; + pDest->nSdst = dest.nSdst; + sqlite3SelectDelete(db, pDelete); + return rc; +} +#endif /* SQLITE_OMIT_COMPOUND_SELECT */ + +/* +** Code an output subroutine for a coroutine implementation of a +** SELECT statment. +** +** The data to be output is contained in pIn->iSdst. There are +** pIn->nSdst columns to be output. pDest is where the output should +** be sent. +** +** regReturn is the number of the register holding the subroutine +** return address. +** +** If regPrev>0 then it is the first register in a vector that +** records the previous output. mem[regPrev] is a flag that is false +** if there has been no previous output. If regPrev>0 then code is +** generated to suppress duplicates. pKeyInfo is used for comparing +** keys. +** +** If the LIMIT found in p->iLimit is reached, jump immediately to +** iBreak. +*/ +static int generateOutputSubroutine( + Parse *pParse, /* Parsing context */ + Select *p, /* The SELECT statement */ + SelectDest *pIn, /* Coroutine supplying data */ + SelectDest *pDest, /* Where to send the data */ + int regReturn, /* The return address register */ + int regPrev, /* Previous result register. No uniqueness if 0 */ + KeyInfo *pKeyInfo, /* For comparing with previous entry */ + int iBreak /* Jump here if we hit the LIMIT */ +){ + Vdbe *v = pParse->pVdbe; + int iContinue; + int addr; + + addr = sqlite3VdbeCurrentAddr(v); + iContinue = sqlite3VdbeMakeLabel(v); + + /* Suppress duplicates for UNION, EXCEPT, and INTERSECT + */ + if( regPrev ){ + int j1, j2; + j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); VdbeCoverage(v); + j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst, + (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); + sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, j1); + sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1); + sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev); + } + if( pParse->db->mallocFailed ) return 0; + + /* Suppress the first OFFSET entries if there is an OFFSET clause + */ + codeOffset(v, p->iOffset, iContinue); + + switch( pDest->eDest ){ + /* Store the result as data using a unique key. + */ + case SRT_Table: + case SRT_EphemTab: { + int r1 = sqlite3GetTempReg(pParse); + int r2 = sqlite3GetTempReg(pParse); + testcase( pDest->eDest==SRT_Table ); + testcase( pDest->eDest==SRT_EphemTab ); + sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1); + sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iSDParm, r2); + sqlite3VdbeAddOp3(v, OP_Insert, pDest->iSDParm, r1, r2); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3ReleaseTempReg(pParse, r2); + sqlite3ReleaseTempReg(pParse, r1); + 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 r1; + assert( pIn->nSdst==1 || pParse->nErr>0 ); + pDest->affSdst = + sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst); + r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &pDest->affSdst,1); + sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, 1); + sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1); + sqlite3ReleaseTempReg(pParse, r1); + break; + } + +#if 0 /* Never occurs on an ORDER BY query */ + /* If any row exist in the result set, record that fact and abort. + */ + case SRT_Exists: { + sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iSDParm); + /* The LIMIT clause will terminate the loop for us */ + break; + } +#endif + + /* 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( pIn->nSdst==1 || pParse->nErr>0 ); testcase( pIn->nSdst!=1 ); + sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1); + /* The LIMIT clause will jump out of the loop for us */ + break; + } +#endif /* #ifndef SQLITE_OMIT_SUBQUERY */ + + /* The results are stored in a sequence of registers + ** starting at pDest->iSdst. Then the co-routine yields. + */ + case SRT_Coroutine: { + if( pDest->iSdst==0 ){ + pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst); + pDest->nSdst = pIn->nSdst; + } + sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pIn->nSdst); + sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); + break; + } + + /* If none of the above, then the result destination must be + ** SRT_Output. This routine is never called with any other + ** destination other than the ones handled above or SRT_Output. + ** + ** For SRT_Output, results are stored in a sequence of registers. + ** Then the OP_ResultRow opcode is used to cause sqlite3_step() to + ** return the next row of result. + */ + default: { + assert( pDest->eDest==SRT_Output ); + sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst); + sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst); + break; + } + } + + /* Jump to the end of the loop if the LIMIT is reached. + */ + if( p->iLimit ){ + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v); + } + + /* Generate the subroutine return + */ + sqlite3VdbeResolveLabel(v, iContinue); + sqlite3VdbeAddOp1(v, OP_Return, regReturn); + + return addr; +} + +/* +** Alternative compound select code generator for cases when there +** is an ORDER BY clause. +** +** We assume a query of the following form: +** +** ORDER BY +** +** is one of UNION ALL, UNION, EXCEPT, or INTERSECT. The idea +** is to code both and with the ORDER BY clause as +** co-routines. Then run the co-routines in parallel and merge the results +** into the output. In addition to the two coroutines (called selectA and +** selectB) there are 7 subroutines: +** +** outA: Move the output of the selectA coroutine into the output +** of the compound query. +** +** outB: Move the output of the selectB coroutine into the output +** of the compound query. (Only generated for UNION and +** UNION ALL. EXCEPT and INSERTSECT never output a row that +** appears only in B.) +** +** AltB: Called when there is data from both coroutines and AB. +** +** EofA: Called when data is exhausted from selectA. +** +** EofB: Called when data is exhausted from selectB. +** +** The implementation of the latter five subroutines depend on which +** is used: +** +** +** UNION ALL UNION EXCEPT INTERSECT +** ------------- ----------------- -------------- ----------------- +** AltB: outA, nextA outA, nextA outA, nextA nextA +** +** AeqB: outA, nextA nextA nextA outA, nextA +** +** AgtB: outB, nextB outB, nextB nextB nextB +** +** EofA: outB, nextB outB, nextB halt halt +** +** EofB: outA, nextA outA, nextA outA, nextA halt +** +** In the AltB, AeqB, and AgtB subroutines, an EOF on A following nextA +** causes an immediate jump to EofA and an EOF on B following nextB causes +** an immediate jump to EofB. Within EofA and EofB, and EOF on entry or +** following nextX causes a jump to the end of the select processing. +** +** Duplicate removal in the UNION, EXCEPT, and INTERSECT cases is handled +** within the output subroutine. The regPrev register set holds the previously +** output value. A comparison is made against this value and the output +** is skipped if the next results would be the same as the previous. +** +** The implementation plan is to implement the two coroutines and seven +** subroutines first, then put the control logic at the bottom. Like this: +** +** goto Init +** coA: coroutine for left query (A) +** coB: coroutine for right query (B) +** outA: output one row of A +** outB: output one row of B (UNION and UNION ALL only) +** EofA: ... +** EofB: ... +** AltB: ... +** AeqB: ... +** AgtB: ... +** Init: initialize coroutine registers +** yield coA +** if eof(A) goto EofA +** yield coB +** if eof(B) goto EofB +** Cmpr: Compare A, B +** Jump AltB, AeqB, AgtB +** End: ... +** +** We call AltB, AeqB, AgtB, EofA, and EofB "subroutines" but they are not +** actually called using Gosub and they do not Return. EofA and EofB loop +** until all data is exhausted then jump to the "end" labe. AltB, AeqB, +** and AgtB jump to either L2 or to one of EofA or EofB. +*/ +#ifndef SQLITE_OMIT_COMPOUND_SELECT +static int multiSelectOrderBy( + Parse *pParse, /* Parsing context */ + Select *p, /* The right-most of SELECTs to be coded */ + SelectDest *pDest /* What to do with query results */ +){ + int i, j; /* Loop counters */ + Select *pPrior; /* Another SELECT immediately to our left */ + Vdbe *v; /* Generate code to this VDBE */ + SelectDest destA; /* Destination for coroutine A */ + SelectDest destB; /* Destination for coroutine B */ + int regAddrA; /* Address register for select-A coroutine */ + int regAddrB; /* Address register for select-B coroutine */ + int addrSelectA; /* Address of the select-A coroutine */ + int addrSelectB; /* Address of the select-B coroutine */ + int regOutA; /* Address register for the output-A subroutine */ + int regOutB; /* Address register for the output-B subroutine */ + int addrOutA; /* Address of the output-A subroutine */ + int addrOutB = 0; /* Address of the output-B subroutine */ + int addrEofA; /* Address of the select-A-exhausted subroutine */ + int addrEofA_noB; /* Alternate addrEofA if B is uninitialized */ + int addrEofB; /* Address of the select-B-exhausted subroutine */ + int addrAltB; /* Address of the AB subroutine */ + int regLimitA; /* Limit register for select-A */ + int regLimitB; /* Limit register for select-A */ + int regPrev; /* A range of registers to hold previous output */ + int savedLimit; /* Saved value of p->iLimit */ + int savedOffset; /* Saved value of p->iOffset */ + int labelCmpr; /* Label for the start of the merge algorithm */ + int labelEnd; /* Label for the end of the overall SELECT stmt */ + int j1; /* Jump instructions that get retargetted */ + int op; /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */ + KeyInfo *pKeyDup = 0; /* Comparison information for duplicate removal */ + KeyInfo *pKeyMerge; /* Comparison information for merging rows */ + sqlite3 *db; /* Database connection */ + ExprList *pOrderBy; /* The ORDER BY clause */ + int nOrderBy; /* Number of terms in the ORDER BY clause */ + int *aPermute; /* Mapping from ORDER BY terms to result set columns */ +#ifndef SQLITE_OMIT_EXPLAIN + int iSub1; /* EQP id of left-hand query */ + int iSub2; /* EQP id of right-hand query */ +#endif + + assert( p->pOrderBy!=0 ); + assert( pKeyDup==0 ); /* "Managed" code needs this. Ticket #3382. */ + db = pParse->db; + v = pParse->pVdbe; + assert( v!=0 ); /* Already thrown the error if VDBE alloc failed */ + labelEnd = sqlite3VdbeMakeLabel(v); + labelCmpr = sqlite3VdbeMakeLabel(v); + + + /* Patch up the ORDER BY clause + */ + op = p->op; + pPrior = p->pPrior; + assert( pPrior->pOrderBy==0 ); + pOrderBy = p->pOrderBy; + assert( pOrderBy ); + nOrderBy = pOrderBy->nExpr; + + /* For operators other than UNION ALL we have to make sure that + ** the ORDER BY clause covers every term of the result set. Add + ** terms to the ORDER BY clause as necessary. + */ + if( op!=TK_ALL ){ + for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){ + struct ExprList_item *pItem; + for(j=0, pItem=pOrderBy->a; ju.x.iOrderByCol>0 ); + if( pItem->u.x.iOrderByCol==i ) break; + } + if( j==nOrderBy ){ + Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); + if( pNew==0 ) return SQLITE_NOMEM; + pNew->flags |= EP_IntValue; + pNew->u.iValue = i; + pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew); + if( pOrderBy ) pOrderBy->a[nOrderBy++].u.x.iOrderByCol = (u16)i; + } + } + } + + /* Compute the comparison permutation and keyinfo that is used with + ** the permutation used to determine if the next + ** row of results comes from selectA or selectB. Also add explicit + ** collations to the ORDER BY clause terms so that when the subqueries + ** to the right and the left are evaluated, they use the correct + ** collation. + */ + aPermute = sqlite3DbMallocRaw(db, sizeof(int)*nOrderBy); + if( aPermute ){ + struct ExprList_item *pItem; + for(i=0, pItem=pOrderBy->a; iu.x.iOrderByCol>0 ); + /* assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr ) is also true + ** but only for well-formed SELECT statements. */ + testcase( pItem->u.x.iOrderByCol > p->pEList->nExpr ); + aPermute[i] = pItem->u.x.iOrderByCol - 1; + } + pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1); + }else{ + pKeyMerge = 0; + } + + /* Reattach the ORDER BY clause to the query. + */ + p->pOrderBy = pOrderBy; + pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy, 0); + + /* Allocate a range of temporary registers and the KeyInfo needed + ** for the logic that removes duplicate result rows when the + ** operator is UNION, EXCEPT, or INTERSECT (but not UNION ALL). + */ + if( op==TK_ALL ){ + regPrev = 0; + }else{ + int nExpr = p->pEList->nExpr; + assert( nOrderBy>=nExpr || db->mallocFailed ); + regPrev = pParse->nMem+1; + pParse->nMem += nExpr+1; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev); + pKeyDup = sqlite3KeyInfoAlloc(db, nExpr, 1); + if( pKeyDup ){ + assert( sqlite3KeyInfoIsWriteable(pKeyDup) ); + for(i=0; iaColl[i] = multiSelectCollSeq(pParse, p, i); + pKeyDup->aSortOrder[i] = 0; + } + } + } + + /* Separate the left and the right query from one another + */ + p->pPrior = 0; + pPrior->pNext = 0; + sqlite3ResolveOrderGroupBy(pParse, p, p->pOrderBy, "ORDER"); + if( pPrior->pPrior==0 ){ + sqlite3ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER"); + } + + /* Compute the limit registers */ + computeLimitRegisters(pParse, p, labelEnd); + if( p->iLimit && op==TK_ALL ){ + regLimitA = ++pParse->nMem; + regLimitB = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Copy, p->iOffset ? p->iOffset+1 : p->iLimit, + regLimitA); + sqlite3VdbeAddOp2(v, OP_Copy, regLimitA, regLimitB); + }else{ + regLimitA = regLimitB = 0; + } + sqlite3ExprDelete(db, p->pLimit); + p->pLimit = 0; + sqlite3ExprDelete(db, p->pOffset); + p->pOffset = 0; + + regAddrA = ++pParse->nMem; + regAddrB = ++pParse->nMem; + regOutA = ++pParse->nMem; + regOutB = ++pParse->nMem; + sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA); + sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB); + + /* Generate a coroutine to evaluate the SELECT statement to the + ** left of the compound operator - the "A" select. + */ + addrSelectA = sqlite3VdbeCurrentAddr(v) + 1; + j1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA); + VdbeComment((v, "left SELECT")); + pPrior->iLimit = regLimitA; + explainSetInteger(iSub1, pParse->iNextSelectId); + sqlite3Select(pParse, pPrior, &destA); + sqlite3VdbeAddOp1(v, OP_EndCoroutine, regAddrA); + sqlite3VdbeJumpHere(v, j1); + + /* Generate a coroutine to evaluate the SELECT statement on + ** the right - the "B" select + */ + addrSelectB = sqlite3VdbeCurrentAddr(v) + 1; + j1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB); + VdbeComment((v, "right SELECT")); + savedLimit = p->iLimit; + savedOffset = p->iOffset; + p->iLimit = regLimitB; + p->iOffset = 0; + explainSetInteger(iSub2, pParse->iNextSelectId); + sqlite3Select(pParse, p, &destB); + p->iLimit = savedLimit; + p->iOffset = savedOffset; + sqlite3VdbeAddOp1(v, OP_EndCoroutine, regAddrB); + + /* Generate a subroutine that outputs the current row of the A + ** select as the next output row of the compound select. + */ + VdbeNoopComment((v, "Output routine for A")); + addrOutA = generateOutputSubroutine(pParse, + p, &destA, pDest, regOutA, + regPrev, pKeyDup, labelEnd); + + /* Generate a subroutine that outputs the current row of the B + ** select as the next output row of the compound select. + */ + if( op==TK_ALL || op==TK_UNION ){ + VdbeNoopComment((v, "Output routine for B")); + addrOutB = generateOutputSubroutine(pParse, + p, &destB, pDest, regOutB, + regPrev, pKeyDup, labelEnd); + } + sqlite3KeyInfoUnref(pKeyDup); + + /* Generate a subroutine to run when the results from select A + ** are exhausted and only data in select B remains. + */ + if( op==TK_EXCEPT || op==TK_INTERSECT ){ + addrEofA_noB = addrEofA = labelEnd; + }else{ + VdbeNoopComment((v, "eof-A subroutine")); + addrEofA = sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); + addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofA); + p->nSelectRow += pPrior->nSelectRow; + } + + /* Generate a subroutine to run when the results from select B + ** are exhausted and only data in select A remains. + */ + if( op==TK_INTERSECT ){ + addrEofB = addrEofA; + if( p->nSelectRow > pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow; + }else{ + VdbeNoopComment((v, "eof-B subroutine")); + addrEofB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, labelEnd); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofB); + } + + /* Generate code to handle the case of AB + */ + VdbeNoopComment((v, "A-gt-B subroutine")); + addrAgtB = sqlite3VdbeCurrentAddr(v); + if( op==TK_ALL || op==TK_UNION ){ + sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); + } + sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr); + + /* This code runs once to initialize everything. + */ + sqlite3VdbeJumpHere(v, j1); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v); + + /* Implement the main merge loop + */ + sqlite3VdbeResolveLabel(v, labelCmpr); + sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY); + sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy, + (char*)pKeyMerge, P4_KEYINFO); + sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE); + sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); VdbeCoverage(v); + + /* Jump to the this point in order to terminate the query. + */ + sqlite3VdbeResolveLabel(v, labelEnd); + + /* Set the number of output columns + */ + if( pDest->eDest==SRT_Output ){ + Select *pFirst = pPrior; + while( pFirst->pPrior ) pFirst = pFirst->pPrior; + generateColumnNames(pParse, 0, pFirst->pEList); + } + + /* Reassembly the compound query so that it will be freed correctly + ** by the calling function */ + if( p->pPrior ){ + sqlite3SelectDelete(db, p->pPrior); + } + p->pPrior = pPrior; + pPrior->pNext = p; + + /*** TBD: Insert subroutine calls to close cursors on incomplete + **** subqueries ****/ + explainComposite(pParse, p->op, iSub1, iSub2, 0); + return pParse->nErr!=0; +} +#endif + +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) +/* Forward Declarations */ +static void substExprList(sqlite3*, ExprList*, int, ExprList*); +static void substSelect(sqlite3*, Select *, int, ExprList *); + +/* +** Scan through the expression pExpr. Replace every reference to +** a column in table number iTable with a copy of the iColumn-th +** entry in pEList. (But leave references to the ROWID column +** unchanged.) +** +** This routine is part of the flattening procedure. A subquery +** whose result set is defined by pEList appears as entry in the +** FROM clause of a SELECT such that the VDBE cursor assigned to that +** FORM clause entry is iTable. This routine make the necessary +** changes to pExpr so that it refers directly to the source table +** of the subquery rather the result set of the subquery. +*/ +static Expr *substExpr( + sqlite3 *db, /* Report malloc errors to this connection */ + Expr *pExpr, /* Expr in which substitution occurs */ + int iTable, /* Table to be substituted */ + ExprList *pEList /* Substitute expressions */ +){ + if( pExpr==0 ) return 0; + if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){ + if( pExpr->iColumn<0 ){ + pExpr->op = TK_NULL; + }else{ + Expr *pNew; + assert( pEList!=0 && pExpr->iColumnnExpr ); + assert( pExpr->pLeft==0 && pExpr->pRight==0 ); + pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0); + sqlite3ExprDelete(db, pExpr); + pExpr = pNew; + } + }else{ + pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList); + pExpr->pRight = substExpr(db, pExpr->pRight, iTable, pEList); + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + substSelect(db, pExpr->x.pSelect, iTable, pEList); + }else{ + substExprList(db, pExpr->x.pList, iTable, pEList); + } + } + return pExpr; +} +static void substExprList( + sqlite3 *db, /* Report malloc errors here */ + ExprList *pList, /* List to scan and in which to make substitutes */ + int iTable, /* Table to be substituted */ + ExprList *pEList /* Substitute values */ +){ + int i; + if( pList==0 ) return; + for(i=0; inExpr; i++){ + pList->a[i].pExpr = substExpr(db, pList->a[i].pExpr, iTable, pEList); + } +} +static void substSelect( + sqlite3 *db, /* Report malloc errors here */ + Select *p, /* SELECT statement in which to make substitutions */ + int iTable, /* Table to be replaced */ + ExprList *pEList /* Substitute values */ +){ + SrcList *pSrc; + struct SrcList_item *pItem; + int i; + if( !p ) return; + substExprList(db, p->pEList, iTable, pEList); + substExprList(db, p->pGroupBy, iTable, pEList); + substExprList(db, p->pOrderBy, iTable, pEList); + p->pHaving = substExpr(db, p->pHaving, iTable, pEList); + p->pWhere = substExpr(db, p->pWhere, iTable, pEList); + substSelect(db, p->pPrior, iTable, pEList); + pSrc = p->pSrc; + assert( pSrc ); /* Even for (SELECT 1) we have: pSrc!=0 but pSrc->nSrc==0 */ + if( ALWAYS(pSrc) ){ + for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ + substSelect(db, pItem->pSelect, iTable, pEList); + } + } +} +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) +/* +** This routine attempts to flatten subqueries as a performance optimization. +** This routine returns 1 if it makes changes and 0 if no flattening occurs. +** +** To understand the concept of flattening, consider the following +** query: +** +** SELECT a FROM (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5 +** +** The default way of implementing this query is to execute the +** subquery first and store the results in a temporary table, then +** run the outer query on that temporary table. This requires two +** passes over the data. Furthermore, because the temporary table +** has no indices, the WHERE clause on the outer query cannot be +** optimized. +** +** This routine attempts to rewrite queries such as the above into +** a single flat select, like this: +** +** SELECT x+y AS a FROM t1 WHERE z<100 AND a>5 +** +** The code generated for this simplification gives the same result +** but only has to scan the data once. And because indices might +** exist on the table t1, a complete scan of the data might be +** avoided. +** +** Flattening is only attempted if all of the following are true: +** +** (1) The subquery and the outer query do not both use aggregates. +** +** (2) The subquery is not an aggregate or (2a) the outer query is not a join +** and (2b) the outer query does not use subqueries other than the one +** FROM-clause subquery that is a candidate for flattening. (2b is +** due to ticket [2f7170d73bf9abf80] from 2015-02-09.) +** +** (3) The subquery is not the right operand of a left outer join +** (Originally ticket #306. Strengthened by ticket #3300) +** +** (4) The subquery is not DISTINCT. +** +** (**) At one point restrictions (4) and (5) defined a subset of DISTINCT +** sub-queries that were excluded from this optimization. Restriction +** (4) has since been expanded to exclude all DISTINCT subqueries. +** +** (6) The subquery does not use aggregates or the outer query is not +** DISTINCT. +** +** (7) The subquery has a FROM clause. TODO: For subqueries without +** A FROM clause, consider adding a FROM close with the special +** table sqlite_once that consists of a single row containing a +** single NULL. +** +** (8) The subquery does not use LIMIT or the outer query is not a join. +** +** (9) The subquery does not use LIMIT or the outer query does not use +** aggregates. +** +** (**) Restriction (10) was removed from the code on 2005-02-05 but we +** accidently carried the comment forward until 2014-09-15. Original +** text: "The subquery does not use aggregates or the outer query does not +** use LIMIT." +** +** (11) The subquery and the outer query do not both have ORDER BY clauses. +** +** (**) Not implemented. Subsumed into restriction (3). Was previously +** a separate restriction deriving from ticket #350. +** +** (13) The subquery and outer query do not both use LIMIT. +** +** (14) The subquery does not use OFFSET. +** +** (15) The outer query is not part of a compound select or the +** subquery does not have a LIMIT clause. +** (See ticket #2339 and ticket [02a8e81d44]). +** +** (16) The outer query is not an aggregate or the subquery does +** not contain ORDER BY. (Ticket #2942) This used to not matter +** until we introduced the group_concat() function. +** +** (17) The sub-query is not a compound select, or it is a UNION ALL +** compound clause made up entirely of non-aggregate queries, and +** the parent query: +** +** * is not itself part of a compound select, +** * is not an aggregate or DISTINCT query, and +** * is not a join +** +** The parent and sub-query may contain WHERE clauses. Subject to +** rules (11), (13) and (14), they may also contain ORDER BY, +** LIMIT and OFFSET clauses. The subquery cannot use any compound +** operator other than UNION ALL because all the other compound +** operators have an implied DISTINCT which is disallowed by +** restriction (4). +** +** Also, each component of the sub-query must return the same number +** of result columns. This is actually a requirement for any compound +** SELECT statement, but all the code here does is make sure that no +** such (illegal) sub-query is flattened. The caller will detect the +** syntax error and return a detailed message. +** +** (18) If the sub-query is a compound select, then all terms of the +** ORDER by clause of the parent must be simple references to +** columns of the sub-query. +** +** (19) The subquery does not use LIMIT or the outer query does not +** have a WHERE clause. +** +** (20) If the sub-query is a compound select, then it must not use +** an ORDER BY clause. Ticket #3773. We could relax this constraint +** somewhat by saying that the terms of the ORDER BY clause must +** appear as unmodified result columns in the outer query. But we +** have other optimizations in mind to deal with that case. +** +** (21) The subquery does not use LIMIT or the outer query is not +** DISTINCT. (See ticket [752e1646fc]). +** +** (22) The subquery is not a recursive CTE. +** +** (23) The parent is not a recursive CTE, or the sub-query is not a +** compound query. This restriction is because transforming the +** parent to a compound query confuses the code that handles +** recursive queries in multiSelect(). +** +** (24) The subquery is not an aggregate that uses the built-in min() or +** or max() functions. (Without this restriction, a query like: +** "SELECT x FROM (SELECT max(y), x FROM t1)" would not necessarily +** return the value X for which Y was maximal.) +** +** +** In this routine, the "p" parameter is a pointer to the outer query. +** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query +** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates. +** +** If flattening is not attempted, this routine is a no-op and returns 0. +** If flattening is attempted this routine returns 1. +** +** All of the expression analysis must occur on both the outer query and +** the subquery before this routine runs. +*/ +static int flattenSubquery( + Parse *pParse, /* Parsing context */ + Select *p, /* The parent or outer SELECT statement */ + int iFrom, /* Index in p->pSrc->a[] of the inner subquery */ + int isAgg, /* True if outer SELECT uses aggregate functions */ + int subqueryIsAgg /* True if the subquery uses aggregate functions */ +){ + const char *zSavedAuthContext = pParse->zAuthContext; + Select *pParent; + Select *pSub; /* The inner query or "subquery" */ + Select *pSub1; /* Pointer to the rightmost select in sub-query */ + SrcList *pSrc; /* The FROM clause of the outer query */ + SrcList *pSubSrc; /* The FROM clause of the subquery */ + ExprList *pList; /* The result set of the outer query */ + int iParent; /* VDBE cursor number of the pSub result set temp table */ + int i; /* Loop counter */ + Expr *pWhere; /* The WHERE clause */ + struct SrcList_item *pSubitem; /* The subquery */ + sqlite3 *db = pParse->db; + + /* Check to see if flattening is permitted. Return 0 if not. + */ + assert( p!=0 ); + assert( p->pPrior==0 ); /* Unable to flatten compound queries */ + if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0; + pSrc = p->pSrc; + assert( pSrc && iFrom>=0 && iFromnSrc ); + pSubitem = &pSrc->a[iFrom]; + iParent = pSubitem->iCursor; + pSub = pSubitem->pSelect; + assert( pSub!=0 ); + if( subqueryIsAgg ){ + if( isAgg ) return 0; /* Restriction (1) */ + if( pSrc->nSrc>1 ) return 0; /* Restriction (2a) */ + if( (p->pWhere && ExprHasProperty(p->pWhere,EP_Subquery)) + || (sqlite3ExprListFlags(p->pEList) & EP_Subquery)!=0 + || (sqlite3ExprListFlags(p->pOrderBy) & EP_Subquery)!=0 + ){ + return 0; /* Restriction (2b) */ + } + } + + pSubSrc = pSub->pSrc; + assert( pSubSrc ); + /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants, + ** not arbitrary expressions, we allowed some combining of LIMIT and OFFSET + ** because they could be computed at compile-time. But when LIMIT and OFFSET + ** became arbitrary expressions, we were forced to add restrictions (13) + ** and (14). */ + if( pSub->pLimit && p->pLimit ) return 0; /* Restriction (13) */ + if( pSub->pOffset ) return 0; /* Restriction (14) */ + if( (p->selFlags & SF_Compound)!=0 && pSub->pLimit ){ + return 0; /* Restriction (15) */ + } + if( pSubSrc->nSrc==0 ) return 0; /* Restriction (7) */ + if( pSub->selFlags & SF_Distinct ) return 0; /* Restriction (5) */ + if( pSub->pLimit && (pSrc->nSrc>1 || isAgg) ){ + return 0; /* Restrictions (8)(9) */ + } + if( (p->selFlags & SF_Distinct)!=0 && subqueryIsAgg ){ + return 0; /* Restriction (6) */ + } + if( p->pOrderBy && pSub->pOrderBy ){ + return 0; /* Restriction (11) */ + } + if( isAgg && pSub->pOrderBy ) return 0; /* Restriction (16) */ + if( pSub->pLimit && p->pWhere ) return 0; /* Restriction (19) */ + if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){ + return 0; /* Restriction (21) */ + } + testcase( pSub->selFlags & SF_Recursive ); + testcase( pSub->selFlags & SF_MinMaxAgg ); + if( pSub->selFlags & (SF_Recursive|SF_MinMaxAgg) ){ + return 0; /* Restrictions (22) and (24) */ + } + if( (p->selFlags & SF_Recursive) && pSub->pPrior ){ + return 0; /* Restriction (23) */ + } + + /* OBSOLETE COMMENT 1: + ** 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) + ** + ** If we flatten the above, we would get + ** + ** (t1 LEFT OUTER JOIN t2) JOIN t3 + ** + ** which is not at all the same thing. + ** + ** OBSOLETE COMMENT 2: + ** Restriction 12: If the subquery is the right operand of a left outer + ** join, make sure the subquery has no WHERE clause. + ** An examples of why this is not allowed: + ** + ** t1 LEFT OUTER JOIN (SELECT * FROM t2 WHERE t2.x>0) + ** + ** If we flatten the above, we would get + ** + ** (t1 LEFT OUTER JOIN t2) WHERE t2.x>0 + ** + ** But the t2.x>0 test will always fail on a NULL row of t2, which + ** effectively converts the OUTER JOIN into an INNER JOIN. + ** + ** THIS OVERRIDES OBSOLETE COMMENTS 1 AND 2 ABOVE: + ** Ticket #3300 shows that flattening the right term of a LEFT JOIN + ** is fraught with danger. Best to avoid the whole thing. If the + ** subquery is the right term of a LEFT JOIN, then do not flatten. + */ + if( (pSubitem->jointype & JT_OUTER)!=0 ){ + return 0; + } + + /* Restriction 17: If the sub-query is a compound SELECT, then it must + ** use only the UNION ALL operator. And none of the simple select queries + ** that make up the compound SELECT are allowed to be aggregate or distinct + ** queries. + */ + if( pSub->pPrior ){ + if( pSub->pOrderBy ){ + return 0; /* Restriction 20 */ + } + if( isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){ + return 0; + } + for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){ + testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ); + testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); + assert( pSub->pSrc!=0 ); + if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 + || (pSub1->pPrior && pSub1->op!=TK_ALL) + || pSub1->pSrc->nSrc<1 + || pSub->pEList->nExpr!=pSub1->pEList->nExpr + ){ + return 0; + } + testcase( pSub1->pSrc->nSrc>1 ); + } + + /* Restriction 18. */ + if( p->pOrderBy ){ + int ii; + for(ii=0; iipOrderBy->nExpr; ii++){ + if( p->pOrderBy->a[ii].u.x.iOrderByCol==0 ) return 0; + } + } + } + + /***** If we reach this point, flattening is permitted. *****/ + SELECTTRACE(1,pParse,p,("flatten %s.%p from term %d\n", + pSub->zSelName, pSub, iFrom)); + + /* Authorize the subquery */ + pParse->zAuthContext = pSubitem->zName; + TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0); + testcase( i==SQLITE_DENY ); + pParse->zAuthContext = zSavedAuthContext; + + /* If the sub-query is a compound SELECT statement, then (by restrictions + ** 17 and 18 above) it must be a UNION ALL and the parent query must + ** be of the form: + ** + ** SELECT FROM () + ** + ** followed by any ORDER BY, LIMIT and/or OFFSET clauses. This block + ** creates N-1 copies of the parent query without any ORDER BY, LIMIT or + ** OFFSET clauses and joins them to the left-hand-side of the original + ** using UNION ALL operators. In this case N is the number of simple + ** select statements in the compound sub-query. + ** + ** Example: + ** + ** SELECT a+1 FROM ( + ** SELECT x FROM tab + ** UNION ALL + ** SELECT y FROM tab + ** UNION ALL + ** SELECT abs(z*2) FROM tab2 + ** ) WHERE a!=5 ORDER BY 1 + ** + ** Transformed into: + ** + ** SELECT x+1 FROM tab WHERE x+1!=5 + ** UNION ALL + ** SELECT y+1 FROM tab WHERE y+1!=5 + ** UNION ALL + ** SELECT abs(z*2)+1 FROM tab2 WHERE abs(z*2)+1!=5 + ** ORDER BY 1 + ** + ** We call this the "compound-subquery flattening". + */ + for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){ + Select *pNew; + ExprList *pOrderBy = p->pOrderBy; + Expr *pLimit = p->pLimit; + Expr *pOffset = p->pOffset; + Select *pPrior = p->pPrior; + p->pOrderBy = 0; + p->pSrc = 0; + p->pPrior = 0; + p->pLimit = 0; + p->pOffset = 0; + pNew = sqlite3SelectDup(db, p, 0); + sqlite3SelectSetName(pNew, pSub->zSelName); + p->pOffset = pOffset; + p->pLimit = pLimit; + p->pOrderBy = pOrderBy; + p->pSrc = pSrc; + p->op = TK_ALL; + if( pNew==0 ){ + p->pPrior = pPrior; + }else{ + pNew->pPrior = pPrior; + if( pPrior ) pPrior->pNext = pNew; + pNew->pNext = p; + p->pPrior = pNew; + SELECTTRACE(2,pParse,p, + ("compound-subquery flattener creates %s.%p as peer\n", + pNew->zSelName, pNew)); + } + if( db->mallocFailed ) return 1; + } + + /* Begin flattening the iFrom-th entry of the FROM clause + ** in the outer query. + */ + pSub = pSub1 = pSubitem->pSelect; + + /* Delete the transient table structure associated with the + ** subquery + */ + sqlite3DbFree(db, pSubitem->zDatabase); + sqlite3DbFree(db, pSubitem->zName); + sqlite3DbFree(db, pSubitem->zAlias); + pSubitem->zDatabase = 0; + pSubitem->zName = 0; + pSubitem->zAlias = 0; + pSubitem->pSelect = 0; + + /* Defer deleting the Table object associated with the + ** subquery until code generation is + ** complete, since there may still exist Expr.pTab entries that + ** refer to the subquery even after flattening. Ticket #3346. + ** + ** pSubitem->pTab is always non-NULL by test restrictions and tests above. + */ + if( ALWAYS(pSubitem->pTab!=0) ){ + Table *pTabToDel = pSubitem->pTab; + if( pTabToDel->nRef==1 ){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + pTabToDel->pNextZombie = pToplevel->pZombieTab; + pToplevel->pZombieTab = pTabToDel; + }else{ + pTabToDel->nRef--; + } + pSubitem->pTab = 0; + } + + /* The following loop runs once for each term in a compound-subquery + ** flattening (as described above). If we are doing a different kind + ** of flattening - a flattening other than a compound-subquery flattening - + ** then this loop only runs once. + ** + ** This loop moves all of the FROM elements of the subquery into the + ** the FROM clause of the outer query. Before doing this, remember + ** the cursor number for the original outer query FROM element in + ** iParent. The iParent cursor will never be used. Subsequent code + ** will scan expressions looking for iParent references and replace + ** those references with expressions that resolve to the subquery FROM + ** elements we are now copying in. + */ + for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){ + int nSubSrc; + u8 jointype = 0; + pSubSrc = pSub->pSrc; /* FROM clause of subquery */ + nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */ + pSrc = pParent->pSrc; /* FROM clause of the outer query */ + + if( pSrc ){ + assert( pParent==p ); /* First time through the loop */ + jointype = pSubitem->jointype; + }else{ + assert( pParent!=p ); /* 2nd and subsequent times through the loop */ + pSrc = pParent->pSrc = sqlite3SrcListAppend(db, 0, 0, 0); + if( pSrc==0 ){ + assert( db->mallocFailed ); + break; + } + } + + /* The subquery uses a single slot of the FROM clause of the outer + ** query. If the subquery has more than one element in its FROM clause, + ** then expand the outer query to make space for it to hold all elements + ** of the subquery. + ** + ** Example: + ** + ** SELECT * FROM tabA, (SELECT * FROM sub1, sub2), tabB; + ** + ** The outer query has 3 slots in its FROM clause. One slot of the + ** outer query (the middle slot) is used by the subquery. The next + ** block of code will expand the out query to 4 slots. The middle + ** slot is expanded to two slots in order to make space for the + ** two elements in the FROM clause of the subquery. + */ + if( nSubSrc>1 ){ + pParent->pSrc = pSrc = sqlite3SrcListEnlarge(db, pSrc, nSubSrc-1,iFrom+1); + if( db->mallocFailed ){ + break; + } + } + + /* Transfer the FROM clause terms from the subquery into the + ** outer query. + */ + for(i=0; ia[i+iFrom].pUsing); + pSrc->a[i+iFrom] = pSubSrc->a[i]; + memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); + } + pSrc->a[iFrom].jointype = jointype; + + /* Now begin substituting subquery result set expressions for + ** references to the iParent in the outer query. + ** + ** Example: + ** + ** SELECT a+5, b*10 FROM (SELECT x*3 AS a, y+10 AS b FROM t1) WHERE a>b; + ** \ \_____________ subquery __________/ / + ** \_____________________ outer query ______________________________/ + ** + ** We look at every expression in the outer query and every place we see + ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10". + */ + pList = pParent->pEList; + for(i=0; inExpr; i++){ + if( pList->a[i].zName==0 ){ + char *zName = sqlite3DbStrDup(db, pList->a[i].zSpan); + sqlite3Dequote(zName); + pList->a[i].zName = zName; + } + } + substExprList(db, pParent->pEList, iParent, pSub->pEList); + if( isAgg ){ + substExprList(db, pParent->pGroupBy, iParent, pSub->pEList); + pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList); + } + if( pSub->pOrderBy ){ + /* At this point, any non-zero iOrderByCol values indicate that the + ** ORDER BY column expression is identical to the iOrderByCol'th + ** expression returned by SELECT statement pSub. Since these values + ** do not necessarily correspond to columns in SELECT statement pParent, + ** zero them before transfering the ORDER BY clause. + ** + ** Not doing this may cause an error if a subsequent call to this + ** function attempts to flatten a compound sub-query into pParent + ** (the only way this can happen is if the compound sub-query is + ** currently part of pSub->pSrc). See ticket [d11a6e908f]. */ + ExprList *pOrderBy = pSub->pOrderBy; + for(i=0; inExpr; i++){ + pOrderBy->a[i].u.x.iOrderByCol = 0; + } + assert( pParent->pOrderBy==0 ); + assert( pSub->pPrior==0 ); + pParent->pOrderBy = pOrderBy; + pSub->pOrderBy = 0; + }else if( pParent->pOrderBy ){ + substExprList(db, pParent->pOrderBy, iParent, pSub->pEList); + } + if( pSub->pWhere ){ + pWhere = sqlite3ExprDup(db, pSub->pWhere, 0); + }else{ + pWhere = 0; + } + if( subqueryIsAgg ){ + assert( pParent->pHaving==0 ); + pParent->pHaving = pParent->pWhere; + pParent->pWhere = pWhere; + pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList); + pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving, + sqlite3ExprDup(db, pSub->pHaving, 0)); + assert( pParent->pGroupBy==0 ); + pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0); + }else{ + pParent->pWhere = substExpr(db, pParent->pWhere, iParent, pSub->pEList); + pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere); + } + + /* The flattened query is distinct if either the inner or the + ** outer query is distinct. + */ + pParent->selFlags |= pSub->selFlags & SF_Distinct; + + /* + ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y; + ** + ** One is tempted to try to add a and b to combine the limits. But this + ** does not work if either limit is negative. + */ + if( pSub->pLimit ){ + pParent->pLimit = pSub->pLimit; + pSub->pLimit = 0; + } + } + + /* Finially, delete what is left of the subquery and return + ** success. + */ + sqlite3SelectDelete(db, pSub1); + +#if SELECTTRACE_ENABLED + if( sqlite3SelectTrace & 0x100 ){ + sqlite3DebugPrintf("After flattening:\n"); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + + return 1; +} +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + +/* +** Based on the contents of the AggInfo structure indicated by the first +** argument, this function checks if the following are true: +** +** * the query contains just a single aggregate function, +** * the aggregate function is either min() or max(), and +** * the argument to the aggregate function is a column value. +** +** If all of the above are true, then WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX +** is returned as appropriate. Also, *ppMinMax is set to point to the +** list of arguments passed to the aggregate before returning. +** +** Or, if the conditions above are not met, *ppMinMax is set to 0 and +** WHERE_ORDERBY_NORMAL is returned. +*/ +static u8 minMaxQuery(AggInfo *pAggInfo, ExprList **ppMinMax){ + int eRet = WHERE_ORDERBY_NORMAL; /* Return value */ + + *ppMinMax = 0; + if( pAggInfo->nFunc==1 ){ + Expr *pExpr = pAggInfo->aFunc[0].pExpr; /* Aggregate function */ + ExprList *pEList = pExpr->x.pList; /* Arguments to agg function */ + + assert( pExpr->op==TK_AGG_FUNCTION ); + if( pEList && pEList->nExpr==1 && pEList->a[0].pExpr->op==TK_AGG_COLUMN ){ + const char *zFunc = pExpr->u.zToken; + if( sqlite3StrICmp(zFunc, "min")==0 ){ + eRet = WHERE_ORDERBY_MIN; + *ppMinMax = pEList; + }else if( sqlite3StrICmp(zFunc, "max")==0 ){ + eRet = WHERE_ORDERBY_MAX; + *ppMinMax = pEList; + } + } + } + + assert( *ppMinMax==0 || (*ppMinMax)->nExpr==1 ); + return eRet; +} + +/* +** The select statement passed as the first argument is an aggregate query. +** The second argument is the associated aggregate-info object. This +** function tests if the SELECT is of the form: +** +** SELECT count(*) FROM +** +** where table is a database table, not a sub-select or view. If the query +** does match this pattern, then a pointer to the Table object representing +** is returned. Otherwise, 0 is returned. +*/ +static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ + Table *pTab; + Expr *pExpr; + + assert( !p->pGroupBy ); + + if( p->pWhere || p->pEList->nExpr!=1 + || p->pSrc->nSrc!=1 || p->pSrc->a[0].pSelect + ){ + return 0; + } + pTab = p->pSrc->a[0].pTab; + pExpr = p->pEList->a[0].pExpr; + assert( pTab && !pTab->pSelect && pExpr ); + + if( IsVirtual(pTab) ) return 0; + if( pExpr->op!=TK_AGG_FUNCTION ) return 0; + if( NEVER(pAggInfo->nFunc==0) ) return 0; + if( (pAggInfo->aFunc[0].pFunc->funcFlags&SQLITE_FUNC_COUNT)==0 ) return 0; + if( pExpr->flags&EP_Distinct ) return 0; + + return pTab; +} + +/* +** If the source-list item passed as an argument was augmented with an +** INDEXED BY clause, then try to locate the specified index. If there +** was such a clause and the named index cannot be found, return +** SQLITE_ERROR and leave an error in pParse. Otherwise, populate +** pFrom->pIndex and return SQLITE_OK. +*/ +SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pFrom){ + if( pFrom->pTab && pFrom->zIndex ){ + Table *pTab = pFrom->pTab; + char *zIndex = pFrom->zIndex; + Index *pIdx; + for(pIdx=pTab->pIndex; + pIdx && sqlite3StrICmp(pIdx->zName, zIndex); + pIdx=pIdx->pNext + ); + if( !pIdx ){ + sqlite3ErrorMsg(pParse, "no such index: %s", zIndex, 0); + pParse->checkSchema = 1; + return SQLITE_ERROR; + } + pFrom->pIndex = pIdx; + } + return SQLITE_OK; +} +/* +** Detect compound SELECT statements that use an ORDER BY clause with +** an alternative collating sequence. +** +** SELECT ... FROM t1 EXCEPT SELECT ... FROM t2 ORDER BY .. COLLATE ... +** +** These are rewritten as a subquery: +** +** SELECT * FROM (SELECT ... FROM t1 EXCEPT SELECT ... FROM t2) +** ORDER BY ... COLLATE ... +** +** This transformation is necessary because the multiSelectOrderBy() routine +** above that generates the code for a compound SELECT with an ORDER BY clause +** uses a merge algorithm that requires the same collating sequence on the +** result columns as on the ORDER BY clause. See ticket +** http://www.sqlite.org/src/info/6709574d2a +** +** This transformation is only needed for EXCEPT, INTERSECT, and UNION. +** The UNION ALL operator works fine with multiSelectOrderBy() even when +** there are COLLATE terms in the ORDER BY. +*/ +static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ + int i; + Select *pNew; + Select *pX; + sqlite3 *db; + struct ExprList_item *a; + SrcList *pNewSrc; + Parse *pParse; + Token dummy; + + if( p->pPrior==0 ) return WRC_Continue; + if( p->pOrderBy==0 ) return WRC_Continue; + for(pX=p; pX && (pX->op==TK_ALL || pX->op==TK_SELECT); pX=pX->pPrior){} + if( pX==0 ) return WRC_Continue; + a = p->pOrderBy->a; + for(i=p->pOrderBy->nExpr-1; i>=0; i--){ + if( a[i].pExpr->flags & EP_Collate ) break; + } + if( i<0 ) return WRC_Continue; + + /* If we reach this point, that means the transformation is required. */ + + pParse = pWalker->pParse; + db = pParse->db; + pNew = sqlite3DbMallocZero(db, sizeof(*pNew) ); + if( pNew==0 ) return WRC_Abort; + memset(&dummy, 0, sizeof(dummy)); + pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0,0); + if( pNewSrc==0 ) return WRC_Abort; + *pNew = *p; + p->pSrc = pNewSrc; + p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ALL, 0)); + p->op = TK_SELECT; + p->pWhere = 0; + pNew->pGroupBy = 0; + pNew->pHaving = 0; + pNew->pOrderBy = 0; + p->pPrior = 0; + p->pNext = 0; + p->pWith = 0; + p->selFlags &= ~SF_Compound; + assert( (p->selFlags & SF_Converted)==0 ); + p->selFlags |= SF_Converted; + assert( pNew->pPrior!=0 ); + pNew->pPrior->pNext = pNew; + pNew->pLimit = 0; + pNew->pOffset = 0; + return WRC_Continue; +} + +#ifndef SQLITE_OMIT_CTE +/* +** Argument pWith (which may be NULL) points to a linked list of nested +** WITH contexts, from inner to outermost. If the table identified by +** FROM clause element pItem is really a common-table-expression (CTE) +** then return a pointer to the CTE definition for that table. Otherwise +** return NULL. +** +** If a non-NULL value is returned, set *ppContext to point to the With +** object that the returned CTE belongs to. +*/ +static struct Cte *searchWith( + With *pWith, /* Current outermost WITH clause */ + struct SrcList_item *pItem, /* FROM clause element to resolve */ + With **ppContext /* OUT: WITH clause return value belongs to */ +){ + const char *zName; + if( pItem->zDatabase==0 && (zName = pItem->zName)!=0 ){ + With *p; + for(p=pWith; p; p=p->pOuter){ + int i; + for(i=0; inCte; i++){ + if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){ + *ppContext = p; + return &p->a[i]; + } + } + } + } + return 0; +} + +/* The code generator maintains a stack of active WITH clauses +** with the inner-most WITH clause being at the top of the stack. +** +** This routine pushes the WITH clause passed as the second argument +** onto the top of the stack. If argument bFree is true, then this +** WITH clause will never be popped from the stack. In this case it +** should be freed along with the Parse object. In other cases, when +** bFree==0, the With object will be freed along with the SELECT +** statement with which it is associated. +*/ +SQLITE_PRIVATE void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ + assert( bFree==0 || pParse->pWith==0 ); + if( pWith ){ + pWith->pOuter = pParse->pWith; + pParse->pWith = pWith; + pParse->bFreeWith = bFree; + } +} + +/* +** This function checks if argument pFrom refers to a CTE declared by +** a WITH clause on the stack currently maintained by the parser. And, +** if currently processing a CTE expression, if it is a recursive +** reference to the current CTE. +** +** If pFrom falls into either of the two categories above, pFrom->pTab +** and other fields are populated accordingly. The caller should check +** (pFrom->pTab!=0) to determine whether or not a successful match +** was found. +** +** Whether or not a match is found, SQLITE_OK is returned if no error +** occurs. If an error does occur, an error message is stored in the +** parser and some error code other than SQLITE_OK returned. +*/ +static int withExpand( + Walker *pWalker, + struct SrcList_item *pFrom +){ + Parse *pParse = pWalker->pParse; + sqlite3 *db = pParse->db; + struct Cte *pCte; /* Matched CTE (or NULL if no match) */ + With *pWith; /* WITH clause that pCte belongs to */ + + assert( pFrom->pTab==0 ); + + pCte = searchWith(pParse->pWith, pFrom, &pWith); + if( pCte ){ + Table *pTab; + ExprList *pEList; + Select *pSel; + Select *pLeft; /* Left-most SELECT statement */ + int bMayRecursive; /* True if compound joined by UNION [ALL] */ + With *pSavedWith; /* Initial value of pParse->pWith */ + + /* If pCte->zErr is non-NULL at this point, then this is an illegal + ** recursive reference to CTE pCte. Leave an error in pParse and return + ** early. If pCte->zErr is NULL, then this is not a recursive reference. + ** In this case, proceed. */ + if( pCte->zErr ){ + sqlite3ErrorMsg(pParse, pCte->zErr, pCte->zName); + return SQLITE_ERROR; + } + + assert( pFrom->pTab==0 ); + pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); + if( pTab==0 ) return WRC_Abort; + pTab->nRef = 1; + pTab->zName = sqlite3DbStrDup(db, pCte->zName); + pTab->iPKey = -1; + pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); + pTab->tabFlags |= TF_Ephemeral; + pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0); + if( db->mallocFailed ) return SQLITE_NOMEM; + assert( pFrom->pSelect ); + + /* Check if this is a recursive CTE. */ + pSel = pFrom->pSelect; + bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION ); + if( bMayRecursive ){ + int i; + SrcList *pSrc = pFrom->pSelect->pSrc; + for(i=0; inSrc; i++){ + struct SrcList_item *pItem = &pSrc->a[i]; + if( pItem->zDatabase==0 + && pItem->zName!=0 + && 0==sqlite3StrICmp(pItem->zName, pCte->zName) + ){ + pItem->pTab = pTab; + pItem->isRecursive = 1; + pTab->nRef++; + pSel->selFlags |= SF_Recursive; + } + } + } + + /* Only one recursive reference is permitted. */ + if( pTab->nRef>2 ){ + sqlite3ErrorMsg( + pParse, "multiple references to recursive table: %s", pCte->zName + ); + return SQLITE_ERROR; + } + assert( pTab->nRef==1 || ((pSel->selFlags&SF_Recursive) && pTab->nRef==2 )); + + pCte->zErr = "circular reference: %s"; + pSavedWith = pParse->pWith; + pParse->pWith = pWith; + sqlite3WalkSelect(pWalker, bMayRecursive ? pSel->pPrior : pSel); + + for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior); + pEList = pLeft->pEList; + if( pCte->pCols ){ + if( pEList && pEList->nExpr!=pCte->pCols->nExpr ){ + sqlite3ErrorMsg(pParse, "table %s has %d values for %d columns", + pCte->zName, pEList->nExpr, pCte->pCols->nExpr + ); + pParse->pWith = pSavedWith; + return SQLITE_ERROR; + } + pEList = pCte->pCols; + } + + selectColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol); + if( bMayRecursive ){ + if( pSel->selFlags & SF_Recursive ){ + pCte->zErr = "multiple recursive references: %s"; + }else{ + pCte->zErr = "recursive reference in a subquery: %s"; + } + sqlite3WalkSelect(pWalker, pSel); + } + pCte->zErr = 0; + pParse->pWith = pSavedWith; + } + + return SQLITE_OK; +} +#endif + +#ifndef SQLITE_OMIT_CTE +/* +** If the SELECT passed as the second argument has an associated WITH +** clause, pop it from the stack stored as part of the Parse object. +** +** This function is used as the xSelectCallback2() callback by +** sqlite3SelectExpand() when walking a SELECT tree to resolve table +** names and other FROM clause elements. +*/ +static void selectPopWith(Walker *pWalker, Select *p){ + Parse *pParse = pWalker->pParse; + With *pWith = findRightmost(p)->pWith; + if( pWith!=0 ){ + assert( pParse->pWith==pWith ); + pParse->pWith = pWith->pOuter; + } +} +#else +#define selectPopWith 0 +#endif + +/* +** This routine is a Walker callback for "expanding" a SELECT statement. +** "Expanding" means to do the following: +** +** (1) Make sure VDBE cursor numbers have been assigned to every +** element of the FROM clause. +** +** (2) Fill in the pTabList->a[].pTab fields in the SrcList that +** defines FROM clause. When views appear in the FROM clause, +** fill pTabList->a[].pSelect with a copy of the SELECT statement +** that implements the view. A copy is made of the view's SELECT +** statement so that we can freely modify or delete that statement +** without worrying about messing up the persistent representation +** of the view. +** +** (3) Add terms to the WHERE clause to accommodate the NATURAL keyword +** on joins and the ON and USING clause of joins. +** +** (4) Scan the list of columns in the result set (pEList) looking +** for instances of the "*" operator or the TABLE.* operator. +** If found, expand each "*" to be every column in every table +** and TABLE.* to be every column in TABLE. +** +*/ +static int selectExpander(Walker *pWalker, Select *p){ + Parse *pParse = pWalker->pParse; + int i, j, k; + SrcList *pTabList; + ExprList *pEList; + struct SrcList_item *pFrom; + sqlite3 *db = pParse->db; + Expr *pE, *pRight, *pExpr; + u16 selFlags = p->selFlags; + + p->selFlags |= SF_Expanded; + if( db->mallocFailed ){ + return WRC_Abort; + } + if( NEVER(p->pSrc==0) || (selFlags & SF_Expanded)!=0 ){ + return WRC_Prune; + } + pTabList = p->pSrc; + pEList = p->pEList; + if( pWalker->xSelectCallback2==selectPopWith ){ + sqlite3WithPush(pParse, findRightmost(p)->pWith, 0); + } + + /* Make sure cursor numbers have been assigned to all entries in + ** the FROM clause of the SELECT statement. + */ + sqlite3SrcListAssignCursors(pParse, pTabList); + + /* Look up every table named in the FROM clause of the select. If + ** an entry of the FROM clause is a subquery instead of a table or view, + ** then create a transient table structure to describe the subquery. + */ + for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ + Table *pTab; + assert( pFrom->isRecursive==0 || pFrom->pTab ); + if( pFrom->isRecursive ) continue; + if( pFrom->pTab!=0 ){ + /* This statement has already been prepared. There is no need + ** to go further. */ + assert( i==0 ); +#ifndef SQLITE_OMIT_CTE + selectPopWith(pWalker, p); +#endif + return WRC_Prune; + } +#ifndef SQLITE_OMIT_CTE + if( withExpand(pWalker, pFrom) ) return WRC_Abort; + if( pFrom->pTab ) {} else +#endif + if( pFrom->zName==0 ){ +#ifndef SQLITE_OMIT_SUBQUERY + Select *pSel = pFrom->pSelect; + /* A sub-query in the FROM clause of a SELECT */ + assert( pSel!=0 ); + assert( pFrom->pTab==0 ); + if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort; + pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); + if( pTab==0 ) return WRC_Abort; + pTab->nRef = 1; + pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab); + while( pSel->pPrior ){ pSel = pSel->pPrior; } + selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol); + pTab->iPKey = -1; + pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); + pTab->tabFlags |= TF_Ephemeral; +#endif + }else{ + /* An ordinary table or view name in the FROM clause */ + assert( pFrom->pTab==0 ); + pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom); + if( pTab==0 ) return WRC_Abort; + if( pTab->nRef==0xffff ){ + sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535", + pTab->zName); + pFrom->pTab = 0; + return WRC_Abort; + } + pTab->nRef++; +#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE) + if( pTab->pSelect || IsVirtual(pTab) ){ + /* We reach here if the named table is a really a view */ + if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; + assert( pFrom->pSelect==0 ); + pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0); + sqlite3SelectSetName(pFrom->pSelect, pTab->zName); + sqlite3WalkSelect(pWalker, pFrom->pSelect); + } +#endif + } + + /* Locate the index named by the INDEXED BY clause, if any. */ + if( sqlite3IndexedByLookup(pParse, pFrom) ){ + return WRC_Abort; + } + } + + /* Process NATURAL keywords, and ON and USING clauses of joins. + */ + if( db->mallocFailed || sqliteProcessJoin(pParse, p) ){ + return WRC_Abort; + } + + /* For every "*" that occurs in the column list, insert the names of + ** all columns in all tables. And for every TABLE.* insert the names + ** of all columns in TABLE. The parser inserted a special expression + ** with the TK_ALL operator for each "*" that it found in the column list. + ** The following code just has to locate the TK_ALL expressions and expand + ** each one to the list of all columns in all tables. + ** + ** The first loop just checks to see if there are any "*" operators + ** that need expanding. + */ + for(k=0; knExpr; k++){ + pE = pEList->a[k].pExpr; + if( pE->op==TK_ALL ) break; + assert( pE->op!=TK_DOT || pE->pRight!=0 ); + assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) ); + if( pE->op==TK_DOT && pE->pRight->op==TK_ALL ) break; + } + if( knExpr ){ + /* + ** 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; + + /* When processing FROM-clause subqueries, it is always the case + ** that full_column_names=OFF and short_column_names=ON. The + ** sqlite3ResultSetOfSelect() routine makes it so. */ + assert( (p->selFlags & SF_NestedFrom)==0 + || ((flags & SQLITE_FullColNames)==0 && + (flags & SQLITE_ShortColNames)!=0) ); + + for(k=0; knExpr; k++){ + pE = a[k].pExpr; + pRight = pE->pRight; + assert( pE->op!=TK_DOT || pRight!=0 ); + if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pRight->op!=TK_ALL) ){ + /* This particular expression does not need to be expanded. + */ + pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr); + if( pNew ){ + pNew->a[pNew->nExpr-1].zName = a[k].zName; + pNew->a[pNew->nExpr-1].zSpan = a[k].zSpan; + a[k].zName = 0; + a[k].zSpan = 0; + } + a[k].pExpr = 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 = 0; /* text of name of TABLE */ + if( pE->op==TK_DOT ){ + assert( pE->pLeft!=0 ); + assert( !ExprHasProperty(pE->pLeft, EP_IntValue) ); + zTName = pE->pLeft->u.zToken; + } + for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ + Table *pTab = pFrom->pTab; + Select *pSub = pFrom->pSelect; + char *zTabName = pFrom->zAlias; + const char *zSchemaName = 0; + int iDb; + if( zTabName==0 ){ + zTabName = pTab->zName; + } + if( db->mallocFailed ) break; + if( pSub==0 || (pSub->selFlags & SF_NestedFrom)==0 ){ + pSub = 0; + if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){ + continue; + } + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + zSchemaName = iDb>=0 ? db->aDb[iDb].zName : "*"; + } + for(j=0; jnCol; j++){ + char *zName = pTab->aCol[j].zName; + char *zColname; /* The computed column name */ + char *zToFree; /* Malloced string that needs to be freed */ + Token sColname; /* Computed column name as a token */ + + assert( zName ); + if( zTName && pSub + && sqlite3MatchSpanName(pSub->pEList->a[j].zSpan, 0, zTName, 0)==0 + ){ + continue; + } + + /* If a column is marked as 'hidden' (currently only possible + ** for virtual tables), do not include it in the expanded + ** result-set list. + */ + if( IsHiddenColumn(&pTab->aCol[j]) ){ + assert(IsVirtual(pTab)); + continue; + } + tableSeen = 1; + + if( i>0 && zTName==0 ){ + if( (pFrom->jointype & JT_NATURAL)!=0 + && tableAndColumnIndex(pTabList, i, zName, 0, 0) + ){ + /* In a NATURAL join, omit the join columns from the + ** table to the right of the join */ + continue; + } + if( sqlite3IdListIndex(pFrom->pUsing, zName)>=0 ){ + /* In a join with a USING clause, omit columns in the + ** using clause from the table on the right. */ + continue; + } + } + pRight = sqlite3Expr(db, TK_ID, zName); + zColname = zName; + zToFree = 0; + if( longNames || pTabList->nSrc>1 ){ + Expr *pLeft; + pLeft = sqlite3Expr(db, TK_ID, zTabName); + pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0); + if( zSchemaName ){ + pLeft = sqlite3Expr(db, TK_ID, zSchemaName); + pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr, 0); + } + if( longNames ){ + zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName); + zToFree = zColname; + } + }else{ + pExpr = pRight; + } + pNew = sqlite3ExprListAppend(pParse, pNew, pExpr); + sColname.z = zColname; + sColname.n = sqlite3Strlen30(zColname); + sqlite3ExprListSetName(pParse, pNew, &sColname, 0); + if( pNew && (p->selFlags & SF_NestedFrom)!=0 ){ + struct ExprList_item *pX = &pNew->a[pNew->nExpr-1]; + if( pSub ){ + pX->zSpan = sqlite3DbStrDup(db, pSub->pEList->a[j].zSpan); + testcase( pX->zSpan==0 ); + }else{ + pX->zSpan = sqlite3MPrintf(db, "%s.%s.%s", + zSchemaName, zTabName, zColname); + testcase( pX->zSpan==0 ); + } + pX->bSpanIsTab = 1; + } + sqlite3DbFree(db, zToFree); + } + } + if( !tableSeen ){ + if( zTName ){ + sqlite3ErrorMsg(pParse, "no such table: %s", zTName); + }else{ + sqlite3ErrorMsg(pParse, "no tables specified"); + } + } + } + } + sqlite3ExprListDelete(db, pEList); + p->pEList = pNew; + } +#if SQLITE_MAX_COLUMN + if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ + sqlite3ErrorMsg(pParse, "too many columns in result set"); + } +#endif + return WRC_Continue; +} + +/* +** No-op routine for the parse-tree walker. +** +** When this routine is the Walker.xExprCallback then expression trees +** are walked without any actions being taken at each node. Presumably, +** when this routine is used for Walker.xExprCallback then +** Walker.xSelectCallback is set to do something useful for every +** subquery in the parser tree. +*/ +static int exprWalkNoop(Walker *NotUsed, Expr *NotUsed2){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + return WRC_Continue; +} + +/* +** This routine "expands" a SELECT statement and all of its subqueries. +** For additional information on what it means to "expand" a SELECT +** statement, see the comment on the selectExpand worker callback above. +** +** Expanding a SELECT statement is the first step in processing a +** SELECT statement. The SELECT statement must be expanded before +** name resolution is performed. +** +** If anything goes wrong, an error message is written into pParse. +** The calling function can detect the problem by looking at pParse->nErr +** and/or pParse->db->mallocFailed. +*/ +static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){ + Walker w; + memset(&w, 0, sizeof(w)); + w.xExprCallback = exprWalkNoop; + w.pParse = pParse; + if( pParse->hasCompound ){ + w.xSelectCallback = convertCompoundSelectToSubquery; + sqlite3WalkSelect(&w, pSelect); + } + w.xSelectCallback = selectExpander; + if( (pSelect->selFlags & SF_MultiValue)==0 ){ + w.xSelectCallback2 = selectPopWith; + } + sqlite3WalkSelect(&w, pSelect); +} + + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** This is a Walker.xSelectCallback callback for the sqlite3SelectTypeInfo() +** interface. +** +** For each FROM-clause subquery, add Column.zType and Column.zColl +** information to the Table structure that represents the result set +** of that subquery. +** +** The Table structure that represents the result set was constructed +** by selectExpander() but the type and collation information was omitted +** at that point because identifiers had not yet been resolved. This +** routine is called after identifier resolution. +*/ +static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ + Parse *pParse; + int i; + SrcList *pTabList; + struct SrcList_item *pFrom; + + assert( p->selFlags & SF_Resolved ); + if( (p->selFlags & SF_HasTypeInfo)==0 ){ + p->selFlags |= SF_HasTypeInfo; + pParse = pWalker->pParse; + pTabList = p->pSrc; + for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ + Table *pTab = pFrom->pTab; + if( ALWAYS(pTab!=0) && (pTab->tabFlags & TF_Ephemeral)!=0 ){ + /* A sub-query in the FROM clause of a SELECT */ + Select *pSel = pFrom->pSelect; + if( pSel ){ + while( pSel->pPrior ) pSel = pSel->pPrior; + selectAddColumnTypeAndCollation(pParse, pTab, pSel); + } + } + } + } +} +#endif + + +/* +** This routine adds datatype and collating sequence information to +** the Table structures of all FROM-clause subqueries in a +** SELECT statement. +** +** Use this routine after name resolution. +*/ +static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){ +#ifndef SQLITE_OMIT_SUBQUERY + Walker w; + memset(&w, 0, sizeof(w)); + w.xSelectCallback2 = selectAddSubqueryTypeInfo; + w.xExprCallback = exprWalkNoop; + w.pParse = pParse; + sqlite3WalkSelect(&w, pSelect); +#endif +} + + +/* +** This routine sets up a SELECT statement for processing. The +** following is accomplished: +** +** * VDBE Cursor numbers are assigned to all FROM-clause terms. +** * Ephemeral Table objects are created for all FROM-clause subqueries. +** * ON and USING clauses are shifted into WHERE statements +** * Wildcards "*" and "TABLE.*" in result sets are expanded. +** * Identifiers in expression are matched to tables. +** +** This routine acts recursively on all subqueries within the SELECT. +*/ +SQLITE_PRIVATE void sqlite3SelectPrep( + Parse *pParse, /* The parser context */ + Select *p, /* The SELECT statement being coded. */ + NameContext *pOuterNC /* Name context for container */ +){ + sqlite3 *db; + if( NEVER(p==0) ) return; + db = pParse->db; + if( db->mallocFailed ) return; + if( p->selFlags & SF_HasTypeInfo ) return; + sqlite3SelectExpand(pParse, p); + if( pParse->nErr || db->mallocFailed ) return; + sqlite3ResolveSelectNames(pParse, p, pOuterNC); + if( pParse->nErr || db->mallocFailed ) return; + sqlite3SelectAddTypeInfo(pParse, p); +} + +/* +** Reset the aggregate accumulator. +** +** The aggregate accumulator is a set of memory cells that hold +** intermediate results while calculating an aggregate. This +** routine generates code that 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; + int nReg = pAggInfo->nFunc + pAggInfo->nColumn; + if( nReg==0 ) return; +#ifdef SQLITE_DEBUG + /* Verify that all AggInfo registers are within the range specified by + ** AggInfo.mnReg..AggInfo.mxReg */ + assert( nReg==pAggInfo->mxReg-pAggInfo->mnReg+1 ); + for(i=0; inColumn; i++){ + assert( pAggInfo->aCol[i].iMem>=pAggInfo->mnReg + && pAggInfo->aCol[i].iMem<=pAggInfo->mxReg ); + } + for(i=0; inFunc; i++){ + assert( pAggInfo->aFunc[i].iMem>=pAggInfo->mnReg + && pAggInfo->aFunc[i].iMem<=pAggInfo->mxReg ); + } +#endif + sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->mnReg, pAggInfo->mxReg); + for(pFunc=pAggInfo->aFunc, i=0; inFunc; i++, pFunc++){ + if( pFunc->iDistinct>=0 ){ + Expr *pE = pFunc->pExpr; + assert( !ExprHasProperty(pE, EP_xIsSelect) ); + if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){ + sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one " + "argument"); + pFunc->iDistinct = -1; + }else{ + KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList, 0, 0); + sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0, + (char*)pKeyInfo, P4_KEYINFO); + } + } + } +} + +/* +** 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; inFunc; i++, pF++){ + ExprList *pList = pF->pExpr->x.pList; + assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) ); + sqlite3VdbeAddOp4(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0, 0, + (void*)pF->pFunc, P4_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; + int regHit = 0; + int addrHitTest = 0; + struct AggInfo_func *pF; + struct AggInfo_col *pC; + + pAggInfo->directMode = 1; + for(i=0, pF=pAggInfo->aFunc; inFunc; i++, pF++){ + int nArg; + int addrNext = 0; + int regAgg; + ExprList *pList = pF->pExpr->x.pList; + assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) ); + if( pList ){ + nArg = pList->nExpr; + regAgg = sqlite3GetTempRange(pParse, nArg); + sqlite3ExprCodeExprList(pParse, pList, regAgg, SQLITE_ECEL_DUP); + }else{ + nArg = 0; + regAgg = 0; + } + if( pF->iDistinct>=0 ){ + addrNext = sqlite3VdbeMakeLabel(v); + testcase( nArg==0 ); /* Error condition */ + testcase( nArg>1 ); /* Also an error */ + codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg); + } + if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ + CollSeq *pColl = 0; + struct ExprList_item *pItem; + int j; + assert( pList!=0 ); /* pList!=0 if pF->pFunc has NEEDCOLL */ + for(j=0, pItem=pList->a; !pColl && jpExpr); + } + if( !pColl ){ + pColl = pParse->db->pDfltColl; + } + if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; + sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ); + } + sqlite3VdbeAddOp4(v, OP_AggStep, 0, regAgg, pF->iMem, + (void*)pF->pFunc, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg); + sqlite3ReleaseTempRange(pParse, regAgg, nArg); + if( addrNext ){ + sqlite3VdbeResolveLabel(v, addrNext); + sqlite3ExprCacheClear(pParse); + } + } + + /* Before populating the accumulator registers, clear the column cache. + ** Otherwise, if any of the required column values are already present + ** in registers, sqlite3ExprCode() may use OP_SCopy to copy the value + ** to pC->iMem. But by the time the value is used, the original register + ** may have been used, invalidating the underlying buffer holding the + ** text or blob value. See ticket [883034dcb5]. + ** + ** Another solution would be to change the OP_SCopy used to copy cached + ** values to an OP_Copy. + */ + if( regHit ){ + addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v); + } + sqlite3ExprCacheClear(pParse); + for(i=0, pC=pAggInfo->aCol; inAccumulator; i++, pC++){ + sqlite3ExprCode(pParse, pC->pExpr, pC->iMem); + } + pAggInfo->directMode = 0; + sqlite3ExprCacheClear(pParse); + if( addrHitTest ){ + sqlite3VdbeJumpHere(v, addrHitTest); + } +} + +/* +** Add a single OP_Explain instruction to the VDBE to explain a simple +** count(*) query ("SELECT count(*) FROM pTab"). +*/ +#ifndef SQLITE_OMIT_EXPLAIN +static void explainSimpleCount( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being queried */ + Index *pIdx /* Index used to optimize scan, or NULL */ +){ + if( pParse->explain==2 ){ + int bCover = (pIdx!=0 && (HasRowid(pTab) || !IsPrimaryKeyIndex(pIdx))); + char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s%s%s", + pTab->zName, + bCover ? " USING COVERING INDEX " : "", + bCover ? pIdx->zName : "" + ); + sqlite3VdbeAddOp4( + pParse->pVdbe, OP_Explain, pParse->iSelectId, 0, 0, zEqp, P4_DYNAMIC + ); + } +} +#else +# define explainSimpleCount(a,b,c) +#endif + +/* +** Generate code for the SELECT statement given in the p argument. +** +** The results are returned according to the SelectDest structure. +** See comments in sqliteInt.h for further information. +** +** This routine returns the number of errors. If any errors are +** encountered, then an appropriate error message is left in +** pParse->zErrMsg. +** +** This routine does NOT free the Select structure passed in. The +** calling function needs to do that. +*/ +SQLITE_PRIVATE int sqlite3Select( + Parse *pParse, /* The parser context */ + Select *p, /* The SELECT statement being coded. */ + SelectDest *pDest /* What to do with the query results */ +){ + 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 *pGroupBy; /* The GROUP BY clause. May be NULL */ + Expr *pHaving; /* The HAVING clause. May be NULL */ + int rc = 1; /* Value to return from this function */ + DistinctCtx sDistinct; /* Info on how to code the DISTINCT keyword */ + SortCtx sSort; /* Info on how to code the ORDER BY clause */ + AggInfo sAggInfo; /* Information used by aggregate queries */ + int iEnd; /* Address of the end of the query */ + sqlite3 *db; /* The database connection */ + +#ifndef SQLITE_OMIT_EXPLAIN + int iRestoreSelectId = pParse->iSelectId; + pParse->iSelectId = pParse->iNextSelectId++; +#endif + + db = pParse->db; + if( p==0 || db->mallocFailed || pParse->nErr ){ + return 1; + } + if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; + memset(&sAggInfo, 0, sizeof(sAggInfo)); +#if SELECTTRACE_ENABLED + pParse->nSelectIndent++; + SELECTTRACE(1,pParse,p, ("begin processing:\n")); + if( sqlite3SelectTrace & 0x100 ){ + sqlite3TreeViewSelect(0, p, 0); + } +#endif + + assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo ); + assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo ); + assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue ); + assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue ); + if( IgnorableOrderby(pDest) ){ + assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || + pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard || + pDest->eDest==SRT_Queue || pDest->eDest==SRT_DistFifo || + pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_Fifo); + /* If ORDER BY makes no difference in the output then neither does + ** DISTINCT so it can be removed too. */ + sqlite3ExprListDelete(db, p->pOrderBy); + p->pOrderBy = 0; + p->selFlags &= ~SF_Distinct; + } + sqlite3SelectPrep(pParse, p, 0); + memset(&sSort, 0, sizeof(sSort)); + sSort.pOrderBy = p->pOrderBy; + pTabList = p->pSrc; + pEList = p->pEList; + if( pParse->nErr || db->mallocFailed ){ + goto select_end; + } + isAgg = (p->selFlags & SF_Aggregate)!=0; + assert( pEList!=0 ); +#if SELECTTRACE_ENABLED + if( sqlite3SelectTrace & 0x100 ){ + SELECTTRACE(0x100,pParse,p, ("after name resolution:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + + + /* Begin generating code. + */ + v = sqlite3GetVdbe(pParse); + if( v==0 ) goto select_end; + + /* If writing to memory or generating a set + ** only a single column may be output. + */ +#ifndef SQLITE_OMIT_SUBQUERY + if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){ + goto select_end; + } +#endif + + /* Generate code for all sub-queries in the FROM clause + */ +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) + for(i=0; !p->pPrior && inSrc; i++){ + struct SrcList_item *pItem = &pTabList->a[i]; + SelectDest dest; + Select *pSub = pItem->pSelect; + int isAggSub; + + if( pSub==0 ) continue; + + /* Sometimes the code for a subquery will be generated more than + ** once, if the subquery is part of the WHERE clause in a LEFT JOIN, + ** for example. In that case, do not regenerate the code to manifest + ** a view or the co-routine to implement a view. The first instance + ** is sufficient, though the subroutine to manifest the view does need + ** to be invoked again. */ + if( pItem->addrFillSub ){ + if( pItem->viaCoroutine==0 ){ + sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub); + } + continue; + } + + /* Increment Parse.nHeight by the height of the largest expression + ** tree referred to by this, the parent select. The child select + ** may contain expression trees of at most + ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit + ** more conservative than necessary, but much easier than enforcing + ** an exact limit. + */ + pParse->nHeight += sqlite3SelectExprHeight(p); + + isAggSub = (pSub->selFlags & SF_Aggregate)!=0; + if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){ + /* This subquery can be absorbed into its parent. */ + if( isAggSub ){ + isAgg = 1; + p->selFlags |= SF_Aggregate; + } + i = -1; + }else if( pTabList->nSrc==1 + && OptimizationEnabled(db, SQLITE_SubqCoroutine) + ){ + /* Implement a co-routine that will return a single row of the result + ** set on each invocation. + */ + int addrTop = sqlite3VdbeCurrentAddr(v)+1; + pItem->regReturn = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop); + VdbeComment((v, "%s", pItem->pTab->zName)); + pItem->addrFillSub = addrTop; + sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); + explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); + sqlite3Select(pParse, pSub, &dest); + pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow); + pItem->viaCoroutine = 1; + pItem->regResult = dest.iSdst; + sqlite3VdbeAddOp1(v, OP_EndCoroutine, pItem->regReturn); + sqlite3VdbeJumpHere(v, addrTop-1); + sqlite3ClearTempRegCache(pParse); + }else{ + /* Generate a subroutine that will fill an ephemeral table with + ** the content of this subquery. pItem->addrFillSub will point + ** to the address of the generated subroutine. pItem->regReturn + ** is a register allocated to hold the subroutine return address + */ + int topAddr; + int onceAddr = 0; + int retAddr; + assert( pItem->addrFillSub==0 ); + pItem->regReturn = ++pParse->nMem; + topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn); + pItem->addrFillSub = topAddr+1; + if( pItem->isCorrelated==0 ){ + /* If the subquery is not correlated and if we are not inside of + ** a trigger, then we only need to compute the value of the subquery + ** once. */ + onceAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v); + VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName)); + }else{ + VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName)); + } + sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); + explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); + sqlite3Select(pParse, pSub, &dest); + pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow); + if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); + retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn); + VdbeComment((v, "end %s", pItem->pTab->zName)); + sqlite3VdbeChangeP1(v, topAddr, retAddr); + sqlite3ClearTempRegCache(pParse); + } + if( /*pParse->nErr ||*/ db->mallocFailed ){ + goto select_end; + } + pParse->nHeight -= sqlite3SelectExprHeight(p); + pTabList = p->pSrc; + if( !IgnorableOrderby(pDest) ){ + sSort.pOrderBy = p->pOrderBy; + } + } + pEList = p->pEList; +#endif + pWhere = p->pWhere; + pGroupBy = p->pGroupBy; + pHaving = p->pHaving; + sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0; + +#ifndef SQLITE_OMIT_COMPOUND_SELECT + /* If there is are a sequence of queries, do the earlier ones first. + */ + if( p->pPrior ){ + rc = multiSelect(pParse, p, pDest); + explainSetInteger(pParse->iSelectId, iRestoreSelectId); +#if SELECTTRACE_ENABLED + SELECTTRACE(1,pParse,p,("end compound-select processing\n")); + pParse->nSelectIndent--; +#endif + return rc; + } +#endif + + /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and + ** if the select-list is the same as the ORDER BY list, then this query + ** can be rewritten as a GROUP BY. In other words, this: + ** + ** SELECT DISTINCT xyz FROM ... ORDER BY xyz + ** + ** is transformed to: + ** + ** SELECT xyz FROM ... GROUP BY xyz ORDER BY xyz + ** + ** The second form is preferred as a single index (or temp-table) may be + ** used for both the ORDER BY and DISTINCT processing. As originally + ** written the query must use a temp-table for at least one of the ORDER + ** BY and DISTINCT, and an index or separate temp-table for the other. + */ + if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct + && sqlite3ExprListCompare(sSort.pOrderBy, p->pEList, -1)==0 + ){ + p->selFlags &= ~SF_Distinct; + p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0); + pGroupBy = p->pGroupBy; + /* Notice that even thought SF_Distinct has been cleared from p->selFlags, + ** the sDistinct.isTnct is still set. Hence, isTnct represents the + ** original setting of the SF_Distinct flag, not the current setting */ + assert( sDistinct.isTnct ); + } + + /* If there is an ORDER BY clause, then 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_OpenEphemeral 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( sSort.pOrderBy ){ + KeyInfo *pKeyInfo; + pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, pEList->nExpr); + sSort.iECursor = pParse->nTab++; + sSort.addrSortIndex = + sqlite3VdbeAddOp4(v, OP_OpenEphemeral, + sSort.iECursor, sSort.pOrderBy->nExpr+1+pEList->nExpr, 0, + (char*)pKeyInfo, P4_KEYINFO + ); + }else{ + sSort.addrSortIndex = -1; + } + + /* If the output is destined for a temporary table, open that table. + */ + if( pDest->eDest==SRT_EphemTab ){ + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr); + } + + /* Set the limiter. + */ + iEnd = sqlite3VdbeMakeLabel(v); + p->nSelectRow = LARGEST_INT64; + computeLimitRegisters(pParse, p, iEnd); + if( p->iLimit==0 && sSort.addrSortIndex>=0 ){ + sqlite3VdbeGetOp(v, sSort.addrSortIndex)->opcode = OP_SorterOpen; + sSort.sortFlags |= SORTFLAG_UseSorter; + } + + /* Open a virtual index to use for the distinct set. + */ + if( p->selFlags & SF_Distinct ){ + sDistinct.tabTnct = pParse->nTab++; + sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, + sDistinct.tabTnct, 0, 0, + (char*)keyInfoFromExprList(pParse, p->pEList,0,0), + P4_KEYINFO); + sqlite3VdbeChangeP5(v, BTREE_UNORDERED); + sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED; + }else{ + sDistinct.eTnctType = WHERE_DISTINCT_NOOP; + } + + if( !isAgg && pGroupBy==0 ){ + /* No aggregate functions and no GROUP BY clause */ + u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0); + + /* Begin the database scan. */ + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy, + p->pEList, wctrlFlags, 0); + if( pWInfo==0 ) goto select_end; + if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){ + p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo); + } + if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){ + sDistinct.eTnctType = sqlite3WhereIsDistinct(pWInfo); + } + if( sSort.pOrderBy ){ + sSort.nOBSat = sqlite3WhereIsOrdered(pWInfo); + if( sSort.nOBSat==sSort.pOrderBy->nExpr ){ + sSort.pOrderBy = 0; + } + } + + /* If sorting index that was created by a prior OP_OpenEphemeral + ** instruction ended up not being needed, then change the OP_OpenEphemeral + ** into an OP_Noop. + */ + if( sSort.addrSortIndex>=0 && sSort.pOrderBy==0 ){ + sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex); + } + + /* Use the standard inner loop. */ + selectInnerLoop(pParse, p, pEList, -1, &sSort, &sDistinct, pDest, + sqlite3WhereContinueLabel(pWInfo), + sqlite3WhereBreakLabel(pWInfo)); + + /* End the database scan loop. + */ + sqlite3WhereEnd(pWInfo); + }else{ + /* This case when there exist aggregate functions or a GROUP BY clause + ** or both */ + 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 */ + int addrEnd; /* End of processing for this SELECT */ + int sortPTab = 0; /* Pseudotable used to decode sorting results */ + int sortOut = 0; /* Output register from the sorter */ + int orderByGrp = 0; /* True if the GROUP BY and ORDER BY are the same */ + + /* Remove any and all aliases between the result set and the + ** GROUP BY clause. + */ + if( pGroupBy ){ + int k; /* Loop counter */ + struct ExprList_item *pItem; /* For looping over expression in a list */ + + for(k=p->pEList->nExpr, pItem=p->pEList->a; k>0; k--, pItem++){ + pItem->u.x.iAlias = 0; + } + for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){ + pItem->u.x.iAlias = 0; + } + if( p->nSelectRow>100 ) p->nSelectRow = 100; + }else{ + p->nSelectRow = 1; + } + + + /* If there is both a GROUP BY and an ORDER BY clause and they are + ** identical, then it may be possible to disable the ORDER BY clause + ** on the grounds that the GROUP BY will cause elements to come out + ** in the correct order. It also may not - the GROUP BY may use a + ** database index that causes rows to be grouped together as required + ** but not actually sorted. Either way, record the fact that the + ** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp + ** variable. */ + if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){ + orderByGrp = 1; + } + + /* Create a label to jump to when we want to abort the query */ + 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.mnReg = pParse->nMem+1; + sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0; + sAggInfo.pGroupBy = pGroupBy; + sqlite3ExprAnalyzeAggList(&sNC, pEList); + sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy); + if( pHaving ){ + sqlite3ExprAnalyzeAggregates(&sNC, pHaving); + } + sAggInfo.nAccumulator = sAggInfo.nColumn; + for(i=0; ix.pList); + sNC.ncFlags &= ~NC_InAggFunc; + } + sAggInfo.mxReg = pParse->nMem; + if( db->mallocFailed ) goto select_end; + + /* Processing for aggregates with GROUP BY is very different and + ** much more complex than aggregates without a GROUP BY. + */ + if( pGroupBy ){ + KeyInfo *pKeyInfo; /* Keying information for the group by clause */ + int j1; /* A-vs-B comparision jump */ + int addrOutputRow; /* Start of subroutine that outputs a result row */ + int regOutputRow; /* Return address register for output subroutine */ + int addrSetAbort; /* Set the abort flag and return */ + int addrTopOfLoop; /* Top of the input loop */ + int addrSortingIdx; /* The OP_OpenEphemeral for the sorting index */ + int addrReset; /* Subroutine for resetting the accumulator */ + int regReset; /* Return address register for reset subroutine */ + + /* 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 OP_SorterOpen instruction + ** will be converted into a Noop. + */ + sAggInfo.sortingIdx = pParse->nTab++; + pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0, sAggInfo.nColumn); + addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, + sAggInfo.sortingIdx, sAggInfo.nSortingColumn, + 0, (char*)pKeyInfo, P4_KEYINFO); + + /* Initialize memory locations used by GROUP BY aggregate processing + */ + iUseFlag = ++pParse->nMem; + iAbortFlag = ++pParse->nMem; + regOutputRow = ++pParse->nMem; + addrOutputRow = sqlite3VdbeMakeLabel(v); + regReset = ++pParse->nMem; + addrReset = sqlite3VdbeMakeLabel(v); + iAMem = pParse->nMem + 1; + pParse->nMem += pGroupBy->nExpr; + iBMem = pParse->nMem + 1; + pParse->nMem += pGroupBy->nExpr; + sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag); + VdbeComment((v, "clear abort flag")); + sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); + VdbeComment((v, "indicate accumulator empty")); + sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1); + + /* 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. + */ + sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, + WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0), 0 + ); + if( pWInfo==0 ) goto select_end; + if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){ + /* The optimizer is able to deliver rows in group by order so + ** we do not have to sort. The OP_OpenEphemeral table will be + ** cancelled later because we still need to use the pKeyInfo + */ + 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 + */ + int regBase; + int regRecord; + int nCol; + int nGroupBy; + + explainTempTable(pParse, + (sDistinct.isTnct && (p->selFlags&SF_Distinct)==0) ? + "DISTINCT" : "GROUP BY"); + + groupBySort = 1; + nGroupBy = pGroupBy->nExpr; + nCol = nGroupBy; + j = nGroupBy; + for(i=0; i=j ){ + nCol++; + j++; + } + } + regBase = sqlite3GetTempRange(pParse, nCol); + sqlite3ExprCacheClear(pParse); + sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0); + j = nGroupBy; + for(i=0; iiSorterColumn>=j ){ + int r1 = j + regBase; + int r2; + + r2 = sqlite3ExprCodeGetColumn(pParse, + pCol->pTab, pCol->iColumn, pCol->iTable, r1, 0); + if( r1!=r2 ){ + sqlite3VdbeAddOp2(v, OP_SCopy, r2, r1); + } + j++; + } + } + regRecord = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); + sqlite3VdbeAddOp2(v, OP_SorterInsert, sAggInfo.sortingIdx, regRecord); + sqlite3ReleaseTempReg(pParse, regRecord); + sqlite3ReleaseTempRange(pParse, regBase, nCol); + sqlite3WhereEnd(pWInfo); + sAggInfo.sortingIdxPTab = sortPTab = pParse->nTab++; + sortOut = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); + sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd); + VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v); + sAggInfo.useSortingIdx = 1; + sqlite3ExprCacheClear(pParse); + + } + + /* If the index or temporary table used by the GROUP BY sort + ** will naturally deliver rows in the order required by the ORDER BY + ** clause, cancel the ephemeral table open coded earlier. + ** + ** This is an optimization - the correct answer should result regardless. + ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER to + ** disable this optimization for testing purposes. */ + if( orderByGrp && OptimizationEnabled(db, SQLITE_GroupByOrder) + && (groupBySort || sqlite3WhereIsSorted(pWInfo)) + ){ + sSort.pOrderBy = 0; + sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex); + } + + /* 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); + sqlite3ExprCacheClear(pParse); + if( groupBySort ){ + sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx, sortOut,sortPTab); + } + for(j=0; jnExpr; j++){ + if( groupBySort ){ + sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); + }else{ + sAggInfo.directMode = 1; + sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); + } + } + sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr, + (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); + j1 = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp3(v, OP_Jump, j1+1, 0, j1+1); VdbeCoverage(v); + + /* Generate code that runs whenever the GROUP BY changes. + ** Changes 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. + */ + sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr); + sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); + VdbeComment((v, "output one row")); + sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v); + VdbeComment((v, "check abort flag")); + sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); + VdbeComment((v, "reset accumulator")); + + /* Update the aggregate accumulators based on the content of + ** the current row + */ + sqlite3VdbeJumpHere(v, j1); + updateAccumulator(pParse, &sAggInfo); + sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag); + VdbeComment((v, "indicate data in accumulator")); + + /* End of the loop + */ + if( groupBySort ){ + sqlite3VdbeAddOp2(v, OP_SorterNext, sAggInfo.sortingIdx, addrTopOfLoop); + VdbeCoverage(v); + }else{ + sqlite3WhereEnd(pWInfo); + sqlite3VdbeChangeToNoop(v, addrSortingIdx); + } + + /* Output the final row of result + */ + sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); + VdbeComment((v, "output final row")); + + /* Jump over the subroutines + */ + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEnd); + + /* 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); + sqlite3VdbeAddOp2(v, OP_Integer, 1, iAbortFlag); + VdbeComment((v, "set abort flag")); + sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); + sqlite3VdbeResolveLabel(v, addrOutputRow); + addrOutputRow = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2); VdbeCoverage(v); + VdbeComment((v, "Groupby result generator entry point")); + sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); + finalizeAggFunctions(pParse, &sAggInfo); + sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL); + selectInnerLoop(pParse, p, p->pEList, -1, &sSort, + &sDistinct, pDest, + addrOutputRow+1, addrSetAbort); + sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); + VdbeComment((v, "end groupby result generator")); + + /* Generate a subroutine that will reset the group-by accumulator + */ + sqlite3VdbeResolveLabel(v, addrReset); + resetAccumulator(pParse, &sAggInfo); + sqlite3VdbeAddOp1(v, OP_Return, regReset); + + } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */ + else { + ExprList *pDel = 0; +#ifndef SQLITE_OMIT_BTREECOUNT + Table *pTab; + if( (pTab = isSimpleCount(p, &sAggInfo))!=0 ){ + /* If isSimpleCount() returns a pointer to a Table structure, then + ** the SQL statement is of the form: + ** + ** SELECT count(*) FROM + ** + ** where the Table structure returned represents table . + ** + ** This statement is so common that it is optimized specially. The + ** OP_Count instruction is executed either on the intkey table that + ** contains the data for table or on one of its indexes. It + ** is better to execute the op on an index, as indexes are almost + ** always spread across less pages than their corresponding tables. + */ + const int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + const int iCsr = pParse->nTab++; /* Cursor to scan b-tree */ + Index *pIdx; /* Iterator variable */ + KeyInfo *pKeyInfo = 0; /* Keyinfo for scanned index */ + Index *pBest = 0; /* Best index found so far */ + int iRoot = pTab->tnum; /* Root page of scanned b-tree */ + + sqlite3CodeVerifySchema(pParse, iDb); + sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + + /* Search for the index that has the lowest scan cost. + ** + ** (2011-04-15) Do not do a full scan of an unordered index. + ** + ** (2013-10-03) Do not count the entries in a partial index. + ** + ** In practice the KeyInfo structure will not be used. It is only + ** passed to keep OP_OpenRead happy. + */ + if( !HasRowid(pTab) ) pBest = sqlite3PrimaryKeyIndex(pTab); + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->bUnordered==0 + && pIdx->szIdxRowszTabRow + && pIdx->pPartIdxWhere==0 + && (!pBest || pIdx->szIdxRowszIdxRow) + ){ + pBest = pIdx; + } + } + if( pBest ){ + iRoot = pBest->tnum; + pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pBest); + } + + /* Open a read-only cursor, execute the OP_Count, close the cursor. */ + sqlite3VdbeAddOp4Int(v, OP_OpenRead, iCsr, iRoot, iDb, 1); + if( pKeyInfo ){ + sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO); + } + sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem); + sqlite3VdbeAddOp1(v, OP_Close, iCsr); + explainSimpleCount(pParse, pTab, pBest); + }else +#endif /* SQLITE_OMIT_BTREECOUNT */ + { + /* Check if the query is of one of the following forms: + ** + ** SELECT min(x) FROM ... + ** SELECT max(x) FROM ... + ** + ** If it is, then ask the code in where.c to attempt to sort results + ** as if there was an "ORDER ON x" or "ORDER ON x DESC" clause. + ** If where.c is able to produce results sorted in this order, then + ** add vdbe code to break out of the processing loop after the + ** first iteration (since the first iteration of the loop is + ** guaranteed to operate on the row with the minimum or maximum + ** value of x, the only row required). + ** + ** A special flag must be passed to sqlite3WhereBegin() to slightly + ** modify behavior as follows: + ** + ** + If the query is a "SELECT min(x)", then the loop coded by + ** where.c should not iterate over any values with a NULL value + ** for x. + ** + ** + The optimizer code in where.c (the thing that decides which + ** index or indices to use) should place a different priority on + ** satisfying the 'ORDER BY' clause than it does in other cases. + ** Refer to code and comments in where.c for details. + */ + ExprList *pMinMax = 0; + u8 flag = WHERE_ORDERBY_NORMAL; + + assert( p->pGroupBy==0 ); + assert( flag==0 ); + if( p->pHaving==0 ){ + flag = minMaxQuery(&sAggInfo, &pMinMax); + } + assert( flag==0 || (pMinMax!=0 && pMinMax->nExpr==1) ); + + if( flag ){ + pMinMax = sqlite3ExprListDup(db, pMinMax, 0); + pDel = pMinMax; + if( pMinMax && !db->mallocFailed ){ + pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0; + pMinMax->a[0].pExpr->op = TK_COLUMN; + } + } + + /* 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, pMinMax,0,flag,0); + if( pWInfo==0 ){ + sqlite3ExprListDelete(db, pDel); + goto select_end; + } + updateAccumulator(pParse, &sAggInfo); + assert( pMinMax==0 || pMinMax->nExpr==1 ); + if( sqlite3WhereIsOrdered(pWInfo)>0 ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3WhereBreakLabel(pWInfo)); + VdbeComment((v, "%s() by index", + (flag==WHERE_ORDERBY_MIN?"min":"max"))); + } + sqlite3WhereEnd(pWInfo); + finalizeAggFunctions(pParse, &sAggInfo); + } + + sSort.pOrderBy = 0; + sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL); + selectInnerLoop(pParse, p, p->pEList, -1, 0, 0, + pDest, addrEnd, addrEnd); + sqlite3ExprListDelete(db, pDel); + } + sqlite3VdbeResolveLabel(v, addrEnd); + + } /* endif aggregate query */ + + if( sDistinct.eTnctType==WHERE_DISTINCT_UNORDERED ){ + explainTempTable(pParse, "DISTINCT"); + } + + /* If there is an ORDER BY clause, then we need to sort the results + ** and send them to the callback one by one. + */ + if( sSort.pOrderBy ){ + explainTempTable(pParse, sSort.nOBSat>0 ? "RIGHT PART OF ORDER BY":"ORDER BY"); + generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest); + } + + /* Jump here to skip this query + */ + sqlite3VdbeResolveLabel(v, iEnd); + + /* The SELECT has been coded. If there is an error in the Parse structure, + ** set the return code to 1. Otherwise 0. */ + rc = (pParse->nErr>0); + + /* Control jumps to here if an error is encountered above, or upon + ** successful coding of the SELECT. + */ +select_end: + explainSetInteger(pParse->iSelectId, iRestoreSelectId); + + /* Identify column names if results of the SELECT are to be output. + */ + if( rc==SQLITE_OK && pDest->eDest==SRT_Output ){ + generateColumnNames(pParse, pTabList, pEList); + } + + sqlite3DbFree(db, sAggInfo.aCol); + sqlite3DbFree(db, sAggInfo.aFunc); +#if SELECTTRACE_ENABLED + SELECTTRACE(1,pParse,p,("end processing\n")); + pParse->nSelectIndent--; +#endif + return rc; +} + +#ifdef SQLITE_DEBUG +/* +** Generate a human-readable description of a the Select object. +*/ +SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ + int n = 0; + pView = sqlite3TreeViewPush(pView, moreToFollow); + sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p)", + ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""), + ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p + ); + if( p->pSrc && p->pSrc->nSrc ) n++; + if( p->pWhere ) n++; + if( p->pGroupBy ) n++; + if( p->pHaving ) n++; + if( p->pOrderBy ) n++; + if( p->pLimit ) n++; + if( p->pOffset ) n++; + if( p->pPrior ) n++; + sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set"); + if( p->pSrc && p->pSrc->nSrc ){ + int i; + pView = sqlite3TreeViewPush(pView, (n--)>0); + sqlite3TreeViewLine(pView, "FROM"); + for(i=0; ipSrc->nSrc; i++){ + struct SrcList_item *pItem = &p->pSrc->a[i]; + StrAccum x; + char zLine[100]; + sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); + sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor); + if( pItem->zDatabase ){ + sqlite3XPrintf(&x, 0, " %s.%s", pItem->zDatabase, pItem->zName); + }else if( pItem->zName ){ + sqlite3XPrintf(&x, 0, " %s", pItem->zName); + } + if( pItem->pTab ){ + sqlite3XPrintf(&x, 0, " tabname=%Q", pItem->pTab->zName); + } + if( pItem->zAlias ){ + sqlite3XPrintf(&x, 0, " (AS %s)", pItem->zAlias); + } + if( pItem->jointype & JT_LEFT ){ + sqlite3XPrintf(&x, 0, " LEFT-JOIN"); + } + sqlite3StrAccumFinish(&x); + sqlite3TreeViewItem(pView, zLine, ipSrc->nSrc-1); + if( pItem->pSelect ){ + sqlite3TreeViewSelect(pView, pItem->pSelect, 0); + } + sqlite3TreeViewPop(pView); + } + sqlite3TreeViewPop(pView); + } + if( p->pWhere ){ + sqlite3TreeViewItem(pView, "WHERE", (n--)>0); + sqlite3TreeViewExpr(pView, p->pWhere, 0); + sqlite3TreeViewPop(pView); + } + if( p->pGroupBy ){ + sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY"); + } + if( p->pHaving ){ + sqlite3TreeViewItem(pView, "HAVING", (n--)>0); + sqlite3TreeViewExpr(pView, p->pHaving, 0); + sqlite3TreeViewPop(pView); + } + if( p->pOrderBy ){ + sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY"); + } + if( p->pLimit ){ + sqlite3TreeViewItem(pView, "LIMIT", (n--)>0); + sqlite3TreeViewExpr(pView, p->pLimit, 0); + sqlite3TreeViewPop(pView); + } + if( p->pOffset ){ + sqlite3TreeViewItem(pView, "OFFSET", (n--)>0); + sqlite3TreeViewExpr(pView, p->pOffset, 0); + sqlite3TreeViewPop(pView); + } + if( p->pPrior ){ + const char *zOp = "UNION"; + switch( p->op ){ + case TK_ALL: zOp = "UNION ALL"; break; + case TK_INTERSECT: zOp = "INTERSECT"; break; + case TK_EXCEPT: zOp = "EXCEPT"; break; + } + sqlite3TreeViewItem(pView, zOp, (n--)>0); + sqlite3TreeViewSelect(pView, p->pPrior, 0); + sqlite3TreeViewPop(pView); + } + sqlite3TreeViewPop(pView); +} +#endif /* SQLITE_DEBUG */ + +/************** End of select.c **********************************************/ +/************** Begin file table.c *******************************************/ +/* +** 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. +** +************************************************************************* +** 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 */ +/* #include */ + +#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; /* Accumulated output */ + char *zErrMsg; /* Error message text, if an error occurs */ + u32 nAlloc; /* Slots allocated for azResult[] */ + u32 nRow; /* Number of rows in the result */ + u32 nColumn; /* Number of columns in the result */ + u32 nData; /* Slots used in azResult[]. (nRow+1)*nColumn */ + int rc; /* Return code from sqlite3_exec() */ +} TabResult; + +/* +** This routine is called once for each row in the result table. Its job +** is to fill in the TabResult structure appropriately, allocating new +** memory as necessary. +*/ +static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){ + TabResult *p = (TabResult*)pArg; /* Result accumulator */ + int need; /* Slots needed in p->azResult[] */ + int i; /* Loop counter */ + char *z; /* A single column of result */ + + /* Make sure there is enough space in p->azResult to hold everything + ** we need to remember from this invocation of the callback. + */ + if( p->nRow==0 && argv!=0 ){ + need = nCol*2; + }else{ + need = nCol; + } + if( p->nData + need > p->nAlloc ){ + char **azNew; + p->nAlloc = p->nAlloc*2 + need; + azNew = sqlite3_realloc64( p->azResult, sizeof(char*)*p->nAlloc ); + if( azNew==0 ) goto malloc_failed; + p->azResult = azNew; + } + + /* If this is the first row, then generate an extra row containing + ** the names of all columns. + */ + if( p->nRow==0 ){ + p->nColumn = nCol; + for(i=0; iazResult[p->nData++] = z; + } + }else if( (int)p->nColumn!=nCol ){ + sqlite3_free(p->zErrMsg); + p->zErrMsg = sqlite3_mprintf( + "sqlite3_get_table() called with two or more incompatible queries" + ); + p->rc = SQLITE_ERROR; + return 1; + } + + /* Copy over the row data + */ + if( argv!=0 ){ + for(i=0; iazResult[p->nData++] = z; + } + p->nRow++; + } + return 0; + +malloc_failed: + p->rc = SQLITE_NOMEM; + return 1; +} + +/* +** Query the database. But instead of invoking a callback for each row, +** malloc() for space to hold the result and return the entire results +** at the conclusion of the call. +** +** The result that is written to ***pazResult is held in memory obtained +** from malloc(). But the caller cannot free this memory directly. +** Instead, the entire table should be passed to sqlite3_free_table() when +** the calling procedure is finished using it. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_get_table( + sqlite3 *db, /* The database on which the SQL executes */ + const char *zSql, /* The SQL to be executed */ + char ***pazResult, /* Write the result table here */ + int *pnRow, /* Write the number of rows in the result here */ + int *pnColumn, /* Write the number of columns of result here */ + char **pzErrMsg /* Write error messages here */ +){ + int rc; + TabResult res; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || pazResult==0 ) return SQLITE_MISUSE_BKPT; +#endif + *pazResult = 0; + if( pnColumn ) *pnColumn = 0; + if( pnRow ) *pnRow = 0; + if( pzErrMsg ) *pzErrMsg = 0; + res.zErrMsg = 0; + res.nRow = 0; + res.nColumn = 0; + res.nData = 1; + res.nAlloc = 20; + res.rc = SQLITE_OK; + res.azResult = sqlite3_malloc64(sizeof(char*)*res.nAlloc ); + if( res.azResult==0 ){ + db->errCode = SQLITE_NOMEM; + return SQLITE_NOMEM; + } + res.azResult[0] = 0; + rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg); + assert( sizeof(res.azResult[0])>= sizeof(res.nData) ); + res.azResult[0] = SQLITE_INT_TO_PTR(res.nData); + if( (rc&0xff)==SQLITE_ABORT ){ + sqlite3_free_table(&res.azResult[1]); + if( res.zErrMsg ){ + if( pzErrMsg ){ + sqlite3_free(*pzErrMsg); + *pzErrMsg = sqlite3_mprintf("%s",res.zErrMsg); + } + sqlite3_free(res.zErrMsg); + } + db->errCode = res.rc; /* Assume 32-bit assignment is atomic */ + return res.rc; + } + sqlite3_free(res.zErrMsg); + if( rc!=SQLITE_OK ){ + sqlite3_free_table(&res.azResult[1]); + return rc; + } + if( res.nAlloc>res.nData ){ + char **azNew; + azNew = sqlite3_realloc64( res.azResult, sizeof(char*)*res.nData ); + if( azNew==0 ){ + sqlite3_free_table(&res.azResult[1]); + db->errCode = SQLITE_NOMEM; + return SQLITE_NOMEM; + } + res.azResult = azNew; + } + *pazResult = &res.azResult[1]; + if( pnColumn ) *pnColumn = res.nColumn; + if( pnRow ) *pnRow = res.nRow; + return rc; +} + +/* +** This routine frees the space the sqlite3_get_table() malloced. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_free_table( + char **azResult /* Result returned from sqlite3_get_table() */ +){ + if( azResult ){ + int i, n; + azResult--; + assert( azResult!=0 ); + n = SQLITE_PTR_TO_INT(azResult[0]); + for(i=1; ipNext; + + sqlite3ExprDelete(db, pTmp->pWhere); + sqlite3ExprListDelete(db, pTmp->pExprList); + sqlite3SelectDelete(db, pTmp->pSelect); + sqlite3IdListDelete(db, pTmp->pIdList); + + sqlite3DbFree(db, pTmp); + } +} + +/* +** Given table pTab, return a list of all the triggers attached to +** the table. The list is connected by Trigger.pNext pointers. +** +** All of the triggers on pTab that are in the same database as pTab +** are already attached to pTab->pTrigger. But there might be additional +** triggers on pTab in the TEMP schema. This routine prepends all +** TEMP triggers on pTab to the beginning of the pTab->pTrigger list +** and returns the combined list. +** +** To state it another way: This routine returns a list of all triggers +** that fire off of pTab. The list will include any TEMP triggers on +** pTab as well as the triggers lised in pTab->pTrigger. +*/ +SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){ + Schema * const pTmpSchema = pParse->db->aDb[1].pSchema; + Trigger *pList = 0; /* List of triggers to return */ + + if( pParse->disableTriggers ){ + return 0; + } + + if( pTmpSchema!=pTab->pSchema ){ + HashElem *p; + assert( sqlite3SchemaMutexHeld(pParse->db, 0, pTmpSchema) ); + for(p=sqliteHashFirst(&pTmpSchema->trigHash); p; p=sqliteHashNext(p)){ + Trigger *pTrig = (Trigger *)sqliteHashData(p); + if( pTrig->pTabSchema==pTab->pSchema + && 0==sqlite3StrICmp(pTrig->table, pTab->zName) + ){ + pTrig->pNext = (pList ? pList : pTab->pTrigger); + pList = pTrig; + } + } + } + + return (pList ? pList : pTab->pTrigger); +} + +/* +** This is called by the parser when it sees a CREATE TRIGGER statement +** up to the point of the BEGIN before the trigger actions. A Trigger +** structure is generated based on the information available and stored +** in pParse->pNewTrigger. After the trigger actions have been parsed, the +** sqlite3FinishTrigger() function is called to complete the trigger +** construction process. +*/ +SQLITE_PRIVATE void sqlite3BeginTrigger( + Parse *pParse, /* The parse context of the CREATE TRIGGER statement */ + Token *pName1, /* The name of the trigger */ + Token *pName2, /* The name of the trigger */ + int tr_tm, /* One of TK_BEFORE, TK_AFTER, TK_INSTEAD */ + 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 */ + Expr *pWhen, /* WHEN clause */ + int isTemp, /* True if the TEMPORARY keyword is present */ + int noErr /* Suppress errors if the trigger already exists */ +){ + Trigger *pTrigger = 0; /* The new trigger */ + Table *pTab; /* Table that the trigger fires off of */ + char *zName = 0; /* Name of the trigger */ + sqlite3 *db = pParse->db; /* The database connection */ + int iDb; /* The database to store the trigger in */ + Token *pName; /* The unqualified db name */ + DbFixer sFix; /* State vector for the DB fixer */ + int iTabDb; /* Index of the database holding pTab */ + + assert( pName1!=0 ); /* pName1->z might be NULL, but not pName1 itself */ + assert( pName2!=0 ); + assert( op==TK_INSERT || op==TK_UPDATE || op==TK_DELETE ); + assert( op>0 && op<0xff ); + if( isTemp ){ + /* If TEMP was specified, then the trigger name may not be qualified. */ + if( pName2->n>0 ){ + sqlite3ErrorMsg(pParse, "temporary trigger may not have qualified name"); + goto trigger_cleanup; + } + iDb = 1; + pName = pName1; + }else{ + /* Figure out the db that the trigger will be created in */ + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); + if( iDb<0 ){ + goto trigger_cleanup; + } + } + if( !pTableName || db->mallocFailed ){ + goto trigger_cleanup; + } + + /* A long-standing parser bug is that this syntax was allowed: + ** + ** CREATE TRIGGER attached.demo AFTER INSERT ON attached.tab .... + ** ^^^^^^^^ + ** + ** To maintain backwards compatibility, ignore the database + ** name on pTableName if we are reparsing out of SQLITE_MASTER. + */ + if( db->init.busy && iDb!=1 ){ + sqlite3DbFree(db, pTableName->a[0].zDatabase); + pTableName->a[0].zDatabase = 0; + } + + /* 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. + */ + pTab = sqlite3SrcListLookup(pParse, pTableName); + if( db->init.busy==0 && 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( db->mallocFailed ) goto trigger_cleanup; + assert( pTableName->nSrc==1 ); + sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName); + if( sqlite3FixSrcList(&sFix, pTableName) ){ + goto trigger_cleanup; + } + pTab = sqlite3SrcListLookup(pParse, pTableName); + if( !pTab ){ + /* The table does not exist. */ + if( db->init.iDb==1 ){ + /* Ticket #3810. + ** Normally, whenever a table is dropped, all associated triggers are + ** dropped too. But if a TEMP trigger is created on a non-TEMP table + ** and the table is dropped by a different database connection, the + ** trigger is not visible to the database connection that does the + ** drop so the trigger cannot be dropped. This results in an + ** "orphaned trigger" - a trigger whose associated table is missing. + */ + db->init.orphanTrigger = 1; + } + goto trigger_cleanup; + } + if( IsVirtual(pTab) ){ + sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables"); + goto trigger_cleanup; + } + + /* Check that the trigger name is not reserved and that no trigger of the + ** specified name exists */ + zName = sqlite3NameFromToken(db, pName); + if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ + goto trigger_cleanup; + } + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){ + if( !noErr ){ + sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); + }else{ + assert( !db->init.busy ); + sqlite3CodeVerifySchema(pParse, iDb); + } + 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"); + goto trigger_cleanup; + } + + /* INSTEAD of triggers are only for views and views only support INSTEAD + ** of triggers. + */ + if( pTab->pSelect && tr_tm!=TK_INSTEAD ){ + sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S", + (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0); + 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*)sqlite3DbMallocZero(db, sizeof(Trigger)); + if( pTrigger==0 ) goto trigger_cleanup; + pTrigger->zName = zName; + zName = 0; + pTrigger->table = sqlite3DbStrDup(db, pTableName->a[0].zName); + pTrigger->pSchema = db->aDb[iDb].pSchema; + pTrigger->pTabSchema = pTab->pSchema; + pTrigger->op = (u8)op; + pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER; + pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); + pTrigger->pColumns = sqlite3IdListDup(db, pColumns); + assert( pParse->pNewTrigger==0 ); + pParse->pNewTrigger = pTrigger; + +trigger_cleanup: + sqlite3DbFree(db, zName); + sqlite3SrcListDelete(db, pTableName); + sqlite3IdListDelete(db, pColumns); + sqlite3ExprDelete(db, pWhen); + if( !pParse->pNewTrigger ){ + sqlite3DeleteTrigger(db, 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. +*/ +SQLITE_PRIVATE void sqlite3FinishTrigger( + Parse *pParse, /* Parser context */ + TriggerStep *pStepList, /* The triggered program */ + Token *pAll /* Token that describes the complete CREATE TRIGGER */ +){ + Trigger *pTrig = pParse->pNewTrigger; /* Trigger being finished */ + char *zName; /* Name of trigger */ + sqlite3 *db = pParse->db; /* The database */ + DbFixer sFix; /* Fixer object */ + int iDb; /* Database containing the trigger */ + Token nameToken; /* Trigger name for error reporting */ + + pParse->pNewTrigger = 0; + if( NEVER(pParse->nErr) || !pTrig ) goto triggerfinish_cleanup; + zName = pTrig->zName; + iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema); + pTrig->step_list = pStepList; + while( pStepList ){ + pStepList->pTrig = pTrig; + pStepList = pStepList->pNext; + } + nameToken.z = pTrig->zName; + nameToken.n = sqlite3Strlen30(nameToken.z); + sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken); + if( sqlite3FixTriggerStep(&sFix, pTrig->step_list) + || sqlite3FixExpr(&sFix, pTrig->pWhen) + ){ + goto triggerfinish_cleanup; + } + + /* if we are not initializing, + ** build the sqlite_master entry + */ + if( !db->init.busy ){ + Vdbe *v; + char *z; + + /* Make an entry in the sqlite_master table */ + v = sqlite3GetVdbe(pParse); + if( v==0 ) goto triggerfinish_cleanup; + sqlite3BeginWriteOperation(pParse, 0, iDb); + z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n); + sqlite3NestedParse(pParse, + "INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')", + db->aDb[iDb].zName, SCHEMA_TABLE(iDb), zName, + pTrig->table, z); + sqlite3DbFree(db, z); + sqlite3ChangeCookie(pParse, iDb); + sqlite3VdbeAddParseSchemaOp(v, iDb, + sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName)); + } + + if( db->init.busy ){ + Trigger *pLink = pTrig; + Hash *pHash = &db->aDb[iDb].pSchema->trigHash; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pTrig = sqlite3HashInsert(pHash, zName, pTrig); + if( pTrig ){ + db->mallocFailed = 1; + }else if( pLink->pSchema==pLink->pTabSchema ){ + Table *pTab; + pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table); + assert( pTab!=0 ); + pLink->pNext = pTab->pTrigger; + pTab->pTrigger = pLink; + } + } + +triggerfinish_cleanup: + sqlite3DeleteTrigger(db, pTrig); + assert( !pParse->pNewTrigger ); + sqlite3DeleteTriggerStep(db, pStepList); +} + +/* +** Turn a SELECT statement (that the pSelect parameter points to) into +** 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. +*/ +SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelect){ + TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep)); + if( pTriggerStep==0 ) { + sqlite3SelectDelete(db, pSelect); + return 0; + } + pTriggerStep->op = TK_SELECT; + pTriggerStep->pSelect = pSelect; + pTriggerStep->orconf = OE_Default; + return pTriggerStep; +} + +/* +** Allocate space to hold a new trigger step. The allocated space +** holds both the TriggerStep object and the TriggerStep.target.z string. +** +** If an OOM error occurs, NULL is returned and db->mallocFailed is set. +*/ +static TriggerStep *triggerStepAllocate( + sqlite3 *db, /* Database connection */ + u8 op, /* Trigger opcode */ + Token *pName /* The target name */ +){ + TriggerStep *pTriggerStep; + + pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1); + if( pTriggerStep ){ + char *z = (char*)&pTriggerStep[1]; + memcpy(z, pName->z, pName->n); + sqlite3Dequote(z); + pTriggerStep->zTarget = z; + pTriggerStep->op = op; + } + return pTriggerStep; +} + +/* +** Build a trigger step out of an INSERT statement. Return a pointer +** to the new trigger step. +** +** The parser calls this routine when it sees an INSERT inside the +** body of a trigger. +*/ +SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep( + sqlite3 *db, /* The database connection */ + Token *pTableName, /* Name of the table into which we insert */ + IdList *pColumn, /* List of columns in pTableName to insert into */ + Select *pSelect, /* A SELECT statement that supplies values */ + u8 orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */ +){ + TriggerStep *pTriggerStep; + + assert(pSelect != 0 || db->mallocFailed); + + pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName); + if( pTriggerStep ){ + pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + pTriggerStep->pIdList = pColumn; + pTriggerStep->orconf = orconf; + }else{ + sqlite3IdListDelete(db, pColumn); + } + sqlite3SelectDelete(db, 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 +** sees an UPDATE statement inside the body of a CREATE TRIGGER. +*/ +SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep( + sqlite3 *db, /* The database connection */ + Token *pTableName, /* Name of the table to be updated */ + ExprList *pEList, /* The SET clause: list of column and new values */ + Expr *pWhere, /* The WHERE clause */ + u8 orconf /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */ +){ + TriggerStep *pTriggerStep; + + pTriggerStep = triggerStepAllocate(db, TK_UPDATE, pTableName); + if( pTriggerStep ){ + pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE); + pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + pTriggerStep->orconf = orconf; + } + sqlite3ExprListDelete(db, pEList); + sqlite3ExprDelete(db, pWhere); + return pTriggerStep; +} + +/* +** Construct a trigger step that implements a DELETE statement and return +** a pointer to that trigger step. The parser calls this routine when it +** sees a DELETE statement inside the body of a CREATE TRIGGER. +*/ +SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep( + sqlite3 *db, /* Database connection */ + Token *pTableName, /* The table from which rows are deleted */ + Expr *pWhere /* The WHERE clause */ +){ + TriggerStep *pTriggerStep; + + pTriggerStep = triggerStepAllocate(db, TK_DELETE, pTableName); + if( pTriggerStep ){ + pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + pTriggerStep->orconf = OE_Default; + } + sqlite3ExprDelete(db, pWhere); + return pTriggerStep; +} + +/* +** Recursively delete a Trigger structure +*/ +SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){ + if( pTrigger==0 ) return; + sqlite3DeleteTriggerStep(db, pTrigger->step_list); + sqlite3DbFree(db, pTrigger->zName); + sqlite3DbFree(db, pTrigger->table); + sqlite3ExprDelete(db, pTrigger->pWhen); + sqlite3IdListDelete(db, pTrigger->pColumns); + sqlite3DbFree(db, pTrigger); +} + +/* +** This function is called to drop a trigger from the database schema. +** +** This may be called directly from the parser and therefore identifies +** the trigger by name. The sqlite3DropTriggerPtr() routine does the +** same job as this routine except it takes a pointer to the trigger +** instead of the trigger name. +**/ +SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){ + Trigger *pTrigger = 0; + int i; + const char *zDb; + const char *zName; + sqlite3 *db = pParse->db; + + if( db->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; + assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); + for(i=OMIT_TEMPDB; inDb; i++){ + int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ + if( zDb && sqlite3StrICmp(db->aDb[j].zName, zDb) ) continue; + assert( sqlite3SchemaMutexHeld(db, j, 0) ); + pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName); + if( pTrigger ) break; + } + if( !pTrigger ){ + if( !noErr ){ + sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0); + }else{ + sqlite3CodeVerifyNamedSchema(pParse, zDb); + } + pParse->checkSchema = 1; + goto drop_trigger_cleanup; + } + sqlite3DropTriggerPtr(pParse, pTrigger); + +drop_trigger_cleanup: + sqlite3SrcListDelete(db, pName); +} + +/* +** Return a pointer to the Table structure for the table that a trigger +** is set on. +*/ +static Table *tableOfTrigger(Trigger *pTrigger){ + return sqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table); +} + + +/* +** Drop a trigger given a pointer to that trigger. +*/ +SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){ + Table *pTable; + Vdbe *v; + sqlite3 *db = pParse->db; + int iDb; + + iDb = sqlite3SchemaToIndex(pParse->db, pTrigger->pSchema); + assert( iDb>=0 && iDbnDb ); + pTable = tableOfTrigger(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->zName, pTable->zName, zDb) || + sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){ + return; + } + } +#endif + + /* Generate code to destroy the database record of the trigger. + */ + assert( pTable!=0 ); + if( (v = sqlite3GetVdbe(pParse))!=0 ){ + int base; + static const int iLn = VDBE_OFFSET_LINENO(2); + static const VdbeOpList dropTrigger[] = { + { OP_Rewind, 0, ADDR(9), 0}, + { OP_String8, 0, 1, 0}, /* 1 */ + { OP_Column, 0, 1, 2}, + { OP_Ne, 2, ADDR(8), 1}, + { OP_String8, 0, 1, 0}, /* 4: "trigger" */ + { OP_Column, 0, 0, 2}, + { OP_Ne, 2, ADDR(8), 1}, + { 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, iLn); + sqlite3VdbeChangeP4(v, base+1, pTrigger->zName, P4_TRANSIENT); + sqlite3VdbeChangeP4(v, base+4, "trigger", P4_STATIC); + sqlite3ChangeCookie(pParse, iDb); + sqlite3VdbeAddOp2(v, OP_Close, 0, 0); + sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0); + if( pParse->nMem<3 ){ + pParse->nMem = 3; + } + } +} + +/* +** Remove a trigger from the hash tables of the sqlite* pointer. +*/ +SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){ + Trigger *pTrigger; + Hash *pHash; + + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pHash = &(db->aDb[iDb].pSchema->trigHash); + pTrigger = sqlite3HashInsert(pHash, zName, 0); + if( ALWAYS(pTrigger) ){ + if( pTrigger->pSchema==pTrigger->pTabSchema ){ + Table *pTab = tableOfTrigger(pTrigger); + Trigger **pp; + for(pp=&pTab->pTrigger; *pp!=pTrigger; pp=&((*pp)->pNext)); + *pp = (*pp)->pNext; + } + sqlite3DeleteTrigger(db, pTrigger); + db->flags |= SQLITE_InternChanges; + } +} + +/* +** pEList is the SET clause of an UPDATE statement. Each entry +** in pEList is of the format =. If any of the entries +** in pEList have an which matches an identifier in pIdList, +** then return TRUE. If pIdList==NULL, then it is considered a +** wildcard that matches anything. Likewise if pEList==NULL then +** it matches anything so always return true. Return false only +** if there is no match. +*/ +static int checkColumnOverlap(IdList *pIdList, ExprList *pEList){ + int e; + if( pIdList==0 || NEVER(pEList==0) ) return 1; + for(e=0; enExpr; e++){ + if( sqlite3IdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1; + } + return 0; +} + +/* +** Return a list of all triggers on table pTab if there exists at least +** one trigger that must be fired when an operation of type 'op' is +** performed on the table, and, if that operation is an UPDATE, if at +** least one of the columns in pChanges is being modified. +*/ +SQLITE_PRIVATE Trigger *sqlite3TriggersExist( + Parse *pParse, /* Parse context */ + Table *pTab, /* The table the contains the triggers */ + int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */ + ExprList *pChanges, /* Columns that change in an UPDATE statement */ + int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */ +){ + int mask = 0; + Trigger *pList = 0; + Trigger *p; + + if( (pParse->db->flags & SQLITE_EnableTrigger)!=0 ){ + pList = sqlite3TriggerList(pParse, pTab); + } + assert( pList==0 || IsVirtual(pTab)==0 ); + for(p=pList; p; p=p->pNext){ + if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){ + mask |= p->tr_tm; + } + } + if( pMask ){ + *pMask = mask; + } + return (mask ? pList : 0); +} + +/* +** Convert the pStep->zTarget string into a SrcList and return a pointer +** to that SrcList. +** +** This routine adds a specific database name, if needed, to the target when +** forming the SrcList. This prevents a trigger in one database from +** referring to a target in another database. An exception is when the +** trigger is in TEMP in which case it can refer to any other database it +** wants. +*/ +static SrcList *targetSrcList( + Parse *pParse, /* The parsing context */ + TriggerStep *pStep /* The trigger containing the target token */ +){ + sqlite3 *db = pParse->db; + int iDb; /* Index of the database to use */ + SrcList *pSrc; /* SrcList to be returned */ + + pSrc = sqlite3SrcListAppend(db, 0, 0, 0); + if( pSrc ){ + assert( pSrc->nSrc>0 ); + pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget); + iDb = sqlite3SchemaToIndex(db, pStep->pTrig->pSchema); + if( iDb==0 || iDb>=2 ){ + assert( iDbnDb ); + pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName); + } + } + return pSrc; +} + +/* +** Generate VDBE code for the statements inside the body of a single +** trigger. +*/ +static int codeTriggerProgram( + Parse *pParse, /* The parser context */ + TriggerStep *pStepList, /* List of statements inside the trigger body */ + int orconf /* Conflict algorithm. (OE_Abort, etc) */ +){ + TriggerStep *pStep; + Vdbe *v = pParse->pVdbe; + sqlite3 *db = pParse->db; + + assert( pParse->pTriggerTab && pParse->pToplevel ); + assert( pStepList ); + assert( v!=0 ); + for(pStep=pStepList; pStep; pStep=pStep->pNext){ + /* Figure out the ON CONFLICT policy that will be used for this step + ** of the trigger program. If the statement that caused this trigger + ** to fire had an explicit ON CONFLICT, then use it. Otherwise, use + ** the ON CONFLICT policy that was specified as part of the trigger + ** step statement. Example: + ** + ** CREATE TRIGGER AFTER INSERT ON t1 BEGIN; + ** INSERT OR REPLACE INTO t2 VALUES(new.a, new.b); + ** END; + ** + ** INSERT INTO t1 ... ; -- insert into t2 uses REPLACE policy + ** INSERT OR IGNORE INTO t1 ... ; -- insert into t2 uses IGNORE policy + */ + pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf; + assert( pParse->okConstFactor==0 ); + + switch( pStep->op ){ + case TK_UPDATE: { + sqlite3Update(pParse, + targetSrcList(pParse, pStep), + sqlite3ExprListDup(db, pStep->pExprList, 0), + sqlite3ExprDup(db, pStep->pWhere, 0), + pParse->eOrconf + ); + break; + } + case TK_INSERT: { + sqlite3Insert(pParse, + targetSrcList(pParse, pStep), + sqlite3SelectDup(db, pStep->pSelect, 0), + sqlite3IdListDup(db, pStep->pIdList), + pParse->eOrconf + ); + break; + } + case TK_DELETE: { + sqlite3DeleteFrom(pParse, + targetSrcList(pParse, pStep), + sqlite3ExprDup(db, pStep->pWhere, 0) + ); + break; + } + default: assert( pStep->op==TK_SELECT ); { + SelectDest sDest; + Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0); + sqlite3SelectDestInit(&sDest, SRT_Discard, 0); + sqlite3Select(pParse, pSelect, &sDest); + sqlite3SelectDelete(db, pSelect); + break; + } + } + if( pStep->op!=TK_SELECT ){ + sqlite3VdbeAddOp0(v, OP_ResetCount); + } + } + + return 0; +} + +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS +/* +** This function is used to add VdbeComment() annotations to a VDBE +** program. It is not used in production code, only for debugging. +*/ +static const char *onErrorText(int onError){ + switch( onError ){ + case OE_Abort: return "abort"; + case OE_Rollback: return "rollback"; + case OE_Fail: return "fail"; + case OE_Replace: return "replace"; + case OE_Ignore: return "ignore"; + case OE_Default: return "default"; + } + return "n/a"; +} +#endif + +/* +** Parse context structure pFrom has just been used to create a sub-vdbe +** (trigger program). If an error has occurred, transfer error information +** from pFrom to pTo. +*/ +static void transferParseError(Parse *pTo, Parse *pFrom){ + assert( pFrom->zErrMsg==0 || pFrom->nErr ); + assert( pTo->zErrMsg==0 || pTo->nErr ); + if( pTo->nErr==0 ){ + pTo->zErrMsg = pFrom->zErrMsg; + pTo->nErr = pFrom->nErr; + pTo->rc = pFrom->rc; + }else{ + sqlite3DbFree(pFrom->db, pFrom->zErrMsg); + } +} + +/* +** Create and populate a new TriggerPrg object with a sub-program +** implementing trigger pTrigger with ON CONFLICT policy orconf. +*/ +static TriggerPrg *codeRowTrigger( + Parse *pParse, /* Current parse context */ + Trigger *pTrigger, /* Trigger to code */ + Table *pTab, /* The table pTrigger is attached to */ + int orconf /* ON CONFLICT policy to code trigger program with */ +){ + Parse *pTop = sqlite3ParseToplevel(pParse); + sqlite3 *db = pParse->db; /* Database handle */ + TriggerPrg *pPrg; /* Value to return */ + Expr *pWhen = 0; /* Duplicate of trigger WHEN expression */ + Vdbe *v; /* Temporary VM */ + NameContext sNC; /* Name context for sub-vdbe */ + SubProgram *pProgram = 0; /* Sub-vdbe for trigger program */ + Parse *pSubParse; /* Parse context for sub-vdbe */ + int iEndTrigger = 0; /* Label to jump to if WHEN is false */ + + assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) ); + assert( pTop->pVdbe ); + + /* Allocate the TriggerPrg and SubProgram objects. To ensure that they + ** are freed if an error occurs, link them into the Parse.pTriggerPrg + ** list of the top-level Parse object sooner rather than later. */ + pPrg = sqlite3DbMallocZero(db, sizeof(TriggerPrg)); + if( !pPrg ) return 0; + pPrg->pNext = pTop->pTriggerPrg; + pTop->pTriggerPrg = pPrg; + pPrg->pProgram = pProgram = sqlite3DbMallocZero(db, sizeof(SubProgram)); + if( !pProgram ) return 0; + sqlite3VdbeLinkSubProgram(pTop->pVdbe, pProgram); + pPrg->pTrigger = pTrigger; + pPrg->orconf = orconf; + pPrg->aColmask[0] = 0xffffffff; + pPrg->aColmask[1] = 0xffffffff; + + /* Allocate and populate a new Parse context to use for coding the + ** trigger sub-program. */ + pSubParse = sqlite3StackAllocZero(db, sizeof(Parse)); + if( !pSubParse ) return 0; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pSubParse; + pSubParse->db = db; + pSubParse->pTriggerTab = pTab; + pSubParse->pToplevel = pTop; + pSubParse->zAuthContext = pTrigger->zName; + pSubParse->eTriggerOp = pTrigger->op; + pSubParse->nQueryLoop = pParse->nQueryLoop; + + v = sqlite3GetVdbe(pSubParse); + if( v ){ + VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", + pTrigger->zName, onErrorText(orconf), + (pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"), + (pTrigger->op==TK_UPDATE ? "UPDATE" : ""), + (pTrigger->op==TK_INSERT ? "INSERT" : ""), + (pTrigger->op==TK_DELETE ? "DELETE" : ""), + pTab->zName + )); +#ifndef SQLITE_OMIT_TRACE + sqlite3VdbeChangeP4(v, -1, + sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC + ); +#endif + + /* If one was specified, code the WHEN clause. If it evaluates to false + ** (or NULL) the sub-vdbe is immediately halted by jumping to the + ** OP_Halt inserted at the end of the program. */ + if( pTrigger->pWhen ){ + pWhen = sqlite3ExprDup(db, pTrigger->pWhen, 0); + if( SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen) + && db->mallocFailed==0 + ){ + iEndTrigger = sqlite3VdbeMakeLabel(v); + sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL); + } + sqlite3ExprDelete(db, pWhen); + } + + /* Code the trigger program into the sub-vdbe. */ + codeTriggerProgram(pSubParse, pTrigger->step_list, orconf); + + /* Insert an OP_Halt at the end of the sub-program. */ + if( iEndTrigger ){ + sqlite3VdbeResolveLabel(v, iEndTrigger); + } + sqlite3VdbeAddOp0(v, OP_Halt); + VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf))); + + transferParseError(pParse, pSubParse); + if( db->mallocFailed==0 ){ + pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg); + } + pProgram->nMem = pSubParse->nMem; + pProgram->nCsr = pSubParse->nTab; + pProgram->nOnce = pSubParse->nOnce; + pProgram->token = (void *)pTrigger; + pPrg->aColmask[0] = pSubParse->oldmask; + pPrg->aColmask[1] = pSubParse->newmask; + sqlite3VdbeDelete(v); + } + + assert( !pSubParse->pAinc && !pSubParse->pZombieTab ); + assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg ); + sqlite3ParserReset(pSubParse); + sqlite3StackFree(db, pSubParse); + + return pPrg; +} + +/* +** Return a pointer to a TriggerPrg object containing the sub-program for +** trigger pTrigger with default ON CONFLICT algorithm orconf. If no such +** TriggerPrg object exists, a new object is allocated and populated before +** being returned. +*/ +static TriggerPrg *getRowTrigger( + Parse *pParse, /* Current parse context */ + Trigger *pTrigger, /* Trigger to code */ + Table *pTab, /* The table trigger pTrigger is attached to */ + int orconf /* ON CONFLICT algorithm. */ +){ + Parse *pRoot = sqlite3ParseToplevel(pParse); + TriggerPrg *pPrg; + + assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) ); + + /* It may be that this trigger has already been coded (or is in the + ** process of being coded). If this is the case, then an entry with + ** a matching TriggerPrg.pTrigger field will be present somewhere + ** in the Parse.pTriggerPrg list. Search for such an entry. */ + for(pPrg=pRoot->pTriggerPrg; + pPrg && (pPrg->pTrigger!=pTrigger || pPrg->orconf!=orconf); + pPrg=pPrg->pNext + ); + + /* If an existing TriggerPrg could not be located, create a new one. */ + if( !pPrg ){ + pPrg = codeRowTrigger(pParse, pTrigger, pTab, orconf); + } + + return pPrg; +} + +/* +** Generate code for the trigger program associated with trigger p on +** table pTab. The reg, orconf and ignoreJump parameters passed to this +** function are the same as those described in the header function for +** sqlite3CodeRowTrigger() +*/ +SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect( + Parse *pParse, /* Parse context */ + Trigger *p, /* Trigger to code */ + Table *pTab, /* The table to code triggers from */ + int reg, /* Reg array containing OLD.* and NEW.* values */ + int orconf, /* ON CONFLICT policy */ + int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */ +){ + Vdbe *v = sqlite3GetVdbe(pParse); /* Main VM */ + TriggerPrg *pPrg; + pPrg = getRowTrigger(pParse, p, pTab, orconf); + assert( pPrg || pParse->nErr || pParse->db->mallocFailed ); + + /* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program + ** is a pointer to the sub-vdbe containing the trigger program. */ + if( pPrg ){ + int bRecursive = (p->zName && 0==(pParse->db->flags&SQLITE_RecTriggers)); + + sqlite3VdbeAddOp3(v, OP_Program, reg, ignoreJump, ++pParse->nMem); + sqlite3VdbeChangeP4(v, -1, (const char *)pPrg->pProgram, P4_SUBPROGRAM); + VdbeComment( + (v, "Call: %s.%s", (p->zName?p->zName:"fkey"), onErrorText(orconf))); + + /* Set the P5 operand of the OP_Program instruction to non-zero if + ** recursive invocation of this trigger program is disallowed. Recursive + ** invocation is disallowed if (a) the sub-program is really a trigger, + ** not a foreign key action, and (b) the flag to enable recursive triggers + ** is clear. */ + sqlite3VdbeChangeP5(v, (u8)bRecursive); + } +} + +/* +** This is called to code the required FOR EACH ROW triggers for an operation +** on table pTab. The operation to code triggers for (INSERT, UPDATE or DELETE) +** is given by the op parameter. The tr_tm parameter determines whether the +** BEFORE or AFTER triggers are coded. If the operation is an UPDATE, then +** parameter pChanges is passed the list of columns being modified. +** +** If there are no triggers that fire at the specified time for the specified +** operation on pTab, this function is a no-op. +** +** The reg argument is the address of the first in an array of registers +** that contain the values substituted for the new.* and old.* references +** in the trigger program. If N is the number of columns in table pTab +** (a copy of pTab->nCol), then registers are populated as follows: +** +** Register Contains +** ------------------------------------------------------ +** reg+0 OLD.rowid +** reg+1 OLD.* value of left-most column of pTab +** ... ... +** reg+N OLD.* value of right-most column of pTab +** reg+N+1 NEW.rowid +** reg+N+2 OLD.* value of left-most column of pTab +** ... ... +** reg+N+N+1 NEW.* value of right-most column of pTab +** +** For ON DELETE triggers, the registers containing the NEW.* values will +** never be accessed by the trigger program, so they are not allocated or +** populated by the caller (there is no data to populate them with anyway). +** Similarly, for ON INSERT triggers the values stored in the OLD.* registers +** are never accessed, and so are not allocated by the caller. So, for an +** ON INSERT trigger, the value passed to this function as parameter reg +** is not a readable register, although registers (reg+N) through +** (reg+N+N+1) are. +** +** Parameter orconf is the default conflict resolution algorithm for the +** trigger program to use (REPLACE, IGNORE etc.). Parameter ignoreJump +** is the instruction that control should jump to if a trigger program +** raises an IGNORE exception. +*/ +SQLITE_PRIVATE void sqlite3CodeRowTrigger( + Parse *pParse, /* Parse context */ + Trigger *pTrigger, /* List of triggers on table pTab */ + int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */ + ExprList *pChanges, /* Changes list for any UPDATE OF triggers */ + int tr_tm, /* One of TRIGGER_BEFORE, TRIGGER_AFTER */ + Table *pTab, /* The table to code triggers from */ + int reg, /* The first in an array of registers (see above) */ + int orconf, /* ON CONFLICT policy */ + int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */ +){ + Trigger *p; /* Used to iterate through pTrigger list */ + + assert( op==TK_UPDATE || op==TK_INSERT || op==TK_DELETE ); + assert( tr_tm==TRIGGER_BEFORE || tr_tm==TRIGGER_AFTER ); + assert( (op==TK_UPDATE)==(pChanges!=0) ); + + for(p=pTrigger; p; p=p->pNext){ + + /* Sanity checking: The schema for the trigger and for the table are + ** always defined. The trigger must be in the same schema as the table + ** or else it must be a TEMP trigger. */ + assert( p->pSchema!=0 ); + assert( p->pTabSchema!=0 ); + assert( p->pSchema==p->pTabSchema + || p->pSchema==pParse->db->aDb[1].pSchema ); + + /* Determine whether we should code this trigger */ + if( p->op==op + && p->tr_tm==tr_tm + && checkColumnOverlap(p->pColumns, pChanges) + ){ + sqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump); + } + } +} + +/* +** Triggers may access values stored in the old.* or new.* pseudo-table. +** This function returns a 32-bit bitmask indicating which columns of the +** old.* or new.* tables actually are used by triggers. This information +** may be used by the caller, for example, to avoid having to load the entire +** old.* record into memory when executing an UPDATE or DELETE command. +** +** Bit 0 of the returned mask is set if the left-most column of the +** table may be accessed using an [old|new].reference. Bit 1 is set if +** the second leftmost column value is required, and so on. If there +** are more than 32 columns in the table, and at least one of the columns +** with an index greater than 32 may be accessed, 0xffffffff is returned. +** +** It is not possible to determine if the old.rowid or new.rowid column is +** accessed by triggers. The caller must always assume that it is. +** +** Parameter isNew must be either 1 or 0. If it is 0, then the mask returned +** applies to the old.* table. If 1, the new.* table. +** +** Parameter tr_tm must be a mask with one or both of the TRIGGER_BEFORE +** and TRIGGER_AFTER bits set. Values accessed by BEFORE triggers are only +** included in the returned mask if the TRIGGER_BEFORE bit is set in the +** tr_tm parameter. Similarly, values accessed by AFTER triggers are only +** included in the returned mask if the TRIGGER_AFTER bit is set in tr_tm. +*/ +SQLITE_PRIVATE u32 sqlite3TriggerColmask( + Parse *pParse, /* Parse context */ + Trigger *pTrigger, /* List of triggers on table pTab */ + ExprList *pChanges, /* Changes list for any UPDATE OF triggers */ + int isNew, /* 1 for new.* ref mask, 0 for old.* ref mask */ + int tr_tm, /* Mask of TRIGGER_BEFORE|TRIGGER_AFTER */ + Table *pTab, /* The table to code triggers from */ + int orconf /* Default ON CONFLICT policy for trigger steps */ +){ + const int op = pChanges ? TK_UPDATE : TK_DELETE; + u32 mask = 0; + Trigger *p; + + assert( isNew==1 || isNew==0 ); + for(p=pTrigger; p; p=p->pNext){ + if( p->op==op && (tr_tm&p->tr_tm) + && checkColumnOverlap(p->pColumns,pChanges) + ){ + TriggerPrg *pPrg; + pPrg = getRowTrigger(pParse, p, pTab, orconf); + if( pPrg ){ + mask |= pPrg->aColmask[isNew]; + } + } + } + + return mask; +} + +#endif /* !defined(SQLITE_OMIT_TRIGGER) */ + +/************** End of trigger.c *********************************************/ +/************** Begin file update.c ******************************************/ +/* +** 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. +** +************************************************************************* +** This file contains C code routines that are called by the parser +** to handle UPDATE statements. +*/ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Forward declaration */ +static void updateVirtualTable( + Parse *pParse, /* The parsing context */ + SrcList *pSrc, /* The virtual table to be modified */ + Table *pTab, /* The virtual table */ + ExprList *pChanges, /* The columns to change in the UPDATE statement */ + Expr *pRowidExpr, /* Expression used to recompute the rowid */ + int *aXRef, /* Mapping from columns of pTab to entries in pChanges */ + Expr *pWhere, /* WHERE clause of the UPDATE statement */ + int onError /* ON CONFLICT strategy */ +); +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +/* +** The most recently coded instruction was an OP_Column to retrieve the +** i-th column of table pTab. This routine sets the P4 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 P4 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 P4 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 P4 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. +** +** If parameter iReg is not negative, code an OP_RealAffinity instruction +** on register iReg. This is used when an equivalent integer value is +** stored in place of an 8-byte floating point value in order to save +** space. +*/ +SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ + assert( pTab!=0 ); + if( !pTab->pSelect ){ + sqlite3_value *pValue = 0; + u8 enc = ENC(sqlite3VdbeDb(v)); + Column *pCol = &pTab->aCol[i]; + VdbeComment((v, "%s.%s", pTab->zName, pCol->zName)); + assert( inCol ); + sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, + pCol->affinity, &pValue); + if( pValue ){ + sqlite3VdbeChangeP4(v, -1, (const char *)pValue, P4_MEM); + } +#ifndef SQLITE_OMIT_FLOATING_POINT + if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); + } +#endif + } +} + +/* +** 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 +*/ +SQLITE_PRIVATE void sqlite3Update( + Parse *pParse, /* The parser context */ + SrcList *pTabList, /* The table in which we should change things */ + ExprList *pChanges, /* Things to be changed */ + Expr *pWhere, /* The WHERE clause. May be null */ + int onError /* How to handle constraint errors */ +){ + int i, j; /* Loop counters */ + Table *pTab; /* The table to be updated */ + int addrTop = 0; /* VDBE instruction address of the start of the loop */ + WhereInfo *pWInfo; /* Information about the WHERE clause */ + Vdbe *v; /* The virtual database engine */ + Index *pIdx; /* For looping over indices */ + Index *pPk; /* The PRIMARY KEY index for WITHOUT ROWID tables */ + int nIdx; /* Number of indices that need updating */ + int iBaseCur; /* Base cursor number */ + int iDataCur; /* Cursor for the canonical data btree */ + int iIdxCur; /* Cursor for the first index */ + sqlite3 *db; /* The database structure */ + int *aRegIdx = 0; /* One register assigned to each index to be updated */ + 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. */ + u8 *aToOpen; /* 1 for tables and indices to be opened */ + u8 chngPk; /* PRIMARY KEY changed in a WITHOUT ROWID table */ + u8 chngRowid; /* Rowid changed in a normal table */ + u8 chngKey; /* Either chngPk or chngRowid */ + Expr *pRowidExpr = 0; /* Expression defining the new record number */ + AuthContext sContext; /* The authorization context */ + NameContext sNC; /* The name-context to resolve expressions in */ + int iDb; /* Database containing the table being updated */ + int okOnePass; /* True for one-pass algorithm without the FIFO */ + int hasFK; /* True if foreign key processing is required */ + int labelBreak; /* Jump here to break out of UPDATE loop */ + int labelContinue; /* Jump here to continue next step of UPDATE loop */ + +#ifndef SQLITE_OMIT_TRIGGER + int isView; /* True when updating a view (INSTEAD OF trigger) */ + Trigger *pTrigger; /* List of triggers on pTab, if required */ + int tmask; /* Mask of TRIGGER_BEFORE|TRIGGER_AFTER */ +#endif + int newmask; /* Mask of NEW.* columns accessed by BEFORE triggers */ + int iEph = 0; /* Ephemeral table holding all primary key values */ + int nKey = 0; /* Number of elements in regKey for WITHOUT ROWID */ + int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */ + + /* Register Allocations */ + int regRowCount = 0; /* A count of rows changed */ + int regOldRowid; /* The old rowid */ + int regNewRowid; /* The new rowid */ + int regNew; /* Content of the NEW.* table in triggers */ + int regOld = 0; /* Content of OLD.* table in triggers */ + int regRowSet = 0; /* Rowset of rows to be updated */ + int regKey = 0; /* composite PRIMARY KEY value */ + + memset(&sContext, 0, sizeof(sContext)); + db = pParse->db; + if( pParse->nErr || db->mallocFailed ){ + goto update_cleanup; + } + 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 + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges, &tmask); + isView = pTab->pSelect!=0; + assert( pTrigger || tmask==0 ); +#else +# define pTrigger 0 +# define isView 0 +# define tmask 0 +#endif +#ifdef SQLITE_OMIT_VIEW +# undef isView +# define isView 0 +#endif + + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto update_cleanup; + } + if( sqlite3IsReadOnly(pParse, pTab, tmask) ){ + goto update_cleanup; + } + + /* Allocate a cursors for the main database table and for all indices. + ** The index cursors might not be used, but if they are used they + ** need to occur right after the database cursor. So go ahead and + ** allocate enough space, just in case. + */ + pTabList->a[0].iCursor = iBaseCur = iDataCur = pParse->nTab++; + iIdxCur = iDataCur+1; + pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); + for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ + if( IsPrimaryKeyIndex(pIdx) && pPk!=0 ){ + iDataCur = pParse->nTab; + pTabList->a[0].iCursor = iDataCur; + } + pParse->nTab++; + } + + /* Allocate space for aXRef[], aRegIdx[], and aToOpen[]. + ** Initialize aXRef[] and aToOpen[] to their default values. + */ + aXRef = sqlite3DbMallocRaw(db, sizeof(int) * (pTab->nCol+nIdx) + nIdx+2 ); + if( aXRef==0 ) goto update_cleanup; + aRegIdx = aXRef+pTab->nCol; + aToOpen = (u8*)(aRegIdx+nIdx); + memset(aToOpen, 1, nIdx+1); + aToOpen[nIdx+1] = 0; + for(i=0; inCol; i++) aXRef[i] = -1; + + /* Initialize the name-context */ + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + sNC.pSrcList = pTabList; + + /* 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 = chngPk = 0; + for(i=0; inExpr; i++){ + if( sqlite3ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){ + goto update_cleanup; + } + for(j=0; jnCol; j++){ + if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){ + if( j==pTab->iPKey ){ + chngRowid = 1; + pRowidExpr = pChanges->a[i].pExpr; + }else if( pPk && (pTab->aCol[j].colFlags & COLFLAG_PRIMKEY)!=0 ){ + chngPk = 1; + } + aXRef[j] = i; + break; + } + } + if( j>=pTab->nCol ){ + if( pPk==0 && sqlite3IsRowid(pChanges->a[i].zName) ){ + j = -1; + chngRowid = 1; + pRowidExpr = pChanges->a[i].pExpr; + }else{ + sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName); + pParse->checkSchema = 1; + goto update_cleanup; + } + } +#ifndef SQLITE_OMIT_AUTHORIZATION + { + int rc; + rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName, + j<0 ? "ROWID" : pTab->aCol[j].zName, + db->aDb[iDb].zName); + if( rc==SQLITE_DENY ){ + goto update_cleanup; + }else if( rc==SQLITE_IGNORE ){ + aXRef[j] = -1; + } + } +#endif + } + assert( (chngRowid & chngPk)==0 ); + assert( chngRowid==0 || chngRowid==1 ); + assert( chngPk==0 || chngPk==1 ); + chngKey = chngRowid + chngPk; + + /* The SET expressions are not actually used inside the WHERE loop. + ** So reset the colUsed mask + */ + pTabList->a[0].colUsed = 0; + + hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey); + + /* There is one entry in the aRegIdx[] array for each index on the table + ** being updated. Fill in aRegIdx[] with a register number that will hold + ** the key for accessing each index. + */ + for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ + int reg; + if( chngKey || hasFK || pIdx->pPartIdxWhere || pIdx==pPk ){ + reg = ++pParse->nMem; + }else{ + reg = 0; + for(i=0; inKeyCol; i++){ + if( aXRef[pIdx->aiColumn[i]]>=0 ){ + reg = ++pParse->nMem; + break; + } + } + } + if( reg==0 ) aToOpen[j+1] = 0; + aRegIdx[j] = reg; + } + + /* Begin generating code. */ + v = sqlite3GetVdbe(pParse); + if( v==0 ) goto update_cleanup; + if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); + sqlite3BeginWriteOperation(pParse, 1, iDb); + +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* Virtual tables must be handled separately */ + if( IsVirtual(pTab) ){ + updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef, + pWhere, onError); + pWhere = 0; + pTabList = 0; + goto update_cleanup; + } +#endif + + /* Allocate required registers. */ + regRowSet = ++pParse->nMem; + regOldRowid = regNewRowid = ++pParse->nMem; + if( chngPk || pTrigger || hasFK ){ + regOld = pParse->nMem + 1; + pParse->nMem += pTab->nCol; + } + if( chngKey || pTrigger || hasFK ){ + regNewRowid = ++pParse->nMem; + } + regNew = pParse->nMem + 1; + pParse->nMem += pTab->nCol; + + /* Start the view context. */ + if( isView ){ + sqlite3AuthContextPush(pParse, &sContext, pTab->zName); + } + + /* If we are trying to update a view, realize that view into + ** an ephemeral table. + */ +#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) + if( isView ){ + sqlite3MaterializeView(pParse, pTab, pWhere, iDataCur); + } +#endif + + /* Resolve the column names in all the expressions in the + ** WHERE clause. + */ + if( sqlite3ResolveExprNames(&sNC, pWhere) ){ + goto update_cleanup; + } + + /* Begin the database scan + */ + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid); + pWInfo = sqlite3WhereBegin( + pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED, iIdxCur + ); + if( pWInfo==0 ) goto update_cleanup; + okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); + + /* Remember the rowid of every item to be updated. + */ + sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid); + if( !okOnePass ){ + sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid); + } + + /* End the database scan loop. + */ + sqlite3WhereEnd(pWInfo); + }else{ + int iPk; /* First of nPk memory cells holding PRIMARY KEY value */ + i16 nPk; /* Number of components of the PRIMARY KEY */ + int addrOpen; /* Address of the OpenEphemeral instruction */ + + assert( pPk!=0 ); + nPk = pPk->nKeyCol; + iPk = pParse->nMem+1; + pParse->nMem += nPk; + regKey = ++pParse->nMem; + iEph = pParse->nTab++; + sqlite3VdbeAddOp2(v, OP_Null, 0, iPk); + addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk); + sqlite3VdbeSetP4KeyInfo(pParse, pPk); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, + WHERE_ONEPASS_DESIRED, iIdxCur); + if( pWInfo==0 ) goto update_cleanup; + okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); + for(i=0; iaiColumn[i], + iPk+i); + } + if( okOnePass ){ + sqlite3VdbeChangeToNoop(v, addrOpen); + nKey = nPk; + regKey = iPk; + }else{ + sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey, + sqlite3IndexAffinityStr(v, pPk), nPk); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, regKey); + } + sqlite3WhereEnd(pWInfo); + } + + /* Initialize the count of updated rows + */ + if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){ + regRowCount = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); + } + + labelBreak = sqlite3VdbeMakeLabel(v); + 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. + */ + if( onError==OE_Replace ){ + memset(aToOpen, 1, nIdx+1); + }else{ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->onError==OE_Replace ){ + memset(aToOpen, 1, nIdx+1); + break; + } + } + } + if( okOnePass ){ + if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0; + if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0; + } + sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iBaseCur, aToOpen, + 0, 0); + } + + /* Top of the update loop */ + if( okOnePass ){ + if( aToOpen[iDataCur-iBaseCur] && !isView ){ + assert( pPk ); + sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey); + VdbeCoverageNeverTaken(v); + } + labelContinue = labelBreak; + sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak); + VdbeCoverageIf(v, pPk==0); + VdbeCoverageIf(v, pPk!=0); + }else if( pPk ){ + labelContinue = sqlite3VdbeMakeLabel(v); + sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v); + addrTop = sqlite3VdbeAddOp2(v, OP_RowKey, iEph, regKey); + sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0); + VdbeCoverage(v); + }else{ + labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, labelBreak, + regOldRowid); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid); + VdbeCoverage(v); + } + + /* If the record number will change, set register regNewRowid to + ** contain the new value. If the record number is not being modified, + ** then regNewRowid is the same register as regOldRowid, which is + ** already populated. */ + assert( chngKey || pTrigger || hasFK || regOldRowid==regNewRowid ); + if( chngRowid ){ + sqlite3ExprCode(pParse, pRowidExpr, regNewRowid); + sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid); VdbeCoverage(v); + } + + /* Compute the old pre-UPDATE content of the row being changed, if that + ** information is needed */ + if( chngPk || hasFK || pTrigger ){ + u32 oldmask = (hasFK ? sqlite3FkOldmask(pParse, pTab) : 0); + oldmask |= sqlite3TriggerColmask(pParse, + pTrigger, pChanges, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onError + ); + for(i=0; inCol; i++){ + if( oldmask==0xffffffff + || (i<32 && (oldmask & MASKBIT32(i))!=0) + || (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0 + ){ + testcase( oldmask!=0xffffffff && i==31 ); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regOld+i); + }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, regOld+i); + } + } + if( chngRowid==0 && pPk==0 ){ + sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid); + } + } + + /* Populate the array of registers beginning at regNew with the new + ** row data. This array is used to check constants, create the new + ** table and index records, and as the values for any new.* references + ** made by triggers. + ** + ** If there are one or more BEFORE triggers, then do not populate the + ** registers associated with columns that are (a) not modified by + ** this UPDATE statement and (b) not accessed by new.* references. The + ** values for registers not modified by the UPDATE must be reloaded from + ** the database after the BEFORE triggers are fired anyway (as the trigger + ** may have modified them). So not loading those that are not going to + ** be used eliminates some redundant opcodes. + */ + newmask = sqlite3TriggerColmask( + pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError + ); + /*sqlite3VdbeAddOp3(v, OP_Null, 0, regNew, regNew+pTab->nCol-1);*/ + for(i=0; inCol; i++){ + if( i==pTab->iPKey ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i); + }else{ + j = aXRef[i]; + if( j>=0 ){ + sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i); + }else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask & MASKBIT32(i)) ){ + /* This branch loads the value of a column that will not be changed + ** into a register. This is done if there are no BEFORE triggers, or + ** if there are one or more BEFORE triggers that use this value via + ** a new.* reference in a trigger program. + */ + testcase( i==31 ); + testcase( i==32 ); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i); + }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i); + } + } + } + + /* Fire any BEFORE UPDATE triggers. This happens before constraints are + ** verified. One could argue that this is wrong. + */ + if( tmask&TRIGGER_BEFORE ){ + sqlite3TableAffinity(v, pTab, regNew); + sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, + TRIGGER_BEFORE, pTab, regOldRowid, onError, labelContinue); + + /* The row-trigger may have deleted the row being updated. In this + ** case, jump to the next row. No updates or AFTER triggers are + ** required. This behavior - what happens when the row being updated + ** is deleted or renamed by a BEFORE trigger - is left undefined in the + ** documentation. + */ + if( pPk ){ + sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue,regKey,nKey); + VdbeCoverage(v); + }else{ + sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid); + VdbeCoverage(v); + } + + /* If it did not delete it, the row-trigger may still have modified + ** some of the columns of the row being updated. Load the values for + ** all columns not modified by the update statement into their + ** registers in case this has happened. + */ + for(i=0; inCol; i++){ + if( aXRef[i]<0 && i!=pTab->iPKey ){ + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i); + } + } + } + + if( !isView ){ + int j1 = 0; /* Address of jump instruction */ + int bReplace = 0; /* True if REPLACE conflict resolution might happen */ + + /* Do constraint checks. */ + assert( regOldRowid>0 ); + sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, + regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace); + + /* Do FK constraint checks. */ + if( hasFK ){ + sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngKey); + } + + /* Delete the index entries associated with the current record. */ + if( bReplace || chngKey ){ + if( pPk ){ + j1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, 0, regKey, nKey); + }else{ + j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid); + } + VdbeCoverageNeverTaken(v); + } + sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx); + + /* If changing the record number, delete the old record. */ + if( hasFK || chngKey || pPk!=0 ){ + sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0); + } + if( bReplace || chngKey ){ + sqlite3VdbeJumpHere(v, j1); + } + + if( hasFK ){ + sqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngKey); + } + + /* Insert the new index entries and the new record. */ + sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur, + regNewRowid, aRegIdx, 1, 0, 0); + + /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to + ** handle rows (possibly in other tables) that refer via a foreign key + ** to the row just updated. */ + if( hasFK ){ + sqlite3FkActions(pParse, pTab, pChanges, regOldRowid, aXRef, chngKey); + } + } + + /* Increment the row counter + */ + if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab){ + sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); + } + + sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, + TRIGGER_AFTER, pTab, regOldRowid, onError, labelContinue); + + /* Repeat the above with the next record to be updated, until + ** all record selected by the WHERE clause have been updated. + */ + if( okOnePass ){ + /* Nothing to do at end-of-loop for a single-pass */ + }else if( pPk ){ + sqlite3VdbeResolveLabel(v, labelContinue); + sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop); VdbeCoverage(v); + }else{ + sqlite3VdbeAddOp2(v, OP_Goto, 0, labelContinue); + } + sqlite3VdbeResolveLabel(v, labelBreak); + + /* Close all tables */ + for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ + assert( aRegIdx ); + if( aToOpen[i+1] ){ + sqlite3VdbeAddOp2(v, OP_Close, iIdxCur+i, 0); + } + } + if( iDataCurnested==0 && pParse->pTriggerTab==0 ){ + sqlite3AutoincrementEnd(pParse); + } + + /* + ** Return the number of rows that were changed. If this routine is + ** generating code because of a call to sqlite3NestedParse(), do not + ** invoke the callback function. + */ + if( (db->flags&SQLITE_CountRows) && !pParse->pTriggerTab && !pParse->nested ){ + sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC); + } + +update_cleanup: + sqlite3AuthContextPop(&sContext); + sqlite3DbFree(db, aXRef); /* Also frees aRegIdx[] and aToOpen[] */ + sqlite3SrcListDelete(db, pTabList); + sqlite3ExprListDelete(db, pChanges); + sqlite3ExprDelete(db, pWhere); + return; +} +/* Make sure "isView" and other macros defined above are undefined. Otherwise +** they may interfere with compilation of other functions in this file +** (or in another file, if this file becomes part of the amalgamation). */ +#ifdef isView + #undef isView +#endif +#ifdef pTrigger + #undef pTrigger +#endif + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Generate code for an UPDATE of a virtual table. +** +** The strategy is that we create an ephemeral table that contains +** for each row to be changed: +** +** (A) The original rowid of that row. +** (B) The revised rowid for the row. (note1) +** (C) The content of every column in the row. +** +** Then we loop over this ephemeral table and for each row in +** the ephemeral table call VUpdate. +** +** When finished, drop the ephemeral table. +** +** (note1) Actually, if we know in advance that (A) is always the same +** as (B) we only store (A), then duplicate (A) when pulling +** it out of the ephemeral table before calling VUpdate. +*/ +static void updateVirtualTable( + Parse *pParse, /* The parsing context */ + SrcList *pSrc, /* The virtual table to be modified */ + Table *pTab, /* The virtual table */ + ExprList *pChanges, /* The columns to change in the UPDATE statement */ + Expr *pRowid, /* Expression used to recompute the rowid */ + int *aXRef, /* Mapping from columns of pTab to entries in pChanges */ + Expr *pWhere, /* WHERE clause of the UPDATE statement */ + int onError /* ON CONFLICT strategy */ +){ + Vdbe *v = pParse->pVdbe; /* Virtual machine under construction */ + ExprList *pEList = 0; /* The result set of the SELECT statement */ + Select *pSelect = 0; /* The SELECT statement */ + Expr *pExpr; /* Temporary expression */ + int ephemTab; /* Table holding the result of the SELECT */ + int i; /* Loop counter */ + int addr; /* Address of top of loop */ + int iReg; /* First register in set passed to OP_VUpdate */ + sqlite3 *db = pParse->db; /* Database connection */ + const char *pVTab = (const char*)sqlite3GetVTable(db, pTab); + SelectDest dest; + + /* Construct the SELECT statement that will find the new values for + ** all updated rows. + */ + pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, "_rowid_")); + if( pRowid ){ + pEList = sqlite3ExprListAppend(pParse, pEList, + sqlite3ExprDup(db, pRowid, 0)); + } + assert( pTab->iPKey<0 ); + for(i=0; inCol; i++){ + if( aXRef[i]>=0 ){ + pExpr = sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr, 0); + }else{ + pExpr = sqlite3Expr(db, TK_ID, pTab->aCol[i].zName); + } + pEList = sqlite3ExprListAppend(pParse, pEList, pExpr); + } + pSelect = sqlite3SelectNew(pParse, pEList, pSrc, pWhere, 0, 0, 0, 0, 0, 0); + + /* Create the ephemeral table into which the update results will + ** be stored. + */ + assert( v ); + ephemTab = pParse->nTab++; + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, pTab->nCol+1+(pRowid!=0)); + sqlite3VdbeChangeP5(v, BTREE_UNORDERED); + + /* fill the ephemeral table + */ + sqlite3SelectDestInit(&dest, SRT_Table, ephemTab); + sqlite3Select(pParse, pSelect, &dest); + + /* Generate code to scan the ephemeral table and call VUpdate. */ + iReg = ++pParse->nMem; + pParse->nMem += pTab->nCol+1; + addr = sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_Column, ephemTab, 0, iReg); + sqlite3VdbeAddOp3(v, OP_Column, ephemTab, (pRowid?1:0), iReg+1); + for(i=0; inCol; i++){ + sqlite3VdbeAddOp3(v, OP_Column, ephemTab, i+1+(pRowid!=0), iReg+2+i); + } + sqlite3VtabMakeWritable(pParse, pTab); + sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, iReg, pVTab, P4_VTAB); + sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError); + sqlite3MayAbort(pParse); + sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr); + sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0); + + /* Cleanup */ + sqlite3SelectDelete(db, pSelect); +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +/************** End of update.c **********************************************/ +/************** Begin file vacuum.c ******************************************/ +/* +** 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 VACUUM command. +** +** Most of the code in this file may be omitted by defining the +** SQLITE_OMIT_VACUUM macro. +*/ + +#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) +/* +** Finalize a prepared statement. If there was an error, store the +** text of the error message in *pzErrMsg. Return the result code. +*/ +static int vacuumFinalize(sqlite3 *db, sqlite3_stmt *pStmt, char **pzErrMsg){ + int rc; + rc = sqlite3VdbeFinalize((Vdbe*)pStmt); + if( rc ){ + sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db)); + } + return rc; +} + +/* +** Execute zSql on database db. Return an error code. +*/ +static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){ + sqlite3_stmt *pStmt; + VVA_ONLY( int rc; ) + if( !zSql ){ + return SQLITE_NOMEM; + } + if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){ + sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db)); + return sqlite3_errcode(db); + } + VVA_ONLY( rc = ) sqlite3_step(pStmt); + assert( rc!=SQLITE_ROW || (db->flags&SQLITE_CountRows) ); + return vacuumFinalize(db, pStmt, pzErrMsg); +} + +/* +** Execute zSql on database db. The statement returns exactly +** one column. Execute this as SQL on the same database. +*/ +static int execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){ + 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, pzErrMsg, (char*)sqlite3_column_text(pStmt, 0)); + if( rc!=SQLITE_OK ){ + vacuumFinalize(db, pStmt, pzErrMsg); + return rc; + } + } + + return vacuumFinalize(db, pStmt, pzErrMsg); +} + +/* +** The VACUUM command is used to clean up the database, +** collapse free space, etc. It is modelled after the VACUUM command +** in PostgreSQL. The VACUUM command works as follows: +** +** (1) Create a new transient database file +** (2) Copy all content from the database being vacuumed into +** the new transient database file +** (3) Copy content from the transient database back into the +** original database. +** +** The transient database requires temporary disk space approximately +** equal to the size of the original database. The copy operation of +** step (3) requires additional temporary disk space approximately equal +** to the size of the original database for the rollback journal. +** Hence, temporary disk space that is approximately 2x the size of the +** original database is required. Every page of the database is written +** approximately 3 times: Once for step (2) and twice for step (3). +** Two writes per page are required in step (3) because the original +** database content must be written into the rollback journal prior to +** overwriting the database with the vacuumed content. +** +** Only 1x temporary space and only 1x writes would be required if +** the copy of step (3) were replaced by deleting the original database +** and renaming the transient database as the original. But that will +** not work if other processes are attached to the original database. +** And a power loss in between deleting the original and renaming the +** transient would cause the database file to appear to be deleted +** following reboot. +*/ +SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse){ + Vdbe *v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3VdbeAddOp2(v, OP_Vacuum, 0, 0); + sqlite3VdbeUsesBtree(v, 0); + } + return; +} + +/* +** This routine implements the OP_Vacuum opcode of the VDBE. +*/ +SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ + int rc = SQLITE_OK; /* Return code from service routines */ + Btree *pMain; /* The database being vacuumed */ + Btree *pTemp; /* The temporary database we vacuum into */ + char *zSql = 0; /* SQL statements */ + int saved_flags; /* Saved value of the db->flags */ + int saved_nChange; /* Saved value of db->nChange */ + int saved_nTotalChange; /* Saved value of db->nTotalChange */ + void (*saved_xTrace)(void*,const char*); /* Saved db->xTrace */ + Db *pDb = 0; /* Database to detach at end of vacuum */ + int isMemDb; /* True if vacuuming a :memory: database */ + int nRes; /* Bytes of reserved space at the end of each page */ + int nDb; /* Number of attached databases */ + + if( !db->autoCommit ){ + sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); + return SQLITE_ERROR; + } + if( db->nVdbeActive>1 ){ + sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress"); + return SQLITE_ERROR; + } + + /* Save the current value of the database flags so that it can be + ** restored before returning. Then set the writable-schema flag, and + ** disable CHECK and foreign key constraints. */ + saved_flags = db->flags; + saved_nChange = db->nChange; + saved_nTotalChange = db->nTotalChange; + saved_xTrace = db->xTrace; + db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin; + db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder); + db->xTrace = 0; + + pMain = db->aDb[0].pBt; + isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain)); + + /* Attach the temporary database as 'vacuum_db'. The synchronous pragma + ** can be set to 'off' for this file, as it is not recovered if a crash + ** occurs anyway. The integrity of the database is maintained by a + ** (possibly synchronous) transaction opened on the main database before + ** sqlite3BtreeCopyFile() is called. + ** + ** An optimisation would be to use a non-journaled pager. + ** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but + ** that actually made the VACUUM run slower. Very little journalling + ** actually occurs when doing a vacuum since the vacuum_db is initially + ** empty. Only the journal header is written. Apparently it takes more + ** time to parse and run the PRAGMA to turn journalling off than it does + ** to write the journal header file. + */ + nDb = db->nDb; + if( sqlite3TempInMemory(db) ){ + zSql = "ATTACH ':memory:' AS vacuum_db;"; + }else{ + zSql = "ATTACH '' AS vacuum_db;"; + } + rc = execSql(db, pzErrMsg, zSql); + if( db->nDb>nDb ){ + pDb = &db->aDb[db->nDb-1]; + assert( strcmp(pDb->zName,"vacuum_db")==0 ); + } + if( rc!=SQLITE_OK ) goto end_of_vacuum; + pTemp = db->aDb[db->nDb-1].pBt; + + /* The call to execSql() to attach the temp database has left the file + ** locked (as there was more than one active statement when the transaction + ** to read the schema was concluded. Unlock it here so that this doesn't + ** cause problems for the call to BtreeSetPageSize() below. */ + sqlite3BtreeCommit(pTemp); + + nRes = sqlite3BtreeGetOptimalReserve(pMain); + + /* A VACUUM cannot change the pagesize of an encrypted database. */ +#ifdef SQLITE_HAS_CODEC + if( db->nextPagesize ){ + extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*); + int nKey; + char *zKey; + sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); + if( nKey ) db->nextPagesize = 0; + } +#endif + + rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF"); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + + /* Begin a transaction and take an exclusive lock on the main database + ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below, + ** to ensure that we do not try to change the page-size on a WAL database. + */ + rc = execSql(db, pzErrMsg, "BEGIN;"); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + rc = sqlite3BtreeBeginTrans(pMain, 2); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + + /* Do not attempt to change the page size for a WAL database */ + if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain)) + ==PAGER_JOURNALMODE_WAL ){ + db->nextPagesize = 0; + } + + if( sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), nRes, 0) + || (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0)) + || NEVER(db->mallocFailed) + ){ + rc = SQLITE_NOMEM; + goto end_of_vacuum; + } + +#ifndef SQLITE_OMIT_AUTOVACUUM + sqlite3BtreeSetAutoVacuum(pTemp, db->nextAutovac>=0 ? db->nextAutovac : + sqlite3BtreeGetAutoVacuum(pMain)); +#endif + + /* Query the schema of the main database. Create a mirror schema + ** in the temporary database. + */ + rc = execExecSql(db, pzErrMsg, + "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14) " + " FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'" + " AND coalesce(rootpage,1)>0" + ); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + rc = execExecSql(db, pzErrMsg, + "SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14)" + " FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %' "); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + rc = execExecSql(db, pzErrMsg, + "SELECT 'CREATE UNIQUE INDEX vacuum_db.' || substr(sql,21) " + " FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'"); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + + /* Loop through the tables in the main database. For each, do + ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy + ** the contents to the temporary database. + */ + assert( (db->flags & SQLITE_Vacuum)==0 ); + db->flags |= SQLITE_Vacuum; + rc = execExecSql(db, pzErrMsg, + "SELECT 'INSERT INTO vacuum_db.' || quote(name) " + "|| ' SELECT * FROM main.' || quote(name) || ';'" + "FROM main.sqlite_master " + "WHERE type = 'table' AND name!='sqlite_sequence' " + " AND coalesce(rootpage,1)>0" + ); + assert( (db->flags & SQLITE_Vacuum)!=0 ); + db->flags &= ~SQLITE_Vacuum; + if( rc!=SQLITE_OK ) goto end_of_vacuum; + + /* Copy over the sequence table + */ + rc = execExecSql(db, pzErrMsg, + "SELECT 'DELETE FROM vacuum_db.' || quote(name) || ';' " + "FROM vacuum_db.sqlite_master WHERE name='sqlite_sequence' " + ); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + rc = execExecSql(db, pzErrMsg, + "SELECT 'INSERT INTO vacuum_db.' || quote(name) " + "|| ' SELECT * FROM main.' || quote(name) || ';' " + "FROM vacuum_db.sqlite_master WHERE name=='sqlite_sequence';" + ); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + + + /* Copy the triggers, views, and virtual tables from the main database + ** over to the temporary database. None of these objects has any + ** associated storage, so all we have to do is copy their entries + ** from the SQLITE_MASTER table. + */ + rc = execSql(db, pzErrMsg, + "INSERT INTO vacuum_db.sqlite_master " + " SELECT type, name, tbl_name, rootpage, sql" + " FROM main.sqlite_master" + " WHERE type='view' OR type='trigger'" + " OR (type='table' AND rootpage=0)" + ); + if( rc ) goto end_of_vacuum; + + /* At this point, there is a write transaction open on both the + ** vacuum database and the main database. Assuming no error occurs, + ** both transactions are closed by this block - the main database + ** transaction by sqlite3BtreeCopyFile() and the other by an explicit + ** call to sqlite3BtreeCommit(). + */ + { + 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[] = { + BTREE_SCHEMA_VERSION, 1, /* Add one to the old schema cookie */ + BTREE_DEFAULT_CACHE_SIZE, 0, /* Preserve the default page cache size */ + BTREE_TEXT_ENCODING, 0, /* Preserve the text encoding */ + BTREE_USER_VERSION, 0, /* Preserve the user version */ + BTREE_APPLICATION_ID, 0, /* Preserve the application id */ + }; + + assert( 1==sqlite3BtreeIsInTrans(pTemp) ); + assert( 1==sqlite3BtreeIsInTrans(pMain) ); + + /* Copy Btree meta values */ + for(i=0; iflags */ + db->flags = saved_flags; + db->nChange = saved_nChange; + db->nTotalChange = saved_nTotalChange; + db->xTrace = saved_xTrace; + sqlite3BtreeSetPageSize(pMain, -1, -1, 1); + + /* 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 ){ + sqlite3BtreeClose(pDb->pBt); + pDb->pBt = 0; + pDb->pSchema = 0; + } + + /* This both clears the schemas and reduces the size of the db->aDb[] + ** array. */ + sqlite3ResetAllSchemasOfConnection(db); + + return rc; +} + +#endif /* SQLITE_OMIT_VACUUM && SQLITE_OMIT_ATTACH */ + +/************** End of vacuum.c **********************************************/ +/************** Begin file vtab.c ********************************************/ +/* +** 2006 June 10 +** +** 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 help implement virtual tables. +*/ +#ifndef SQLITE_OMIT_VIRTUALTABLE + +/* +** Before a virtual table xCreate() or xConnect() method is invoked, the +** sqlite3.pVtabCtx member variable is set to point to an instance of +** this struct allocated on the stack. It is used by the implementation of +** the sqlite3_declare_vtab() and sqlite3_vtab_config() APIs, both of which +** are invoked only from within xCreate and xConnect methods. +*/ +struct VtabCtx { + VTable *pVTable; /* The virtual table being constructed */ + Table *pTab; /* The Table object to which the virtual table belongs */ + VtabCtx *pPrior; /* Parent context (if any) */ + int bDeclared; /* True after sqlite3_declare_vtab() is called */ +}; + +/* +** The actual function that does the work of creating a new module. +** This function implements the sqlite3_create_module() and +** sqlite3_create_module_v2() interfaces. +*/ +static int createModule( + sqlite3 *db, /* Database in which module is registered */ + const char *zName, /* Name assigned to this module */ + const sqlite3_module *pModule, /* The definition of the module */ + void *pAux, /* Context pointer for xCreate/xConnect */ + void (*xDestroy)(void *) /* Module destructor function */ +){ + int rc = SQLITE_OK; + int nName; + + sqlite3_mutex_enter(db->mutex); + nName = sqlite3Strlen30(zName); + if( sqlite3HashFind(&db->aModule, zName) ){ + rc = SQLITE_MISUSE_BKPT; + }else{ + Module *pMod; + pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1); + if( pMod ){ + Module *pDel; + char *zCopy = (char *)(&pMod[1]); + memcpy(zCopy, zName, nName+1); + pMod->zName = zCopy; + pMod->pModule = pModule; + pMod->pAux = pAux; + pMod->xDestroy = xDestroy; + pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod); + assert( pDel==0 || pDel==pMod ); + if( pDel ){ + db->mallocFailed = 1; + sqlite3DbFree(db, pDel); + } + } + } + rc = sqlite3ApiExit(db, rc); + if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux); + + sqlite3_mutex_leave(db->mutex); + return rc; +} + + +/* +** External API function used to create a new virtual-table module. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_create_module( + sqlite3 *db, /* Database in which module is registered */ + const char *zName, /* Name assigned to this module */ + const sqlite3_module *pModule, /* The definition of the module */ + void *pAux /* Context pointer for xCreate/xConnect */ +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; +#endif + return createModule(db, zName, pModule, pAux, 0); +} + +/* +** External API function used to create a new virtual-table module. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_create_module_v2( + sqlite3 *db, /* Database in which module is registered */ + const char *zName, /* Name assigned to this module */ + const sqlite3_module *pModule, /* The definition of the module */ + void *pAux, /* Context pointer for xCreate/xConnect */ + void (*xDestroy)(void *) /* Module destructor function */ +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; +#endif + return createModule(db, zName, pModule, pAux, xDestroy); +} + +/* +** Lock the virtual table so that it cannot be disconnected. +** Locks nest. Every lock should have a corresponding unlock. +** If an unlock is omitted, resources leaks will occur. +** +** If a disconnect is attempted while a virtual table is locked, +** the disconnect is deferred until all locks have been removed. +*/ +SQLITE_PRIVATE void sqlite3VtabLock(VTable *pVTab){ + pVTab->nRef++; +} + + +/* +** pTab is a pointer to a Table structure representing a virtual-table. +** Return a pointer to the VTable object used by connection db to access +** this virtual-table, if one has been created, or NULL otherwise. +*/ +SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3 *db, Table *pTab){ + VTable *pVtab; + assert( IsVirtual(pTab) ); + for(pVtab=pTab->pVTable; pVtab && pVtab->db!=db; pVtab=pVtab->pNext); + return pVtab; +} + +/* +** Decrement the ref-count on a virtual table object. When the ref-count +** reaches zero, call the xDisconnect() method to delete the object. +*/ +SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *pVTab){ + sqlite3 *db = pVTab->db; + + assert( db ); + assert( pVTab->nRef>0 ); + assert( db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_ZOMBIE ); + + pVTab->nRef--; + if( pVTab->nRef==0 ){ + sqlite3_vtab *p = pVTab->pVtab; + if( p ){ + p->pModule->xDisconnect(p); + } + sqlite3DbFree(db, pVTab); + } +} + +/* +** Table p is a virtual table. This function moves all elements in the +** p->pVTable list to the sqlite3.pDisconnect lists of their associated +** database connections to be disconnected at the next opportunity. +** Except, if argument db is not NULL, then the entry associated with +** connection db is left in the p->pVTable list. +*/ +static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){ + VTable *pRet = 0; + VTable *pVTable = p->pVTable; + p->pVTable = 0; + + /* Assert that the mutex (if any) associated with the BtShared database + ** that contains table p is held by the caller. See header comments + ** above function sqlite3VtabUnlockList() for an explanation of why + ** this makes it safe to access the sqlite3.pDisconnect list of any + ** database connection that may have an entry in the p->pVTable list. + */ + assert( db==0 || sqlite3SchemaMutexHeld(db, 0, p->pSchema) ); + + while( pVTable ){ + sqlite3 *db2 = pVTable->db; + VTable *pNext = pVTable->pNext; + assert( db2 ); + if( db2==db ){ + pRet = pVTable; + p->pVTable = pRet; + pRet->pNext = 0; + }else{ + pVTable->pNext = db2->pDisconnect; + db2->pDisconnect = pVTable; + } + pVTable = pNext; + } + + assert( !db || pRet ); + return pRet; +} + +/* +** Table *p is a virtual table. This function removes the VTable object +** for table *p associated with database connection db from the linked +** list in p->pVTab. It also decrements the VTable ref count. This is +** used when closing database connection db to free all of its VTable +** objects without disturbing the rest of the Schema object (which may +** be being used by other shared-cache connections). +*/ +SQLITE_PRIVATE void sqlite3VtabDisconnect(sqlite3 *db, Table *p){ + VTable **ppVTab; + + assert( IsVirtual(p) ); + assert( sqlite3BtreeHoldsAllMutexes(db) ); + assert( sqlite3_mutex_held(db->mutex) ); + + for(ppVTab=&p->pVTable; *ppVTab; ppVTab=&(*ppVTab)->pNext){ + if( (*ppVTab)->db==db ){ + VTable *pVTab = *ppVTab; + *ppVTab = pVTab->pNext; + sqlite3VtabUnlock(pVTab); + break; + } + } +} + + +/* +** Disconnect all the virtual table objects in the sqlite3.pDisconnect list. +** +** This function may only be called when the mutexes associated with all +** shared b-tree databases opened using connection db are held by the +** caller. This is done to protect the sqlite3.pDisconnect list. The +** sqlite3.pDisconnect list is accessed only as follows: +** +** 1) By this function. In this case, all BtShared mutexes and the mutex +** associated with the database handle itself must be held. +** +** 2) By function vtabDisconnectAll(), when it adds a VTable entry to +** the sqlite3.pDisconnect list. In this case either the BtShared mutex +** associated with the database the virtual table is stored in is held +** or, if the virtual table is stored in a non-sharable database, then +** the database handle mutex is held. +** +** As a result, a sqlite3.pDisconnect cannot be accessed simultaneously +** by multiple threads. It is thread-safe. +*/ +SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3 *db){ + VTable *p = db->pDisconnect; + db->pDisconnect = 0; + + assert( sqlite3BtreeHoldsAllMutexes(db) ); + assert( sqlite3_mutex_held(db->mutex) ); + + if( p ){ + sqlite3ExpirePreparedStatements(db); + do { + VTable *pNext = p->pNext; + sqlite3VtabUnlock(p); + p = pNext; + }while( p ); + } +} + +/* +** Clear any and all virtual-table information from the Table record. +** This routine is called, for example, just before deleting the Table +** record. +** +** Since it is a virtual-table, the Table structure contains a pointer +** to the head of a linked list of VTable structures. Each VTable +** structure is associated with a single sqlite3* user of the schema. +** The reference count of the VTable structure associated with database +** connection db is decremented immediately (which may lead to the +** structure being xDisconnected and free). Any other VTable structures +** in the list are moved to the sqlite3.pDisconnect list of the associated +** database connection. +*/ +SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){ + if( !db || db->pnBytesFreed==0 ) vtabDisconnectAll(0, p); + if( p->azModuleArg ){ + int i; + for(i=0; inModuleArg; i++){ + if( i!=1 ) sqlite3DbFree(db, p->azModuleArg[i]); + } + sqlite3DbFree(db, p->azModuleArg); + } +} + +/* +** Add a new module argument to pTable->azModuleArg[]. +** The string is not copied - the pointer is stored. The +** string will be freed automatically when the table is +** deleted. +*/ +static void addModuleArgument(sqlite3 *db, Table *pTable, char *zArg){ + int i = pTable->nModuleArg++; + int nBytes = sizeof(char *)*(1+pTable->nModuleArg); + char **azModuleArg; + azModuleArg = sqlite3DbRealloc(db, pTable->azModuleArg, nBytes); + if( azModuleArg==0 ){ + int j; + for(j=0; jazModuleArg[j]); + } + sqlite3DbFree(db, zArg); + sqlite3DbFree(db, pTable->azModuleArg); + pTable->nModuleArg = 0; + }else{ + azModuleArg[i] = zArg; + azModuleArg[i+1] = 0; + } + pTable->azModuleArg = azModuleArg; +} + +/* +** The parser calls this routine when it first sees a CREATE VIRTUAL TABLE +** statement. The module name has been parsed, but the optional list +** of parameters that follow the module name are still pending. +*/ +SQLITE_PRIVATE void sqlite3VtabBeginParse( + Parse *pParse, /* Parsing context */ + Token *pName1, /* Name of new table, or database name */ + Token *pName2, /* Name of new table or NULL */ + Token *pModuleName, /* Name of the module for the virtual table */ + int ifNotExists /* No error if the table already exists */ +){ + int iDb; /* The database the table is being created in */ + Table *pTable; /* The new virtual table */ + sqlite3 *db; /* Database connection */ + + sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, ifNotExists); + pTable = pParse->pNewTable; + if( pTable==0 ) return; + assert( 0==pTable->pIndex ); + + db = pParse->db; + iDb = sqlite3SchemaToIndex(db, pTable->pSchema); + assert( iDb>=0 ); + + pTable->tabFlags |= TF_Virtual; + pTable->nModuleArg = 0; + addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName)); + addModuleArgument(db, pTable, 0); + addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName)); + assert( (pParse->sNameToken.z==pName2->z && pName2->z!=0) + || (pParse->sNameToken.z==pName1->z && pName2->z==0) + ); + pParse->sNameToken.n = (int)( + &pModuleName->z[pModuleName->n] - pParse->sNameToken.z + ); + +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Creating a virtual table invokes the authorization callback twice. + ** The first invocation, to obtain permission to INSERT a row into the + ** sqlite_master table, has already been made by sqlite3StartTable(). + ** The second call, to obtain permission to create the table, is made now. + */ + if( pTable->azModuleArg ){ + sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, + pTable->azModuleArg[0], pParse->db->aDb[iDb].zName); + } +#endif +} + +/* +** This routine takes the module argument that has been accumulating +** in pParse->zArg[] and appends it to the list of arguments on the +** virtual table currently under construction in pParse->pTable. +*/ +static void addArgumentToVtab(Parse *pParse){ + if( pParse->sArg.z && pParse->pNewTable ){ + const char *z = (const char*)pParse->sArg.z; + int n = pParse->sArg.n; + sqlite3 *db = pParse->db; + addModuleArgument(db, pParse->pNewTable, sqlite3DbStrNDup(db, z, n)); + } +} + +/* +** The parser calls this routine after the CREATE VIRTUAL TABLE statement +** has been completely parsed. +*/ +SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ + Table *pTab = pParse->pNewTable; /* The table being constructed */ + sqlite3 *db = pParse->db; /* The database connection */ + + if( pTab==0 ) return; + addArgumentToVtab(pParse); + pParse->sArg.z = 0; + if( pTab->nModuleArg<1 ) return; + + /* If the CREATE VIRTUAL TABLE statement is being entered for the + ** first time (in other words if the virtual table is actually being + ** created now instead of just being read out of sqlite_master) then + ** do additional initialization work and store the statement text + ** in the sqlite_master table. + */ + if( !db->init.busy ){ + char *zStmt; + char *zWhere; + int iDb; + int iReg; + Vdbe *v; + + /* Compute the complete text of the CREATE VIRTUAL TABLE statement */ + if( pEnd ){ + pParse->sNameToken.n = (int)(pEnd->z - pParse->sNameToken.z) + pEnd->n; + } + zStmt = sqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken); + + /* 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 VM register number pParse->regRowid holds the rowid of an + ** entry in the sqlite_master table tht was created for this vtab + ** by sqlite3StartTable(). + */ + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + sqlite3NestedParse(pParse, + "UPDATE %Q.%s " + "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q " + "WHERE rowid=#%d", + db->aDb[iDb].zName, SCHEMA_TABLE(iDb), + pTab->zName, + pTab->zName, + zStmt, + pParse->regRowid + ); + sqlite3DbFree(db, zStmt); + v = sqlite3GetVdbe(pParse); + sqlite3ChangeCookie(pParse, iDb); + + sqlite3VdbeAddOp2(v, OP_Expire, 0, 0); + zWhere = sqlite3MPrintf(db, "name='%q' AND type='table'", pTab->zName); + sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere); + + iReg = ++pParse->nMem; + sqlite3VdbeAddOp4(v, OP_String8, 0, iReg, 0, pTab->zName, 0); + sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg); + } + + /* If we are rereading the sqlite_master table create the in-memory + ** record of the table. The xConnect() method is not called until + ** the first time the virtual table is used in an SQL statement. This + ** allows a schema that contains virtual tables to be loaded before + ** the required virtual table implementations are registered. */ + else { + Table *pOld; + Schema *pSchema = pTab->pSchema; + const char *zName = pTab->zName; + assert( sqlite3SchemaMutexHeld(db, 0, pSchema) ); + pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab); + if( pOld ){ + db->mallocFailed = 1; + assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */ + return; + } + pParse->pNewTable = 0; + } +} + +/* +** The parser calls this routine when it sees the first token +** of an argument to the module name in a CREATE VIRTUAL TABLE statement. +*/ +SQLITE_PRIVATE void sqlite3VtabArgInit(Parse *pParse){ + addArgumentToVtab(pParse); + pParse->sArg.z = 0; + pParse->sArg.n = 0; +} + +/* +** The parser calls this routine for each token after the first token +** in an argument to the module name in a CREATE VIRTUAL TABLE statement. +*/ +SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse *pParse, Token *p){ + Token *pArg = &pParse->sArg; + if( pArg->z==0 ){ + pArg->z = p->z; + pArg->n = p->n; + }else{ + assert(pArg->z <= p->z); + pArg->n = (int)(&p->z[p->n] - pArg->z); + } +} + +/* +** Invoke a virtual table constructor (either xCreate or xConnect). The +** pointer to the function to invoke is passed as the fourth parameter +** to this procedure. +*/ +static int vtabCallConstructor( + sqlite3 *db, + Table *pTab, + Module *pMod, + int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**), + char **pzErr +){ + VtabCtx sCtx; + VTable *pVTable; + int rc; + const char *const*azArg = (const char *const*)pTab->azModuleArg; + int nArg = pTab->nModuleArg; + char *zErr = 0; + char *zModuleName; + int iDb; + VtabCtx *pCtx; + + /* Check that the virtual-table is not already being initialized */ + for(pCtx=db->pVtabCtx; pCtx; pCtx=pCtx->pPrior){ + if( pCtx->pTab==pTab ){ + *pzErr = sqlite3MPrintf(db, + "vtable constructor called recursively: %s", pTab->zName + ); + return SQLITE_LOCKED; + } + } + + zModuleName = sqlite3MPrintf(db, "%s", pTab->zName); + if( !zModuleName ){ + return SQLITE_NOMEM; + } + + pVTable = sqlite3DbMallocZero(db, sizeof(VTable)); + if( !pVTable ){ + sqlite3DbFree(db, zModuleName); + return SQLITE_NOMEM; + } + pVTable->db = db; + pVTable->pMod = pMod; + + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + pTab->azModuleArg[1] = db->aDb[iDb].zName; + + /* Invoke the virtual table constructor */ + assert( &db->pVtabCtx ); + assert( xConstruct ); + sCtx.pTab = pTab; + sCtx.pVTable = pVTable; + sCtx.pPrior = db->pVtabCtx; + sCtx.bDeclared = 0; + db->pVtabCtx = &sCtx; + rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); + db->pVtabCtx = sCtx.pPrior; + if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; + assert( sCtx.pTab==pTab ); + + if( SQLITE_OK!=rc ){ + if( zErr==0 ){ + *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName); + }else { + *pzErr = sqlite3MPrintf(db, "%s", zErr); + sqlite3_free(zErr); + } + sqlite3DbFree(db, pVTable); + }else if( ALWAYS(pVTable->pVtab) ){ + /* Justification of ALWAYS(): A correct vtab constructor must allocate + ** the sqlite3_vtab object if successful. */ + memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0])); + pVTable->pVtab->pModule = pMod->pModule; + pVTable->nRef = 1; + if( sCtx.bDeclared==0 ){ + const char *zFormat = "vtable constructor did not declare schema: %s"; + *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); + sqlite3VtabUnlock(pVTable); + rc = SQLITE_ERROR; + }else{ + int iCol; + u8 oooHidden = 0; + /* If everything went according to plan, link the new VTable structure + ** into the linked list headed by pTab->pVTable. Then loop through the + ** columns of the table to see if any of them contain the token "hidden". + ** If so, set the Column COLFLAG_HIDDEN flag and remove the token from + ** the type string. */ + pVTable->pNext = pTab->pVTable; + pTab->pVTable = pVTable; + + for(iCol=0; iColnCol; iCol++){ + char *zType = pTab->aCol[iCol].zType; + int nType; + int i = 0; + if( !zType ){ + pTab->tabFlags |= oooHidden; + continue; + } + nType = sqlite3Strlen30(zType); + if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){ + for(i=0; i0 ){ + assert(zType[i-1]==' '); + zType[i-1] = '\0'; + } + pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN; + oooHidden = TF_OOOHidden; + }else{ + pTab->tabFlags |= oooHidden; + } + } + } + } + + sqlite3DbFree(db, zModuleName); + return rc; +} + +/* +** This function is invoked by the parser to call the xConnect() method +** of the virtual table pTab. If an error occurs, an error code is returned +** and an error left in pParse. +** +** This call is a no-op if table pTab is not a virtual table. +*/ +SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){ + sqlite3 *db = pParse->db; + const char *zMod; + Module *pMod; + int rc; + + assert( pTab ); + if( (pTab->tabFlags & TF_Virtual)==0 || sqlite3GetVTable(db, pTab) ){ + return SQLITE_OK; + } + + /* Locate the required virtual table module */ + zMod = pTab->azModuleArg[0]; + pMod = (Module*)sqlite3HashFind(&db->aModule, zMod); + + if( !pMod ){ + const char *zModule = pTab->azModuleArg[0]; + sqlite3ErrorMsg(pParse, "no such module: %s", zModule); + rc = SQLITE_ERROR; + }else{ + char *zErr = 0; + rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr); + if( rc!=SQLITE_OK ){ + sqlite3ErrorMsg(pParse, "%s", zErr); + } + sqlite3DbFree(db, zErr); + } + + return rc; +} +/* +** Grow the db->aVTrans[] array so that there is room for at least one +** more v-table. Return SQLITE_NOMEM if a malloc fails, or SQLITE_OK otherwise. +*/ +static int growVTrans(sqlite3 *db){ + const int ARRAY_INCR = 5; + + /* Grow the sqlite3.aVTrans array if required */ + if( (db->nVTrans%ARRAY_INCR)==0 ){ + VTable **aVTrans; + int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR); + aVTrans = sqlite3DbRealloc(db, (void *)db->aVTrans, nBytes); + if( !aVTrans ){ + return SQLITE_NOMEM; + } + memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR); + db->aVTrans = aVTrans; + } + + return SQLITE_OK; +} + +/* +** Add the virtual table pVTab to the array sqlite3.aVTrans[]. Space should +** have already been reserved using growVTrans(). +*/ +static void addToVTrans(sqlite3 *db, VTable *pVTab){ + /* Add pVtab to the end of sqlite3.aVTrans */ + db->aVTrans[db->nVTrans++] = pVTab; + sqlite3VtabLock(pVTab); +} + +/* +** This function is invoked by the vdbe to call the xCreate method +** of the virtual table named zTab in database iDb. +** +** If an error occurs, *pzErr is set to point an an English language +** description of the error and an SQLITE_XXX error code is returned. +** In this case the caller must call sqlite3DbFree(db, ) on *pzErr. +*/ +SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){ + int rc = SQLITE_OK; + Table *pTab; + Module *pMod; + const char *zMod; + + pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName); + assert( pTab && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVTable ); + + /* Locate the required virtual table module */ + zMod = pTab->azModuleArg[0]; + pMod = (Module*)sqlite3HashFind(&db->aModule, zMod); + + /* If the module has been registered and includes a Create method, + ** invoke it now. If the module has not been registered, return an + ** error. Otherwise, do nothing. + */ + if( !pMod ){ + *pzErr = sqlite3MPrintf(db, "no such module: %s", zMod); + rc = SQLITE_ERROR; + }else{ + rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr); + } + + /* Justification of ALWAYS(): The xConstructor method is required to + ** create a valid sqlite3_vtab if it returns SQLITE_OK. */ + if( rc==SQLITE_OK && ALWAYS(sqlite3GetVTable(db, pTab)) ){ + rc = growVTrans(db); + if( rc==SQLITE_OK ){ + addToVTrans(db, sqlite3GetVTable(db, pTab)); + } + } + + return rc; +} + +/* +** This function is used to set the schema of a virtual table. It is only +** valid to call this function from within the xCreate() or xConnect() of a +** virtual table module. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ + VtabCtx *pCtx; + Parse *pParse; + int rc = SQLITE_OK; + Table *pTab; + char *zErr = 0; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + sqlite3_mutex_enter(db->mutex); + pCtx = db->pVtabCtx; + if( !pCtx || pCtx->bDeclared ){ + sqlite3Error(db, SQLITE_MISUSE); + sqlite3_mutex_leave(db->mutex); + return SQLITE_MISUSE_BKPT; + } + pTab = pCtx->pTab; + assert( (pTab->tabFlags & TF_Virtual)!=0 ); + + pParse = sqlite3StackAllocZero(db, sizeof(*pParse)); + if( pParse==0 ){ + rc = SQLITE_NOMEM; + }else{ + pParse->declareVtab = 1; + pParse->db = db; + pParse->nQueryLoop = 1; + + if( SQLITE_OK==sqlite3RunParser(pParse, zCreateTable, &zErr) + && pParse->pNewTable + && !db->mallocFailed + && !pParse->pNewTable->pSelect + && (pParse->pNewTable->tabFlags & TF_Virtual)==0 + ){ + if( !pTab->aCol ){ + pTab->aCol = pParse->pNewTable->aCol; + pTab->nCol = pParse->pNewTable->nCol; + pParse->pNewTable->nCol = 0; + pParse->pNewTable->aCol = 0; + } + pCtx->bDeclared = 1; + }else{ + sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr); + sqlite3DbFree(db, zErr); + rc = SQLITE_ERROR; + } + pParse->declareVtab = 0; + + if( pParse->pVdbe ){ + sqlite3VdbeFinalize(pParse->pVdbe); + } + sqlite3DeleteTable(db, pParse->pNewTable); + sqlite3ParserReset(pParse); + sqlite3StackFree(db, pParse); + } + + assert( (rc&0xff)==rc ); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** This function is invoked by the vdbe to call the xDestroy method +** of the virtual table named zTab in database iDb. This occurs +** when a DROP TABLE is mentioned. +** +** This call is a no-op if zTab is not a virtual table. +*/ +SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){ + int rc = SQLITE_OK; + Table *pTab; + + pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName); + if( ALWAYS(pTab!=0 && pTab->pVTable!=0) ){ + VTable *p; + for(p=pTab->pVTable; p; p=p->pNext){ + assert( p->pVtab ); + if( p->pVtab->nRef>0 ){ + return SQLITE_LOCKED; + } + } + p = vtabDisconnectAll(db, pTab); + rc = p->pMod->pModule->xDestroy(p->pVtab); + /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */ + if( rc==SQLITE_OK ){ + assert( pTab->pVTable==p && p->pNext==0 ); + p->pVtab = 0; + pTab->pVTable = 0; + sqlite3VtabUnlock(p); + } + } + + return rc; +} + +/* +** This function invokes either the xRollback or xCommit method +** of each of the virtual tables in the sqlite3.aVTrans array. The method +** called is identified by the second argument, "offset", which is +** the offset of the method to call in the sqlite3_module structure. +** +** The array is cleared after invoking the callbacks. +*/ +static void callFinaliser(sqlite3 *db, int offset){ + int i; + if( db->aVTrans ){ + for(i=0; inVTrans; i++){ + VTable *pVTab = db->aVTrans[i]; + sqlite3_vtab *p = pVTab->pVtab; + if( p ){ + int (*x)(sqlite3_vtab *); + x = *(int (**)(sqlite3_vtab *))((char *)p->pModule + offset); + if( x ) x(p); + } + pVTab->iSavepoint = 0; + sqlite3VtabUnlock(pVTab); + } + sqlite3DbFree(db, db->aVTrans); + db->nVTrans = 0; + db->aVTrans = 0; + } +} + +/* +** Invoke the xSync method of all virtual tables in the sqlite3.aVTrans +** array. Return the error code for the first error that occurs, or +** SQLITE_OK if all xSync operations are successful. +** +** If an error message is available, leave it in p->zErrMsg. +*/ +SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, Vdbe *p){ + int i; + int rc = SQLITE_OK; + VTable **aVTrans = db->aVTrans; + + db->aVTrans = 0; + for(i=0; rc==SQLITE_OK && inVTrans; i++){ + int (*x)(sqlite3_vtab *); + sqlite3_vtab *pVtab = aVTrans[i]->pVtab; + if( pVtab && (x = pVtab->pModule->xSync)!=0 ){ + rc = x(pVtab); + sqlite3VtabImportErrmsg(p, pVtab); + } + } + db->aVTrans = aVTrans; + return rc; +} + +/* +** Invoke the xRollback method of all virtual tables in the +** sqlite3.aVTrans array. Then clear the array itself. +*/ +SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db){ + callFinaliser(db, offsetof(sqlite3_module,xRollback)); + return SQLITE_OK; +} + +/* +** Invoke the xCommit method of all virtual tables in the +** sqlite3.aVTrans array. Then clear the array itself. +*/ +SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db){ + callFinaliser(db, offsetof(sqlite3_module,xCommit)); + return SQLITE_OK; +} + +/* +** If the virtual table pVtab supports the transaction interface +** (xBegin/xRollback/xCommit and optionally xSync) and a transaction is +** not currently open, invoke the xBegin method now. +** +** If the xBegin call is successful, place the sqlite3_vtab pointer +** in the sqlite3.aVTrans array. +*/ +SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *db, VTable *pVTab){ + int rc = SQLITE_OK; + const sqlite3_module *pModule; + + /* Special case: If db->aVTrans is NULL and db->nVTrans is greater + ** than zero, then this function is being called from within a + ** virtual module xSync() callback. It is illegal to write to + ** virtual module tables in this case, so return SQLITE_LOCKED. + */ + if( sqlite3VtabInSync(db) ){ + return SQLITE_LOCKED; + } + if( !pVTab ){ + return SQLITE_OK; + } + pModule = pVTab->pVtab->pModule; + + if( pModule->xBegin ){ + int i; + + /* If pVtab is already in the aVTrans array, return early */ + for(i=0; inVTrans; i++){ + if( db->aVTrans[i]==pVTab ){ + return SQLITE_OK; + } + } + + /* Invoke the xBegin method. If successful, add the vtab to the + ** sqlite3.aVTrans[] array. */ + rc = growVTrans(db); + if( rc==SQLITE_OK ){ + rc = pModule->xBegin(pVTab->pVtab); + if( rc==SQLITE_OK ){ + addToVTrans(db, pVTab); + } + } + } + return rc; +} + +/* +** Invoke either the xSavepoint, xRollbackTo or xRelease method of all +** virtual tables that currently have an open transaction. Pass iSavepoint +** as the second argument to the virtual table method invoked. +** +** If op is SAVEPOINT_BEGIN, the xSavepoint method is invoked. If it is +** SAVEPOINT_ROLLBACK, the xRollbackTo method. Otherwise, if op is +** SAVEPOINT_RELEASE, then the xRelease method of each virtual table with +** an open transaction is invoked. +** +** If any virtual table method returns an error code other than SQLITE_OK, +** processing is abandoned and the error returned to the caller of this +** function immediately. If all calls to virtual table methods are successful, +** SQLITE_OK is returned. +*/ +SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){ + int rc = SQLITE_OK; + + assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN ); + assert( iSavepoint>=-1 ); + if( db->aVTrans ){ + int i; + for(i=0; rc==SQLITE_OK && inVTrans; i++){ + VTable *pVTab = db->aVTrans[i]; + const sqlite3_module *pMod = pVTab->pMod->pModule; + if( pVTab->pVtab && pMod->iVersion>=2 ){ + int (*xMethod)(sqlite3_vtab *, int); + switch( op ){ + case SAVEPOINT_BEGIN: + xMethod = pMod->xSavepoint; + pVTab->iSavepoint = iSavepoint+1; + break; + case SAVEPOINT_ROLLBACK: + xMethod = pMod->xRollbackTo; + break; + default: + xMethod = pMod->xRelease; + break; + } + if( xMethod && pVTab->iSavepoint>iSavepoint ){ + rc = xMethod(pVTab->pVtab, iSavepoint); + } + } + } + } + return rc; +} + +/* +** The first parameter (pDef) is a function implementation. The +** second parameter (pExpr) is the first argument to this function. +** If pExpr is a column in a virtual table, then let the virtual +** table implementation have an opportunity to overload the function. +** +** This routine is used to allow virtual table implementations to +** overload MATCH, LIKE, GLOB, and REGEXP operators. +** +** Return either the pDef argument (indicating no change) or a +** new FuncDef structure that is marked as ephemeral using the +** SQLITE_FUNC_EPHEM flag. +*/ +SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction( + sqlite3 *db, /* Database connection for reporting malloc problems */ + FuncDef *pDef, /* Function to possibly overload */ + int nArg, /* Number of arguments to the function */ + Expr *pExpr /* First argument to the function */ +){ + Table *pTab; + sqlite3_vtab *pVtab; + sqlite3_module *pMod; + void (*xFunc)(sqlite3_context*,int,sqlite3_value**) = 0; + void *pArg = 0; + FuncDef *pNew; + int rc = 0; + char *zLowerName; + unsigned char *z; + + + /* Check to see the left operand is a column in a virtual table */ + if( NEVER(pExpr==0) ) return pDef; + if( pExpr->op!=TK_COLUMN ) return pDef; + pTab = pExpr->pTab; + if( NEVER(pTab==0) ) return pDef; + if( (pTab->tabFlags & TF_Virtual)==0 ) return pDef; + pVtab = sqlite3GetVTable(db, pTab)->pVtab; + assert( pVtab!=0 ); + assert( pVtab->pModule!=0 ); + pMod = (sqlite3_module *)pVtab->pModule; + if( pMod->xFindFunction==0 ) return pDef; + + /* Call the xFindFunction method on the virtual table implementation + ** to see if the implementation wants to overload this function + */ + zLowerName = sqlite3DbStrDup(db, pDef->zName); + if( zLowerName ){ + for(z=(unsigned char*)zLowerName; *z; z++){ + *z = sqlite3UpperToLower[*z]; + } + rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xFunc, &pArg); + sqlite3DbFree(db, zLowerName); + } + if( rc==0 ){ + return pDef; + } + + /* Create a new ephemeral function definition for the overloaded + ** function */ + pNew = sqlite3DbMallocZero(db, sizeof(*pNew) + + sqlite3Strlen30(pDef->zName) + 1); + if( pNew==0 ){ + return pDef; + } + *pNew = *pDef; + pNew->zName = (char *)&pNew[1]; + memcpy(pNew->zName, pDef->zName, sqlite3Strlen30(pDef->zName)+1); + pNew->xFunc = xFunc; + pNew->pUserData = pArg; + pNew->funcFlags |= SQLITE_FUNC_EPHEM; + return pNew; +} + +/* +** Make sure virtual table pTab is contained in the pParse->apVirtualLock[] +** array so that an OP_VBegin will get generated for it. Add pTab to the +** array if it is missing. If pTab is already in the array, this routine +** is a no-op. +*/ +SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + int i, n; + Table **apVtabLock; + + assert( IsVirtual(pTab) ); + for(i=0; inVtabLock; i++){ + if( pTab==pToplevel->apVtabLock[i] ) return; + } + n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]); + apVtabLock = sqlite3_realloc64(pToplevel->apVtabLock, n); + if( apVtabLock ){ + pToplevel->apVtabLock = apVtabLock; + pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab; + }else{ + pToplevel->db->mallocFailed = 1; + } +} + +/* +** Return the ON CONFLICT resolution mode in effect for the virtual +** table update operation currently in progress. +** +** The results of this routine are undefined unless it is called from +** within an xUpdate method. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *db){ + static const unsigned char aMap[] = { + SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE + }; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + assert( OE_Rollback==1 && OE_Abort==2 && OE_Fail==3 ); + assert( OE_Ignore==4 && OE_Replace==5 ); + assert( db->vtabOnConflict>=1 && db->vtabOnConflict<=5 ); + return (int)aMap[db->vtabOnConflict-1]; +} + +/* +** Call from within the xCreate() or xConnect() methods to provide +** the SQLite core with additional information about the behavior +** of the virtual table being implemented. +*/ +SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3 *db, int op, ...){ + va_list ap; + int rc = SQLITE_OK; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + va_start(ap, op); + switch( op ){ + case SQLITE_VTAB_CONSTRAINT_SUPPORT: { + VtabCtx *p = db->pVtabCtx; + if( !p ){ + rc = SQLITE_MISUSE_BKPT; + }else{ + assert( p->pTab==0 || (p->pTab->tabFlags & TF_Virtual)!=0 ); + p->pVTable->bConstraint = (u8)va_arg(ap, int); + } + break; + } + default: + rc = SQLITE_MISUSE_BKPT; + break; + } + va_end(ap); + + if( rc!=SQLITE_OK ) sqlite3Error(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +/************** End of vtab.c ************************************************/ +/************** Begin file where.c *******************************************/ +/* +** 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. +** +************************************************************************* +** This module contains C code that generates VDBE code used to process +** the WHERE clause of SQL statements. This module is responsible 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". +*/ +/************** Include whereInt.h in the middle of where.c ******************/ +/************** Begin file whereInt.h ****************************************/ +/* +** 2013-11-12 +** +** 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 structure and macro definitions for the query +** planner logic in "where.c". These definitions are broken out into +** a separate source file for easier editing. +*/ + +/* +** Trace output macros +*/ +#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) +/***/ int sqlite3WhereTrace = 0; +#endif +#if defined(SQLITE_DEBUG) \ + && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE)) +# define WHERETRACE(K,X) if(sqlite3WhereTrace&(K)) sqlite3DebugPrintf X +# define WHERETRACE_ENABLED 1 +#else +# define WHERETRACE(K,X) +#endif + +/* Forward references +*/ +typedef struct WhereClause WhereClause; +typedef struct WhereMaskSet WhereMaskSet; +typedef struct WhereOrInfo WhereOrInfo; +typedef struct WhereAndInfo WhereAndInfo; +typedef struct WhereLevel WhereLevel; +typedef struct WhereLoop WhereLoop; +typedef struct WherePath WherePath; +typedef struct WhereTerm WhereTerm; +typedef struct WhereLoopBuilder WhereLoopBuilder; +typedef struct WhereScan WhereScan; +typedef struct WhereOrCost WhereOrCost; +typedef struct WhereOrSet WhereOrSet; + +/* +** This object contains information needed to implement a single nested +** loop in WHERE clause. +** +** Contrast this object with WhereLoop. This object describes the +** implementation of the loop. WhereLoop describes the algorithm. +** This object contains a pointer to the WhereLoop algorithm as one of +** its elements. +** +** The WhereInfo object contains a single instance of this object for +** each term in the FROM clause (which is to say, for each of the +** nested loops as implemented). The order of WhereLevel objects determines +** the loop nested order, with WhereInfo.a[0] being the outer loop and +** WhereInfo.a[WhereInfo.nLevel-1] being the inner loop. +*/ +struct WhereLevel { + int iLeftJoin; /* Memory cell used to implement LEFT OUTER JOIN */ + int iTabCur; /* The VDBE cursor used to access the table */ + int iIdxCur; /* The VDBE cursor used to access pIdx */ + int addrBrk; /* Jump here to break out of the loop */ + int addrNxt; /* Jump here to start the next IN combination */ + int addrSkip; /* Jump here for next iteration of skip-scan */ + int addrCont; /* Jump here to continue with the next loop cycle */ + int addrFirst; /* First instruction of interior of the loop */ + int addrBody; /* Beginning of the body of this loop */ + int iLikeRepCntr; /* LIKE range processing counter register */ + int addrLikeRep; /* LIKE range processing address */ + u8 iFrom; /* Which entry in the FROM clause */ + u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */ + int p1, p2; /* Operands of the opcode used to ends the loop */ + union { /* Information that depends on pWLoop->wsFlags */ + struct { + int nIn; /* Number of entries in aInLoop[] */ + struct InLoop { + int iCur; /* The VDBE cursor used by this IN operator */ + int addrInTop; /* Top of the IN loop */ + u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */ + } *aInLoop; /* Information about each nested IN operator */ + } in; /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */ + Index *pCovidx; /* Possible covering index for WHERE_MULTI_OR */ + } u; + struct WhereLoop *pWLoop; /* The selected WhereLoop object */ + Bitmask notReady; /* FROM entries not usable at this level */ +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + int addrVisit; /* Address at which row is visited */ +#endif +}; + +/* +** Each instance of this object represents an algorithm for evaluating one +** term of a join. Every term of the FROM clause will have at least +** one corresponding WhereLoop object (unless INDEXED BY constraints +** prevent a query solution - which is an error) and many terms of the +** FROM clause will have multiple WhereLoop objects, each describing a +** potential way of implementing that FROM-clause term, together with +** dependencies and cost estimates for using the chosen algorithm. +** +** Query planning consists of building up a collection of these WhereLoop +** objects, then computing a particular sequence of WhereLoop objects, with +** one WhereLoop object per FROM clause term, that satisfy all dependencies +** and that minimize the overall cost. +*/ +struct WhereLoop { + Bitmask prereq; /* Bitmask of other loops that must run first */ + Bitmask maskSelf; /* Bitmask identifying table iTab */ +#ifdef SQLITE_DEBUG + char cId; /* Symbolic ID of this loop for debugging use */ +#endif + u8 iTab; /* Position in FROM clause of table for this loop */ + u8 iSortIdx; /* Sorting index number. 0==None */ + LogEst rSetup; /* One-time setup cost (ex: create transient index) */ + LogEst rRun; /* Cost of running each loop */ + LogEst nOut; /* Estimated number of output rows */ + union { + struct { /* Information for internal btree tables */ + u16 nEq; /* Number of equality constraints */ + Index *pIndex; /* Index used, or NULL */ + } btree; + struct { /* Information for virtual tables */ + int idxNum; /* Index number */ + u8 needFree; /* True if sqlite3_free(idxStr) is needed */ + i8 isOrdered; /* True if satisfies ORDER BY */ + u16 omitMask; /* Terms that may be omitted */ + char *idxStr; /* Index identifier string */ + } vtab; + } u; + u32 wsFlags; /* WHERE_* flags describing the plan */ + u16 nLTerm; /* Number of entries in aLTerm[] */ + u16 nSkip; /* Number of NULL aLTerm[] entries */ + /**** whereLoopXfer() copies fields above ***********************/ +# define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot) + u16 nLSlot; /* Number of slots allocated for aLTerm[] */ + WhereTerm **aLTerm; /* WhereTerms used */ + WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */ + WhereTerm *aLTermSpace[3]; /* Initial aLTerm[] space */ +}; + +/* This object holds the prerequisites and the cost of running a +** subquery on one operand of an OR operator in the WHERE clause. +** See WhereOrSet for additional information +*/ +struct WhereOrCost { + Bitmask prereq; /* Prerequisites */ + LogEst rRun; /* Cost of running this subquery */ + LogEst nOut; /* Number of outputs for this subquery */ +}; + +/* The WhereOrSet object holds a set of possible WhereOrCosts that +** correspond to the subquery(s) of OR-clause processing. Only the +** best N_OR_COST elements are retained. +*/ +#define N_OR_COST 3 +struct WhereOrSet { + u16 n; /* Number of valid a[] entries */ + WhereOrCost a[N_OR_COST]; /* Set of best costs */ +}; + + +/* Forward declaration of methods */ +static int whereLoopResize(sqlite3*, WhereLoop*, int); + +/* +** Each instance of this object holds a sequence of WhereLoop objects +** that implement some or all of a query plan. +** +** Think of each WhereLoop object as a node in a graph with arcs +** showing dependencies and costs for travelling between nodes. (That is +** not a completely accurate description because WhereLoop costs are a +** vector, not a scalar, and because dependencies are many-to-one, not +** one-to-one as are graph nodes. But it is a useful visualization aid.) +** Then a WherePath object is a path through the graph that visits some +** or all of the WhereLoop objects once. +** +** The "solver" works by creating the N best WherePath objects of length +** 1. Then using those as a basis to compute the N best WherePath objects +** of length 2. And so forth until the length of WherePaths equals the +** number of nodes in the FROM clause. The best (lowest cost) WherePath +** at the end is the chosen query plan. +*/ +struct WherePath { + Bitmask maskLoop; /* Bitmask of all WhereLoop objects in this path */ + Bitmask revLoop; /* aLoop[]s that should be reversed for ORDER BY */ + LogEst nRow; /* Estimated number of rows generated by this path */ + LogEst rCost; /* Total cost of this path */ + LogEst rUnsorted; /* Total cost of this path ignoring sorting costs */ + i8 isOrdered; /* No. of ORDER BY terms satisfied. -1 for unknown */ + WhereLoop **aLoop; /* Array of WhereLoop objects implementing this path */ +}; + +/* +** 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 AND operators, +** usually, or sometimes subexpressions separated by OR. +** +** 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 +** +** where X is a column name and is one of certain operators, +** then WhereTerm.leftCursor and WhereTerm.u.leftColumn record the +** cursor number and column number for X. WhereTerm.eOperator records +** the 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. +** +** A WhereTerm might also be two or more subterms connected by OR: +** +** (t1.X ) OR (t1.Y ) OR .... +** +** In this second case, wtFlag has the TERM_ORINFO bit set and eOperator==WO_OR +** and the WhereTerm.u.pOrInfo field points to auxiliary information that +** is collected about the OR clause. +** +** If a term in the WHERE clause does not match either of the two previous +** categories, then eOperator==0. The WhereTerm.pExpr field is still set +** to the original subexpression content and wtFlags is set up appropriately +** but no other fields in the WhereTerm object are meaningful. +** +** When eOperator!=0, prereqRight and prereqAll record sets of cursor numbers, +** but they do so indirectly. A single WhereMaskSet 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 WhereMaskSet +** 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. +** +** The number of terms in a join is limited by the number of bits +** in prereqRight and prereqAll. The default is 64 bits, hence SQLite +** is only able to process joins with 64 or fewer tables. +*/ +struct WhereTerm { + Expr *pExpr; /* Pointer to the subexpression that is this term */ + int iParent; /* Disable pWC->a[iParent] when this term disabled */ + int leftCursor; /* Cursor number of X in "X " */ + union { + int leftColumn; /* Column number of X in "X " */ + WhereOrInfo *pOrInfo; /* Extra information if (eOperator & WO_OR)!=0 */ + WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */ + } u; + LogEst truthProb; /* Probability of truth for this expression */ + u16 eOperator; /* A WO_xx value describing */ + u16 wtFlags; /* TERM_xxx 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 pExpr->pRight */ + Bitmask prereqAll; /* Bitmask of tables referenced by pExpr */ +}; + +/* +** Allowed values of WhereTerm.wtFlags +*/ +#define TERM_DYNAMIC 0x01 /* Need to call sqlite3ExprDelete(db, 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_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */ +#define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */ +#define TERM_OR_OK 0x40 /* Used during OR-clause processing */ +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 +# define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */ +#else +# define TERM_VNULL 0x00 /* Disabled if not using stat3 */ +#endif +#define TERM_LIKEOPT 0x100 /* Virtual terms from the LIKE optimization */ +#define TERM_LIKECOND 0x200 /* Conditionally this LIKE operator term */ +#define TERM_LIKE 0x400 /* The original LIKE operator */ + +/* +** An instance of the WhereScan object is used as an iterator for locating +** terms in the WHERE clause that are useful to the query planner. +*/ +struct WhereScan { + WhereClause *pOrigWC; /* Original, innermost WhereClause */ + WhereClause *pWC; /* WhereClause currently being scanned */ + char *zCollName; /* Required collating sequence, if not NULL */ + char idxaff; /* Must match this affinity, if zCollName!=NULL */ + unsigned char nEquiv; /* Number of entries in aEquiv[] */ + unsigned char iEquiv; /* Next unused slot in aEquiv[] */ + u32 opMask; /* Acceptable operators */ + int k; /* Resume scanning at this->pWC->a[this->k] */ + int aEquiv[22]; /* Cursor,Column pairs for equivalence classes */ +}; + +/* +** An instance of the following structure holds all information about a +** WHERE clause. Mostly this is a container for one or more WhereTerms. +** +** Explanation of pOuter: For a WHERE clause of the form +** +** a AND ((b AND c) OR (d AND e)) AND f +** +** There are separate WhereClause objects for the whole clause and for +** the subclauses "(b AND c)" and "(d AND e)". The pOuter field of the +** subclauses points to the WhereClause object for the whole clause. +*/ +struct WhereClause { + WhereInfo *pWInfo; /* WHERE clause processing context */ + WhereClause *pOuter; /* Outer conjunction */ + u8 op; /* Split operator. TK_AND or TK_OR */ + int nTerm; /* Number of terms */ + int nSlot; /* Number of entries in a[] */ + WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */ +#if defined(SQLITE_SMALL_STACK) + WhereTerm aStatic[1]; /* Initial static space for a[] */ +#else + WhereTerm aStatic[8]; /* Initial static space for a[] */ +#endif +}; + +/* +** A WhereTerm with eOperator==WO_OR has its u.pOrInfo pointer set to +** a dynamically allocated instance of the following structure. +*/ +struct WhereOrInfo { + WhereClause wc; /* Decomposition into subterms */ + Bitmask indexable; /* Bitmask of all indexable tables in the clause */ +}; + +/* +** A WhereTerm with eOperator==WO_AND has its u.pAndInfo pointer set to +** a dynamically allocated instance of the following structure. +*/ +struct WhereAndInfo { + WhereClause wc; /* The subexpression broken out */ +}; + +/* +** 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 +** with 0. +** +** If WhereMaskSet.ix[A]==B it means that The A-th bit of a Bitmask +** corresponds VDBE cursor number B. The A-th bit of a bitmask is 1<3, 5->1, 8->2, 29->0, +** 57->5, 73->4. Or one of 719 other combinations might be used. It +** does not really matter. What is important is that sparse cursor +** numbers all get mapped into bit numbers that begin with 0 and contain +** no gaps. +*/ +struct WhereMaskSet { + int n; /* Number of assigned cursor values */ + int ix[BMS]; /* Cursor assigned to each bit */ +}; + +/* +** This object is a convenience wrapper holding all information needed +** to construct WhereLoop objects for a particular query. +*/ +struct WhereLoopBuilder { + WhereInfo *pWInfo; /* Information about this WHERE */ + WhereClause *pWC; /* WHERE clause terms */ + ExprList *pOrderBy; /* ORDER BY clause */ + WhereLoop *pNew; /* Template WhereLoop */ + WhereOrSet *pOrSet; /* Record best loops here, if not NULL */ +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + UnpackedRecord *pRec; /* Probe for stat4 (if required) */ + int nRecValid; /* Number of valid fields currently in pRec */ +#endif +}; + +/* +** 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 +** into the second half to give some continuity. +** +** An instance of this object holds the complete state of the query +** planner. +*/ +struct WhereInfo { + Parse *pParse; /* Parsing and code generating context */ + SrcList *pTabList; /* List of tables in the join */ + ExprList *pOrderBy; /* The ORDER BY clause or NULL */ + ExprList *pResultSet; /* Result set. DISTINCT operates on these */ + WhereLoop *pLoops; /* List of all WhereLoop objects */ + Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ + LogEst nRowOut; /* Estimated number of output rows */ + u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ + i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */ + u8 sorted; /* True if really sorted (not just grouped) */ + u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE/DELETE */ + u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */ + u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */ + u8 nLevel; /* Number of nested loop */ + int iTop; /* The very beginning of the WHERE loop */ + int iContinue; /* Jump here to continue with next record */ + int iBreak; /* Jump here to break out of the loop */ + int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */ + int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */ + WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */ + WhereClause sWC; /* Decomposition of the WHERE clause */ + WhereLevel a[1]; /* Information about each nest loop in WHERE */ +}; + +/* +** Bitmasks for the operators on WhereTerm objects. These are all +** operators that are of interest to the query planner. An +** OR-ed combination of these values can be used when searching for +** particular WhereTerms within a WhereClause. +*/ +#define WO_IN 0x001 +#define WO_EQ 0x002 +#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)) +#define WO_MATCH 0x040 +#define WO_ISNULL 0x080 +#define WO_OR 0x100 /* Two or more OR-connected terms */ +#define WO_AND 0x200 /* Two or more AND-connected terms */ +#define WO_EQUIV 0x400 /* Of the form A==B, both columns */ +#define WO_NOOP 0x800 /* This term does not restrict search space */ + +#define WO_ALL 0xfff /* Mask of all possible WO_* values */ +#define WO_SINGLE 0x0ff /* Mask of all non-compound WO_* values */ + +/* +** These are definitions of bits in the WhereLoop.wsFlags field. +** The particular combination of bits in each WhereLoop help to +** determine the algorithm that WhereLoop represents. +*/ +#define WHERE_COLUMN_EQ 0x00000001 /* x=EXPR */ +#define WHERE_COLUMN_RANGE 0x00000002 /* xEXPR */ +#define WHERE_COLUMN_IN 0x00000004 /* x IN (...) */ +#define WHERE_COLUMN_NULL 0x00000008 /* x IS NULL */ +#define WHERE_CONSTRAINT 0x0000000f /* Any of the WHERE_COLUMN_xxx values */ +#define WHERE_TOP_LIMIT 0x00000010 /* xEXPR or x>=EXPR constraint */ +#define WHERE_BOTH_LIMIT 0x00000030 /* Both x>EXPR and xnRowOut); +} + +/* +** Return one of the WHERE_DISTINCT_xxxxx values to indicate how this +** WHERE clause returns outputs for DISTINCT processing. +*/ +SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo *pWInfo){ + return pWInfo->eDistinct; +} + +/* +** Return TRUE if the WHERE clause returns rows in ORDER BY order. +** Return FALSE if the output needs to be sorted. +*/ +SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo *pWInfo){ + return pWInfo->nOBSat; +} + +/* +** Return the VDBE address or label to jump to in order to continue +** immediately with the next row of a WHERE clause. +*/ +SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo *pWInfo){ + assert( pWInfo->iContinue!=0 ); + return pWInfo->iContinue; +} + +/* +** Return the VDBE address or label to jump to in order to break +** out of a WHERE loop. +*/ +SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo *pWInfo){ + return pWInfo->iBreak; +} + +/* +** Return TRUE if an UPDATE or DELETE statement can operate directly on +** the rowids returned by a WHERE clause. Return FALSE if doing an +** UPDATE or DELETE might change subsequent WHERE clause results. +** +** If the ONEPASS optimization is used (if this routine returns true) +** then also write the indices of open cursors used by ONEPASS +** into aiCur[0] and aiCur[1]. iaCur[0] gets the cursor of the data +** table and iaCur[1] gets the cursor used by an auxiliary index. +** Either value may be -1, indicating that cursor is not used. +** Any cursors returned will have been opened for writing. +** +** aiCur[0] and aiCur[1] both get -1 if the where-clause logic is +** unable to use the ONEPASS optimization. +*/ +SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo *pWInfo, int *aiCur){ + memcpy(aiCur, pWInfo->aiCurOnePass, sizeof(int)*2); + return pWInfo->okOnePass; +} + +/* +** Move the content of pSrc into pDest +*/ +static void whereOrMove(WhereOrSet *pDest, WhereOrSet *pSrc){ + pDest->n = pSrc->n; + memcpy(pDest->a, pSrc->a, pDest->n*sizeof(pDest->a[0])); +} + +/* +** Try to insert a new prerequisite/cost entry into the WhereOrSet pSet. +** +** The new entry might overwrite an existing entry, or it might be +** appended, or it might be discarded. Do whatever is the right thing +** so that pSet keeps the N_OR_COST best entries seen so far. +*/ +static int whereOrInsert( + WhereOrSet *pSet, /* The WhereOrSet to be updated */ + Bitmask prereq, /* Prerequisites of the new entry */ + LogEst rRun, /* Run-cost of the new entry */ + LogEst nOut /* Number of outputs for the new entry */ +){ + u16 i; + WhereOrCost *p; + for(i=pSet->n, p=pSet->a; i>0; i--, p++){ + if( rRun<=p->rRun && (prereq & p->prereq)==prereq ){ + goto whereOrInsert_done; + } + if( p->rRun<=rRun && (p->prereq & prereq)==p->prereq ){ + return 0; + } + } + if( pSet->na[pSet->n++]; + p->nOut = nOut; + }else{ + p = pSet->a; + for(i=1; in; i++){ + if( p->rRun>pSet->a[i].rRun ) p = pSet->a + i; + } + if( p->rRun<=rRun ) return 0; + } +whereOrInsert_done: + p->prereq = prereq; + p->rRun = rRun; + if( p->nOut>nOut ) p->nOut = nOut; + return 1; +} + +/* +** Initialize a preallocated WhereClause structure. +*/ +static void whereClauseInit( + WhereClause *pWC, /* The WhereClause to be initialized */ + WhereInfo *pWInfo /* The WHERE processing context */ +){ + pWC->pWInfo = pWInfo; + pWC->pOuter = 0; + pWC->nTerm = 0; + pWC->nSlot = ArraySize(pWC->aStatic); + pWC->a = pWC->aStatic; +} + +/* Forward reference */ +static void whereClauseClear(WhereClause*); + +/* +** Deallocate all memory associated with a WhereOrInfo object. +*/ +static void whereOrInfoDelete(sqlite3 *db, WhereOrInfo *p){ + whereClauseClear(&p->wc); + sqlite3DbFree(db, p); +} + +/* +** Deallocate all memory associated with a WhereAndInfo object. +*/ +static void whereAndInfoDelete(sqlite3 *db, WhereAndInfo *p){ + whereClauseClear(&p->wc); + sqlite3DbFree(db, p); +} + +/* +** 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; + sqlite3 *db = pWC->pWInfo->pParse->db; + for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){ + if( a->wtFlags & TERM_DYNAMIC ){ + sqlite3ExprDelete(db, a->pExpr); + } + if( a->wtFlags & TERM_ORINFO ){ + whereOrInfoDelete(db, a->u.pOrInfo); + }else if( a->wtFlags & TERM_ANDINFO ){ + whereAndInfoDelete(db, a->u.pAndInfo); + } + } + if( pWC->a!=pWC->aStatic ){ + sqlite3DbFree(db, pWC->a); + } +} + +/* +** Add a single new WhereTerm entry to the WhereClause object pWC. +** The new WhereTerm object is constructed from Expr p and with wtFlags. +** The index in pWC->a[] of the new WhereTerm is returned on success. +** 0 is returned if the new WhereTerm could not be added due to a memory +** allocation error. The memory allocation failure will be recorded in +** the db->mallocFailed flag so that higher-level functions can detect it. +** +** This routine will increase the size of the pWC->a[] array as necessary. +** +** If the wtFlags argument includes TERM_DYNAMIC, then responsibility +** for freeing the expression p is assumed by the WhereClause object pWC. +** This is true even if this routine fails to allocate a new WhereTerm. +** +** WARNING: This routine might reallocate the space used to store +** WhereTerms. All pointers to WhereTerms should be invalidated after +** calling this routine. Such pointers may be reinitialized by referencing +** the pWC->a[] array. +*/ +static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){ + WhereTerm *pTerm; + int idx; + testcase( wtFlags & TERM_VIRTUAL ); + if( pWC->nTerm>=pWC->nSlot ){ + WhereTerm *pOld = pWC->a; + sqlite3 *db = pWC->pWInfo->pParse->db; + pWC->a = sqlite3DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 ); + if( pWC->a==0 ){ + if( wtFlags & TERM_DYNAMIC ){ + sqlite3ExprDelete(db, p); + } + pWC->a = pOld; + return 0; + } + memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm); + if( pOld!=pWC->aStatic ){ + sqlite3DbFree(db, pOld); + } + pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]); + memset(&pWC->a[pWC->nTerm], 0, sizeof(pWC->a[0])*(pWC->nSlot-pWC->nTerm)); + } + pTerm = &pWC->a[idx = pWC->nTerm++]; + if( p && ExprHasProperty(p, EP_Unlikely) ){ + pTerm->truthProb = sqlite3LogEst(p->iTable) - 270; + }else{ + pTerm->truthProb = 1; + } + pTerm->pExpr = sqlite3ExprSkipCollate(p); + pTerm->wtFlags = wtFlags; + 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. The slot[] array grows as needed to contain +** all terms of the WHERE clause. +*/ +static void whereSplit(WhereClause *pWC, Expr *pExpr, u8 op){ + Expr *pE2 = sqlite3ExprSkipCollate(pExpr); + pWC->op = op; + if( pE2==0 ) return; + if( pE2->op!=op ){ + whereClauseInsert(pWC, pExpr, 0); + }else{ + whereSplit(pWC, pE2->pLeft, op); + whereSplit(pWC, pE2->pRight, op); + } +} + +/* +** Initialize a WhereMaskSet object +*/ +#define initMaskSet(P) (P)->n=0 + +/* +** Return the bitmask for the given cursor number. Return 0 if +** iCursor is not in the set. +*/ +static Bitmask getMask(WhereMaskSet *pMaskSet, int iCursor){ + int i; + assert( pMaskSet->n<=(int)sizeof(Bitmask)*8 ); + for(i=0; in; i++){ + if( pMaskSet->ix[i]==iCursor ){ + return MASKBIT(i); + } + } + 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(WhereMaskSet *pMaskSet, int iCursor){ + assert( pMaskSet->n < ArraySize(pMaskSet->ix) ); + pMaskSet->ix[pMaskSet->n++] = iCursor; +} + +/* +** These routines walk (recursively) an expression tree and generate +** a bitmask indicating which tables are used in that expression +** tree. +*/ +static Bitmask exprListTableUsage(WhereMaskSet*, ExprList*); +static Bitmask exprSelectTableUsage(WhereMaskSet*, Select*); +static Bitmask exprTableUsage(WhereMaskSet *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); + if( ExprHasProperty(p, EP_xIsSelect) ){ + mask |= exprSelectTableUsage(pMaskSet, p->x.pSelect); + }else{ + mask |= exprListTableUsage(pMaskSet, p->x.pList); + } + return mask; +} +static Bitmask exprListTableUsage(WhereMaskSet *pMaskSet, ExprList *pList){ + int i; + Bitmask mask = 0; + if( pList ){ + for(i=0; inExpr; i++){ + mask |= exprTableUsage(pMaskSet, pList->a[i].pExpr); + } + } + return mask; +} +static Bitmask exprSelectTableUsage(WhereMaskSet *pMaskSet, Select *pS){ + Bitmask mask = 0; + while( pS ){ + SrcList *pSrc = pS->pSrc; + 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); + if( ALWAYS(pSrc!=0) ){ + int i; + for(i=0; inSrc; i++){ + mask |= exprSelectTableUsage(pMaskSet, pSrc->a[i].pSelect); + mask |= exprTableUsage(pMaskSet, pSrc->a[i].pOn); + } + } + pS = pS->pPrior; + } + 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 +** "=", "<", ">", "<=", ">=", "IN", and "IS NULL" +*/ +static int allowedOp(int op){ + assert( TK_GT>TK_EQ && TK_GTTK_EQ && TK_LTTK_EQ && TK_LE=TK_EQ && op<=TK_GE) || op==TK_ISNULL; +} + +/* +** Commute a comparison operator. Expressions of the form "X op Y" +** are converted into "Y op X". +** +** If left/right precedence rules come into play when determining the +** collating sequence, then COLLATE operators are adjusted to ensure +** that the collating sequence does not change. For example: +** "Y collate NOCASE op X" becomes "X op Y" because any collation sequence on +** the left hand side of a comparison overrides any collation sequence +** attached to the right. For the same reason the EP_Collate flag +** is not commuted. +*/ +static void exprCommute(Parse *pParse, Expr *pExpr){ + u16 expRight = (pExpr->pRight->flags & EP_Collate); + u16 expLeft = (pExpr->pLeft->flags & EP_Collate); + assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN ); + if( expRight==expLeft ){ + /* Either X and Y both have COLLATE operator or neither do */ + if( expRight ){ + /* Both X and Y have COLLATE operators. Make sure X is always + ** used by clearing the EP_Collate flag from Y. */ + pExpr->pRight->flags &= ~EP_Collate; + }else if( sqlite3ExprCollSeq(pParse, pExpr->pLeft)!=0 ){ + /* Neither X nor Y have COLLATE operators, but X has a non-default + ** collating sequence. So add the EP_Collate marker on X to cause + ** it to be searched first. */ + pExpr->pLeft->flags |= EP_Collate; + } + } + 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_GTop>=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 u16 operatorMask(int op){ + u16 c; + assert( allowedOp(op) ); + if( op==TK_IN ){ + c = WO_IN; + }else if( op==TK_ISNULL ){ + c = WO_ISNULL; + }else{ + assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff ); + c = (u16)(WO_EQ<<(op-TK_EQ)); + } + assert( op!=TK_ISNULL || c==WO_ISNULL ); + 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; +} + +/* +** Advance to the next WhereTerm that matches according to the criteria +** established when the pScan object was initialized by whereScanInit(). +** Return NULL if there are no more matching WhereTerms. +*/ +static WhereTerm *whereScanNext(WhereScan *pScan){ + int iCur; /* The cursor on the LHS of the term */ + int iColumn; /* The column on the LHS of the term. -1 for IPK */ + Expr *pX; /* An expression being tested */ + WhereClause *pWC; /* Shorthand for pScan->pWC */ + WhereTerm *pTerm; /* The term being tested */ + int k = pScan->k; /* Where to start scanning */ + + while( pScan->iEquiv<=pScan->nEquiv ){ + iCur = pScan->aEquiv[pScan->iEquiv-2]; + iColumn = pScan->aEquiv[pScan->iEquiv-1]; + while( (pWC = pScan->pWC)!=0 ){ + for(pTerm=pWC->a+k; knTerm; k++, pTerm++){ + if( pTerm->leftCursor==iCur + && pTerm->u.leftColumn==iColumn + && (pScan->iEquiv<=2 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin)) + ){ + if( (pTerm->eOperator & WO_EQUIV)!=0 + && pScan->nEquivaEquiv) + ){ + int j; + pX = sqlite3ExprSkipCollate(pTerm->pExpr->pRight); + assert( pX->op==TK_COLUMN ); + for(j=0; jnEquiv; j+=2){ + if( pScan->aEquiv[j]==pX->iTable + && pScan->aEquiv[j+1]==pX->iColumn ){ + break; + } + } + if( j==pScan->nEquiv ){ + pScan->aEquiv[j] = pX->iTable; + pScan->aEquiv[j+1] = pX->iColumn; + pScan->nEquiv += 2; + } + } + if( (pTerm->eOperator & pScan->opMask)!=0 ){ + /* Verify the affinity and collating sequence match */ + if( pScan->zCollName && (pTerm->eOperator & WO_ISNULL)==0 ){ + CollSeq *pColl; + Parse *pParse = pWC->pWInfo->pParse; + pX = pTerm->pExpr; + if( !sqlite3IndexAffinityOk(pX, pScan->idxaff) ){ + continue; + } + assert(pX->pLeft); + pColl = sqlite3BinaryCompareCollSeq(pParse, + pX->pLeft, pX->pRight); + if( pColl==0 ) pColl = pParse->db->pDfltColl; + if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){ + continue; + } + } + if( (pTerm->eOperator & WO_EQ)!=0 + && (pX = pTerm->pExpr->pRight)->op==TK_COLUMN + && pX->iTable==pScan->aEquiv[0] + && pX->iColumn==pScan->aEquiv[1] + ){ + continue; + } + pScan->k = k+1; + return pTerm; + } + } + } + pScan->pWC = pScan->pWC->pOuter; + k = 0; + } + pScan->pWC = pScan->pOrigWC; + k = 0; + pScan->iEquiv += 2; + } + return 0; +} + +/* +** Initialize a WHERE clause scanner object. Return a pointer to the +** first match. Return NULL if there are no matches. +** +** The scanner will be searching the WHERE clause pWC. It will look +** for terms of the form "X " where X is column iColumn of table +** iCur. The must be one of the operators described by opMask. +** +** If the search is for X and the WHERE clause contains terms of the +** form X=Y then this routine might also return terms of the form +** "Y ". The number of levels of transitivity is limited, +** but is enough to handle most commonly occurring SQL statements. +** +** If X is not the INTEGER PRIMARY KEY then X must be compatible with +** index pIdx. +*/ +static WhereTerm *whereScanInit( + WhereScan *pScan, /* The WhereScan object being initialized */ + WhereClause *pWC, /* The WHERE clause to be scanned */ + int iCur, /* Cursor to scan for */ + int iColumn, /* Column to scan for */ + u32 opMask, /* Operator(s) to scan for */ + Index *pIdx /* Must be compatible with this index */ +){ + int j; + + /* memset(pScan, 0, sizeof(*pScan)); */ + pScan->pOrigWC = pWC; + pScan->pWC = pWC; + if( pIdx && iColumn>=0 ){ + pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity; + for(j=0; pIdx->aiColumn[j]!=iColumn; j++){ + if( NEVER(j>pIdx->nColumn) ) return 0; + } + pScan->zCollName = pIdx->azColl[j]; + }else{ + pScan->idxaff = 0; + pScan->zCollName = 0; + } + pScan->opMask = opMask; + pScan->k = 0; + pScan->aEquiv[0] = iCur; + pScan->aEquiv[1] = iColumn; + pScan->nEquiv = 2; + pScan->iEquiv = 2; + return whereScanNext(pScan); +} + +/* +** Search for a term in the WHERE clause that is of the form "X " +** where X is a reference to the iColumn of table iCur and is one of +** the WO_xx operator codes specified by the op parameter. +** Return a pointer to the term. Return 0 if not found. +** +** The term returned might by Y= if there is another constraint in +** the WHERE clause that specifies that X=Y. Any such constraints will be +** identified by the WO_EQUIV bit in the pTerm->eOperator field. The +** aEquiv[] array holds X and all its equivalents, with each SQL variable +** taking up two slots in aEquiv[]. The first slot is for the cursor number +** and the second is for the column number. There are 22 slots in aEquiv[] +** so that means we can look for X plus up to 10 other equivalent values. +** Hence a search for X will return if X=A1 and A1=A2 and A2=A3 +** and ... and A9=A10 and A10=. +** +** If there are multiple terms in the WHERE clause of the form "X " +** then try for the one with no dependencies on - in other words where +** is a constant expression of some kind. Only return entries of +** the form "X Y" where Y is a column in another table if no terms of +** the form "X " exist. If no terms with a constant RHS +** exist, try to return a term that does not use WO_EQUIV. +*/ +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 */ + u32 op, /* Mask of WO_xx values describing operator */ + Index *pIdx /* Must be compatible with this index, if not NULL */ +){ + WhereTerm *pResult = 0; + WhereTerm *p; + WhereScan scan; + + p = whereScanInit(&scan, pWC, iCur, iColumn, op, pIdx); + while( p ){ + if( (p->prereqRight & notReady)==0 ){ + if( p->prereqRight==0 && (p->eOperator&WO_EQ)!=0 ){ + return p; + } + if( pResult==0 ) pResult = p; + } + p = whereScanNext(&scan); + } + return pResult; +} + +/* Forward reference */ +static void exprAnalyze(SrcList*, WhereClause*, int); + +/* +** Call exprAnalyze on all terms in a WHERE clause. +*/ +static void exprAnalyzeAll( + SrcList *pTabList, /* the FROM clause */ + WhereClause *pWC /* the WHERE clause to be analyzed */ +){ + int i; + for(i=pWC->nTerm-1; i>=0; i--){ + exprAnalyze(pTabList, 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. The LHS must be a column +** that may only be NULL, a string, or a BLOB, never a number. (This means +** that virtual tables cannot participate in the LIKE optimization.) If the +** collating sequence for the column on the LHS must be appropriate for +** the operator. +*/ +static int isLikeOrGlob( + Parse *pParse, /* Parsing and code generating context */ + Expr *pExpr, /* Test this expression */ + Expr **ppPrefix, /* Pointer to TK_STRING expression with pattern prefix */ + int *pisComplete, /* True if the only wildcard is % in the last character */ + int *pnoCase /* True if uppercase is equivalent to lowercase */ +){ + const char *z = 0; /* String on RHS of LIKE operator */ + Expr *pRight, *pLeft; /* Right and left size of LIKE operator */ + ExprList *pList; /* List of operands to the LIKE operator */ + int c; /* One character in z[] */ + int cnt; /* Number of non-wildcard prefix characters */ + char wc[3]; /* Wildcard characters */ + sqlite3 *db = pParse->db; /* Database connection */ + sqlite3_value *pVal = 0; + int op; /* Opcode of pRight */ + + if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, wc) ){ + return 0; + } +#ifdef SQLITE_EBCDIC + if( *pnoCase ) return 0; +#endif + pList = pExpr->x.pList; + pLeft = pList->a[1].pExpr; + if( pLeft->op!=TK_COLUMN + || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT + || IsVirtual(pLeft->pTab) /* Value might be numeric */ + ){ + /* IMP: R-02065-49465 The left-hand side of the LIKE or GLOB operator must + ** be the name of an indexed column with TEXT affinity. */ + return 0; + } + assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */ + + pRight = sqlite3ExprSkipCollate(pList->a[0].pExpr); + op = pRight->op; + if( op==TK_VARIABLE ){ + Vdbe *pReprepare = pParse->pReprepare; + int iCol = pRight->iColumn; + pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_NONE); + if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){ + z = (char *)sqlite3_value_text(pVal); + } + sqlite3VdbeSetVarmask(pParse->pVdbe, iCol); + assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER ); + }else if( op==TK_STRING ){ + z = pRight->u.zToken; + } + if( z ){ + cnt = 0; + while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){ + cnt++; + } + if( cnt!=0 && 255!=(u8)z[cnt-1] ){ + Expr *pPrefix; + *pisComplete = c==wc[0] && z[cnt+1]==0; + pPrefix = sqlite3Expr(db, TK_STRING, z); + if( pPrefix ) pPrefix->u.zToken[cnt] = 0; + *ppPrefix = pPrefix; + if( op==TK_VARIABLE ){ + Vdbe *v = pParse->pVdbe; + sqlite3VdbeSetVarmask(v, pRight->iColumn); + if( *pisComplete && pRight->u.zToken[1] ){ + /* If the rhs of the LIKE expression is a variable, and the current + ** value of the variable means there is no need to invoke the LIKE + ** function, then no OP_Variable will be added to the program. + ** This causes problems for the sqlite3_bind_parameter_name() + ** API. To work around them, add a dummy OP_Variable here. + */ + int r1 = sqlite3GetTempReg(pParse); + sqlite3ExprCodeTarget(pParse, pRight, r1); + sqlite3VdbeChangeP3(v, sqlite3VdbeCurrentAddr(v)-1, 0); + sqlite3ReleaseTempReg(pParse, r1); + } + } + }else{ + z = 0; + } + } + + sqlite3ValueFree(pVal); + return (z!=0); +} +#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ + + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Check to see if the given expression is of the form +** +** column MATCH expr +** +** If it is then return TRUE. If not, return FALSE. +*/ +static int isMatchOfColumn( + Expr *pExpr /* Test this expression */ +){ + ExprList *pList; + + if( pExpr->op!=TK_FUNCTION ){ + return 0; + } + if( sqlite3StrICmp(pExpr->u.zToken,"match")!=0 ){ + return 0; + } + pList = pExpr->x.pList; + if( pList->nExpr!=2 ){ + return 0; + } + if( pList->a[1].pExpr->op != TK_COLUMN ){ + return 0; + } + return 1; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +/* +** 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){ + if( pDerived ){ + pDerived->flags |= pBase->flags & EP_FromJoin; + pDerived->iRightJoinTable = pBase->iRightJoinTable; + } +} + +/* +** Mark term iChild as being a child of term iParent +*/ +static void markTermAsChild(WhereClause *pWC, int iChild, int iParent){ + pWC->a[iChild].iParent = iParent; + pWC->a[iChild].truthProb = pWC->a[iParent].truthProb; + pWC->a[iParent].nChild++; +} + +/* +** Return the N-th AND-connected subterm of pTerm. Or if pTerm is not +** a conjunction, then return just pTerm when N==0. If N is exceeds +** the number of available subterms, return NULL. +*/ +static WhereTerm *whereNthSubterm(WhereTerm *pTerm, int N){ + if( pTerm->eOperator!=WO_AND ){ + return N==0 ? pTerm : 0; + } + if( Nu.pAndInfo->wc.nTerm ){ + return &pTerm->u.pAndInfo->wc.a[N]; + } + return 0; +} + +/* +** Subterms pOne and pTwo are contained within WHERE clause pWC. The +** two subterms are in disjunction - they are OR-ed together. +** +** If these two terms are both of the form: "A op B" with the same +** A and B values but different operators and if the operators are +** compatible (if one is = and the other is <, for example) then +** add a new virtual AND term to pWC that is the combination of the +** two. +** +** Some examples: +** +** x x<=y +** x=y OR x=y --> x=y +** x<=y OR x x<=y +** +** The following is NOT generated: +** +** xy --> x!=y +*/ +static void whereCombineDisjuncts( + SrcList *pSrc, /* the FROM clause */ + WhereClause *pWC, /* The complete WHERE clause */ + WhereTerm *pOne, /* First disjunct */ + WhereTerm *pTwo /* Second disjunct */ +){ + u16 eOp = pOne->eOperator | pTwo->eOperator; + sqlite3 *db; /* Database connection (for malloc) */ + Expr *pNew; /* New virtual expression */ + int op; /* Operator for the combined expression */ + int idxNew; /* Index in pWC of the next virtual term */ + + if( (pOne->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return; + if( (pTwo->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return; + if( (eOp & (WO_EQ|WO_LT|WO_LE))!=eOp + && (eOp & (WO_EQ|WO_GT|WO_GE))!=eOp ) return; + assert( pOne->pExpr->pLeft!=0 && pOne->pExpr->pRight!=0 ); + assert( pTwo->pExpr->pLeft!=0 && pTwo->pExpr->pRight!=0 ); + if( sqlite3ExprCompare(pOne->pExpr->pLeft, pTwo->pExpr->pLeft, -1) ) return; + if( sqlite3ExprCompare(pOne->pExpr->pRight, pTwo->pExpr->pRight, -1) )return; + /* If we reach this point, it means the two subterms can be combined */ + if( (eOp & (eOp-1))!=0 ){ + if( eOp & (WO_LT|WO_LE) ){ + eOp = WO_LE; + }else{ + assert( eOp & (WO_GT|WO_GE) ); + eOp = WO_GE; + } + } + db = pWC->pWInfo->pParse->db; + pNew = sqlite3ExprDup(db, pOne->pExpr, 0); + if( pNew==0 ) return; + for(op=TK_EQ; eOp!=(WO_EQ<<(op-TK_EQ)); op++){ assert( opop = op; + idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); + exprAnalyze(pSrc, pWC, idxNew); +} + +#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY) +/* +** Analyze a term that consists of two or more OR-connected +** subterms. So in: +** +** ... WHERE (a=5) AND (b=7 OR c=9 OR d=13) AND (d=13) +** ^^^^^^^^^^^^^^^^^^^^ +** +** This routine analyzes terms such as the middle term in the above example. +** A WhereOrTerm object is computed and attached to the term under +** analysis, regardless of the outcome of the analysis. Hence: +** +** WhereTerm.wtFlags |= TERM_ORINFO +** WhereTerm.u.pOrInfo = a dynamically allocated WhereOrTerm object +** +** The term being analyzed must have two or more of OR-connected subterms. +** A single subterm might be a set of AND-connected sub-subterms. +** Examples of terms under analysis: +** +** (A) t1.x=t2.y OR t1.x=t2.z OR t1.y=15 OR t1.z=t3.a+5 +** (B) x=expr1 OR expr2=x OR x=expr3 +** (C) t1.x=t2.y OR (t1.x=t2.z AND t1.y=15) +** (D) x=expr1 OR (y>11 AND y<22 AND z LIKE '*hello*') +** (E) (p.a=1 AND q.b=2 AND r.c=3) OR (p.x=4 AND q.y=5 AND r.z=6) +** (F) x>A OR (x=A AND y>=B) +** +** CASE 1: +** +** If all subterms are of the form T.C=expr for some single column of C and +** a single table T (as shown in example B above) then create a new virtual +** term that is an equivalent IN expression. In other words, if the term +** being analyzed is: +** +** x = expr1 OR expr2 = x OR x = expr3 +** +** then create a new virtual term like this: +** +** x IN (expr1,expr2,expr3) +** +** CASE 2: +** +** If there are exactly two disjuncts one side has x>A and the other side +** has x=A (for the same x and A) then add a new virtual conjunct term to the +** WHERE clause of the form "x>=A". Example: +** +** x>A OR (x=A AND y>B) adds: x>=A +** +** The added conjunct can sometimes be helpful in query planning. +** +** CASE 3: +** +** If all subterms are indexable by a single table T, then set +** +** WhereTerm.eOperator = WO_OR +** WhereTerm.u.pOrInfo->indexable |= the cursor number for table T +** +** A subterm is "indexable" if it is of the form +** "T.C " where C is any column of table T and +** is one of "=", "<", "<=", ">", ">=", "IS NULL", or "IN". +** A subterm is also indexable if it is an AND of two or more +** subsubterms at least one of which is indexable. Indexable AND +** subterms have their eOperator set to WO_AND and they have +** u.pAndInfo set to a dynamically allocated WhereAndTerm object. +** +** From another point of view, "indexable" means that the subterm could +** potentially be used with an index if an appropriate index exists. +** This analysis does not consider whether or not the index exists; that +** is decided elsewhere. This analysis only looks at whether subterms +** appropriate for indexing exist. +** +** All examples A through E above satisfy case 2. But if a term +** also satisfies case 1 (such as B) we know that the optimizer will +** always prefer case 1, so in that case we pretend that case 2 is not +** satisfied. +** +** It might be the case that multiple tables are indexable. For example, +** (E) above is indexable on tables P, Q, and R. +** +** Terms that satisfy case 2 are candidates for lookup by using +** separate indices to find rowids for each subterm and composing +** the union of all rowids using a RowSet object. This is similar +** to "bitmap indices" in other database engines. +** +** OTHERWISE: +** +** If neither case 1 nor case 2 apply, then leave the eOperator set to +** zero. This term is not useful for search. +*/ +static void exprAnalyzeOrTerm( + SrcList *pSrc, /* the FROM clause */ + WhereClause *pWC, /* the complete WHERE clause */ + int idxTerm /* Index of the OR-term to be analyzed */ +){ + WhereInfo *pWInfo = pWC->pWInfo; /* WHERE clause processing context */ + Parse *pParse = pWInfo->pParse; /* Parser context */ + sqlite3 *db = pParse->db; /* Database connection */ + WhereTerm *pTerm = &pWC->a[idxTerm]; /* The term to be analyzed */ + Expr *pExpr = pTerm->pExpr; /* The expression of the term */ + int i; /* Loop counters */ + WhereClause *pOrWc; /* Breakup of pTerm into subterms */ + WhereTerm *pOrTerm; /* A Sub-term within the pOrWc */ + WhereOrInfo *pOrInfo; /* Additional information associated with pTerm */ + Bitmask chngToIN; /* Tables that might satisfy case 1 */ + Bitmask indexable; /* Tables that are indexable, satisfying case 2 */ + + /* + ** Break the OR clause into its separate subterms. The subterms are + ** stored in a WhereClause structure containing within the WhereOrInfo + ** object that is attached to the original OR clause term. + */ + assert( (pTerm->wtFlags & (TERM_DYNAMIC|TERM_ORINFO|TERM_ANDINFO))==0 ); + assert( pExpr->op==TK_OR ); + pTerm->u.pOrInfo = pOrInfo = sqlite3DbMallocZero(db, sizeof(*pOrInfo)); + if( pOrInfo==0 ) return; + pTerm->wtFlags |= TERM_ORINFO; + pOrWc = &pOrInfo->wc; + whereClauseInit(pOrWc, pWInfo); + whereSplit(pOrWc, pExpr, TK_OR); + exprAnalyzeAll(pSrc, pOrWc); + if( db->mallocFailed ) return; + assert( pOrWc->nTerm>=2 ); + + /* + ** Compute the set of tables that might satisfy cases 1 or 2. + */ + indexable = ~(Bitmask)0; + chngToIN = ~(Bitmask)0; + for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0 && indexable; i--, pOrTerm++){ + if( (pOrTerm->eOperator & WO_SINGLE)==0 ){ + WhereAndInfo *pAndInfo; + assert( (pOrTerm->wtFlags & (TERM_ANDINFO|TERM_ORINFO))==0 ); + chngToIN = 0; + pAndInfo = sqlite3DbMallocRaw(db, sizeof(*pAndInfo)); + if( pAndInfo ){ + WhereClause *pAndWC; + WhereTerm *pAndTerm; + int j; + Bitmask b = 0; + pOrTerm->u.pAndInfo = pAndInfo; + pOrTerm->wtFlags |= TERM_ANDINFO; + pOrTerm->eOperator = WO_AND; + pAndWC = &pAndInfo->wc; + whereClauseInit(pAndWC, pWC->pWInfo); + whereSplit(pAndWC, pOrTerm->pExpr, TK_AND); + exprAnalyzeAll(pSrc, pAndWC); + pAndWC->pOuter = pWC; + testcase( db->mallocFailed ); + if( !db->mallocFailed ){ + for(j=0, pAndTerm=pAndWC->a; jnTerm; j++, pAndTerm++){ + assert( pAndTerm->pExpr ); + if( allowedOp(pAndTerm->pExpr->op) ){ + b |= getMask(&pWInfo->sMaskSet, pAndTerm->leftCursor); + } + } + } + indexable &= b; + } + }else if( pOrTerm->wtFlags & TERM_COPIED ){ + /* Skip this term for now. We revisit it when we process the + ** corresponding TERM_VIRTUAL term */ + }else{ + Bitmask b; + b = getMask(&pWInfo->sMaskSet, pOrTerm->leftCursor); + if( pOrTerm->wtFlags & TERM_VIRTUAL ){ + WhereTerm *pOther = &pOrWc->a[pOrTerm->iParent]; + b |= getMask(&pWInfo->sMaskSet, pOther->leftCursor); + } + indexable &= b; + if( (pOrTerm->eOperator & WO_EQ)==0 ){ + chngToIN = 0; + }else{ + chngToIN &= b; + } + } + } + + /* + ** Record the set of tables that satisfy case 3. The set might be + ** empty. + */ + pOrInfo->indexable = indexable; + pTerm->eOperator = indexable==0 ? 0 : WO_OR; + + /* For a two-way OR, attempt to implementation case 2. + */ + if( indexable && pOrWc->nTerm==2 ){ + int iOne = 0; + WhereTerm *pOne; + while( (pOne = whereNthSubterm(&pOrWc->a[0],iOne++))!=0 ){ + int iTwo = 0; + WhereTerm *pTwo; + while( (pTwo = whereNthSubterm(&pOrWc->a[1],iTwo++))!=0 ){ + whereCombineDisjuncts(pSrc, pWC, pOne, pTwo); + } + } + } + + /* + ** chngToIN holds a set of tables that *might* satisfy case 1. But + ** we have to do some additional checking to see if case 1 really + ** is satisfied. + ** + ** chngToIN will hold either 0, 1, or 2 bits. The 0-bit case means + ** that there is no possibility of transforming the OR clause into an + ** IN operator because one or more terms in the OR clause contain + ** something other than == on a column in the single table. The 1-bit + ** case means that every term of the OR clause is of the form + ** "table.column=expr" for some single table. The one bit that is set + ** will correspond to the common table. We still need to check to make + ** sure the same column is used on all terms. The 2-bit case is when + ** the all terms are of the form "table1.column=table2.column". It + ** might be possible to form an IN operator with either table1.column + ** or table2.column as the LHS if either is common to every term of + ** the OR clause. + ** + ** Note that terms of the form "table.column1=table.column2" (the + ** same table on both sizes of the ==) cannot be optimized. + */ + if( chngToIN ){ + int okToChngToIN = 0; /* True if the conversion to IN is valid */ + int iColumn = -1; /* Column index on lhs of IN operator */ + int iCursor = -1; /* Table cursor common to all terms */ + int j = 0; /* Loop counter */ + + /* Search for a table and column that appears on one side or the + ** other of the == operator in every subterm. That table and column + ** will be recorded in iCursor and iColumn. There might not be any + ** such table and column. Set okToChngToIN if an appropriate table + ** and column is found but leave okToChngToIN false if not found. + */ + for(j=0; j<2 && !okToChngToIN; j++){ + pOrTerm = pOrWc->a; + for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){ + assert( pOrTerm->eOperator & WO_EQ ); + pOrTerm->wtFlags &= ~TERM_OR_OK; + if( pOrTerm->leftCursor==iCursor ){ + /* This is the 2-bit case and we are on the second iteration and + ** current term is from the first iteration. So skip this term. */ + assert( j==1 ); + continue; + } + if( (chngToIN & getMask(&pWInfo->sMaskSet, pOrTerm->leftCursor))==0 ){ + /* This term must be of the form t1.a==t2.b where t2 is in the + ** chngToIN set but t1 is not. This term will be either preceded + ** or follwed by an inverted copy (t2.b==t1.a). Skip this term + ** and use its inversion. */ + testcase( pOrTerm->wtFlags & TERM_COPIED ); + testcase( pOrTerm->wtFlags & TERM_VIRTUAL ); + assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) ); + continue; + } + iColumn = pOrTerm->u.leftColumn; + iCursor = pOrTerm->leftCursor; + break; + } + if( i<0 ){ + /* No candidate table+column was found. This can only occur + ** on the second iteration */ + assert( j==1 ); + assert( IsPowerOfTwo(chngToIN) ); + assert( chngToIN==getMask(&pWInfo->sMaskSet, iCursor) ); + break; + } + testcase( j==1 ); + + /* We have found a candidate table and column. Check to see if that + ** table and column is common to every term in the OR clause */ + okToChngToIN = 1; + for(; i>=0 && okToChngToIN; i--, pOrTerm++){ + assert( pOrTerm->eOperator & WO_EQ ); + if( pOrTerm->leftCursor!=iCursor ){ + pOrTerm->wtFlags &= ~TERM_OR_OK; + }else if( pOrTerm->u.leftColumn!=iColumn ){ + okToChngToIN = 0; + }else{ + int affLeft, affRight; + /* If the right-hand side is also a column, then the affinities + ** of both right and left sides must be such that no type + ** conversions are required on the right. (Ticket #2249) + */ + affRight = sqlite3ExprAffinity(pOrTerm->pExpr->pRight); + affLeft = sqlite3ExprAffinity(pOrTerm->pExpr->pLeft); + if( affRight!=0 && affRight!=affLeft ){ + okToChngToIN = 0; + }else{ + pOrTerm->wtFlags |= TERM_OR_OK; + } + } + } + } + + /* At this point, okToChngToIN is true if original pTerm satisfies + ** case 1. In that case, construct a new virtual term that is + ** pTerm converted into an IN operator. + */ + if( okToChngToIN ){ + Expr *pDup; /* A transient duplicate expression */ + ExprList *pList = 0; /* The RHS of the IN operator */ + Expr *pLeft = 0; /* The LHS of the IN operator */ + Expr *pNew; /* The complete IN operator */ + + for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0; i--, pOrTerm++){ + if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue; + assert( pOrTerm->eOperator & WO_EQ ); + assert( pOrTerm->leftCursor==iCursor ); + assert( pOrTerm->u.leftColumn==iColumn ); + pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0); + pList = sqlite3ExprListAppend(pWInfo->pParse, pList, pDup); + pLeft = pOrTerm->pExpr->pLeft; + } + assert( pLeft!=0 ); + pDup = sqlite3ExprDup(db, pLeft, 0); + pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0, 0); + if( pNew ){ + int idxNew; + transferJoinMarkings(pNew, pExpr); + assert( !ExprHasProperty(pNew, EP_xIsSelect) ); + pNew->x.pList = pList; + idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); + testcase( idxNew==0 ); + exprAnalyze(pSrc, pWC, idxNew); + pTerm = &pWC->a[idxTerm]; + markTermAsChild(pWC, idxNew, idxTerm); + }else{ + sqlite3ExprListDelete(db, pList); + } + pTerm->eOperator = WO_NOOP; /* case 1 trumps case 3 */ + } + } +} +#endif /* !SQLITE_OMIT_OR_OPTIMIZATION && !SQLITE_OMIT_SUBQUERY */ + +/* +** 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 " X" it gets commuted +** to the standard form of "X ". +** +** If the expression is of the form "X Y" where both X and Y are +** columns, then the original expression is unchanged and a new virtual +** term of the form "Y X" is added to the WHERE clause and +** analyzed separately. The original term is marked with TERM_COPIED +** and the new term is marked with TERM_DYNAMIC (because it's pExpr +** needs to be freed with the WhereClause) and TERM_VIRTUAL (because it +** is a commuted copy of a prior term.) The original term has nChild=1 +** and the copy has idxParent set to the index of the original term. +*/ +static void exprAnalyze( + SrcList *pSrc, /* the FROM clause */ + WhereClause *pWC, /* the WHERE clause */ + int idxTerm /* Index of the term to be analyzed */ +){ + WhereInfo *pWInfo = pWC->pWInfo; /* WHERE clause processing context */ + WhereTerm *pTerm; /* The term to be analyzed */ + WhereMaskSet *pMaskSet; /* Set of table index masks */ + Expr *pExpr; /* The expression to be analyzed */ + Bitmask prereqLeft; /* Prerequesites of the pExpr->pLeft */ + Bitmask prereqAll; /* Prerequesites of pExpr */ + Bitmask extraRight = 0; /* Extra dependencies on LEFT JOIN */ + Expr *pStr1 = 0; /* RHS of LIKE/GLOB operator */ + int isComplete = 0; /* RHS of LIKE/GLOB ends with wildcard */ + int noCase = 0; /* uppercase equivalent to lowercase */ + int op; /* Top-level operator. pExpr->op */ + Parse *pParse = pWInfo->pParse; /* Parsing context */ + sqlite3 *db = pParse->db; /* Database connection */ + + if( db->mallocFailed ){ + return; + } + pTerm = &pWC->a[idxTerm]; + pMaskSet = &pWInfo->sMaskSet; + pExpr = pTerm->pExpr; + assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE ); + prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft); + op = pExpr->op; + if( op==TK_IN ){ + assert( pExpr->pRight==0 ); + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + pTerm->prereqRight = exprSelectTableUsage(pMaskSet, pExpr->x.pSelect); + }else{ + pTerm->prereqRight = exprListTableUsage(pMaskSet, pExpr->x.pList); + } + }else if( op==TK_ISNULL ){ + pTerm->prereqRight = 0; + }else{ + pTerm->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight); + } + prereqAll = exprTableUsage(pMaskSet, pExpr); + if( ExprHasProperty(pExpr, EP_FromJoin) ){ + Bitmask x = getMask(pMaskSet, pExpr->iRightJoinTable); + prereqAll |= x; + extraRight = x-1; /* ON clause terms may not be used with an index + ** on left table of a LEFT JOIN. Ticket #3015 */ + } + pTerm->prereqAll = prereqAll; + pTerm->leftCursor = -1; + pTerm->iParent = -1; + pTerm->eOperator = 0; + if( allowedOp(op) ){ + Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft); + Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight); + u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV; + if( pLeft->op==TK_COLUMN ){ + pTerm->leftCursor = pLeft->iTable; + pTerm->u.leftColumn = pLeft->iColumn; + pTerm->eOperator = operatorMask(op) & opMask; + } + if( pRight && pRight->op==TK_COLUMN ){ + WhereTerm *pNew; + Expr *pDup; + u16 eExtraOp = 0; /* Extra bits for pNew->eOperator */ + if( pTerm->leftCursor>=0 ){ + int idxNew; + pDup = sqlite3ExprDup(db, pExpr, 0); + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pDup); + return; + } + idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC); + if( idxNew==0 ) return; + pNew = &pWC->a[idxNew]; + markTermAsChild(pWC, idxNew, idxTerm); + pTerm = &pWC->a[idxTerm]; + pTerm->wtFlags |= TERM_COPIED; + if( pExpr->op==TK_EQ + && !ExprHasProperty(pExpr, EP_FromJoin) + && OptimizationEnabled(db, SQLITE_Transitive) + ){ + pTerm->eOperator |= WO_EQUIV; + eExtraOp = WO_EQUIV; + } + }else{ + pDup = pExpr; + pNew = pTerm; + } + exprCommute(pParse, pDup); + pLeft = sqlite3ExprSkipCollate(pDup->pLeft); + pNew->leftCursor = pLeft->iTable; + pNew->u.leftColumn = pLeft->iColumn; + testcase( (prereqLeft | extraRight) != prereqLeft ); + pNew->prereqRight = prereqLeft | extraRight; + pNew->prereqAll = prereqAll; + pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask; + } + } + +#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. For example: + ** + ** a BETWEEN b AND c + ** + ** is converted into: + ** + ** (a BETWEEN b AND c) AND (a>=b) AND (a<=c) + ** + ** The two new terms are added onto the end of the WhereClause object. + ** The new terms are "dynamic" and are children of the original BETWEEN + ** term. That means that if the BETWEEN term is coded, the children are + ** skipped. Or, if the children are satisfied by an index, the original + ** BETWEEN term is skipped. + */ + else if( pExpr->op==TK_BETWEEN && pWC->op==TK_AND ){ + ExprList *pList = pExpr->x.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 = sqlite3PExpr(pParse, ops[i], + sqlite3ExprDup(db, pExpr->pLeft, 0), + sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0); + transferJoinMarkings(pNewExpr, pExpr); + idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); + testcase( idxNew==0 ); + exprAnalyze(pSrc, pWC, idxNew); + pTerm = &pWC->a[idxTerm]; + markTermAsChild(pWC, idxNew, idxTerm); + } + } +#endif /* SQLITE_OMIT_BETWEEN_OPTIMIZATION */ + +#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY) + /* Analyze a term that is composed of two or more subterms connected by + ** an OR operator. + */ + else if( pExpr->op==TK_OR ){ + assert( pWC->op==TK_AND ); + exprAnalyzeOrTerm(pSrc, pWC, idxTerm); + pTerm = &pWC->a[idxTerm]; + } +#endif /* SQLITE_OMIT_OR_OPTIMIZATION */ + +#ifndef SQLITE_OMIT_LIKE_OPTIMIZATION + /* Add constraints to reduce the search space on a LIKE or GLOB + ** operator. + ** + ** A like pattern of the form "x LIKE 'aBc%'" is changed into constraints + ** + ** x>='ABC' AND x<'abd' AND x LIKE 'aBc%' + ** + ** The last character of the prefix "abc" is incremented to form the + ** termination condition "abd". If case is not significant (the default + ** for LIKE) then the lower-bound is made all uppercase and the upper- + ** bound is made all lowercase so that the bounds also work when comparing + ** BLOBs. + */ + if( pWC->op==TK_AND + && isLikeOrGlob(pParse, pExpr, &pStr1, &isComplete, &noCase) + ){ + Expr *pLeft; /* LHS of LIKE/GLOB operator */ + Expr *pStr2; /* Copy of pStr1 - RHS of LIKE/GLOB operator */ + Expr *pNewExpr1; + Expr *pNewExpr2; + int idxNew1; + int idxNew2; + const char *zCollSeqName; /* Name of collating sequence */ + const u16 wtFlags = TERM_LIKEOPT | TERM_VIRTUAL | TERM_DYNAMIC; + + pLeft = pExpr->x.pList->a[1].pExpr; + pStr2 = sqlite3ExprDup(db, pStr1, 0); + + /* Convert the lower bound to upper-case and the upper bound to + ** lower-case (upper-case is less than lower-case in ASCII) so that + ** the range constraints also work for BLOBs + */ + if( noCase && !pParse->db->mallocFailed ){ + int i; + char c; + pTerm->wtFlags |= TERM_LIKE; + for(i=0; (c = pStr1->u.zToken[i])!=0; i++){ + pStr1->u.zToken[i] = sqlite3Toupper(c); + pStr2->u.zToken[i] = sqlite3Tolower(c); + } + } + + if( !db->mallocFailed ){ + u8 c, *pC; /* Last character before the first wildcard */ + pC = (u8*)&pStr2->u.zToken[sqlite3Strlen30(pStr2->u.zToken)-1]; + c = *pC; + if( noCase ){ + /* The point is to increment the last character before the first + ** wildcard. But if we increment '@', that will push it into the + ** alphabetic range where case conversions will mess up the + ** inequality. To avoid this, make sure to also run the full + ** LIKE on all candidate expressions by clearing the isComplete flag + */ + if( c=='A'-1 ) isComplete = 0; + c = sqlite3UpperToLower[c]; + } + *pC = c + 1; + } + zCollSeqName = noCase ? "NOCASE" : "BINARY"; + pNewExpr1 = sqlite3ExprDup(db, pLeft, 0); + pNewExpr1 = sqlite3PExpr(pParse, TK_GE, + sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName), + pStr1, 0); + transferJoinMarkings(pNewExpr1, pExpr); + idxNew1 = whereClauseInsert(pWC, pNewExpr1, wtFlags); + testcase( idxNew1==0 ); + exprAnalyze(pSrc, pWC, idxNew1); + pNewExpr2 = sqlite3ExprDup(db, pLeft, 0); + pNewExpr2 = sqlite3PExpr(pParse, TK_LT, + sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName), + pStr2, 0); + transferJoinMarkings(pNewExpr2, pExpr); + idxNew2 = whereClauseInsert(pWC, pNewExpr2, wtFlags); + testcase( idxNew2==0 ); + exprAnalyze(pSrc, pWC, idxNew2); + pTerm = &pWC->a[idxTerm]; + if( isComplete ){ + markTermAsChild(pWC, idxNew1, idxTerm); + markTermAsChild(pWC, idxNew2, idxTerm); + } + } +#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* Add a WO_MATCH auxiliary term to the constraint set if the + ** current expression is of the form: column MATCH expr. + ** This information is used by the xBestIndex methods of + ** virtual tables. The native query optimizer does not attempt + ** to do anything with MATCH functions. + */ + if( isMatchOfColumn(pExpr) ){ + int idxNew; + Expr *pRight, *pLeft; + WhereTerm *pNewTerm; + Bitmask prereqColumn, prereqExpr; + + pRight = pExpr->x.pList->a[0].pExpr; + pLeft = pExpr->x.pList->a[1].pExpr; + prereqExpr = exprTableUsage(pMaskSet, pRight); + prereqColumn = exprTableUsage(pMaskSet, pLeft); + if( (prereqExpr & prereqColumn)==0 ){ + Expr *pNewExpr; + pNewExpr = sqlite3PExpr(pParse, TK_MATCH, + 0, sqlite3ExprDup(db, pRight, 0), 0); + idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); + testcase( idxNew==0 ); + pNewTerm = &pWC->a[idxNew]; + pNewTerm->prereqRight = prereqExpr; + pNewTerm->leftCursor = pLeft->iTable; + pNewTerm->u.leftColumn = pLeft->iColumn; + pNewTerm->eOperator = WO_MATCH; + markTermAsChild(pWC, idxNew, idxTerm); + pTerm = &pWC->a[idxTerm]; + pTerm->wtFlags |= TERM_COPIED; + pNewTerm->prereqAll = pTerm->prereqAll; + } + } +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + /* When sqlite_stat3 histogram data is available an operator of the + ** form "x IS NOT NULL" can sometimes be evaluated more efficiently + ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a + ** virtual term of that form. + ** + ** Note that the virtual term must be tagged with TERM_VNULL. This + ** TERM_VNULL tag will suppress the not-null check at the beginning + ** of the loop. Without the TERM_VNULL flag, the not-null check at + ** the start of the loop will prevent any results from being returned. + */ + if( pExpr->op==TK_NOTNULL + && pExpr->pLeft->op==TK_COLUMN + && pExpr->pLeft->iColumn>=0 + && OptimizationEnabled(db, SQLITE_Stat34) + ){ + Expr *pNewExpr; + Expr *pLeft = pExpr->pLeft; + int idxNew; + WhereTerm *pNewTerm; + + pNewExpr = sqlite3PExpr(pParse, TK_GT, + sqlite3ExprDup(db, pLeft, 0), + sqlite3PExpr(pParse, TK_NULL, 0, 0, 0), 0); + + idxNew = whereClauseInsert(pWC, pNewExpr, + TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL); + if( idxNew ){ + pNewTerm = &pWC->a[idxNew]; + pNewTerm->prereqRight = 0; + pNewTerm->leftCursor = pLeft->iTable; + pNewTerm->u.leftColumn = pLeft->iColumn; + pNewTerm->eOperator = WO_GT; + markTermAsChild(pWC, idxNew, idxTerm); + pTerm = &pWC->a[idxTerm]; + pTerm->wtFlags |= TERM_COPIED; + pNewTerm->prereqAll = pTerm->prereqAll; + } + } +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ + + /* Prevent ON clause terms of a LEFT JOIN from being used to drive + ** an index for tables to the left of the join. + */ + pTerm->prereqRight |= extraRight; +} + +/* +** This function searches pList for an entry that matches the iCol-th column +** of index pIdx. +** +** If such an expression is found, its index in pList->a[] is returned. If +** no expression is found, -1 is returned. +*/ +static int findIndexCol( + Parse *pParse, /* Parse context */ + ExprList *pList, /* Expression list to search */ + int iBase, /* Cursor for table associated with pIdx */ + Index *pIdx, /* Index to match column of */ + int iCol /* Column of index to match */ +){ + int i; + const char *zColl = pIdx->azColl[iCol]; + + for(i=0; inExpr; i++){ + Expr *p = sqlite3ExprSkipCollate(pList->a[i].pExpr); + if( p->op==TK_COLUMN + && p->iColumn==pIdx->aiColumn[iCol] + && p->iTable==iBase + ){ + CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr); + if( pColl && 0==sqlite3StrICmp(pColl->zName, zColl) ){ + return i; + } + } + } + + return -1; +} + +/* +** Return true if the DISTINCT expression-list passed as the third argument +** is redundant. +** +** A DISTINCT list is redundant if the database contains some subset of +** columns that are unique and non-null. +*/ +static int isDistinctRedundant( + Parse *pParse, /* Parsing context */ + SrcList *pTabList, /* The FROM clause */ + WhereClause *pWC, /* The WHERE clause */ + ExprList *pDistinct /* The result set that needs to be DISTINCT */ +){ + Table *pTab; + Index *pIdx; + int i; + int iBase; + + /* If there is more than one table or sub-select in the FROM clause of + ** this query, then it will not be possible to show that the DISTINCT + ** clause is redundant. */ + if( pTabList->nSrc!=1 ) return 0; + iBase = pTabList->a[0].iCursor; + pTab = pTabList->a[0].pTab; + + /* If any of the expressions is an IPK column on table iBase, then return + ** true. Note: The (p->iTable==iBase) part of this test may be false if the + ** current SELECT is a correlated sub-query. + */ + for(i=0; inExpr; i++){ + Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr); + if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1; + } + + /* Loop through all indices on the table, checking each to see if it makes + ** the DISTINCT qualifier redundant. It does so if: + ** + ** 1. The index is itself UNIQUE, and + ** + ** 2. All of the columns in the index are either part of the pDistinct + ** list, or else the WHERE clause contains a term of the form "col=X", + ** where X is a constant value. The collation sequences of the + ** comparison and select-list expressions must match those of the index. + ** + ** 3. All of those index columns for which the WHERE clause does not + ** contain a "col=X" term are subject to a NOT NULL constraint. + */ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( !IsUniqueIndex(pIdx) ) continue; + for(i=0; inKeyCol; i++){ + i16 iCol = pIdx->aiColumn[i]; + if( 0==findTerm(pWC, iBase, iCol, ~(Bitmask)0, WO_EQ, pIdx) ){ + int iIdxCol = findIndexCol(pParse, pDistinct, iBase, pIdx, i); + if( iIdxCol<0 || pTab->aCol[iCol].notNull==0 ){ + break; + } + } + } + if( i==pIdx->nKeyCol ){ + /* This index implies that the DISTINCT qualifier is redundant. */ + return 1; + } + } + + return 0; +} + + +/* +** Estimate the logarithm of the input value to base 2. +*/ +static LogEst estLog(LogEst N){ + return N<=10 ? 0 : sqlite3LogEst(N) - 33; +} + +/* +** Two routines for printing the content of an sqlite3_index_info +** structure. Used for testing and debugging only. If neither +** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines +** are no-ops. +*/ +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(WHERETRACE_ENABLED) +static void TRACE_IDX_INPUTS(sqlite3_index_info *p){ + int i; + if( !sqlite3WhereTrace ) return; + for(i=0; inConstraint; i++){ + sqlite3DebugPrintf(" constraint[%d]: col=%d termid=%d op=%d usabled=%d\n", + i, + p->aConstraint[i].iColumn, + p->aConstraint[i].iTermOffset, + p->aConstraint[i].op, + p->aConstraint[i].usable); + } + for(i=0; inOrderBy; i++){ + sqlite3DebugPrintf(" orderby[%d]: col=%d desc=%d\n", + i, + p->aOrderBy[i].iColumn, + p->aOrderBy[i].desc); + } +} +static void TRACE_IDX_OUTPUTS(sqlite3_index_info *p){ + int i; + if( !sqlite3WhereTrace ) return; + for(i=0; inConstraint; i++){ + sqlite3DebugPrintf(" usage[%d]: argvIdx=%d omit=%d\n", + i, + p->aConstraintUsage[i].argvIndex, + p->aConstraintUsage[i].omit); + } + sqlite3DebugPrintf(" idxNum=%d\n", p->idxNum); + sqlite3DebugPrintf(" idxStr=%s\n", p->idxStr); + sqlite3DebugPrintf(" orderByConsumed=%d\n", p->orderByConsumed); + sqlite3DebugPrintf(" estimatedCost=%g\n", p->estimatedCost); + sqlite3DebugPrintf(" estimatedRows=%lld\n", p->estimatedRows); +} +#else +#define TRACE_IDX_INPUTS(A) +#define TRACE_IDX_OUTPUTS(A) +#endif + +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX +/* +** Return TRUE if the WHERE clause term pTerm is of a form where it +** could be used with an index to access pSrc, assuming an appropriate +** index existed. +*/ +static int termCanDriveIndex( + WhereTerm *pTerm, /* WHERE clause term to check */ + struct SrcList_item *pSrc, /* Table we are trying to access */ + Bitmask notReady /* Tables in outer loops of the join */ +){ + char aff; + if( pTerm->leftCursor!=pSrc->iCursor ) return 0; + if( (pTerm->eOperator & WO_EQ)==0 ) return 0; + if( (pTerm->prereqRight & notReady)!=0 ) return 0; + if( pTerm->u.leftColumn<0 ) return 0; + aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity; + if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0; + return 1; +} +#endif + + +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX +/* +** Generate code to construct the Index object for an automatic index +** and to set up the WhereLevel object pLevel so that the code generator +** makes use of the automatic index. +*/ +static void constructAutomaticIndex( + Parse *pParse, /* The parsing context */ + WhereClause *pWC, /* The WHERE clause */ + struct SrcList_item *pSrc, /* The FROM clause term to get the next index */ + Bitmask notReady, /* Mask of cursors that are not available */ + WhereLevel *pLevel /* Write new index here */ +){ + int nKeyCol; /* Number of columns in the constructed index */ + WhereTerm *pTerm; /* A single term of the WHERE clause */ + WhereTerm *pWCEnd; /* End of pWC->a[] */ + Index *pIdx; /* Object describing the transient index */ + Vdbe *v; /* Prepared statement under construction */ + int addrInit; /* Address of the initialization bypass jump */ + Table *pTable; /* The table being indexed */ + int addrTop; /* Top of the index fill loop */ + int regRecord; /* Register holding an index record */ + int n; /* Column counter */ + int i; /* Loop counter */ + int mxBitCol; /* Maximum column in pSrc->colUsed */ + CollSeq *pColl; /* Collating sequence to on a column */ + WhereLoop *pLoop; /* The Loop object */ + char *zNotUsed; /* Extra space on the end of pIdx */ + Bitmask idxCols; /* Bitmap of columns used for indexing */ + Bitmask extraCols; /* Bitmap of additional columns */ + u8 sentWarning = 0; /* True if a warnning has been issued */ + Expr *pPartial = 0; /* Partial Index Expression */ + int iContinue = 0; /* Jump here to skip excluded rows */ + + /* Generate code to skip over the creation and initialization of the + ** transient index on 2nd and subsequent iterations of the loop. */ + v = pParse->pVdbe; + assert( v!=0 ); + addrInit = sqlite3CodeOnce(pParse); VdbeCoverage(v); + + /* Count the number of columns that will be added to the index + ** and used to match WHERE clause constraints */ + nKeyCol = 0; + pTable = pSrc->pTab; + pWCEnd = &pWC->a[pWC->nTerm]; + pLoop = pLevel->pWLoop; + idxCols = 0; + for(pTerm=pWC->a; pTermpExpr; + assert( !ExprHasProperty(pExpr, EP_FromJoin) /* prereq always non-zero */ + || pExpr->iRightJoinTable!=pSrc->iCursor /* for the right-hand */ + || pLoop->prereq!=0 ); /* table of a LEFT JOIN */ + if( pLoop->prereq==0 + && (pTerm->wtFlags & TERM_VIRTUAL)==0 + && !ExprHasProperty(pExpr, EP_FromJoin) + && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){ + pPartial = sqlite3ExprAnd(pParse->db, pPartial, + sqlite3ExprDup(pParse->db, pExpr, 0)); + } + if( termCanDriveIndex(pTerm, pSrc, notReady) ){ + int iCol = pTerm->u.leftColumn; + Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol); + testcase( iCol==BMS ); + testcase( iCol==BMS-1 ); + if( !sentWarning ){ + sqlite3_log(SQLITE_WARNING_AUTOINDEX, + "automatic index on %s(%s)", pTable->zName, + pTable->aCol[iCol].zName); + sentWarning = 1; + } + if( (idxCols & cMask)==0 ){ + if( whereLoopResize(pParse->db, pLoop, nKeyCol+1) ){ + goto end_auto_index_create; + } + pLoop->aLTerm[nKeyCol++] = pTerm; + idxCols |= cMask; + } + } + } + assert( nKeyCol>0 ); + pLoop->u.btree.nEq = pLoop->nLTerm = nKeyCol; + pLoop->wsFlags = WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WHERE_INDEXED + | WHERE_AUTO_INDEX; + + /* Count the number of additional columns needed to create a + ** covering index. A "covering index" is an index that contains all + ** columns that are needed by the query. With a covering index, the + ** original table never needs to be accessed. Automatic indices must + ** be a covering index because the index will not be updated if the + ** original table changes and the index and table cannot both be used + ** if they go out of sync. + */ + extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1)); + mxBitCol = MIN(BMS-1,pTable->nCol); + testcase( pTable->nCol==BMS-1 ); + testcase( pTable->nCol==BMS-2 ); + for(i=0; icolUsed & MASKBIT(BMS-1) ){ + nKeyCol += pTable->nCol - BMS + 1; + } + + /* Construct the Index object to describe this index */ + pIdx = sqlite3AllocateIndexObject(pParse->db, nKeyCol+1, 0, &zNotUsed); + if( pIdx==0 ) goto end_auto_index_create; + pLoop->u.btree.pIndex = pIdx; + pIdx->zName = "auto-index"; + pIdx->pTable = pTable; + n = 0; + idxCols = 0; + for(pTerm=pWC->a; pTermu.leftColumn; + Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol); + testcase( iCol==BMS-1 ); + testcase( iCol==BMS ); + if( (idxCols & cMask)==0 ){ + Expr *pX = pTerm->pExpr; + idxCols |= cMask; + pIdx->aiColumn[n] = pTerm->u.leftColumn; + pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight); + pIdx->azColl[n] = pColl ? pColl->zName : "BINARY"; + n++; + } + } + } + assert( (u32)n==pLoop->u.btree.nEq ); + + /* Add additional columns needed to make the automatic index into + ** a covering index */ + for(i=0; iaiColumn[n] = i; + pIdx->azColl[n] = "BINARY"; + n++; + } + } + if( pSrc->colUsed & MASKBIT(BMS-1) ){ + for(i=BMS-1; inCol; i++){ + pIdx->aiColumn[n] = i; + pIdx->azColl[n] = "BINARY"; + n++; + } + } + assert( n==nKeyCol ); + pIdx->aiColumn[n] = -1; + pIdx->azColl[n] = "BINARY"; + + /* Create the automatic index */ + assert( pLevel->iIdxCur>=0 ); + pLevel->iIdxCur = pParse->nTab++; + sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); + VdbeComment((v, "for %s", pTable->zName)); + + /* Fill the automatic index with content */ + sqlite3ExprCachePush(pParse); + addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v); + if( pPartial ){ + iContinue = sqlite3VdbeMakeLabel(v); + sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL); + pLoop->wsFlags |= WHERE_PARTIALIDX; + } + regRecord = sqlite3GetTempReg(pParse); + sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0); + sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); + sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX); + sqlite3VdbeJumpHere(v, addrTop); + sqlite3ReleaseTempReg(pParse, regRecord); + sqlite3ExprCachePop(pParse); + + /* Jump here when skipping the initialization */ + sqlite3VdbeJumpHere(v, addrInit); + +end_auto_index_create: + sqlite3ExprDelete(pParse->db, pPartial); +} +#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Allocate and populate an sqlite3_index_info structure. It is the +** responsibility of the caller to eventually release the structure +** by passing the pointer returned by this function to sqlite3_free(). +*/ +static sqlite3_index_info *allocateIndexInfo( + Parse *pParse, + WhereClause *pWC, + struct SrcList_item *pSrc, + ExprList *pOrderBy +){ + int i, j; + int nTerm; + struct sqlite3_index_constraint *pIdxCons; + struct sqlite3_index_orderby *pIdxOrderBy; + struct sqlite3_index_constraint_usage *pUsage; + WhereTerm *pTerm; + int nOrderBy; + sqlite3_index_info *pIdxInfo; + + /* Count the number of possible WHERE clause constraints referring + ** to this virtual table */ + for(i=nTerm=0, pTerm=pWC->a; inTerm; i++, pTerm++){ + if( pTerm->leftCursor != pSrc->iCursor ) continue; + assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); + testcase( pTerm->eOperator & WO_IN ); + testcase( pTerm->eOperator & WO_ISNULL ); + testcase( pTerm->eOperator & WO_ALL ); + if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV))==0 ) continue; + if( pTerm->wtFlags & TERM_VNULL ) continue; + nTerm++; + } + + /* If the ORDER BY clause contains only columns in the current + ** virtual table then allocate space for the aOrderBy part of + ** the sqlite3_index_info structure. + */ + nOrderBy = 0; + if( pOrderBy ){ + int n = pOrderBy->nExpr; + for(i=0; ia[i].pExpr; + if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break; + } + if( i==n){ + nOrderBy = n; + } + } + + /* Allocate the sqlite3_index_info structure + */ + pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo) + + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm + + sizeof(*pIdxOrderBy)*nOrderBy ); + if( pIdxInfo==0 ){ + sqlite3ErrorMsg(pParse, "out of memory"); + return 0; + } + + /* Initialize the structure. The sqlite3_index_info structure contains + ** many fields that are declared "const" to prevent xBestIndex from + ** changing them. We have to do some funky casting in order to + ** initialize those fields. + */ + pIdxCons = (struct sqlite3_index_constraint*)&pIdxInfo[1]; + pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm]; + pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy]; + *(int*)&pIdxInfo->nConstraint = nTerm; + *(int*)&pIdxInfo->nOrderBy = nOrderBy; + *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint = pIdxCons; + *(struct sqlite3_index_orderby**)&pIdxInfo->aOrderBy = pIdxOrderBy; + *(struct sqlite3_index_constraint_usage**)&pIdxInfo->aConstraintUsage = + pUsage; + + for(i=j=0, pTerm=pWC->a; inTerm; i++, pTerm++){ + u8 op; + if( pTerm->leftCursor != pSrc->iCursor ) continue; + assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); + testcase( pTerm->eOperator & WO_IN ); + testcase( pTerm->eOperator & WO_ISNULL ); + testcase( pTerm->eOperator & WO_ALL ); + if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV))==0 ) continue; + if( pTerm->wtFlags & TERM_VNULL ) continue; + pIdxCons[j].iColumn = pTerm->u.leftColumn; + pIdxCons[j].iTermOffset = i; + op = (u8)pTerm->eOperator & WO_ALL; + if( op==WO_IN ) op = WO_EQ; + pIdxCons[j].op = op; + /* The direct assignment in the previous line is possible only because + ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The + ** following asserts verify this fact. */ + assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ ); + assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT ); + assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE ); + assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT ); + assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE ); + assert( WO_MATCH==SQLITE_INDEX_CONSTRAINT_MATCH ); + assert( pTerm->eOperator & (WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) ); + j++; + } + for(i=0; ia[i].pExpr; + pIdxOrderBy[i].iColumn = pExpr->iColumn; + pIdxOrderBy[i].desc = pOrderBy->a[i].sortOrder; + } + + return pIdxInfo; +} + +/* +** The table object reference passed as the second argument to this function +** must represent a virtual table. This function invokes the xBestIndex() +** method of the virtual table with the sqlite3_index_info object that +** comes in as the 3rd argument to this function. +** +** If an error occurs, pParse is populated with an error message and a +** non-zero value is returned. Otherwise, 0 is returned and the output +** part of the sqlite3_index_info structure is left populated. +** +** Whether or not an error is returned, it is the responsibility of the +** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates +** that this is required. +*/ +static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ + sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab; + int i; + int rc; + + TRACE_IDX_INPUTS(p); + rc = pVtab->pModule->xBestIndex(pVtab, p); + TRACE_IDX_OUTPUTS(p); + + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_NOMEM ){ + pParse->db->mallocFailed = 1; + }else if( !pVtab->zErrMsg ){ + sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc)); + }else{ + sqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg); + } + } + sqlite3_free(pVtab->zErrMsg); + pVtab->zErrMsg = 0; + + for(i=0; inConstraint; i++){ + if( !p->aConstraint[i].usable && p->aConstraintUsage[i].argvIndex>0 ){ + sqlite3ErrorMsg(pParse, + "table %s: xBestIndex returned an invalid plan", pTab->zName); + } + } + + return pParse->nErr; +} +#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */ + +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 +/* +** Estimate the location of a particular key among all keys in an +** index. Store the results in aStat as follows: +** +** aStat[0] Est. number of rows less than pRec +** aStat[1] Est. number of rows equal to pRec +** +** Return the index of the sample that is the smallest sample that +** is greater than or equal to pRec. Note that this index is not an index +** into the aSample[] array - it is an index into a virtual set of samples +** based on the contents of aSample[] and the number of fields in record +** pRec. +*/ +static int whereKeyStats( + Parse *pParse, /* Database connection */ + Index *pIdx, /* Index to consider domain of */ + UnpackedRecord *pRec, /* Vector of values to consider */ + int roundUp, /* Round up if true. Round down if false */ + tRowcnt *aStat /* OUT: stats written here */ +){ + IndexSample *aSample = pIdx->aSample; + int iCol; /* Index of required stats in anEq[] etc. */ + int i; /* Index of first sample >= pRec */ + int iSample; /* Smallest sample larger than or equal to pRec */ + int iMin = 0; /* Smallest sample not yet tested */ + int iTest; /* Next sample to test */ + int res; /* Result of comparison operation */ + int nField; /* Number of fields in pRec */ + tRowcnt iLower = 0; /* anLt[] + anEq[] of largest sample pRec is > */ + +#ifndef SQLITE_DEBUG + UNUSED_PARAMETER( pParse ); +#endif + assert( pRec!=0 ); + assert( pIdx->nSample>0 ); + assert( pRec->nField>0 && pRec->nField<=pIdx->nSampleCol ); + + /* Do a binary search to find the first sample greater than or equal + ** to pRec. If pRec contains a single field, the set of samples to search + ** is simply the aSample[] array. If the samples in aSample[] contain more + ** than one fields, all fields following the first are ignored. + ** + ** If pRec contains N fields, where N is more than one, then as well as the + ** samples in aSample[] (truncated to N fields), the search also has to + ** consider prefixes of those samples. For example, if the set of samples + ** in aSample is: + ** + ** aSample[0] = (a, 5) + ** aSample[1] = (a, 10) + ** aSample[2] = (b, 5) + ** aSample[3] = (c, 100) + ** aSample[4] = (c, 105) + ** + ** Then the search space should ideally be the samples above and the + ** unique prefixes [a], [b] and [c]. But since that is hard to organize, + ** the code actually searches this set: + ** + ** 0: (a) + ** 1: (a, 5) + ** 2: (a, 10) + ** 3: (a, 10) + ** 4: (b) + ** 5: (b, 5) + ** 6: (c) + ** 7: (c, 100) + ** 8: (c, 105) + ** 9: (c, 105) + ** + ** For each sample in the aSample[] array, N samples are present in the + ** effective sample array. In the above, samples 0 and 1 are based on + ** sample aSample[0]. Samples 2 and 3 on aSample[1] etc. + ** + ** Often, sample i of each block of N effective samples has (i+1) fields. + ** Except, each sample may be extended to ensure that it is greater than or + ** equal to the previous sample in the array. For example, in the above, + ** sample 2 is the first sample of a block of N samples, so at first it + ** appears that it should be 1 field in size. However, that would make it + ** smaller than sample 1, so the binary search would not work. As a result, + ** it is extended to two fields. The duplicates that this creates do not + ** cause any problems. + */ + nField = pRec->nField; + iCol = 0; + iSample = pIdx->nSample * nField; + do{ + int iSamp; /* Index in aSample[] of test sample */ + int n; /* Number of fields in test sample */ + + iTest = (iMin+iSample)/2; + iSamp = iTest / nField; + if( iSamp>0 ){ + /* The proposed effective sample is a prefix of sample aSample[iSamp]. + ** Specifically, the shortest prefix of at least (1 + iTest%nField) + ** fields that is greater than the previous effective sample. */ + for(n=(iTest % nField) + 1; nnField = n; + res = sqlite3VdbeRecordCompare(aSample[iSamp].n, aSample[iSamp].p, pRec); + if( res<0 ){ + iLower = aSample[iSamp].anLt[n-1] + aSample[iSamp].anEq[n-1]; + iMin = iTest+1; + }else if( res==0 && ndb->mallocFailed==0 ){ + if( res==0 ){ + /* If (res==0) is true, then pRec must be equal to sample i. */ + assert( inSample ); + assert( iCol==nField-1 ); + pRec->nField = nField; + assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec) + || pParse->db->mallocFailed + ); + }else{ + /* Unless i==pIdx->nSample, indicating that pRec is larger than + ** all samples in the aSample[] array, pRec must be smaller than the + ** (iCol+1) field prefix of sample i. */ + assert( i<=pIdx->nSample && i>=0 ); + pRec->nField = iCol+1; + assert( i==pIdx->nSample + || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0 + || pParse->db->mallocFailed ); + + /* if i==0 and iCol==0, then record pRec is smaller than all samples + ** in the aSample[] array. Otherwise, if (iCol>0) then pRec must + ** be greater than or equal to the (iCol) field prefix of sample i. + ** If (i>0), then pRec must also be greater than sample (i-1). */ + if( iCol>0 ){ + pRec->nField = iCol; + assert( sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)<=0 + || pParse->db->mallocFailed ); + } + if( i>0 ){ + pRec->nField = nField; + assert( sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0 + || pParse->db->mallocFailed ); + } + } + } +#endif /* ifdef SQLITE_DEBUG */ + + if( res==0 ){ + /* Record pRec is equal to sample i */ + assert( iCol==nField-1 ); + aStat[0] = aSample[i].anLt[iCol]; + aStat[1] = aSample[i].anEq[iCol]; + }else{ + /* At this point, the (iCol+1) field prefix of aSample[i] is the first + ** sample that is greater than pRec. Or, if i==pIdx->nSample then pRec + ** is larger than all samples in the array. */ + tRowcnt iUpper, iGap; + if( i>=pIdx->nSample ){ + iUpper = sqlite3LogEstToInt(pIdx->aiRowLogEst[0]); + }else{ + iUpper = aSample[i].anLt[iCol]; + } + + if( iLower>=iUpper ){ + iGap = 0; + }else{ + iGap = iUpper - iLower; + } + if( roundUp ){ + iGap = (iGap*2)/3; + }else{ + iGap = iGap/3; + } + aStat[0] = iLower + iGap; + aStat[1] = pIdx->aAvgEq[iCol]; + } + + /* Restore the pRec->nField value before returning. */ + pRec->nField = nField; + return i; +} +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ + +/* +** If it is not NULL, pTerm is a term that provides an upper or lower +** bound on a range scan. Without considering pTerm, it is estimated +** that the scan will visit nNew rows. This function returns the number +** estimated to be visited after taking pTerm into account. +** +** If the user explicitly specified a likelihood() value for this term, +** then the return value is the likelihood multiplied by the number of +** input rows. Otherwise, this function assumes that an "IS NOT NULL" term +** has a likelihood of 0.50, and any other term a likelihood of 0.25. +*/ +static LogEst whereRangeAdjust(WhereTerm *pTerm, LogEst nNew){ + LogEst nRet = nNew; + if( pTerm ){ + if( pTerm->truthProb<=0 ){ + nRet += pTerm->truthProb; + }else if( (pTerm->wtFlags & TERM_VNULL)==0 ){ + nRet -= 20; assert( 20==sqlite3LogEst(4) ); + } + } + return nRet; +} + +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 +/* +** This function is called to estimate the number of rows visited by a +** range-scan on a skip-scan index. For example: +** +** CREATE INDEX i1 ON t1(a, b, c); +** SELECT * FROM t1 WHERE a=? AND c BETWEEN ? AND ?; +** +** Value pLoop->nOut is currently set to the estimated number of rows +** visited for scanning (a=? AND b=?). This function reduces that estimate +** by some factor to account for the (c BETWEEN ? AND ?) expression based +** on the stat4 data for the index. this scan will be peformed multiple +** times (once for each (a,b) combination that matches a=?) is dealt with +** by the caller. +** +** It does this by scanning through all stat4 samples, comparing values +** extracted from pLower and pUpper with the corresponding column in each +** sample. If L and U are the number of samples found to be less than or +** equal to the values extracted from pLower and pUpper respectively, and +** N is the total number of samples, the pLoop->nOut value is adjusted +** as follows: +** +** nOut = nOut * ( min(U - L, 1) / N ) +** +** If pLower is NULL, or a value cannot be extracted from the term, L is +** set to zero. If pUpper is NULL, or a value cannot be extracted from it, +** U is set to N. +** +** Normally, this function sets *pbDone to 1 before returning. However, +** if no value can be extracted from either pLower or pUpper (and so the +** estimate of the number of rows delivered remains unchanged), *pbDone +** is left as is. +** +** If an error occurs, an SQLite error code is returned. Otherwise, +** SQLITE_OK. +*/ +static int whereRangeSkipScanEst( + Parse *pParse, /* Parsing & code generating context */ + WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */ + WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */ + WhereLoop *pLoop, /* Update the .nOut value of this loop */ + int *pbDone /* Set to true if at least one expr. value extracted */ +){ + Index *p = pLoop->u.btree.pIndex; + int nEq = pLoop->u.btree.nEq; + sqlite3 *db = pParse->db; + int nLower = -1; + int nUpper = p->nSample+1; + int rc = SQLITE_OK; + int iCol = p->aiColumn[nEq]; + u8 aff = iCol>=0 ? p->pTable->aCol[iCol].affinity : SQLITE_AFF_INTEGER; + CollSeq *pColl; + + sqlite3_value *p1 = 0; /* Value extracted from pLower */ + sqlite3_value *p2 = 0; /* Value extracted from pUpper */ + sqlite3_value *pVal = 0; /* Value extracted from record */ + + pColl = sqlite3LocateCollSeq(pParse, p->azColl[nEq]); + if( pLower ){ + rc = sqlite3Stat4ValueFromExpr(pParse, pLower->pExpr->pRight, aff, &p1); + nLower = 0; + } + if( pUpper && rc==SQLITE_OK ){ + rc = sqlite3Stat4ValueFromExpr(pParse, pUpper->pExpr->pRight, aff, &p2); + nUpper = p2 ? 0 : p->nSample; + } + + if( p1 || p2 ){ + int i; + int nDiff; + for(i=0; rc==SQLITE_OK && inSample; i++){ + rc = sqlite3Stat4Column(db, p->aSample[i].p, p->aSample[i].n, nEq, &pVal); + if( rc==SQLITE_OK && p1 ){ + int res = sqlite3MemCompare(p1, pVal, pColl); + if( res>=0 ) nLower++; + } + if( rc==SQLITE_OK && p2 ){ + int res = sqlite3MemCompare(p2, pVal, pColl); + if( res>=0 ) nUpper++; + } + } + nDiff = (nUpper - nLower); + if( nDiff<=0 ) nDiff = 1; + + /* If there is both an upper and lower bound specified, and the + ** comparisons indicate that they are close together, use the fallback + ** method (assume that the scan visits 1/64 of the rows) for estimating + ** the number of rows visited. Otherwise, estimate the number of rows + ** using the method described in the header comment for this function. */ + if( nDiff!=1 || pUpper==0 || pLower==0 ){ + int nAdjust = (sqlite3LogEst(p->nSample) - sqlite3LogEst(nDiff)); + pLoop->nOut -= nAdjust; + *pbDone = 1; + WHERETRACE(0x10, ("range skip-scan regions: %u..%u adjust=%d est=%d\n", + nLower, nUpper, nAdjust*-1, pLoop->nOut)); + } + + }else{ + assert( *pbDone==0 ); + } + + sqlite3ValueFree(p1); + sqlite3ValueFree(p2); + sqlite3ValueFree(pVal); + + return rc; +} +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ + +/* +** This function is used to estimate the number of rows that will be visited +** by scanning an index for a range of values. The range may have an upper +** bound, a lower bound, or both. The WHERE clause terms that set the upper +** and lower bounds are represented by pLower and pUpper respectively. For +** example, assuming that index p is on t1(a): +** +** ... FROM t1 WHERE a > ? AND a < ? ... +** |_____| |_____| +** | | +** pLower pUpper +** +** If either of the upper or lower bound is not present, then NULL is passed in +** place of the corresponding WhereTerm. +** +** The value in (pBuilder->pNew->u.btree.nEq) is the number of the index +** column subject to the range constraint. Or, equivalently, the number of +** equality constraints optimized by the proposed index scan. For example, +** assuming index p is on t1(a, b), and the SQL query is: +** +** ... FROM t1 WHERE a = ? AND b > ? AND b < ? ... +** +** then nEq is set to 1 (as the range restricted column, b, is the second +** left-most column of the index). Or, if the query is: +** +** ... FROM t1 WHERE a > ? AND a < ? ... +** +** then nEq is set to 0. +** +** When this function is called, *pnOut is set to the sqlite3LogEst() of the +** number of rows that the index scan is expected to visit without +** considering the range constraints. If nEq is 0, then *pnOut is the number of +** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced) +** to account for the range constraints pLower and pUpper. +** +** In the absence of sqlite_stat4 ANALYZE data, or if such data cannot be +** used, a single range inequality reduces the search space by a factor of 4. +** and a pair of constraints (x>? AND x123" Might be NULL */ + WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */ + WhereLoop *pLoop /* Modify the .nOut and maybe .rRun fields */ +){ + int rc = SQLITE_OK; + int nOut = pLoop->nOut; + LogEst nNew; + +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + Index *p = pLoop->u.btree.pIndex; + int nEq = pLoop->u.btree.nEq; + + if( p->nSample>0 && nEqnSampleCol ){ + if( nEq==pBuilder->nRecValid ){ + UnpackedRecord *pRec = pBuilder->pRec; + tRowcnt a[2]; + u8 aff; + + /* Variable iLower will be set to the estimate of the number of rows in + ** the index that are less than the lower bound of the range query. The + ** lower bound being the concatenation of $P and $L, where $P is the + ** key-prefix formed by the nEq values matched against the nEq left-most + ** columns of the index, and $L is the value in pLower. + ** + ** Or, if pLower is NULL or $L cannot be extracted from it (because it + ** is not a simple variable or literal value), the lower bound of the + ** range is $P. Due to a quirk in the way whereKeyStats() works, even + ** if $L is available, whereKeyStats() is called for both ($P) and + ** ($P:$L) and the larger of the two returned values is used. + ** + ** Similarly, iUpper is to be set to the estimate of the number of rows + ** less than the upper bound of the range query. Where the upper bound + ** is either ($P) or ($P:$U). Again, even if $U is available, both values + ** of iUpper are requested of whereKeyStats() and the smaller used. + ** + ** The number of rows between the two bounds is then just iUpper-iLower. + */ + tRowcnt iLower; /* Rows less than the lower bound */ + tRowcnt iUpper; /* Rows less than the upper bound */ + int iLwrIdx = -2; /* aSample[] for the lower bound */ + int iUprIdx = -1; /* aSample[] for the upper bound */ + + if( pRec ){ + testcase( pRec->nField!=pBuilder->nRecValid ); + pRec->nField = pBuilder->nRecValid; + } + if( nEq==p->nKeyCol ){ + aff = SQLITE_AFF_INTEGER; + }else{ + aff = p->pTable->aCol[p->aiColumn[nEq]].affinity; + } + /* Determine iLower and iUpper using ($P) only. */ + if( nEq==0 ){ + iLower = 0; + iUpper = p->nRowEst0; + }else{ + /* Note: this call could be optimized away - since the same values must + ** have been requested when testing key $P in whereEqualScanEst(). */ + whereKeyStats(pParse, p, pRec, 0, a); + iLower = a[0]; + iUpper = a[0] + a[1]; + } + + assert( pLower==0 || (pLower->eOperator & (WO_GT|WO_GE))!=0 ); + assert( pUpper==0 || (pUpper->eOperator & (WO_LT|WO_LE))!=0 ); + assert( p->aSortOrder!=0 ); + if( p->aSortOrder[nEq] ){ + /* The roles of pLower and pUpper are swapped for a DESC index */ + SWAP(WhereTerm*, pLower, pUpper); + } + + /* If possible, improve on the iLower estimate using ($P:$L). */ + if( pLower ){ + int bOk; /* True if value is extracted from pExpr */ + Expr *pExpr = pLower->pExpr->pRight; + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk); + if( rc==SQLITE_OK && bOk ){ + tRowcnt iNew; + iLwrIdx = whereKeyStats(pParse, p, pRec, 0, a); + iNew = a[0] + ((pLower->eOperator & (WO_GT|WO_LE)) ? a[1] : 0); + if( iNew>iLower ) iLower = iNew; + nOut--; + pLower = 0; + } + } + + /* If possible, improve on the iUpper estimate using ($P:$U). */ + if( pUpper ){ + int bOk; /* True if value is extracted from pExpr */ + Expr *pExpr = pUpper->pExpr->pRight; + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk); + if( rc==SQLITE_OK && bOk ){ + tRowcnt iNew; + iUprIdx = whereKeyStats(pParse, p, pRec, 1, a); + iNew = a[0] + ((pUpper->eOperator & (WO_GT|WO_LE)) ? a[1] : 0); + if( iNewpRec = pRec; + if( rc==SQLITE_OK ){ + if( iUpper>iLower ){ + nNew = sqlite3LogEst(iUpper - iLower); + /* TUNING: If both iUpper and iLower are derived from the same + ** sample, then assume they are 4x more selective. This brings + ** the estimated selectivity more in line with what it would be + ** if estimated without the use of STAT3/4 tables. */ + if( iLwrIdx==iUprIdx ) nNew -= 20; assert( 20==sqlite3LogEst(4) ); + }else{ + nNew = 10; assert( 10==sqlite3LogEst(2) ); + } + if( nNewwtFlags & TERM_VNULL)==0 ); + nNew = whereRangeAdjust(pLower, nOut); + nNew = whereRangeAdjust(pUpper, nNew); + + /* TUNING: If there is both an upper and lower limit and neither limit + ** has an application-defined likelihood(), assume the range is + ** reduced by an additional 75%. This means that, by default, an open-ended + ** range query (e.g. col > ?) is assumed to match 1/4 of the rows in the + ** index. While a closed range (e.g. col BETWEEN ? AND ?) is estimated to + ** match 1/64 of the index. */ + if( pLower && pLower->truthProb>0 && pUpper && pUpper->truthProb>0 ){ + nNew -= 20; + } + + nOut -= (pLower!=0) + (pUpper!=0); + if( nNew<10 ) nNew = 10; + if( nNewnOut>nOut ){ + WHERETRACE(0x10,("Range scan lowers nOut from %d to %d\n", + pLoop->nOut, nOut)); + } +#endif + pLoop->nOut = (LogEst)nOut; + return rc; +} + +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 +/* +** Estimate the number of rows that will be returned based on +** an equality constraint x=VALUE and where that VALUE occurs in +** the histogram data. This only works when x is the left-most +** column of an index and sqlite_stat3 histogram data is available +** for that index. When pExpr==NULL that means the constraint is +** "x IS NULL" instead of "x=VALUE". +** +** Write the estimated row count into *pnRow and return SQLITE_OK. +** If unable to make an estimate, leave *pnRow unchanged and return +** non-zero. +** +** This routine can fail if it is unable to load a collating sequence +** required for string comparison, or if unable to allocate memory +** for a UTF conversion required for comparison. The error is stored +** in the pParse structure. +*/ +static int whereEqualScanEst( + Parse *pParse, /* Parsing & code generating context */ + WhereLoopBuilder *pBuilder, + Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */ + tRowcnt *pnRow /* Write the revised row estimate here */ +){ + Index *p = pBuilder->pNew->u.btree.pIndex; + int nEq = pBuilder->pNew->u.btree.nEq; + UnpackedRecord *pRec = pBuilder->pRec; + u8 aff; /* Column affinity */ + int rc; /* Subfunction return code */ + tRowcnt a[2]; /* Statistics */ + int bOk; + + assert( nEq>=1 ); + assert( nEq<=p->nColumn ); + assert( p->aSample!=0 ); + assert( p->nSample>0 ); + assert( pBuilder->nRecValidnRecValid<(nEq-1) ){ + return SQLITE_NOTFOUND; + } + + /* This is an optimization only. The call to sqlite3Stat4ProbeSetValue() + ** below would return the same value. */ + if( nEq>=p->nColumn ){ + *pnRow = 1; + return SQLITE_OK; + } + + aff = p->pTable->aCol[p->aiColumn[nEq-1]].affinity; + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq-1, &bOk); + pBuilder->pRec = pRec; + if( rc!=SQLITE_OK ) return rc; + if( bOk==0 ) return SQLITE_NOTFOUND; + pBuilder->nRecValid = nEq; + + whereKeyStats(pParse, p, pRec, 0, a); + WHERETRACE(0x10,("equality scan regions: %d\n", (int)a[1])); + *pnRow = a[1]; + + return rc; +} +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ + +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 +/* +** Estimate the number of rows that will be returned based on +** an IN constraint where the right-hand side of the IN operator +** is a list of values. Example: +** +** WHERE x IN (1,2,3,4) +** +** Write the estimated row count into *pnRow and return SQLITE_OK. +** If unable to make an estimate, leave *pnRow unchanged and return +** non-zero. +** +** This routine can fail if it is unable to load a collating sequence +** required for string comparison, or if unable to allocate memory +** for a UTF conversion required for comparison. The error is stored +** in the pParse structure. +*/ +static int whereInScanEst( + Parse *pParse, /* Parsing & code generating context */ + WhereLoopBuilder *pBuilder, + ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */ + tRowcnt *pnRow /* Write the revised row estimate here */ +){ + Index *p = pBuilder->pNew->u.btree.pIndex; + i64 nRow0 = sqlite3LogEstToInt(p->aiRowLogEst[0]); + int nRecValid = pBuilder->nRecValid; + int rc = SQLITE_OK; /* Subfunction return code */ + tRowcnt nEst; /* Number of rows for a single term */ + tRowcnt nRowEst = 0; /* New estimate of the number of rows */ + int i; /* Loop counter */ + + assert( p->aSample!=0 ); + for(i=0; rc==SQLITE_OK && inExpr; i++){ + nEst = nRow0; + rc = whereEqualScanEst(pParse, pBuilder, pList->a[i].pExpr, &nEst); + nRowEst += nEst; + pBuilder->nRecValid = nRecValid; + } + + if( rc==SQLITE_OK ){ + if( nRowEst > nRow0 ) nRowEst = nRow0; + *pnRow = nRowEst; + WHERETRACE(0x10,("IN row estimate: est=%d\n", nRowEst)); + } + assert( pBuilder->nRecValid==nRecValid ); + return rc; +} +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ + +/* +** 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. +** +** If all the children of a term are disabled, then that term is also +** automatically disabled. In this way, terms get disabled if derived +** virtual terms are tested first. For example: +** +** x GLOB 'abc*' AND x>='abc' AND x<'acd' +** \___________/ \______/ \_____/ +** parent child1 child2 +** +** Only the parent term was in the original WHERE clause. The child1 +** and child2 terms were added by the LIKE optimization. If both of +** the virtual child terms are valid, then testing of the parent can be +** skipped. +** +** Usually the parent term is marked as TERM_CODED. But if the parent +** term was originally TERM_LIKE, then the parent gets TERM_LIKECOND instead. +** The TERM_LIKECOND marking indicates that the term should be coded inside +** a conditional such that is only evaluated on the second pass of a +** LIKE-optimization loop, when scanning BLOBs instead of strings. +*/ +static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ + int nLoop = 0; + while( pTerm + && (pTerm->wtFlags & TERM_CODED)==0 + && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin)) + && (pLevel->notReady & pTerm->prereqAll)==0 + ){ + if( nLoop && (pTerm->wtFlags & TERM_LIKE)!=0 ){ + pTerm->wtFlags |= TERM_LIKECOND; + }else{ + pTerm->wtFlags |= TERM_CODED; + } + if( pTerm->iParent<0 ) break; + pTerm = &pTerm->pWC->a[pTerm->iParent]; + pTerm->nChild--; + if( pTerm->nChild!=0 ) break; + nLoop++; + } +} + +/* +** Code an OP_Affinity opcode to apply the column affinity string zAff +** to the n registers starting at base. +** +** As an optimization, SQLITE_AFF_NONE entries (which are no-ops) at the +** beginning and end of zAff are ignored. If all entries in zAff are +** SQLITE_AFF_NONE, then no code gets generated. +** +** This routine makes its own copy of zAff so that the caller is free +** to modify zAff after this routine returns. +*/ +static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){ + Vdbe *v = pParse->pVdbe; + if( zAff==0 ){ + assert( pParse->db->mallocFailed ); + return; + } + assert( v!=0 ); + + /* Adjust base and n to skip over SQLITE_AFF_NONE entries at the beginning + ** and end of the affinity string. + */ + while( n>0 && zAff[0]==SQLITE_AFF_NONE ){ + n--; + base++; + zAff++; + } + while( n>1 && zAff[n-1]==SQLITE_AFF_NONE ){ + n--; + } + + /* Code the OP_Affinity opcode if there is anything left to do. */ + if( n>0 ){ + sqlite3VdbeAddOp2(v, OP_Affinity, base, n); + sqlite3VdbeChangeP4(v, -1, zAff, n); + sqlite3ExprCacheAffinityChange(pParse, base, n); + } +} + + +/* +** 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 in register iReg. +** +** 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 int codeEqualityTerm( + Parse *pParse, /* The parsing context */ + WhereTerm *pTerm, /* The term of the WHERE clause to be coded */ + WhereLevel *pLevel, /* The level of the FROM clause we are working on */ + int iEq, /* Index of the equality term within this level */ + int bRev, /* True for reverse-order IN operations */ + int iTarget /* Attempt to leave results in this register */ +){ + Expr *pX = pTerm->pExpr; + Vdbe *v = pParse->pVdbe; + int iReg; /* Register holding results */ + + assert( iTarget>0 ); + if( pX->op==TK_EQ ){ + iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget); + }else if( pX->op==TK_ISNULL ){ + iReg = iTarget; + sqlite3VdbeAddOp2(v, OP_Null, 0, iReg); +#ifndef SQLITE_OMIT_SUBQUERY + }else{ + int eType; + int iTab; + struct InLoop *pIn; + WhereLoop *pLoop = pLevel->pWLoop; + + if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 + && pLoop->u.btree.pIndex!=0 + && pLoop->u.btree.pIndex->aSortOrder[iEq] + ){ + testcase( iEq==0 ); + testcase( bRev ); + bRev = !bRev; + } + assert( pX->op==TK_IN ); + iReg = iTarget; + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0); + if( eType==IN_INDEX_INDEX_DESC ){ + testcase( bRev ); + bRev = !bRev; + } + iTab = pX->iTable; + sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); + VdbeCoverageIf(v, bRev); + VdbeCoverageIf(v, !bRev); + assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); + pLoop->wsFlags |= WHERE_IN_ABLE; + if( pLevel->u.in.nIn==0 ){ + pLevel->addrNxt = sqlite3VdbeMakeLabel(v); + } + pLevel->u.in.nIn++; + pLevel->u.in.aInLoop = + sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop, + sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn); + pIn = pLevel->u.in.aInLoop; + if( pIn ){ + pIn += pLevel->u.in.nIn - 1; + pIn->iCur = iTab; + if( eType==IN_INDEX_ROWID ){ + pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iReg); + }else{ + pIn->addrInTop = sqlite3VdbeAddOp3(v, OP_Column, iTab, 0, iReg); + } + pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen; + sqlite3VdbeAddOp1(v, OP_IsNull, iReg); VdbeCoverage(v); + }else{ + pLevel->u.in.nIn = 0; + } +#endif + } + disableTerm(pLevel, pTerm); + return iReg; +} + +/* +** Generate code that will evaluate all == and IN constraints for an +** index scan. +** +** 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 stored +** in consecutive registers and the index of the first register is returned. +** +** 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 and +** compute the affinity string. +** +** The nExtraReg parameter is 0 or 1. It is 0 if all WHERE clause constraints +** are == or IN and are covered by the nEq. nExtraReg is 1 if there is +** an inequality constraint (such as the "c>=5 AND c<10" in the example) that +** occurs after the nEq quality constraints. +** +** This routine allocates a range of nEq+nExtraReg memory cells and returns +** the index of the first memory cell in that range. The code that +** calls this routine will use that memory range to store keys for +** start and termination conditions of the loop. +** key value of the loop. If one or more IN operators appear, then +** this routine allocates an additional nEq memory cells for internal +** use. +** +** Before returning, *pzAff is set to point to a buffer containing a +** copy of the column affinity string of the index allocated using +** sqlite3DbMalloc(). Except, entries in the copy of the string associated +** with equality constraints that use NONE affinity are set to +** SQLITE_AFF_NONE. This is to deal with SQL such as the following: +** +** CREATE TABLE t1(a TEXT PRIMARY KEY, b); +** SELECT ... FROM t1 AS t2, t1 WHERE t1.a = t2.b; +** +** In the example above, the index on t1(a) has TEXT affinity. But since +** the right hand side of the equality constraint (t2.b) has NONE affinity, +** no conversion should be attempted before using a t2.b value as part of +** a key to search the index. Hence the first byte in the returned affinity +** string in this example would be set to SQLITE_AFF_NONE. +*/ +static int codeAllEqualityTerms( + Parse *pParse, /* Parsing context */ + WhereLevel *pLevel, /* Which nested loop of the FROM we are coding */ + int bRev, /* Reverse the order of IN operators */ + int nExtraReg, /* Number of extra registers to allocate */ + char **pzAff /* OUT: Set to point to affinity string */ +){ + u16 nEq; /* The number of == or IN constraints to code */ + u16 nSkip; /* Number of left-most columns to skip */ + Vdbe *v = pParse->pVdbe; /* The vm under construction */ + Index *pIdx; /* The index being used for this loop */ + WhereTerm *pTerm; /* A single constraint term */ + WhereLoop *pLoop; /* The WhereLoop object */ + int j; /* Loop counter */ + int regBase; /* Base register */ + int nReg; /* Number of registers to allocate */ + char *zAff; /* Affinity string to return */ + + /* This module is only called on query plans that use an index. */ + pLoop = pLevel->pWLoop; + assert( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ); + nEq = pLoop->u.btree.nEq; + nSkip = pLoop->nSkip; + pIdx = pLoop->u.btree.pIndex; + assert( pIdx!=0 ); + + /* Figure out how many memory cells we will need then allocate them. + */ + regBase = pParse->nMem + 1; + nReg = pLoop->u.btree.nEq + nExtraReg; + pParse->nMem += nReg; + + zAff = sqlite3DbStrDup(pParse->db, sqlite3IndexAffinityStr(v, pIdx)); + if( !zAff ){ + pParse->db->mallocFailed = 1; + } + + if( nSkip ){ + int iIdxCur = pLevel->iIdxCur; + sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur); + VdbeCoverageIf(v, bRev==0); + VdbeCoverageIf(v, bRev!=0); + VdbeComment((v, "begin skip-scan on %s", pIdx->zName)); + j = sqlite3VdbeAddOp0(v, OP_Goto); + pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT), + iIdxCur, 0, regBase, nSkip); + VdbeCoverageIf(v, bRev==0); + VdbeCoverageIf(v, bRev!=0); + sqlite3VdbeJumpHere(v, j); + for(j=0; jaiColumn[j]>=0 ); + VdbeComment((v, "%s", pIdx->pTable->aCol[pIdx->aiColumn[j]].zName)); + } + } + + /* Evaluate the equality constraints + */ + assert( zAff==0 || (int)strlen(zAff)>=nEq ); + for(j=nSkip; jaLTerm[j]; + assert( pTerm!=0 ); + /* The following testcase is true for indices with redundant columns. + ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */ + testcase( (pTerm->wtFlags & TERM_CODED)!=0 ); + testcase( pTerm->wtFlags & TERM_VIRTUAL ); + r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j); + if( r1!=regBase+j ){ + if( nReg==1 ){ + sqlite3ReleaseTempReg(pParse, regBase); + regBase = r1; + }else{ + sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j); + } + } + testcase( pTerm->eOperator & WO_ISNULL ); + testcase( pTerm->eOperator & WO_IN ); + if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){ + Expr *pRight = pTerm->pExpr->pRight; + if( sqlite3ExprCanBeNull(pRight) ){ + sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk); + VdbeCoverage(v); + } + if( zAff ){ + if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_NONE ){ + zAff[j] = SQLITE_AFF_NONE; + } + if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[j]) ){ + zAff[j] = SQLITE_AFF_NONE; + } + } + } + } + *pzAff = zAff; + return regBase; +} + +#ifndef SQLITE_OMIT_EXPLAIN +/* +** This routine is a helper for explainIndexRange() below +** +** pStr holds the text of an expression that we are building up one term +** at a time. This routine adds a new term to the end of the expression. +** Terms are separated by AND so add the "AND" text for second and subsequent +** terms only. +*/ +static void explainAppendTerm( + StrAccum *pStr, /* The text expression being built */ + int iTerm, /* Index of this term. First is zero */ + const char *zColumn, /* Name of the column */ + const char *zOp /* Name of the operator */ +){ + if( iTerm ) sqlite3StrAccumAppend(pStr, " AND ", 5); + sqlite3StrAccumAppendAll(pStr, zColumn); + sqlite3StrAccumAppend(pStr, zOp, 1); + sqlite3StrAccumAppend(pStr, "?", 1); +} + +/* +** Argument pLevel describes a strategy for scanning table pTab. This +** function appends text to pStr that describes the subset of table +** rows scanned by the strategy in the form of an SQL expression. +** +** For example, if the query: +** +** SELECT * FROM t1 WHERE a=1 AND b>2; +** +** is run and there is an index on (a, b), then this function returns a +** string similar to: +** +** "a=? AND b>?" +*/ +static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop, Table *pTab){ + Index *pIndex = pLoop->u.btree.pIndex; + u16 nEq = pLoop->u.btree.nEq; + u16 nSkip = pLoop->nSkip; + int i, j; + Column *aCol = pTab->aCol; + i16 *aiColumn = pIndex->aiColumn; + + if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return; + sqlite3StrAccumAppend(pStr, " (", 2); + for(i=0; i=nSkip ){ + explainAppendTerm(pStr, i, z, "="); + }else{ + if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5); + sqlite3XPrintf(pStr, 0, "ANY(%s)", z); + } + } + + j = i; + if( pLoop->wsFlags&WHERE_BTM_LIMIT ){ + char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName; + explainAppendTerm(pStr, i++, z, ">"); + } + if( pLoop->wsFlags&WHERE_TOP_LIMIT ){ + char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName; + explainAppendTerm(pStr, i, z, "<"); + } + sqlite3StrAccumAppend(pStr, ")", 1); +} + +/* +** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN +** command, or if either SQLITE_DEBUG or SQLITE_ENABLE_STMT_SCANSTATUS was +** defined at compile-time. If it is not a no-op, a single OP_Explain opcode +** is added to the output to describe the table scan strategy in pLevel. +** +** If an OP_Explain opcode is added to the VM, its address is returned. +** Otherwise, if no OP_Explain is coded, zero is returned. +*/ +static int explainOneScan( + Parse *pParse, /* Parse context */ + SrcList *pTabList, /* Table list this loop refers to */ + WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ + int iLevel, /* Value for "level" column of output */ + int iFrom, /* Value for "from" column of output */ + u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ +){ + int ret = 0; +#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS) + if( pParse->explain==2 ) +#endif + { + struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom]; + Vdbe *v = pParse->pVdbe; /* VM being constructed */ + sqlite3 *db = pParse->db; /* Database handle */ + int iId = pParse->iSelectId; /* Select id (left-most output column) */ + int isSearch; /* True for a SEARCH. False for SCAN. */ + WhereLoop *pLoop; /* The controlling WhereLoop object */ + u32 flags; /* Flags that describe this loop */ + char *zMsg; /* Text to add to EQP output */ + StrAccum str; /* EQP output string */ + char zBuf[100]; /* Initial space for EQP output string */ + + pLoop = pLevel->pWLoop; + flags = pLoop->wsFlags; + if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return 0; + + isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 + || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0)) + || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX)); + + sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); + sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN"); + if( pItem->pSelect ){ + sqlite3XPrintf(&str, 0, " SUBQUERY %d", pItem->iSelectId); + }else{ + sqlite3XPrintf(&str, 0, " TABLE %s", pItem->zName); + } + + if( pItem->zAlias ){ + sqlite3XPrintf(&str, 0, " AS %s", pItem->zAlias); + } + if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){ + const char *zFmt = 0; + Index *pIdx; + + assert( pLoop->u.btree.pIndex!=0 ); + pIdx = pLoop->u.btree.pIndex; + assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) ); + if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){ + if( isSearch ){ + zFmt = "PRIMARY KEY"; + } + }else if( flags & WHERE_PARTIALIDX ){ + zFmt = "AUTOMATIC PARTIAL COVERING INDEX"; + }else if( flags & WHERE_AUTO_INDEX ){ + zFmt = "AUTOMATIC COVERING INDEX"; + }else if( flags & WHERE_IDX_ONLY ){ + zFmt = "COVERING INDEX %s"; + }else{ + zFmt = "INDEX %s"; + } + if( zFmt ){ + sqlite3StrAccumAppend(&str, " USING ", 7); + sqlite3XPrintf(&str, 0, zFmt, pIdx->zName); + explainIndexRange(&str, pLoop, pItem->pTab); + } + }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){ + const char *zRange; + if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){ + zRange = "(rowid=?)"; + }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){ + zRange = "(rowid>? AND rowid?)"; + }else{ + assert( flags&WHERE_TOP_LIMIT); + zRange = "(rowidu.vtab.idxNum, pLoop->u.vtab.idxStr); + } +#endif +#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS + if( pLoop->nOut>=10 ){ + sqlite3XPrintf(&str, 0, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut)); + }else{ + sqlite3StrAccumAppend(&str, " (~1 row)", 9); + } +#endif + zMsg = sqlite3StrAccumFinish(&str); + ret = sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg,P4_DYNAMIC); + } + return ret; +} +#else +# define explainOneScan(u,v,w,x,y,z) 0 +#endif /* SQLITE_OMIT_EXPLAIN */ + +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS +/* +** Configure the VM passed as the first argument with an +** sqlite3_stmt_scanstatus() entry corresponding to the scan used to +** implement level pLvl. Argument pSrclist is a pointer to the FROM +** clause that the scan reads data from. +** +** If argument addrExplain is not 0, it must be the address of an +** OP_Explain instruction that describes the same loop. +*/ +static void addScanStatus( + Vdbe *v, /* Vdbe to add scanstatus entry to */ + SrcList *pSrclist, /* FROM clause pLvl reads data from */ + WhereLevel *pLvl, /* Level to add scanstatus() entry for */ + int addrExplain /* Address of OP_Explain (or 0) */ +){ + const char *zObj = 0; + WhereLoop *pLoop = pLvl->pWLoop; + if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 ){ + zObj = pLoop->u.btree.pIndex->zName; + }else{ + zObj = pSrclist->a[pLvl->iFrom].zName; + } + sqlite3VdbeScanStatus( + v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj + ); +} +#else +# define addScanStatus(a, b, c, d) ((void)d) +#endif + +/* +** If the most recently coded instruction is a constant range contraint +** that originated from the LIKE optimization, then change the P3 to be +** pLoop->iLikeRepCntr and set P5. +** +** The LIKE optimization trys to evaluate "x LIKE 'abc%'" as a range +** expression: "x>='ABC' AND x<'abd'". But this requires that the range +** scan loop run twice, once for strings and a second time for BLOBs. +** The OP_String opcodes on the second pass convert the upper and lower +** bound string contants to blobs. This routine makes the necessary changes +** to the OP_String opcodes for that to happen. +*/ +static void whereLikeOptimizationStringFixup( + Vdbe *v, /* prepared statement under construction */ + WhereLevel *pLevel, /* The loop that contains the LIKE operator */ + WhereTerm *pTerm /* The upper or lower bound just coded */ +){ + if( pTerm->wtFlags & TERM_LIKEOPT ){ + VdbeOp *pOp; + assert( pLevel->iLikeRepCntr>0 ); + pOp = sqlite3VdbeGetOp(v, -1); + assert( pOp!=0 ); + assert( pOp->opcode==OP_String8 + || pTerm->pWC->pWInfo->pParse->db->mallocFailed ); + pOp->p3 = pLevel->iLikeRepCntr; + pOp->p5 = 1; + } +} + +/* +** Generate code for the start of the iLevel-th loop in the WHERE clause +** implementation described by pWInfo. +*/ +static Bitmask codeOneLoopStart( + WhereInfo *pWInfo, /* Complete information about the WHERE clause */ + int iLevel, /* Which level of pWInfo->a[] should be coded */ + Bitmask notReady /* Which tables are currently available */ +){ + int j, k; /* Loop counters */ + int iCur; /* The VDBE cursor for the table */ + int addrNxt; /* Where to jump to continue with the next IN case */ + int omitTable; /* True if we use the index only */ + int bRev; /* True if we need to scan in reverse order */ + WhereLevel *pLevel; /* The where level to be coded */ + WhereLoop *pLoop; /* The WhereLoop object being coded */ + WhereClause *pWC; /* Decomposition of the entire WHERE clause */ + WhereTerm *pTerm; /* A WHERE clause term */ + Parse *pParse; /* Parsing context */ + sqlite3 *db; /* Database connection */ + Vdbe *v; /* The prepared stmt under constructions */ + struct SrcList_item *pTabItem; /* FROM clause term being coded */ + int addrBrk; /* Jump here to break out of the loop */ + int addrCont; /* Jump here to continue with next cycle */ + int iRowidReg = 0; /* Rowid is stored in this register, if not zero */ + int iReleaseReg = 0; /* Temp register to free before returning */ + + pParse = pWInfo->pParse; + v = pParse->pVdbe; + pWC = &pWInfo->sWC; + db = pParse->db; + pLevel = &pWInfo->a[iLevel]; + pLoop = pLevel->pWLoop; + pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; + iCur = pTabItem->iCursor; + pLevel->notReady = notReady & ~getMask(&pWInfo->sMaskSet, iCur); + bRev = (pWInfo->revMask>>iLevel)&1; + omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 + && (pWInfo->wctrlFlags & WHERE_FORCE_TABLE)==0; + VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName)); + + /* Create labels for the "break" and "continue" instructions + ** for the current loop. Jump to addrBrk to break out of a loop. + ** Jump to cont to go immediately to the next iteration of the + ** loop. + ** + ** When there is an IN operator, we also have a "addrNxt" label that + ** means to continue with the next IN value combination. When + ** there are no IN operators in the constraints, the "addrNxt" label + ** is the same as "addrBrk". + */ + addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite3VdbeMakeLabel(v); + addrCont = pLevel->addrCont = 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[0].jointype & JT_LEFT)!=0 ){ + pLevel->iLeftJoin = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin); + VdbeComment((v, "init LEFT JOIN no-match flag")); + } + + /* Special case of a FROM clause subquery implemented as a co-routine */ + if( pTabItem->viaCoroutine ){ + int regYield = pTabItem->regReturn; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); + pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk); + VdbeCoverage(v); + VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName)); + pLevel->op = OP_Goto; + }else + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){ + /* Case 1: The table is a virtual-table. Use the VFilter and VNext + ** to access the data. + */ + int iReg; /* P3 Value for OP_VFilter */ + int addrNotFound; + int nConstraint = pLoop->nLTerm; + + sqlite3ExprCachePush(pParse); + iReg = sqlite3GetTempRange(pParse, nConstraint+2); + addrNotFound = pLevel->addrBrk; + for(j=0; jaLTerm[j]; + if( pTerm==0 ) continue; + if( pTerm->eOperator & WO_IN ){ + codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget); + addrNotFound = pLevel->addrNxt; + }else{ + sqlite3ExprCode(pParse, pTerm->pExpr->pRight, iTarget); + } + } + sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg); + sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1); + sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg, + pLoop->u.vtab.idxStr, + pLoop->u.vtab.needFree ? P4_MPRINTF : P4_STATIC); + VdbeCoverage(v); + pLoop->u.vtab.needFree = 0; + for(j=0; ju.vtab.omitMask>>j)&1 ){ + disableTerm(pLevel, pLoop->aLTerm[j]); + } + } + pLevel->op = OP_VNext; + pLevel->p1 = iCur; + pLevel->p2 = sqlite3VdbeCurrentAddr(v); + sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2); + sqlite3ExprCachePop(pParse); + }else +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + + if( (pLoop->wsFlags & WHERE_IPK)!=0 + && (pLoop->wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_EQ))!=0 + ){ + /* Case 2: 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( pLoop->u.btree.nEq==1 ); + pTerm = pLoop->aLTerm[0]; + assert( pTerm!=0 ); + assert( pTerm->pExpr!=0 ); + assert( omitTable==0 ); + testcase( pTerm->wtFlags & TERM_VIRTUAL ); + iReleaseReg = ++pParse->nMem; + iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg); + if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg); + addrNxt = pLevel->addrNxt; + sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg); + VdbeCoverage(v); + sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1); + sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); + VdbeComment((v, "pk")); + pLevel->op = OP_Noop; + }else if( (pLoop->wsFlags & WHERE_IPK)!=0 + && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0 + ){ + /* Case 3: We have an inequality comparison against the ROWID field. + */ + int testOp = OP_Noop; + int start; + int memEndValue = 0; + WhereTerm *pStart, *pEnd; + + assert( omitTable==0 ); + j = 0; + pStart = pEnd = 0; + if( pLoop->wsFlags & WHERE_BTM_LIMIT ) pStart = pLoop->aLTerm[j++]; + if( pLoop->wsFlags & WHERE_TOP_LIMIT ) pEnd = pLoop->aLTerm[j++]; + assert( pStart!=0 || pEnd!=0 ); + if( bRev ){ + pTerm = pStart; + pStart = pEnd; + pEnd = pTerm; + } + if( pStart ){ + Expr *pX; /* The expression that defines the start bound */ + int r1, rTemp; /* Registers for holding the start boundary */ + + /* The following constant maps TK_xx codes into corresponding + ** seek opcodes. It depends on a particular ordering of TK_xx + */ + const u8 aMoveOp[] = { + /* TK_GT */ OP_SeekGT, + /* TK_LE */ OP_SeekLE, + /* TK_LT */ OP_SeekLT, + /* TK_GE */ OP_SeekGE + }; + assert( TK_LE==TK_GT+1 ); /* Make sure the ordering.. */ + assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */ + assert( TK_GE==TK_GT+3 ); /* ... is correcct. */ + + assert( (pStart->wtFlags & TERM_VNULL)==0 ); + testcase( pStart->wtFlags & TERM_VIRTUAL ); + pX = pStart->pExpr; + assert( pX!=0 ); + testcase( pStart->leftCursor!=iCur ); /* transitive constraints */ + r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp); + sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1); + VdbeComment((v, "pk")); + VdbeCoverageIf(v, pX->op==TK_GT); + VdbeCoverageIf(v, pX->op==TK_LE); + VdbeCoverageIf(v, pX->op==TK_LT); + VdbeCoverageIf(v, pX->op==TK_GE); + sqlite3ExprCacheAffinityChange(pParse, r1, 1); + sqlite3ReleaseTempReg(pParse, rTemp); + disableTerm(pLevel, pStart); + }else{ + sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk); + VdbeCoverageIf(v, bRev==0); + VdbeCoverageIf(v, bRev!=0); + } + if( pEnd ){ + Expr *pX; + pX = pEnd->pExpr; + assert( pX!=0 ); + assert( (pEnd->wtFlags & TERM_VNULL)==0 ); + testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */ + testcase( pEnd->wtFlags & TERM_VIRTUAL ); + memEndValue = ++pParse->nMem; + sqlite3ExprCode(pParse, pX->pRight, memEndValue); + 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; + assert( pLevel->p5==0 ); + if( testOp!=OP_Noop ){ + iRowidReg = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg); + sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); + sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg); + VdbeCoverageIf(v, testOp==OP_Le); + VdbeCoverageIf(v, testOp==OP_Lt); + VdbeCoverageIf(v, testOp==OP_Ge); + VdbeCoverageIf(v, testOp==OP_Gt); + sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL); + } + }else if( pLoop->wsFlags & WHERE_INDEXED ){ + /* Case 4: A scan using an index. + ** + ** The WHERE clause may contain zero or more equality + ** terms ("==" or "IN" operators) that refer to the N + ** left-most columns of the index. It may also contain + ** inequality constraints (>, <, >= or <=) on the indexed + ** column that immediately follows the N equalities. Only + ** the right-most column can be an inequality - the rest must + ** use the "==" and "IN" operators. For example, if the + ** index is on (x,y,z), then the following clauses are all + ** optimized: + ** + ** x=5 + ** x=5 AND y=10 + ** x=5 AND y<10 + ** x=5 AND y>5 AND y<10 + ** x=5 AND y=5 AND z<=10 + ** + ** The z<10 term of the following cannot be used, only + ** the x=5 term: + ** + ** x=5 AND z<10 + ** + ** N may be zero if there are inequality constraints. + ** If there are no inequality constraints, then N is at + ** least one. + ** + ** 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. + */ + static const u8 aStartOp[] = { + 0, + 0, + OP_Rewind, /* 2: (!start_constraints && startEq && !bRev) */ + OP_Last, /* 3: (!start_constraints && startEq && bRev) */ + OP_SeekGT, /* 4: (start_constraints && !startEq && !bRev) */ + OP_SeekLT, /* 5: (start_constraints && !startEq && bRev) */ + OP_SeekGE, /* 6: (start_constraints && startEq && !bRev) */ + OP_SeekLE /* 7: (start_constraints && startEq && bRev) */ + }; + static const u8 aEndOp[] = { + OP_IdxGE, /* 0: (end_constraints && !bRev && !endEq) */ + OP_IdxGT, /* 1: (end_constraints && !bRev && endEq) */ + OP_IdxLE, /* 2: (end_constraints && bRev && !endEq) */ + OP_IdxLT, /* 3: (end_constraints && bRev && endEq) */ + }; + u16 nEq = pLoop->u.btree.nEq; /* Number of == or IN terms */ + int regBase; /* Base register holding constraint values */ + WhereTerm *pRangeStart = 0; /* Inequality constraint at range start */ + WhereTerm *pRangeEnd = 0; /* Inequality constraint at range end */ + int startEq; /* True if range start uses ==, >= or <= */ + int endEq; /* True if range end uses ==, >= or <= */ + int start_constraints; /* Start of range is constrained */ + int nConstraint; /* Number of constraint terms */ + Index *pIdx; /* The index we will be using */ + int iIdxCur; /* The VDBE cursor for the index */ + int nExtraReg = 0; /* Number of extra registers needed */ + int op; /* Instruction opcode */ + char *zStartAff; /* Affinity for start of range constraint */ + char cEndAff = 0; /* Affinity for end of range constraint */ + u8 bSeekPastNull = 0; /* True to seek past initial nulls */ + u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */ + + pIdx = pLoop->u.btree.pIndex; + iIdxCur = pLevel->iIdxCur; + assert( nEq>=pLoop->nSkip ); + + /* If this loop satisfies a sort order (pOrderBy) request that + ** was passed to this function to implement a "SELECT min(x) ..." + ** query, then the caller will only allow the loop to run for + ** a single iteration. This means that the first row returned + ** should not have a NULL value stored in 'x'. If column 'x' is + ** the first one after the nEq equality constraints in the index, + ** this requires some special handling. + */ + assert( pWInfo->pOrderBy==0 + || pWInfo->pOrderBy->nExpr==1 + || (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 ); + if( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0 + && pWInfo->nOBSat>0 + && (pIdx->nKeyCol>nEq) + ){ + assert( pLoop->nSkip==0 ); + bSeekPastNull = 1; + nExtraReg = 1; + } + + /* Find any inequality constraint terms for the start and end + ** of the range. + */ + j = nEq; + if( pLoop->wsFlags & WHERE_BTM_LIMIT ){ + pRangeStart = pLoop->aLTerm[j++]; + nExtraReg = 1; + /* Like optimization range constraints always occur in pairs */ + assert( (pRangeStart->wtFlags & TERM_LIKEOPT)==0 || + (pLoop->wsFlags & WHERE_TOP_LIMIT)!=0 ); + } + if( pLoop->wsFlags & WHERE_TOP_LIMIT ){ + pRangeEnd = pLoop->aLTerm[j++]; + nExtraReg = 1; + if( (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){ + assert( pRangeStart!=0 ); /* LIKE opt constraints */ + assert( pRangeStart->wtFlags & TERM_LIKEOPT ); /* occur in pairs */ + pLevel->iLikeRepCntr = ++pParse->nMem; + testcase( bRev ); + testcase( pIdx->aSortOrder[nEq]==SQLITE_SO_DESC ); + sqlite3VdbeAddOp2(v, OP_Integer, + bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC), + pLevel->iLikeRepCntr); + VdbeComment((v, "LIKE loop counter")); + pLevel->addrLikeRep = sqlite3VdbeCurrentAddr(v); + } + if( pRangeStart==0 + && (j = pIdx->aiColumn[nEq])>=0 + && pIdx->pTable->aCol[j].notNull==0 + ){ + bSeekPastNull = 1; + } + } + assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 ); + + /* Generate code to evaluate all constraint terms using == or IN + ** and store the values of those terms in an array of registers + ** starting at regBase. + */ + regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff); + assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq ); + if( zStartAff ) cEndAff = zStartAff[nEq]; + addrNxt = pLevel->addrNxt; + + /* If we are doing a reverse order scan on an ascending index, or + ** a forward order scan on a descending index, interchange the + ** start and end terms (pRangeStart and pRangeEnd). + */ + if( (nEqnKeyCol && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC)) + || (bRev && pIdx->nKeyCol==nEq) + ){ + SWAP(WhereTerm *, pRangeEnd, pRangeStart); + SWAP(u8, bSeekPastNull, bStopAtNull); + } + + testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 ); + testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 ); + testcase( pRangeEnd && (pRangeEnd->eOperator & WO_LE)!=0 ); + testcase( pRangeEnd && (pRangeEnd->eOperator & WO_GE)!=0 ); + startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE); + endEq = !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE); + start_constraints = pRangeStart || nEq>0; + + /* Seek the index cursor to the start of the range. */ + nConstraint = nEq; + if( pRangeStart ){ + Expr *pRight = pRangeStart->pExpr->pRight; + sqlite3ExprCode(pParse, pRight, regBase+nEq); + whereLikeOptimizationStringFixup(v, pLevel, pRangeStart); + if( (pRangeStart->wtFlags & TERM_VNULL)==0 + && sqlite3ExprCanBeNull(pRight) + ){ + sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); + VdbeCoverage(v); + } + if( zStartAff ){ + if( sqlite3CompareAffinity(pRight, zStartAff[nEq])==SQLITE_AFF_NONE){ + /* Since the comparison is to be performed with no conversions + ** applied to the operands, set the affinity to apply to pRight to + ** SQLITE_AFF_NONE. */ + zStartAff[nEq] = SQLITE_AFF_NONE; + } + if( sqlite3ExprNeedsNoAffinityChange(pRight, zStartAff[nEq]) ){ + zStartAff[nEq] = SQLITE_AFF_NONE; + } + } + nConstraint++; + testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); + }else if( bSeekPastNull ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); + nConstraint++; + startEq = 0; + start_constraints = 1; + } + codeApplyAffinity(pParse, regBase, nConstraint - bSeekPastNull, zStartAff); + op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; + assert( op!=0 ); + sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); + VdbeCoverage(v); + VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind ); + VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last ); + VdbeCoverageIf(v, op==OP_SeekGT); testcase( op==OP_SeekGT ); + VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE ); + VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE ); + VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT ); + + /* Load the value for the inequality constraint at the end of the + ** range (if any). + */ + nConstraint = nEq; + if( pRangeEnd ){ + Expr *pRight = pRangeEnd->pExpr->pRight; + sqlite3ExprCacheRemove(pParse, regBase+nEq, 1); + sqlite3ExprCode(pParse, pRight, regBase+nEq); + whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd); + if( (pRangeEnd->wtFlags & TERM_VNULL)==0 + && sqlite3ExprCanBeNull(pRight) + ){ + sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); + VdbeCoverage(v); + } + if( sqlite3CompareAffinity(pRight, cEndAff)!=SQLITE_AFF_NONE + && !sqlite3ExprNeedsNoAffinityChange(pRight, cEndAff) + ){ + codeApplyAffinity(pParse, regBase+nEq, 1, &cEndAff); + } + nConstraint++; + testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); + }else if( bStopAtNull ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); + endEq = 0; + nConstraint++; + } + sqlite3DbFree(db, zStartAff); + + /* Top of the loop body */ + pLevel->p2 = sqlite3VdbeCurrentAddr(v); + + /* Check if the index cursor is past the end of the range. */ + if( nConstraint ){ + op = aEndOp[bRev*2 + endEq]; + sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); + testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT ); + testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE ); + testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT ); + testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); + } + + /* Seek the table cursor, if required */ + disableTerm(pLevel, pRangeStart); + disableTerm(pLevel, pRangeEnd); + if( omitTable ){ + /* pIdx is a covering index. No need to access the main table. */ + }else if( HasRowid(pIdx->pTable) ){ + iRowidReg = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg); + sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); + sqlite3VdbeAddOp2(v, OP_Seek, iCur, iRowidReg); /* Deferred seek */ + }else if( iCur!=iIdxCur ){ + Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable); + iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol); + for(j=0; jnKeyCol; j++){ + k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]); + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j); + } + sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont, + iRowidReg, pPk->nKeyCol); VdbeCoverage(v); + } + + /* Record the instruction used to terminate the loop. Disable + ** WHERE clause terms made redundant by the index range scan. + */ + if( pLoop->wsFlags & WHERE_ONEROW ){ + pLevel->op = OP_Noop; + }else if( bRev ){ + pLevel->op = OP_Prev; + }else{ + pLevel->op = OP_Next; + } + pLevel->p1 = iIdxCur; + pLevel->p3 = (pLoop->wsFlags&WHERE_UNQ_WANTED)!=0 ? 1:0; + if( (pLoop->wsFlags & WHERE_CONSTRAINT)==0 ){ + pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; + }else{ + assert( pLevel->p5==0 ); + } + }else + +#ifndef SQLITE_OMIT_OR_OPTIMIZATION + if( pLoop->wsFlags & WHERE_MULTI_OR ){ + /* Case 5: Two or more separately indexed terms connected by OR + ** + ** Example: + ** + ** CREATE TABLE t1(a,b,c,d); + ** CREATE INDEX i1 ON t1(a); + ** CREATE INDEX i2 ON t1(b); + ** CREATE INDEX i3 ON t1(c); + ** + ** SELECT * FROM t1 WHERE a=5 OR b=7 OR (c=11 AND d=13) + ** + ** In the example, there are three indexed terms connected by OR. + ** The top of the loop looks like this: + ** + ** Null 1 # Zero the rowset in reg 1 + ** + ** Then, for each indexed term, the following. The arguments to + ** RowSetTest are such that the rowid of the current row is inserted + ** into the RowSet. If it is already present, control skips the + ** Gosub opcode and jumps straight to the code generated by WhereEnd(). + ** + ** sqlite3WhereBegin() + ** RowSetTest # Insert rowid into rowset + ** Gosub 2 A + ** sqlite3WhereEnd() + ** + ** Following the above, code to terminate the loop. Label A, the target + ** of the Gosub above, jumps to the instruction right after the Goto. + ** + ** Null 1 # Zero the rowset in reg 1 + ** Goto B # The loop is finished. + ** + ** A: # Return data, whatever. + ** + ** Return 2 # Jump back to the Gosub + ** + ** B: + ** + ** Added 2014-05-26: If the table is a WITHOUT ROWID table, then + ** use an ephemeral index instead of a RowSet to record the primary + ** keys of the rows we have already seen. + ** + */ + WhereClause *pOrWc; /* The OR-clause broken out into subterms */ + SrcList *pOrTab; /* Shortened table list or OR-clause generation */ + Index *pCov = 0; /* Potential covering index (or NULL) */ + int iCovCur = pParse->nTab++; /* Cursor used for index scans (if any) */ + + int regReturn = ++pParse->nMem; /* Register used with OP_Gosub */ + int regRowset = 0; /* Register for RowSet object */ + int regRowid = 0; /* Register holding rowid */ + int iLoopBody = sqlite3VdbeMakeLabel(v); /* Start of loop body */ + int iRetInit; /* Address of regReturn init */ + int untestedTerms = 0; /* Some terms not completely tested */ + int ii; /* Loop counter */ + u16 wctrlFlags; /* Flags for sub-WHERE clause */ + Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ + Table *pTab = pTabItem->pTab; + + pTerm = pLoop->aLTerm[0]; + assert( pTerm!=0 ); + assert( pTerm->eOperator & WO_OR ); + assert( (pTerm->wtFlags & TERM_ORINFO)!=0 ); + pOrWc = &pTerm->u.pOrInfo->wc; + pLevel->op = OP_Return; + pLevel->p1 = regReturn; + + /* Set up a new SrcList in pOrTab containing the table being scanned + ** by this loop in the a[0] slot and all notReady tables in a[1..] slots. + ** This becomes the SrcList in the recursive call to sqlite3WhereBegin(). + */ + if( pWInfo->nLevel>1 ){ + int nNotReady; /* The number of notReady tables */ + struct SrcList_item *origSrc; /* Original list of tables */ + nNotReady = pWInfo->nLevel - iLevel - 1; + pOrTab = sqlite3StackAllocRaw(db, + sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0])); + if( pOrTab==0 ) return notReady; + pOrTab->nAlloc = (u8)(nNotReady + 1); + pOrTab->nSrc = pOrTab->nAlloc; + memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem)); + origSrc = pWInfo->pTabList->a; + for(k=1; k<=nNotReady; k++){ + memcpy(&pOrTab->a[k], &origSrc[pLevel[k].iFrom], sizeof(pOrTab->a[k])); + } + }else{ + pOrTab = pWInfo->pTabList; + } + + /* Initialize the rowset register to contain NULL. An SQL NULL is + ** equivalent to an empty rowset. Or, create an ephemeral index + ** capable of holding primary keys in the case of a WITHOUT ROWID. + ** + ** Also initialize regReturn to contain the address of the instruction + ** immediately following the OP_Return at the bottom of the loop. This + ** is required in a few obscure LEFT JOIN cases where control jumps + ** over the top of the loop into the body of it. In this case the + ** correct response for the end-of-loop code (the OP_Return) is to + ** fall through to the next instruction, just as an OP_Next does if + ** called on an uninitialized cursor. + */ + if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ + if( HasRowid(pTab) ){ + regRowset = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset); + }else{ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + regRowset = pParse->nTab++; + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, regRowset, pPk->nKeyCol); + sqlite3VdbeSetP4KeyInfo(pParse, pPk); + } + regRowid = ++pParse->nMem; + } + iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn); + + /* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y + ** Then for every term xN, evaluate as the subexpression: xN AND z + ** That way, terms in y that are factored into the disjunction will + ** be picked up by the recursive calls to sqlite3WhereBegin() below. + ** + ** Actually, each subexpression is converted to "xN AND w" where w is + ** the "interesting" terms of z - terms that did not originate in the + ** ON or USING clause of a LEFT JOIN, and terms that are usable as + ** indices. + ** + ** This optimization also only applies if the (x1 OR x2 OR ...) term + ** is not contained in the ON clause of a LEFT JOIN. + ** See ticket http://www.sqlite.org/src/info/f2369304e4 + */ + if( pWC->nTerm>1 ){ + int iTerm; + for(iTerm=0; iTermnTerm; iTerm++){ + Expr *pExpr = pWC->a[iTerm].pExpr; + if( &pWC->a[iTerm] == pTerm ) continue; + if( ExprHasProperty(pExpr, EP_FromJoin) ) continue; + if( (pWC->a[iTerm].wtFlags & TERM_VIRTUAL)!=0 ) continue; + if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue; + testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO ); + pExpr = sqlite3ExprDup(db, pExpr, 0); + pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr); + } + if( pAndExpr ){ + pAndExpr = sqlite3PExpr(pParse, TK_AND, 0, pAndExpr, 0); + } + } + + /* Run a separate WHERE clause for each term of the OR clause. After + ** eliminating duplicates from other WHERE clauses, the action for each + ** sub-WHERE clause is to to invoke the main loop body as a subroutine. + */ + wctrlFlags = WHERE_OMIT_OPEN_CLOSE + | WHERE_FORCE_TABLE + | WHERE_ONETABLE_ONLY + | WHERE_NO_AUTOINDEX; + for(ii=0; iinTerm; ii++){ + WhereTerm *pOrTerm = &pOrWc->a[ii]; + if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ + WhereInfo *pSubWInfo; /* Info for single OR-term scan */ + Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */ + int j1 = 0; /* Address of jump operation */ + if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){ + pAndExpr->pLeft = pOrExpr; + pOrExpr = pAndExpr; + } + /* Loop through table entries that match term pOrTerm. */ + WHERETRACE(0xffff, ("Subplan for OR-clause:\n")); + pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, + wctrlFlags, iCovCur); + assert( pSubWInfo || pParse->nErr || db->mallocFailed ); + if( pSubWInfo ){ + WhereLoop *pSubLoop; + int addrExplain = explainOneScan( + pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0 + ); + addScanStatus(v, pOrTab, &pSubWInfo->a[0], addrExplain); + + /* This is the sub-WHERE clause body. First skip over + ** duplicate rows from prior sub-WHERE clauses, and record the + ** rowid (or PRIMARY KEY) for the current row so that the same + ** row will be skipped in subsequent sub-WHERE clauses. + */ + if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ + int r; + int iSet = ((ii==pOrWc->nTerm-1)?-1:ii); + if( HasRowid(pTab) ){ + r = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, regRowid, 0); + j1 = sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 0, r,iSet); + VdbeCoverage(v); + }else{ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + int nPk = pPk->nKeyCol; + int iPk; + + /* Read the PK into an array of temp registers. */ + r = sqlite3GetTempRange(pParse, nPk); + for(iPk=0; iPkaiColumn[iPk]; + sqlite3ExprCodeGetColumn(pParse, pTab, iCol, iCur, r+iPk, 0); + } + + /* Check if the temp table already contains this key. If so, + ** the row has already been included in the result set and + ** can be ignored (by jumping past the Gosub below). Otherwise, + ** insert the key into the temp table and proceed with processing + ** the row. + ** + ** Use some of the same optimizations as OP_RowSetTest: If iSet + ** is zero, assume that the key cannot already be present in + ** the temp table. And if iSet is -1, assume that there is no + ** need to insert the key into the temp table, as it will never + ** be tested for. */ + if( iSet ){ + j1 = sqlite3VdbeAddOp4Int(v, OP_Found, regRowset, 0, r, nPk); + VdbeCoverage(v); + } + if( iSet>=0 ){ + sqlite3VdbeAddOp3(v, OP_MakeRecord, r, nPk, regRowid); + sqlite3VdbeAddOp3(v, OP_IdxInsert, regRowset, regRowid, 0); + if( iSet ) sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + } + + /* Release the array of temp registers */ + sqlite3ReleaseTempRange(pParse, r, nPk); + } + } + + /* Invoke the main loop body as a subroutine */ + sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody); + + /* Jump here (skipping the main loop body subroutine) if the + ** current sub-WHERE row is a duplicate from prior sub-WHEREs. */ + if( j1 ) sqlite3VdbeJumpHere(v, j1); + + /* The pSubWInfo->untestedTerms flag means that this OR term + ** contained one or more AND term from a notReady table. The + ** terms from the notReady table could not be tested and will + ** need to be tested later. + */ + if( pSubWInfo->untestedTerms ) untestedTerms = 1; + + /* If all of the OR-connected terms are optimized using the same + ** index, and the index is opened using the same cursor number + ** by each call to sqlite3WhereBegin() made by this loop, it may + ** be possible to use that index as a covering index. + ** + ** If the call to sqlite3WhereBegin() above resulted in a scan that + ** uses an index, and this is either the first OR-connected term + ** processed or the index is the same as that used by all previous + ** terms, set pCov to the candidate covering index. Otherwise, set + ** pCov to NULL to indicate that no candidate covering index will + ** be available. + */ + pSubLoop = pSubWInfo->a[0].pWLoop; + assert( (pSubLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); + if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0 + && (ii==0 || pSubLoop->u.btree.pIndex==pCov) + && (HasRowid(pTab) || !IsPrimaryKeyIndex(pSubLoop->u.btree.pIndex)) + ){ + assert( pSubWInfo->a[0].iIdxCur==iCovCur ); + pCov = pSubLoop->u.btree.pIndex; + wctrlFlags |= WHERE_REOPEN_IDX; + }else{ + pCov = 0; + } + + /* Finish the loop through table entries that match term pOrTerm. */ + sqlite3WhereEnd(pSubWInfo); + } + } + } + pLevel->u.pCovidx = pCov; + if( pCov ) pLevel->iIdxCur = iCovCur; + if( pAndExpr ){ + pAndExpr->pLeft = 0; + sqlite3ExprDelete(db, pAndExpr); + } + sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v)); + sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk); + sqlite3VdbeResolveLabel(v, iLoopBody); + + if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab); + if( !untestedTerms ) disableTerm(pLevel, pTerm); + }else +#endif /* SQLITE_OMIT_OR_OPTIMIZATION */ + + { + /* Case 6: There is no usable index. We must do a complete + ** scan of the entire table. + */ + static const u8 aStep[] = { OP_Next, OP_Prev }; + static const u8 aStart[] = { OP_Rewind, OP_Last }; + assert( bRev==0 || bRev==1 ); + if( pTabItem->isRecursive ){ + /* Tables marked isRecursive have only a single row that is stored in + ** a pseudo-cursor. No need to Rewind or Next such cursors. */ + pLevel->op = OP_Noop; + }else{ + pLevel->op = aStep[bRev]; + pLevel->p1 = iCur; + pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk); + VdbeCoverageIf(v, bRev==0); + VdbeCoverageIf(v, bRev!=0); + pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; + } + } + +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + pLevel->addrVisit = sqlite3VdbeCurrentAddr(v); +#endif + + /* Insert code to test every subexpression that can be completely + ** computed using the current set of tables. + */ + for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){ + Expr *pE; + int skipLikeAddr = 0; + testcase( pTerm->wtFlags & TERM_VIRTUAL ); + testcase( pTerm->wtFlags & TERM_CODED ); + if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; + if( (pTerm->prereqAll & pLevel->notReady)!=0 ){ + testcase( pWInfo->untestedTerms==0 + && (pWInfo->wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ); + pWInfo->untestedTerms = 1; + continue; + } + pE = pTerm->pExpr; + assert( pE!=0 ); + if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){ + continue; + } + if( pTerm->wtFlags & TERM_LIKECOND ){ + assert( pLevel->iLikeRepCntr>0 ); + skipLikeAddr = sqlite3VdbeAddOp1(v, OP_IfNot, pLevel->iLikeRepCntr); + VdbeCoverage(v); + } + sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL); + if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr); + pTerm->wtFlags |= TERM_CODED; + } + + /* Insert code to test for implied constraints based on transitivity + ** of the "==" operator. + ** + ** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123" + ** and we are coding the t1 loop and the t2 loop has not yet coded, + ** then we cannot use the "t1.a=t2.b" constraint, but we can code + ** the implied "t1.a=123" constraint. + */ + for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){ + Expr *pE, *pEAlt; + WhereTerm *pAlt; + if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; + if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue; + if( pTerm->leftCursor!=iCur ) continue; + if( pLevel->iLeftJoin ) continue; + pE = pTerm->pExpr; + assert( !ExprHasProperty(pE, EP_FromJoin) ); + assert( (pTerm->prereqRight & pLevel->notReady)!=0 ); + pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0); + if( pAlt==0 ) continue; + if( pAlt->wtFlags & (TERM_CODED) ) continue; + testcase( pAlt->eOperator & WO_EQ ); + testcase( pAlt->eOperator & WO_IN ); + VdbeModuleComment((v, "begin transitive constraint")); + pEAlt = sqlite3StackAllocRaw(db, sizeof(*pEAlt)); + if( pEAlt ){ + *pEAlt = *pAlt->pExpr; + pEAlt->pLeft = pE->pLeft; + sqlite3ExprIfFalse(pParse, pEAlt, addrCont, SQLITE_JUMPIFNULL); + sqlite3StackFree(db, pEAlt); + } + } + + /* 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->addrFirst = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin); + VdbeComment((v, "record LEFT JOIN hit")); + sqlite3ExprCacheClear(pParse); + for(pTerm=pWC->a, j=0; jnTerm; j++, pTerm++){ + testcase( pTerm->wtFlags & TERM_VIRTUAL ); + testcase( pTerm->wtFlags & TERM_CODED ); + if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; + if( (pTerm->prereqAll & pLevel->notReady)!=0 ){ + assert( pWInfo->untestedTerms ); + continue; + } + assert( pTerm->pExpr ); + sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); + pTerm->wtFlags |= TERM_CODED; + } + } + + return pLevel->notReady; +} + +#ifdef WHERETRACE_ENABLED +/* +** Print the content of a WhereTerm object +*/ +static void whereTermPrint(WhereTerm *pTerm, int iTerm){ + if( pTerm==0 ){ + sqlite3DebugPrintf("TERM-%-3d NULL\n", iTerm); + }else{ + char zType[4]; + memcpy(zType, "...", 4); + if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V'; + if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E'; + if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L'; + sqlite3DebugPrintf("TERM-%-3d %p %s cursor=%-3d prob=%-3d op=0x%03x\n", + iTerm, pTerm, zType, pTerm->leftCursor, pTerm->truthProb, + pTerm->eOperator); + sqlite3TreeViewExpr(0, pTerm->pExpr, 0); + } +} +#endif + +#ifdef WHERETRACE_ENABLED +/* +** Print a WhereLoop object for debugging purposes +*/ +static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){ + WhereInfo *pWInfo = pWC->pWInfo; + int nb = 1+(pWInfo->pTabList->nSrc+7)/8; + struct SrcList_item *pItem = pWInfo->pTabList->a + p->iTab; + Table *pTab = pItem->pTab; + sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, + p->iTab, nb, p->maskSelf, nb, p->prereq); + sqlite3DebugPrintf(" %12s", + pItem->zAlias ? pItem->zAlias : pTab->zName); + if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ + const char *zName; + if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){ + if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){ + int i = sqlite3Strlen30(zName) - 1; + while( zName[i]!='_' ) i--; + zName += i; + } + sqlite3DebugPrintf(".%-16s %2d", zName, p->u.btree.nEq); + }else{ + sqlite3DebugPrintf("%20s",""); + } + }else{ + char *z; + if( p->u.vtab.idxStr ){ + z = sqlite3_mprintf("(%d,\"%s\",%x)", + p->u.vtab.idxNum, p->u.vtab.idxStr, p->u.vtab.omitMask); + }else{ + z = sqlite3_mprintf("(%d,%x)", p->u.vtab.idxNum, p->u.vtab.omitMask); + } + sqlite3DebugPrintf(" %-19s", z); + sqlite3_free(z); + } + if( p->wsFlags & WHERE_SKIPSCAN ){ + sqlite3DebugPrintf(" f %05x %d-%d", p->wsFlags, p->nLTerm,p->nSkip); + }else{ + sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm); + } + sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut); + if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){ + int i; + for(i=0; inLTerm; i++){ + whereTermPrint(p->aLTerm[i], i); + } + } +} +#endif + +/* +** Convert bulk memory into a valid WhereLoop that can be passed +** to whereLoopClear harmlessly. +*/ +static void whereLoopInit(WhereLoop *p){ + p->aLTerm = p->aLTermSpace; + p->nLTerm = 0; + p->nLSlot = ArraySize(p->aLTermSpace); + p->wsFlags = 0; +} + +/* +** Clear the WhereLoop.u union. Leave WhereLoop.pLTerm intact. +*/ +static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){ + if( p->wsFlags & (WHERE_VIRTUALTABLE|WHERE_AUTO_INDEX) ){ + if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 && p->u.vtab.needFree ){ + sqlite3_free(p->u.vtab.idxStr); + p->u.vtab.needFree = 0; + p->u.vtab.idxStr = 0; + }else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){ + sqlite3DbFree(db, p->u.btree.pIndex->zColAff); + sqlite3DbFree(db, p->u.btree.pIndex); + p->u.btree.pIndex = 0; + } + } +} + +/* +** Deallocate internal memory used by a WhereLoop object +*/ +static void whereLoopClear(sqlite3 *db, WhereLoop *p){ + if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm); + whereLoopClearUnion(db, p); + whereLoopInit(p); +} + +/* +** Increase the memory allocation for pLoop->aLTerm[] to be at least n. +*/ +static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){ + WhereTerm **paNew; + if( p->nLSlot>=n ) return SQLITE_OK; + n = (n+7)&~7; + paNew = sqlite3DbMallocRaw(db, sizeof(p->aLTerm[0])*n); + if( paNew==0 ) return SQLITE_NOMEM; + memcpy(paNew, p->aLTerm, sizeof(p->aLTerm[0])*p->nLSlot); + if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm); + p->aLTerm = paNew; + p->nLSlot = n; + return SQLITE_OK; +} + +/* +** Transfer content from the second pLoop into the first. +*/ +static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){ + whereLoopClearUnion(db, pTo); + if( whereLoopResize(db, pTo, pFrom->nLTerm) ){ + memset(&pTo->u, 0, sizeof(pTo->u)); + return SQLITE_NOMEM; + } + memcpy(pTo, pFrom, WHERE_LOOP_XFER_SZ); + memcpy(pTo->aLTerm, pFrom->aLTerm, pTo->nLTerm*sizeof(pTo->aLTerm[0])); + if( pFrom->wsFlags & WHERE_VIRTUALTABLE ){ + pFrom->u.vtab.needFree = 0; + }else if( (pFrom->wsFlags & WHERE_AUTO_INDEX)!=0 ){ + pFrom->u.btree.pIndex = 0; + } + return SQLITE_OK; +} + +/* +** Delete a WhereLoop object +*/ +static void whereLoopDelete(sqlite3 *db, WhereLoop *p){ + whereLoopClear(db, p); + sqlite3DbFree(db, p); +} + +/* +** Free a WhereInfo structure +*/ +static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ + if( ALWAYS(pWInfo) ){ + int i; + for(i=0; inLevel; i++){ + WhereLevel *pLevel = &pWInfo->a[i]; + if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){ + sqlite3DbFree(db, pLevel->u.in.aInLoop); + } + } + whereClauseClear(&pWInfo->sWC); + while( pWInfo->pLoops ){ + WhereLoop *p = pWInfo->pLoops; + pWInfo->pLoops = p->pNextLoop; + whereLoopDelete(db, p); + } + sqlite3DbFree(db, pWInfo); + } +} + +/* +** Return TRUE if all of the following are true: +** +** (1) X has the same or lower cost that Y +** (2) X is a proper subset of Y +** (3) X skips at least as many columns as Y +** +** By "proper subset" we mean that X uses fewer WHERE clause terms +** than Y and that every WHERE clause term used by X is also used +** by Y. +** +** If X is a proper subset of Y then Y is a better choice and ought +** to have a lower cost. This routine returns TRUE when that cost +** relationship is inverted and needs to be adjusted. The third rule +** was added because if X uses skip-scan less than Y it still might +** deserve a lower cost even if it is a proper subset of Y. +*/ +static int whereLoopCheaperProperSubset( + const WhereLoop *pX, /* First WhereLoop to compare */ + const WhereLoop *pY /* Compare against this WhereLoop */ +){ + int i, j; + if( pX->nLTerm-pX->nSkip >= pY->nLTerm-pY->nSkip ){ + return 0; /* X is not a subset of Y */ + } + if( pY->nSkip > pX->nSkip ) return 0; + if( pX->rRun >= pY->rRun ){ + if( pX->rRun > pY->rRun ) return 0; /* X costs more than Y */ + if( pX->nOut > pY->nOut ) return 0; /* X costs more than Y */ + } + for(i=pX->nLTerm-1; i>=0; i--){ + if( pX->aLTerm[i]==0 ) continue; + for(j=pY->nLTerm-1; j>=0; j--){ + if( pY->aLTerm[j]==pX->aLTerm[i] ) break; + } + if( j<0 ) return 0; /* X not a subset of Y since term X[i] not used by Y */ + } + return 1; /* All conditions meet */ +} + +/* +** Try to adjust the cost of WhereLoop pTemplate upwards or downwards so +** that: +** +** (1) pTemplate costs less than any other WhereLoops that are a proper +** subset of pTemplate +** +** (2) pTemplate costs more than any other WhereLoops for which pTemplate +** is a proper subset. +** +** To say "WhereLoop X is a proper subset of Y" means that X uses fewer +** WHERE clause terms than Y and that every WHERE clause term used by X is +** also used by Y. +*/ +static void whereLoopAdjustCost(const WhereLoop *p, WhereLoop *pTemplate){ + if( (pTemplate->wsFlags & WHERE_INDEXED)==0 ) return; + for(; p; p=p->pNextLoop){ + if( p->iTab!=pTemplate->iTab ) continue; + if( (p->wsFlags & WHERE_INDEXED)==0 ) continue; + if( whereLoopCheaperProperSubset(p, pTemplate) ){ + /* Adjust pTemplate cost downward so that it is cheaper than its + ** subset p. */ + WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n", + pTemplate->rRun, pTemplate->nOut, p->rRun, p->nOut-1)); + pTemplate->rRun = p->rRun; + pTemplate->nOut = p->nOut - 1; + }else if( whereLoopCheaperProperSubset(pTemplate, p) ){ + /* Adjust pTemplate cost upward so that it is costlier than p since + ** pTemplate is a proper subset of p */ + WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n", + pTemplate->rRun, pTemplate->nOut, p->rRun, p->nOut+1)); + pTemplate->rRun = p->rRun; + pTemplate->nOut = p->nOut + 1; + } + } +} + +/* +** Search the list of WhereLoops in *ppPrev looking for one that can be +** supplanted by pTemplate. +** +** Return NULL if the WhereLoop list contains an entry that can supplant +** pTemplate, in other words if pTemplate does not belong on the list. +** +** If pX is a WhereLoop that pTemplate can supplant, then return the +** link that points to pX. +** +** If pTemplate cannot supplant any existing element of the list but needs +** to be added to the list, then return a pointer to the tail of the list. +*/ +static WhereLoop **whereLoopFindLesser( + WhereLoop **ppPrev, + const WhereLoop *pTemplate +){ + WhereLoop *p; + for(p=(*ppPrev); p; ppPrev=&p->pNextLoop, p=*ppPrev){ + if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ){ + /* If either the iTab or iSortIdx values for two WhereLoop are different + ** then those WhereLoops need to be considered separately. Neither is + ** a candidate to replace the other. */ + continue; + } + /* In the current implementation, the rSetup value is either zero + ** or the cost of building an automatic index (NlogN) and the NlogN + ** is the same for compatible WhereLoops. */ + assert( p->rSetup==0 || pTemplate->rSetup==0 + || p->rSetup==pTemplate->rSetup ); + + /* whereLoopAddBtree() always generates and inserts the automatic index + ** case first. Hence compatible candidate WhereLoops never have a larger + ** rSetup. Call this SETUP-INVARIANT */ + assert( p->rSetup>=pTemplate->rSetup ); + + /* Any loop using an appliation-defined index (or PRIMARY KEY or + ** UNIQUE constraint) with one or more == constraints is better + ** than an automatic index. Unless it is a skip-scan. */ + if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 + && (pTemplate->nSkip)==0 + && (pTemplate->wsFlags & WHERE_INDEXED)!=0 + && (pTemplate->wsFlags & WHERE_COLUMN_EQ)!=0 + && (p->prereq & pTemplate->prereq)==pTemplate->prereq + ){ + break; + } + + /* If existing WhereLoop p is better than pTemplate, pTemplate can be + ** discarded. WhereLoop p is better if: + ** (1) p has no more dependencies than pTemplate, and + ** (2) p has an equal or lower cost than pTemplate + */ + if( (p->prereq & pTemplate->prereq)==p->prereq /* (1) */ + && p->rSetup<=pTemplate->rSetup /* (2a) */ + && p->rRun<=pTemplate->rRun /* (2b) */ + && p->nOut<=pTemplate->nOut /* (2c) */ + ){ + return 0; /* Discard pTemplate */ + } + + /* If pTemplate is always better than p, then cause p to be overwritten + ** with pTemplate. pTemplate is better than p if: + ** (1) pTemplate has no more dependences than p, and + ** (2) pTemplate has an equal or lower cost than p. + */ + if( (p->prereq & pTemplate->prereq)==pTemplate->prereq /* (1) */ + && p->rRun>=pTemplate->rRun /* (2a) */ + && p->nOut>=pTemplate->nOut /* (2b) */ + ){ + assert( p->rSetup>=pTemplate->rSetup ); /* SETUP-INVARIANT above */ + break; /* Cause p to be overwritten by pTemplate */ + } + } + return ppPrev; +} + +/* +** Insert or replace a WhereLoop entry using the template supplied. +** +** An existing WhereLoop entry might be overwritten if the new template +** is better and has fewer dependencies. Or the template will be ignored +** and no insert will occur if an existing WhereLoop is faster and has +** fewer dependencies than the template. Otherwise a new WhereLoop is +** added based on the template. +** +** If pBuilder->pOrSet is not NULL then we care about only the +** prerequisites and rRun and nOut costs of the N best loops. That +** information is gathered in the pBuilder->pOrSet object. This special +** processing mode is used only for OR clause processing. +** +** When accumulating multiple loops (when pBuilder->pOrSet is NULL) we +** still might overwrite similar loops with the new template if the +** new template is better. Loops may be overwritten if the following +** conditions are met: +** +** (1) They have the same iTab. +** (2) They have the same iSortIdx. +** (3) The template has same or fewer dependencies than the current loop +** (4) The template has the same or lower cost than the current loop +*/ +static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ + WhereLoop **ppPrev, *p; + WhereInfo *pWInfo = pBuilder->pWInfo; + sqlite3 *db = pWInfo->pParse->db; + + /* If pBuilder->pOrSet is defined, then only keep track of the costs + ** and prereqs. + */ + if( pBuilder->pOrSet!=0 ){ +#if WHERETRACE_ENABLED + u16 n = pBuilder->pOrSet->n; + int x = +#endif + whereOrInsert(pBuilder->pOrSet, pTemplate->prereq, pTemplate->rRun, + pTemplate->nOut); +#if WHERETRACE_ENABLED /* 0x8 */ + if( sqlite3WhereTrace & 0x8 ){ + sqlite3DebugPrintf(x?" or-%d: ":" or-X: ", n); + whereLoopPrint(pTemplate, pBuilder->pWC); + } +#endif + return SQLITE_OK; + } + + /* Look for an existing WhereLoop to replace with pTemplate + */ + whereLoopAdjustCost(pWInfo->pLoops, pTemplate); + ppPrev = whereLoopFindLesser(&pWInfo->pLoops, pTemplate); + + if( ppPrev==0 ){ + /* There already exists a WhereLoop on the list that is better + ** than pTemplate, so just ignore pTemplate */ +#if WHERETRACE_ENABLED /* 0x8 */ + if( sqlite3WhereTrace & 0x8 ){ + sqlite3DebugPrintf(" skip: "); + whereLoopPrint(pTemplate, pBuilder->pWC); + } +#endif + return SQLITE_OK; + }else{ + p = *ppPrev; + } + + /* If we reach this point it means that either p[] should be overwritten + ** with pTemplate[] if p[] exists, or if p==NULL then allocate a new + ** WhereLoop and insert it. + */ +#if WHERETRACE_ENABLED /* 0x8 */ + if( sqlite3WhereTrace & 0x8 ){ + if( p!=0 ){ + sqlite3DebugPrintf("replace: "); + whereLoopPrint(p, pBuilder->pWC); + } + sqlite3DebugPrintf(" add: "); + whereLoopPrint(pTemplate, pBuilder->pWC); + } +#endif + if( p==0 ){ + /* Allocate a new WhereLoop to add to the end of the list */ + *ppPrev = p = sqlite3DbMallocRaw(db, sizeof(WhereLoop)); + if( p==0 ) return SQLITE_NOMEM; + whereLoopInit(p); + p->pNextLoop = 0; + }else{ + /* We will be overwriting WhereLoop p[]. But before we do, first + ** go through the rest of the list and delete any other entries besides + ** p[] that are also supplated by pTemplate */ + WhereLoop **ppTail = &p->pNextLoop; + WhereLoop *pToDel; + while( *ppTail ){ + ppTail = whereLoopFindLesser(ppTail, pTemplate); + if( ppTail==0 ) break; + pToDel = *ppTail; + if( pToDel==0 ) break; + *ppTail = pToDel->pNextLoop; +#if WHERETRACE_ENABLED /* 0x8 */ + if( sqlite3WhereTrace & 0x8 ){ + sqlite3DebugPrintf(" delete: "); + whereLoopPrint(pToDel, pBuilder->pWC); + } +#endif + whereLoopDelete(db, pToDel); + } + } + whereLoopXfer(db, p, pTemplate); + if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ + Index *pIndex = p->u.btree.pIndex; + if( pIndex && pIndex->tnum==0 ){ + p->u.btree.pIndex = 0; + } + } + return SQLITE_OK; +} + +/* +** Adjust the WhereLoop.nOut value downward to account for terms of the +** WHERE clause that reference the loop but which are not used by an +** index. +* +** For every WHERE clause term that is not used by the index +** and which has a truth probability assigned by one of the likelihood(), +** likely(), or unlikely() SQL functions, reduce the estimated number +** of output rows by the probability specified. +** +** TUNING: For every WHERE clause term that is not used by the index +** and which does not have an assigned truth probability, heuristics +** described below are used to try to estimate the truth probability. +** TODO --> Perhaps this is something that could be improved by better +** table statistics. +** +** Heuristic 1: Estimate the truth probability as 93.75%. The 93.75% +** value corresponds to -1 in LogEst notation, so this means decrement +** the WhereLoop.nOut field for every such WHERE clause term. +** +** Heuristic 2: If there exists one or more WHERE clause terms of the +** form "x==EXPR" and EXPR is not a constant 0 or 1, then make sure the +** final output row estimate is no greater than 1/4 of the total number +** of rows in the table. In other words, assume that x==EXPR will filter +** out at least 3 out of 4 rows. If EXPR is -1 or 0 or 1, then maybe the +** "x" column is boolean or else -1 or 0 or 1 is a common default value +** on the "x" column and so in that case only cap the output row estimate +** at 1/2 instead of 1/4. +*/ +static void whereLoopOutputAdjust( + WhereClause *pWC, /* The WHERE clause */ + WhereLoop *pLoop, /* The loop to adjust downward */ + LogEst nRow /* Number of rows in the entire table */ +){ + WhereTerm *pTerm, *pX; + Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf); + int i, j, k; + LogEst iReduce = 0; /* pLoop->nOut should not exceed nRow-iReduce */ + + assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); + for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){ + if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break; + if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue; + if( (pTerm->prereqAll & notAllowed)!=0 ) continue; + for(j=pLoop->nLTerm-1; j>=0; j--){ + pX = pLoop->aLTerm[j]; + if( pX==0 ) continue; + if( pX==pTerm ) break; + if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break; + } + if( j<0 ){ + if( pTerm->truthProb<=0 ){ + /* If a truth probability is specified using the likelihood() hints, + ** then use the probability provided by the application. */ + pLoop->nOut += pTerm->truthProb; + }else{ + /* In the absence of explicit truth probabilities, use heuristics to + ** guess a reasonable truth probability. */ + pLoop->nOut--; + if( pTerm->eOperator&WO_EQ ){ + Expr *pRight = pTerm->pExpr->pRight; + if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){ + k = 10; + }else{ + k = 20; + } + if( iReducenOut > nRow-iReduce ) pLoop->nOut = nRow - iReduce; +} + +/* +** Adjust the cost C by the costMult facter T. This only occurs if +** compiled with -DSQLITE_ENABLE_COSTMULT +*/ +#ifdef SQLITE_ENABLE_COSTMULT +# define ApplyCostMultiplier(C,T) C += T +#else +# define ApplyCostMultiplier(C,T) +#endif + +/* +** We have so far matched pBuilder->pNew->u.btree.nEq terms of the +** index pIndex. Try to match one more. +** +** When this function is called, pBuilder->pNew->nOut contains the +** number of rows expected to be visited by filtering using the nEq +** terms only. If it is modified, this value is restored before this +** function returns. +** +** If pProbe->tnum==0, that means pIndex is a fake index used for the +** INTEGER PRIMARY KEY. +*/ +static int whereLoopAddBtreeIndex( + WhereLoopBuilder *pBuilder, /* The WhereLoop factory */ + struct SrcList_item *pSrc, /* FROM clause term being analyzed */ + Index *pProbe, /* An index on pSrc */ + LogEst nInMul /* log(Number of iterations due to IN) */ +){ + WhereInfo *pWInfo = pBuilder->pWInfo; /* WHERE analyse context */ + Parse *pParse = pWInfo->pParse; /* Parsing context */ + sqlite3 *db = pParse->db; /* Database connection malloc context */ + WhereLoop *pNew; /* Template WhereLoop under construction */ + WhereTerm *pTerm; /* A WhereTerm under consideration */ + int opMask; /* Valid operators for constraints */ + WhereScan scan; /* Iterator for WHERE terms */ + Bitmask saved_prereq; /* Original value of pNew->prereq */ + u16 saved_nLTerm; /* Original value of pNew->nLTerm */ + u16 saved_nEq; /* Original value of pNew->u.btree.nEq */ + u16 saved_nSkip; /* Original value of pNew->nSkip */ + u32 saved_wsFlags; /* Original value of pNew->wsFlags */ + LogEst saved_nOut; /* Original value of pNew->nOut */ + int iCol; /* Index of the column in the table */ + int rc = SQLITE_OK; /* Return code */ + LogEst rSize; /* Number of rows in the table */ + LogEst rLogSize; /* Logarithm of table size */ + WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */ + + pNew = pBuilder->pNew; + if( db->mallocFailed ) return SQLITE_NOMEM; + + assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 ); + assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 ); + if( pNew->wsFlags & WHERE_BTM_LIMIT ){ + opMask = WO_LT|WO_LE; + }else if( pProbe->tnum<=0 || (pSrc->jointype & JT_LEFT)!=0 ){ + opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE; + }else{ + opMask = WO_EQ|WO_IN|WO_ISNULL|WO_GT|WO_GE|WO_LT|WO_LE; + } + if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); + + assert( pNew->u.btree.nEqnColumn ); + iCol = pProbe->aiColumn[pNew->u.btree.nEq]; + + pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, iCol, + opMask, pProbe); + saved_nEq = pNew->u.btree.nEq; + saved_nSkip = pNew->nSkip; + saved_nLTerm = pNew->nLTerm; + saved_wsFlags = pNew->wsFlags; + saved_prereq = pNew->prereq; + saved_nOut = pNew->nOut; + pNew->rSetup = 0; + rSize = pProbe->aiRowLogEst[0]; + rLogSize = estLog(rSize); + for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ + u16 eOp = pTerm->eOperator; /* Shorthand for pTerm->eOperator */ + LogEst rCostIdx; + LogEst nOutUnadjusted; /* nOut before IN() and WHERE adjustments */ + int nIn = 0; +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + int nRecValid = pBuilder->nRecValid; +#endif + if( (eOp==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0) + && (iCol<0 || pSrc->pTab->aCol[iCol].notNull) + ){ + continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */ + } + if( pTerm->prereqRight & pNew->maskSelf ) continue; + + /* Do not allow the upper bound of a LIKE optimization range constraint + ** to mix with a lower range bound from some other source */ + if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue; + + pNew->wsFlags = saved_wsFlags; + pNew->u.btree.nEq = saved_nEq; + pNew->nLTerm = saved_nLTerm; + if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ + pNew->aLTerm[pNew->nLTerm++] = pTerm; + pNew->prereq = (saved_prereq | pTerm->prereqRight) & ~pNew->maskSelf; + + assert( nInMul==0 + || (pNew->wsFlags & WHERE_COLUMN_NULL)!=0 + || (pNew->wsFlags & WHERE_COLUMN_IN)!=0 + || (pNew->wsFlags & WHERE_SKIPSCAN)!=0 + ); + + if( eOp & WO_IN ){ + Expr *pExpr = pTerm->pExpr; + pNew->wsFlags |= WHERE_COLUMN_IN; + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + /* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */ + nIn = 46; assert( 46==sqlite3LogEst(25) ); + }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){ + /* "x IN (value, value, ...)" */ + nIn = sqlite3LogEst(pExpr->x.pList->nExpr); + } + assert( nIn>0 ); /* RHS always has 2 or more terms... The parser + ** changes "x IN (?)" into "x=?". */ + + }else if( eOp & (WO_EQ) ){ + pNew->wsFlags |= WHERE_COLUMN_EQ; + if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1) ){ + if( iCol>=0 && pProbe->uniqNotNull==0 ){ + pNew->wsFlags |= WHERE_UNQ_WANTED; + }else{ + pNew->wsFlags |= WHERE_ONEROW; + } + } + }else if( eOp & WO_ISNULL ){ + pNew->wsFlags |= WHERE_COLUMN_NULL; + }else if( eOp & (WO_GT|WO_GE) ){ + testcase( eOp & WO_GT ); + testcase( eOp & WO_GE ); + pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT; + pBtm = pTerm; + pTop = 0; + if( pTerm->wtFlags & TERM_LIKEOPT ){ + /* Range contraints that come from the LIKE optimization are + ** always used in pairs. */ + pTop = &pTerm[1]; + assert( (pTop-(pTerm->pWC->a))pWC->nTerm ); + assert( pTop->wtFlags & TERM_LIKEOPT ); + assert( pTop->eOperator==WO_LT ); + if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ + pNew->aLTerm[pNew->nLTerm++] = pTop; + pNew->wsFlags |= WHERE_TOP_LIMIT; + } + }else{ + assert( eOp & (WO_LT|WO_LE) ); + testcase( eOp & WO_LT ); + testcase( eOp & WO_LE ); + pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT; + pTop = pTerm; + pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ? + pNew->aLTerm[pNew->nLTerm-2] : 0; + } + + /* At this point pNew->nOut is set to the number of rows expected to + ** be visited by the index scan before considering term pTerm, or the + ** values of nIn and nInMul. In other words, assuming that all + ** "x IN(...)" terms are replaced with "x = ?". This block updates + ** the value of pNew->nOut to account for pTerm (but not nIn/nInMul). */ + assert( pNew->nOut==saved_nOut ); + if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ + /* Adjust nOut using stat3/stat4 data. Or, if there is no stat3/stat4 + ** data, using some other estimate. */ + whereRangeScanEst(pParse, pBuilder, pBtm, pTop, pNew); + }else{ + int nEq = ++pNew->u.btree.nEq; + assert( eOp & (WO_ISNULL|WO_EQ|WO_IN) ); + + assert( pNew->nOut==saved_nOut ); + if( pTerm->truthProb<=0 && iCol>=0 ){ + assert( (eOp & WO_IN) || nIn==0 ); + testcase( eOp & WO_IN ); + pNew->nOut += pTerm->truthProb; + pNew->nOut -= nIn; + }else{ +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + tRowcnt nOut = 0; + if( nInMul==0 + && pProbe->nSample + && pNew->u.btree.nEq<=pProbe->nSampleCol + && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect)) + ){ + Expr *pExpr = pTerm->pExpr; + if( (eOp & (WO_EQ|WO_ISNULL))!=0 ){ + testcase( eOp & WO_EQ ); + testcase( eOp & WO_ISNULL ); + rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut); + }else{ + rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut); + } + if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; + if( rc!=SQLITE_OK ) break; /* Jump out of the pTerm loop */ + if( nOut ){ + pNew->nOut = sqlite3LogEst(nOut); + if( pNew->nOut>saved_nOut ) pNew->nOut = saved_nOut; + pNew->nOut -= nIn; + } + } + if( nOut==0 ) +#endif + { + pNew->nOut += (pProbe->aiRowLogEst[nEq] - pProbe->aiRowLogEst[nEq-1]); + if( eOp & WO_ISNULL ){ + /* TUNING: If there is no likelihood() value, assume that a + ** "col IS NULL" expression matches twice as many rows + ** as (col=?). */ + pNew->nOut += 10; + } + } + } + } + + /* Set rCostIdx to the cost of visiting selected rows in index. Add + ** it to pNew->rRun, which is currently set to the cost of the index + ** seek only. Then, if this is a non-covering index, add the cost of + ** visiting the rows in the main table. */ + rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; + pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); + if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ + pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); + } + ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult); + + nOutUnadjusted = pNew->nOut; + pNew->rRun += nInMul + nIn; + pNew->nOut += nInMul + nIn; + whereLoopOutputAdjust(pBuilder->pWC, pNew, rSize); + rc = whereLoopInsert(pBuilder, pNew); + + if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ + pNew->nOut = saved_nOut; + }else{ + pNew->nOut = nOutUnadjusted; + } + + if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 + && pNew->u.btree.nEqnColumn + ){ + whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); + } + pNew->nOut = saved_nOut; +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + pBuilder->nRecValid = nRecValid; +#endif + } + pNew->prereq = saved_prereq; + pNew->u.btree.nEq = saved_nEq; + pNew->nSkip = saved_nSkip; + pNew->wsFlags = saved_wsFlags; + pNew->nOut = saved_nOut; + pNew->nLTerm = saved_nLTerm; + + /* Consider using a skip-scan if there are no WHERE clause constraints + ** available for the left-most terms of the index, and if the average + ** number of repeats in the left-most terms is at least 18. + ** + ** The magic number 18 is selected on the basis that scanning 17 rows + ** is almost always quicker than an index seek (even though if the index + ** contains fewer than 2^17 rows we assume otherwise in other parts of + ** the code). And, even if it is not, it should not be too much slower. + ** On the other hand, the extra seeks could end up being significantly + ** more expensive. */ + assert( 42==sqlite3LogEst(18) ); + if( saved_nEq==saved_nSkip + && saved_nEq+1nKeyCol + && pProbe->noSkipScan==0 + && pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */ + && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK + ){ + LogEst nIter; + pNew->u.btree.nEq++; + pNew->nSkip++; + pNew->aLTerm[pNew->nLTerm++] = 0; + pNew->wsFlags |= WHERE_SKIPSCAN; + nIter = pProbe->aiRowLogEst[saved_nEq] - pProbe->aiRowLogEst[saved_nEq+1]; + pNew->nOut -= nIter; + /* TUNING: Because uncertainties in the estimates for skip-scan queries, + ** add a 1.375 fudge factor to make skip-scan slightly less likely. */ + nIter += 5; + whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul); + pNew->nOut = saved_nOut; + pNew->u.btree.nEq = saved_nEq; + pNew->nSkip = saved_nSkip; + pNew->wsFlags = saved_wsFlags; + } + + return rc; +} + +/* +** Return True if it is possible that pIndex might be useful in +** implementing the ORDER BY clause in pBuilder. +** +** Return False if pBuilder does not contain an ORDER BY clause or +** if there is no way for pIndex to be useful in implementing that +** ORDER BY clause. +*/ +static int indexMightHelpWithOrderBy( + WhereLoopBuilder *pBuilder, + Index *pIndex, + int iCursor +){ + ExprList *pOB; + int ii, jj; + + if( pIndex->bUnordered ) return 0; + if( (pOB = pBuilder->pWInfo->pOrderBy)==0 ) return 0; + for(ii=0; iinExpr; ii++){ + Expr *pExpr = sqlite3ExprSkipCollate(pOB->a[ii].pExpr); + if( pExpr->op!=TK_COLUMN ) return 0; + if( pExpr->iTable==iCursor ){ + if( pExpr->iColumn<0 ) return 1; + for(jj=0; jjnKeyCol; jj++){ + if( pExpr->iColumn==pIndex->aiColumn[jj] ) return 1; + } + } + } + return 0; +} + +/* +** Return a bitmask where 1s indicate that the corresponding column of +** the table is used by an index. Only the first 63 columns are considered. +*/ +static Bitmask columnsInIndex(Index *pIdx){ + Bitmask m = 0; + int j; + for(j=pIdx->nColumn-1; j>=0; j--){ + int x = pIdx->aiColumn[j]; + if( x>=0 ){ + testcase( x==BMS-1 ); + testcase( x==BMS-2 ); + if( xa; inTerm; i++, pTerm++){ + Expr *pExpr = pTerm->pExpr; + if( sqlite3ExprImpliesExpr(pExpr, pWhere, iTab) + && (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab) + ){ + return 1; + } + } + return 0; +} + +/* +** Add all WhereLoop objects for a single table of the join where the table +** is idenfied by pBuilder->pNew->iTab. That table is guaranteed to be +** a b-tree table, not a virtual table. +** +** The costs (WhereLoop.rRun) of the b-tree loops added by this function +** are calculated as follows: +** +** For a full scan, assuming the table (or index) contains nRow rows: +** +** cost = nRow * 3.0 // full-table scan +** cost = nRow * K // scan of covering index +** cost = nRow * (K+3.0) // scan of non-covering index +** +** where K is a value between 1.1 and 3.0 set based on the relative +** estimated average size of the index and table records. +** +** For an index scan, where nVisit is the number of index rows visited +** by the scan, and nSeek is the number of seek operations required on +** the index b-tree: +** +** cost = nSeek * (log(nRow) + K * nVisit) // covering index +** cost = nSeek * (log(nRow) + (K+3.0) * nVisit) // non-covering index +** +** Normally, nSeek is 1. nSeek values greater than 1 come about if the +** WHERE clause includes "x IN (....)" terms used in place of "x=?". Or when +** implicit "x IN (SELECT x FROM tbl)" terms are added for skip-scans. +** +** The estimated values (nRow, nVisit, nSeek) often contain a large amount +** of uncertainty. For this reason, scoring is designed to pick plans that +** "do the least harm" if the estimates are inaccurate. For example, a +** log(nRow) factor is omitted from a non-covering index scan in order to +** bias the scoring in favor of using an index, since the worst-case +** performance of using an index is far better than the worst-case performance +** of a full table scan. +*/ +static int whereLoopAddBtree( + WhereLoopBuilder *pBuilder, /* WHERE clause information */ + Bitmask mExtra /* Extra prerequesites for using this table */ +){ + WhereInfo *pWInfo; /* WHERE analysis context */ + Index *pProbe; /* An index we are evaluating */ + Index sPk; /* A fake index object for the primary key */ + LogEst aiRowEstPk[2]; /* The aiRowLogEst[] value for the sPk index */ + i16 aiColumnPk = -1; /* The aColumn[] value for the sPk index */ + SrcList *pTabList; /* The FROM clause */ + struct SrcList_item *pSrc; /* The FROM clause btree term to add */ + WhereLoop *pNew; /* Template WhereLoop object */ + int rc = SQLITE_OK; /* Return code */ + int iSortIdx = 1; /* Index number */ + int b; /* A boolean value */ + LogEst rSize; /* number of rows in the table */ + LogEst rLogSize; /* Logarithm of the number of rows in the table */ + WhereClause *pWC; /* The parsed WHERE clause */ + Table *pTab; /* Table being queried */ + + pNew = pBuilder->pNew; + pWInfo = pBuilder->pWInfo; + pTabList = pWInfo->pTabList; + pSrc = pTabList->a + pNew->iTab; + pTab = pSrc->pTab; + pWC = pBuilder->pWC; + assert( !IsVirtual(pSrc->pTab) ); + + if( pSrc->pIndex ){ + /* An INDEXED BY clause specifies a particular index to use */ + pProbe = pSrc->pIndex; + }else if( !HasRowid(pTab) ){ + pProbe = pTab->pIndex; + }else{ + /* There is no INDEXED BY clause. Create a fake Index object in local + ** variable sPk to represent the rowid primary key index. Make this + ** fake index the first in a chain of Index objects with all of the real + ** indices to follow */ + Index *pFirst; /* First of real indices on the table */ + memset(&sPk, 0, sizeof(Index)); + sPk.nKeyCol = 1; + sPk.nColumn = 1; + sPk.aiColumn = &aiColumnPk; + sPk.aiRowLogEst = aiRowEstPk; + sPk.onError = OE_Replace; + sPk.pTable = pTab; + sPk.szIdxRow = pTab->szTabRow; + aiRowEstPk[0] = pTab->nRowLogEst; + aiRowEstPk[1] = 0; + pFirst = pSrc->pTab->pIndex; + if( pSrc->notIndexed==0 ){ + /* The real indices of the table are only considered if the + ** NOT INDEXED qualifier is omitted from the FROM clause */ + sPk.pNext = pFirst; + } + pProbe = &sPk; + } + rSize = pTab->nRowLogEst; + rLogSize = estLog(rSize); + +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX + /* Automatic indexes */ + if( !pBuilder->pOrSet + && (pWInfo->wctrlFlags & WHERE_NO_AUTOINDEX)==0 + && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0 + && pSrc->pIndex==0 + && !pSrc->viaCoroutine + && !pSrc->notIndexed + && HasRowid(pTab) + && !pSrc->isCorrelated + && !pSrc->isRecursive + ){ + /* Generate auto-index WhereLoops */ + WhereTerm *pTerm; + WhereTerm *pWCEnd = pWC->a + pWC->nTerm; + for(pTerm=pWC->a; rc==SQLITE_OK && pTermprereqRight & pNew->maskSelf ) continue; + if( termCanDriveIndex(pTerm, pSrc, 0) ){ + pNew->u.btree.nEq = 1; + pNew->nSkip = 0; + pNew->u.btree.pIndex = 0; + pNew->nLTerm = 1; + pNew->aLTerm[0] = pTerm; + /* TUNING: One-time cost for computing the automatic index is + ** estimated to be X*N*log2(N) where N is the number of rows in + ** the table being indexed and where X is 7 (LogEst=28) for normal + ** tables or 1.375 (LogEst=4) for views and subqueries. The value + ** of X is smaller for views and subqueries so that the query planner + ** will be more aggressive about generating automatic indexes for + ** those objects, since there is no opportunity to add schema + ** indexes on subqueries and views. */ + pNew->rSetup = rLogSize + rSize + 4; + if( pTab->pSelect==0 && (pTab->tabFlags & TF_Ephemeral)==0 ){ + pNew->rSetup += 24; + } + ApplyCostMultiplier(pNew->rSetup, pTab->costMult); + /* TUNING: Each index lookup yields 20 rows in the table. This + ** is more than the usual guess of 10 rows, since we have no way + ** of knowing how selective the index will ultimately be. It would + ** not be unreasonable to make this value much larger. */ + pNew->nOut = 43; assert( 43==sqlite3LogEst(20) ); + pNew->rRun = sqlite3LogEstAdd(rLogSize,pNew->nOut); + pNew->wsFlags = WHERE_AUTO_INDEX; + pNew->prereq = mExtra | pTerm->prereqRight; + rc = whereLoopInsert(pBuilder, pNew); + } + } + } +#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ + + /* Loop over all indices + */ + for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){ + if( pProbe->pPartIdxWhere!=0 + && !whereUsablePartialIndex(pSrc->iCursor, pWC, pProbe->pPartIdxWhere) ){ + testcase( pNew->iTab!=pSrc->iCursor ); /* See ticket [98d973b8f5] */ + continue; /* Partial index inappropriate for this query */ + } + rSize = pProbe->aiRowLogEst[0]; + pNew->u.btree.nEq = 0; + pNew->nSkip = 0; + pNew->nLTerm = 0; + pNew->iSortIdx = 0; + pNew->rSetup = 0; + pNew->prereq = mExtra; + pNew->nOut = rSize; + pNew->u.btree.pIndex = pProbe; + b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor); + /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */ + assert( (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || b==0 ); + if( pProbe->tnum<=0 ){ + /* Integer primary key index */ + pNew->wsFlags = WHERE_IPK; + + /* Full table scan */ + pNew->iSortIdx = b ? iSortIdx : 0; + /* TUNING: Cost of full table scan is (N*3.0). */ + pNew->rRun = rSize + 16; + ApplyCostMultiplier(pNew->rRun, pTab->costMult); + whereLoopOutputAdjust(pWC, pNew, rSize); + rc = whereLoopInsert(pBuilder, pNew); + pNew->nOut = rSize; + if( rc ) break; + }else{ + Bitmask m; + if( pProbe->isCovering ){ + pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; + m = 0; + }else{ + m = pSrc->colUsed & ~columnsInIndex(pProbe); + pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED; + } + + /* Full scan via index */ + if( b + || !HasRowid(pTab) + || ( m==0 + && pProbe->bUnordered==0 + && (pProbe->szIdxRowszTabRow) + && (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 + && sqlite3GlobalConfig.bUseCis + && OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan) + ) + ){ + pNew->iSortIdx = b ? iSortIdx : 0; + + /* The cost of visiting the index rows is N*K, where K is + ** between 1.1 and 3.0, depending on the relative sizes of the + ** index and table rows. If this is a non-covering index scan, + ** also add the cost of visiting table rows (N*3.0). */ + pNew->rRun = rSize + 1 + (15*pProbe->szIdxRow)/pTab->szTabRow; + if( m!=0 ){ + pNew->rRun = sqlite3LogEstAdd(pNew->rRun, rSize+16); + } + ApplyCostMultiplier(pNew->rRun, pTab->costMult); + whereLoopOutputAdjust(pWC, pNew, rSize); + rc = whereLoopInsert(pBuilder, pNew); + pNew->nOut = rSize; + if( rc ) break; + } + } + + rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0); +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 + sqlite3Stat4ProbeFree(pBuilder->pRec); + pBuilder->nRecValid = 0; + pBuilder->pRec = 0; +#endif + + /* If there was an INDEXED BY clause, then only that one index is + ** considered. */ + if( pSrc->pIndex ) break; + } + return rc; +} + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Add all WhereLoop objects for a table of the join identified by +** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table. +*/ +static int whereLoopAddVirtual( + WhereLoopBuilder *pBuilder, /* WHERE clause information */ + Bitmask mExtra +){ + WhereInfo *pWInfo; /* WHERE analysis context */ + Parse *pParse; /* The parsing context */ + WhereClause *pWC; /* The WHERE clause */ + struct SrcList_item *pSrc; /* The FROM clause term to search */ + Table *pTab; + sqlite3 *db; + sqlite3_index_info *pIdxInfo; + struct sqlite3_index_constraint *pIdxCons; + struct sqlite3_index_constraint_usage *pUsage; + WhereTerm *pTerm; + int i, j; + int iTerm, mxTerm; + int nConstraint; + int seenIn = 0; /* True if an IN operator is seen */ + int seenVar = 0; /* True if a non-constant constraint is seen */ + int iPhase; /* 0: const w/o IN, 1: const, 2: no IN, 2: IN */ + WhereLoop *pNew; + int rc = SQLITE_OK; + + pWInfo = pBuilder->pWInfo; + pParse = pWInfo->pParse; + db = pParse->db; + pWC = pBuilder->pWC; + pNew = pBuilder->pNew; + pSrc = &pWInfo->pTabList->a[pNew->iTab]; + pTab = pSrc->pTab; + assert( IsVirtual(pTab) ); + pIdxInfo = allocateIndexInfo(pParse, pWC, pSrc, pBuilder->pOrderBy); + if( pIdxInfo==0 ) return SQLITE_NOMEM; + pNew->prereq = 0; + pNew->rSetup = 0; + pNew->wsFlags = WHERE_VIRTUALTABLE; + pNew->nLTerm = 0; + pNew->u.vtab.needFree = 0; + pUsage = pIdxInfo->aConstraintUsage; + nConstraint = pIdxInfo->nConstraint; + if( whereLoopResize(db, pNew, nConstraint) ){ + sqlite3DbFree(db, pIdxInfo); + return SQLITE_NOMEM; + } + + for(iPhase=0; iPhase<=3; iPhase++){ + if( !seenIn && (iPhase&1)!=0 ){ + iPhase++; + if( iPhase>3 ) break; + } + if( !seenVar && iPhase>1 ) break; + pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; + for(i=0; inConstraint; i++, pIdxCons++){ + j = pIdxCons->iTermOffset; + pTerm = &pWC->a[j]; + switch( iPhase ){ + case 0: /* Constants without IN operator */ + pIdxCons->usable = 0; + if( (pTerm->eOperator & WO_IN)!=0 ){ + seenIn = 1; + } + if( pTerm->prereqRight!=0 ){ + seenVar = 1; + }else if( (pTerm->eOperator & WO_IN)==0 ){ + pIdxCons->usable = 1; + } + break; + case 1: /* Constants with IN operators */ + assert( seenIn ); + pIdxCons->usable = (pTerm->prereqRight==0); + break; + case 2: /* Variables without IN */ + assert( seenVar ); + pIdxCons->usable = (pTerm->eOperator & WO_IN)==0; + break; + default: /* Variables with IN */ + assert( seenVar && seenIn ); + pIdxCons->usable = 1; + break; + } + } + memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint); + if( pIdxInfo->needToFreeIdxStr ) sqlite3_free(pIdxInfo->idxStr); + pIdxInfo->idxStr = 0; + pIdxInfo->idxNum = 0; + pIdxInfo->needToFreeIdxStr = 0; + pIdxInfo->orderByConsumed = 0; + pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2; + pIdxInfo->estimatedRows = 25; + rc = vtabBestIndex(pParse, pTab, pIdxInfo); + if( rc ) goto whereLoopAddVtab_exit; + pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; + pNew->prereq = mExtra; + mxTerm = -1; + assert( pNew->nLSlot>=nConstraint ); + for(i=0; iaLTerm[i] = 0; + pNew->u.vtab.omitMask = 0; + for(i=0; i=0 ){ + j = pIdxCons->iTermOffset; + if( iTerm>=nConstraint + || j<0 + || j>=pWC->nTerm + || pNew->aLTerm[iTerm]!=0 + ){ + rc = SQLITE_ERROR; + sqlite3ErrorMsg(pParse, "%s.xBestIndex() malfunction", pTab->zName); + goto whereLoopAddVtab_exit; + } + testcase( iTerm==nConstraint-1 ); + testcase( j==0 ); + testcase( j==pWC->nTerm-1 ); + pTerm = &pWC->a[j]; + pNew->prereq |= pTerm->prereqRight; + assert( iTermnLSlot ); + pNew->aLTerm[iTerm] = pTerm; + if( iTerm>mxTerm ) mxTerm = iTerm; + testcase( iTerm==15 ); + testcase( iTerm==16 ); + if( iTerm<16 && pUsage[i].omit ) pNew->u.vtab.omitMask |= 1<eOperator & WO_IN)!=0 ){ + if( pUsage[i].omit==0 ){ + /* Do not attempt to use an IN constraint if the virtual table + ** says that the equivalent EQ constraint cannot be safely omitted. + ** If we do attempt to use such a constraint, some rows might be + ** repeated in the output. */ + break; + } + /* A virtual table that is constrained by an IN clause may not + ** consume the ORDER BY clause because (1) the order of IN terms + ** is not necessarily related to the order of output terms and + ** (2) Multiple outputs from a single IN value will not merge + ** together. */ + pIdxInfo->orderByConsumed = 0; + } + } + } + if( i>=nConstraint ){ + pNew->nLTerm = mxTerm+1; + assert( pNew->nLTerm<=pNew->nLSlot ); + pNew->u.vtab.idxNum = pIdxInfo->idxNum; + pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr; + pIdxInfo->needToFreeIdxStr = 0; + pNew->u.vtab.idxStr = pIdxInfo->idxStr; + pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ? + pIdxInfo->nOrderBy : 0); + pNew->rSetup = 0; + pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost); + pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows); + whereLoopInsert(pBuilder, pNew); + if( pNew->u.vtab.needFree ){ + sqlite3_free(pNew->u.vtab.idxStr); + pNew->u.vtab.needFree = 0; + } + } + } + +whereLoopAddVtab_exit: + if( pIdxInfo->needToFreeIdxStr ) sqlite3_free(pIdxInfo->idxStr); + sqlite3DbFree(db, pIdxInfo); + return rc; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +/* +** Add WhereLoop entries to handle OR terms. This works for either +** btrees or virtual tables. +*/ +static int whereLoopAddOr(WhereLoopBuilder *pBuilder, Bitmask mExtra){ + WhereInfo *pWInfo = pBuilder->pWInfo; + WhereClause *pWC; + WhereLoop *pNew; + WhereTerm *pTerm, *pWCEnd; + int rc = SQLITE_OK; + int iCur; + WhereClause tempWC; + WhereLoopBuilder sSubBuild; + WhereOrSet sSum, sCur; + struct SrcList_item *pItem; + + pWC = pBuilder->pWC; + pWCEnd = pWC->a + pWC->nTerm; + pNew = pBuilder->pNew; + memset(&sSum, 0, sizeof(sSum)); + pItem = pWInfo->pTabList->a + pNew->iTab; + iCur = pItem->iCursor; + + for(pTerm=pWC->a; pTermeOperator & WO_OR)!=0 + && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0 + ){ + WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc; + WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm]; + WhereTerm *pOrTerm; + int once = 1; + int i, j; + + sSubBuild = *pBuilder; + sSubBuild.pOrderBy = 0; + sSubBuild.pOrSet = &sCur; + + WHERETRACE(0x200, ("Begin processing OR-clause %p\n", pTerm)); + for(pOrTerm=pOrWC->a; pOrTermeOperator & WO_AND)!=0 ){ + sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc; + }else if( pOrTerm->leftCursor==iCur ){ + tempWC.pWInfo = pWC->pWInfo; + tempWC.pOuter = pWC; + tempWC.op = TK_AND; + tempWC.nTerm = 1; + tempWC.a = pOrTerm; + sSubBuild.pWC = &tempWC; + }else{ + continue; + } + sCur.n = 0; +#ifdef WHERETRACE_ENABLED + WHERETRACE(0x200, ("OR-term %d of %p has %d subterms:\n", + (int)(pOrTerm-pOrWC->a), pTerm, sSubBuild.pWC->nTerm)); + if( sqlite3WhereTrace & 0x400 ){ + for(i=0; inTerm; i++){ + whereTermPrint(&sSubBuild.pWC->a[i], i); + } + } +#endif +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pItem->pTab) ){ + rc = whereLoopAddVirtual(&sSubBuild, mExtra); + }else +#endif + { + rc = whereLoopAddBtree(&sSubBuild, mExtra); + } + if( rc==SQLITE_OK ){ + rc = whereLoopAddOr(&sSubBuild, mExtra); + } + assert( rc==SQLITE_OK || sCur.n==0 ); + if( sCur.n==0 ){ + sSum.n = 0; + break; + }else if( once ){ + whereOrMove(&sSum, &sCur); + once = 0; + }else{ + WhereOrSet sPrev; + whereOrMove(&sPrev, &sSum); + sSum.n = 0; + for(i=0; inLTerm = 1; + pNew->aLTerm[0] = pTerm; + pNew->wsFlags = WHERE_MULTI_OR; + pNew->rSetup = 0; + pNew->iSortIdx = 0; + memset(&pNew->u, 0, sizeof(pNew->u)); + for(i=0; rc==SQLITE_OK && irRun = sSum.a[i].rRun + 1; + pNew->nOut = sSum.a[i].nOut; + pNew->prereq = sSum.a[i].prereq; + rc = whereLoopInsert(pBuilder, pNew); + } + WHERETRACE(0x200, ("End processing OR-clause %p\n", pTerm)); + } + } + return rc; +} + +/* +** Add all WhereLoop objects for all tables +*/ +static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ + WhereInfo *pWInfo = pBuilder->pWInfo; + Bitmask mExtra = 0; + Bitmask mPrior = 0; + int iTab; + SrcList *pTabList = pWInfo->pTabList; + struct SrcList_item *pItem; + sqlite3 *db = pWInfo->pParse->db; + int nTabList = pWInfo->nLevel; + int rc = SQLITE_OK; + u8 priorJoinType = 0; + WhereLoop *pNew; + + /* Loop over the tables in the join, from left to right */ + pNew = pBuilder->pNew; + whereLoopInit(pNew); + for(iTab=0, pItem=pTabList->a; iTabiTab = iTab; + pNew->maskSelf = getMask(&pWInfo->sMaskSet, pItem->iCursor); + if( ((pItem->jointype|priorJoinType) & (JT_LEFT|JT_CROSS))!=0 ){ + mExtra = mPrior; + } + priorJoinType = pItem->jointype; + if( IsVirtual(pItem->pTab) ){ + rc = whereLoopAddVirtual(pBuilder, mExtra); + }else{ + rc = whereLoopAddBtree(pBuilder, mExtra); + } + if( rc==SQLITE_OK ){ + rc = whereLoopAddOr(pBuilder, mExtra); + } + mPrior |= pNew->maskSelf; + if( rc || db->mallocFailed ) break; + } + whereLoopClear(db, pNew); + return rc; +} + +/* +** Examine a WherePath (with the addition of the extra WhereLoop of the 5th +** parameters) to see if it outputs rows in the requested ORDER BY +** (or GROUP BY) without requiring a separate sort operation. Return N: +** +** N>0: N terms of the ORDER BY clause are satisfied +** N==0: No terms of the ORDER BY clause are satisfied +** N<0: Unknown yet how many terms of ORDER BY might be satisfied. +** +** Note that processing for WHERE_GROUPBY and WHERE_DISTINCTBY is not as +** strict. With GROUP BY and DISTINCT the only requirement is that +** equivalent rows appear immediately adjacent to one another. GROUP BY +** and DISTINCT do not require rows to appear in any particular order as long +** as equivalent rows are grouped together. Thus for GROUP BY and DISTINCT +** the pOrderBy terms can be matched in any order. With ORDER BY, the +** pOrderBy terms must be matched in strict left-to-right order. +*/ +static i8 wherePathSatisfiesOrderBy( + WhereInfo *pWInfo, /* The WHERE clause */ + ExprList *pOrderBy, /* ORDER BY or GROUP BY or DISTINCT clause to check */ + WherePath *pPath, /* The WherePath to check */ + u16 wctrlFlags, /* Might contain WHERE_GROUPBY or WHERE_DISTINCTBY */ + u16 nLoop, /* Number of entries in pPath->aLoop[] */ + WhereLoop *pLast, /* Add this WhereLoop to the end of pPath->aLoop[] */ + Bitmask *pRevMask /* OUT: Mask of WhereLoops to run in reverse order */ +){ + u8 revSet; /* True if rev is known */ + u8 rev; /* Composite sort order */ + u8 revIdx; /* Index sort order */ + u8 isOrderDistinct; /* All prior WhereLoops are order-distinct */ + u8 distinctColumns; /* True if the loop has UNIQUE NOT NULL columns */ + u8 isMatch; /* iColumn matches a term of the ORDER BY clause */ + u16 nKeyCol; /* Number of key columns in pIndex */ + u16 nColumn; /* Total number of ordered columns in the index */ + u16 nOrderBy; /* Number terms in the ORDER BY clause */ + int iLoop; /* Index of WhereLoop in pPath being processed */ + int i, j; /* Loop counters */ + int iCur; /* Cursor number for current WhereLoop */ + int iColumn; /* A column number within table iCur */ + WhereLoop *pLoop = 0; /* Current WhereLoop being processed. */ + WhereTerm *pTerm; /* A single term of the WHERE clause */ + Expr *pOBExpr; /* An expression from the ORDER BY clause */ + CollSeq *pColl; /* COLLATE function from an ORDER BY clause term */ + Index *pIndex; /* The index associated with pLoop */ + sqlite3 *db = pWInfo->pParse->db; /* Database connection */ + Bitmask obSat = 0; /* Mask of ORDER BY terms satisfied so far */ + Bitmask obDone; /* Mask of all ORDER BY terms */ + Bitmask orderDistinctMask; /* Mask of all well-ordered loops */ + Bitmask ready; /* Mask of inner loops */ + + /* + ** We say the WhereLoop is "one-row" if it generates no more than one + ** row of output. A WhereLoop is one-row if all of the following are true: + ** (a) All index columns match with WHERE_COLUMN_EQ. + ** (b) The index is unique + ** Any WhereLoop with an WHERE_COLUMN_EQ constraint on the rowid is one-row. + ** Every one-row WhereLoop will have the WHERE_ONEROW bit set in wsFlags. + ** + ** We say the WhereLoop is "order-distinct" if the set of columns from + ** that WhereLoop that are in the ORDER BY clause are different for every + ** row of the WhereLoop. Every one-row WhereLoop is automatically + ** order-distinct. A WhereLoop that has no columns in the ORDER BY clause + ** is not order-distinct. To be order-distinct is not quite the same as being + ** UNIQUE since a UNIQUE column or index can have multiple rows that + ** are NULL and NULL values are equivalent for the purpose of order-distinct. + ** To be order-distinct, the columns must be UNIQUE and NOT NULL. + ** + ** The rowid for a table is always UNIQUE and NOT NULL so whenever the + ** rowid appears in the ORDER BY clause, the corresponding WhereLoop is + ** automatically order-distinct. + */ + + assert( pOrderBy!=0 ); + if( nLoop && OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0; + + nOrderBy = pOrderBy->nExpr; + testcase( nOrderBy==BMS-1 ); + if( nOrderBy>BMS-1 ) return 0; /* Cannot optimize overly large ORDER BYs */ + isOrderDistinct = 1; + obDone = MASKBIT(nOrderBy)-1; + orderDistinctMask = 0; + ready = 0; + for(iLoop=0; isOrderDistinct && obSat0 ) ready |= pLoop->maskSelf; + pLoop = iLoopaLoop[iLoop] : pLast; + if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){ + if( pLoop->u.vtab.isOrdered ) obSat = obDone; + break; + } + iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor; + + /* Mark off any ORDER BY term X that is a column in the table of + ** the current loop for which there is term in the WHERE + ** clause of the form X IS NULL or X=? that reference only outer + ** loops. + */ + for(i=0; ia[i].pExpr); + if( pOBExpr->op!=TK_COLUMN ) continue; + if( pOBExpr->iTable!=iCur ) continue; + pTerm = findTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn, + ~ready, WO_EQ|WO_ISNULL, 0); + if( pTerm==0 ) continue; + if( (pTerm->eOperator&WO_EQ)!=0 && pOBExpr->iColumn>=0 ){ + const char *z1, *z2; + pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr); + if( !pColl ) pColl = db->pDfltColl; + z1 = pColl->zName; + pColl = sqlite3ExprCollSeq(pWInfo->pParse, pTerm->pExpr); + if( !pColl ) pColl = db->pDfltColl; + z2 = pColl->zName; + if( sqlite3StrICmp(z1, z2)!=0 ) continue; + } + obSat |= MASKBIT(i); + } + + if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){ + if( pLoop->wsFlags & WHERE_IPK ){ + pIndex = 0; + nKeyCol = 0; + nColumn = 1; + }else if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){ + return 0; + }else{ + nKeyCol = pIndex->nKeyCol; + nColumn = pIndex->nColumn; + assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) ); + assert( pIndex->aiColumn[nColumn-1]==(-1) || !HasRowid(pIndex->pTable)); + isOrderDistinct = IsUniqueIndex(pIndex); + } + + /* Loop through all columns of the index and deal with the ones + ** that are not constrained by == or IN. + */ + rev = revSet = 0; + distinctColumns = 0; + for(j=0; ju.btree.nEq + && pLoop->nSkip==0 + && ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL))!=0 + ){ + if( i & WO_ISNULL ){ + testcase( isOrderDistinct ); + isOrderDistinct = 0; + } + continue; + } + + /* Get the column number in the table (iColumn) and sort order + ** (revIdx) for the j-th column of the index. + */ + if( pIndex ){ + iColumn = pIndex->aiColumn[j]; + revIdx = pIndex->aSortOrder[j]; + if( iColumn==pIndex->pTable->iPKey ) iColumn = -1; + }else{ + iColumn = -1; + revIdx = 0; + } + + /* An unconstrained column that might be NULL means that this + ** WhereLoop is not well-ordered + */ + if( isOrderDistinct + && iColumn>=0 + && j>=pLoop->u.btree.nEq + && pIndex->pTable->aCol[iColumn].notNull==0 + ){ + isOrderDistinct = 0; + } + + /* Find the ORDER BY term that corresponds to the j-th column + ** of the index and mark that ORDER BY term off + */ + bOnce = 1; + isMatch = 0; + for(i=0; bOnce && ia[i].pExpr); + testcase( wctrlFlags & WHERE_GROUPBY ); + testcase( wctrlFlags & WHERE_DISTINCTBY ); + if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0; + if( pOBExpr->op!=TK_COLUMN ) continue; + if( pOBExpr->iTable!=iCur ) continue; + if( pOBExpr->iColumn!=iColumn ) continue; + if( iColumn>=0 ){ + pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr); + if( !pColl ) pColl = db->pDfltColl; + if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue; + } + isMatch = 1; + break; + } + if( isMatch && (wctrlFlags & WHERE_GROUPBY)==0 ){ + /* Make sure the sort order is compatible in an ORDER BY clause. + ** Sort order is irrelevant for a GROUP BY clause. */ + if( revSet ){ + if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) isMatch = 0; + }else{ + rev = revIdx ^ pOrderBy->a[i].sortOrder; + if( rev ) *pRevMask |= MASKBIT(iLoop); + revSet = 1; + } + } + if( isMatch ){ + if( iColumn<0 ){ + testcase( distinctColumns==0 ); + distinctColumns = 1; + } + obSat |= MASKBIT(i); + }else{ + /* No match found */ + if( j==0 || jmaskSelf; + for(i=0; ia[i].pExpr; + mTerm = exprTableUsage(&pWInfo->sMaskSet,p); + if( mTerm==0 && !sqlite3ExprIsConstant(p) ) continue; + if( (mTerm&~orderDistinctMask)==0 ){ + obSat |= MASKBIT(i); + } + } + } + } /* End the loop over all WhereLoops from outer-most down to inner-most */ + if( obSat==obDone ) return (i8)nOrderBy; + if( !isOrderDistinct ){ + for(i=nOrderBy-1; i>0; i--){ + Bitmask m = MASKBIT(i) - 1; + if( (obSat&m)==m ) return i; + } + return 0; + } + return -1; +} + + +/* +** If the WHERE_GROUPBY flag is set in the mask passed to sqlite3WhereBegin(), +** the planner assumes that the specified pOrderBy list is actually a GROUP +** BY clause - and so any order that groups rows as required satisfies the +** request. +** +** Normally, in this case it is not possible for the caller to determine +** whether or not the rows are really being delivered in sorted order, or +** just in some other order that provides the required grouping. However, +** if the WHERE_SORTBYGROUP flag is also passed to sqlite3WhereBegin(), then +** this function may be called on the returned WhereInfo object. It returns +** true if the rows really will be sorted in the specified order, or false +** otherwise. +** +** For example, assuming: +** +** CREATE INDEX i1 ON t1(x, Y); +** +** then +** +** SELECT * FROM t1 GROUP BY x,y ORDER BY x,y; -- IsSorted()==1 +** SELECT * FROM t1 GROUP BY y,x ORDER BY y,x; -- IsSorted()==0 +*/ +SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo *pWInfo){ + assert( pWInfo->wctrlFlags & WHERE_GROUPBY ); + assert( pWInfo->wctrlFlags & WHERE_SORTBYGROUP ); + return pWInfo->sorted; +} + +#ifdef WHERETRACE_ENABLED +/* For debugging use only: */ +static const char *wherePathName(WherePath *pPath, int nLoop, WhereLoop *pLast){ + static char zName[65]; + int i; + for(i=0; iaLoop[i]->cId; } + if( pLast ) zName[i++] = pLast->cId; + zName[i] = 0; + return zName; +} +#endif + +/* +** Return the cost of sorting nRow rows, assuming that the keys have +** nOrderby columns and that the first nSorted columns are already in +** order. +*/ +static LogEst whereSortingCost( + WhereInfo *pWInfo, + LogEst nRow, + int nOrderBy, + int nSorted +){ + /* TUNING: Estimated cost of a full external sort, where N is + ** the number of rows to sort is: + ** + ** cost = (3.0 * N * log(N)). + ** + ** Or, if the order-by clause has X terms but only the last Y + ** terms are out of order, then block-sorting will reduce the + ** sorting cost to: + ** + ** cost = (3.0 * N * log(N)) * (Y/X) + ** + ** The (Y/X) term is implemented using stack variable rScale + ** below. */ + LogEst rScale, rSortCost; + assert( nOrderBy>0 && 66==sqlite3LogEst(100) ); + rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66; + rSortCost = nRow + estLog(nRow) + rScale + 16; + + /* TUNING: The cost of implementing DISTINCT using a B-TREE is + ** similar but with a larger constant of proportionality. + ** Multiply by an additional factor of 3.0. */ + if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){ + rSortCost += 16; + } + + return rSortCost; +} + +/* +** Given the list of WhereLoop objects at pWInfo->pLoops, this routine +** attempts to find the lowest cost path that visits each WhereLoop +** once. This path is then loaded into the pWInfo->a[].pWLoop fields. +** +** Assume that the total number of output rows that will need to be sorted +** will be nRowEst (in the 10*log2 representation). Or, ignore sorting +** costs if nRowEst==0. +** +** Return SQLITE_OK on success or SQLITE_NOMEM of a memory allocation +** error occurs. +*/ +static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ + int mxChoice; /* Maximum number of simultaneous paths tracked */ + int nLoop; /* Number of terms in the join */ + Parse *pParse; /* Parsing context */ + sqlite3 *db; /* The database connection */ + int iLoop; /* Loop counter over the terms of the join */ + int ii, jj; /* Loop counters */ + int mxI = 0; /* Index of next entry to replace */ + int nOrderBy; /* Number of ORDER BY clause terms */ + LogEst mxCost = 0; /* Maximum cost of a set of paths */ + LogEst mxUnsorted = 0; /* Maximum unsorted cost of a set of path */ + int nTo, nFrom; /* Number of valid entries in aTo[] and aFrom[] */ + WherePath *aFrom; /* All nFrom paths at the previous level */ + WherePath *aTo; /* The nTo best paths at the current level */ + WherePath *pFrom; /* An element of aFrom[] that we are working on */ + WherePath *pTo; /* An element of aTo[] that we are working on */ + WhereLoop *pWLoop; /* One of the WhereLoop objects */ + WhereLoop **pX; /* Used to divy up the pSpace memory */ + LogEst *aSortCost = 0; /* Sorting and partial sorting costs */ + char *pSpace; /* Temporary memory used by this routine */ + int nSpace; /* Bytes of space allocated at pSpace */ + + pParse = pWInfo->pParse; + db = pParse->db; + nLoop = pWInfo->nLevel; + /* TUNING: For simple queries, only the best path is tracked. + ** For 2-way joins, the 5 best paths are followed. + ** For joins of 3 or more tables, track the 10 best paths */ + mxChoice = (nLoop<=1) ? 1 : (nLoop==2 ? 5 : 10); + assert( nLoop<=pWInfo->pTabList->nSrc ); + WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d)\n", nRowEst)); + + /* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this + ** case the purpose of this call is to estimate the number of rows returned + ** by the overall query. Once this estimate has been obtained, the caller + ** will invoke this function a second time, passing the estimate as the + ** nRowEst parameter. */ + if( pWInfo->pOrderBy==0 || nRowEst==0 ){ + nOrderBy = 0; + }else{ + nOrderBy = pWInfo->pOrderBy->nExpr; + } + + /* Allocate and initialize space for aTo, aFrom and aSortCost[] */ + nSpace = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2; + nSpace += sizeof(LogEst) * nOrderBy; + pSpace = sqlite3DbMallocRaw(db, nSpace); + if( pSpace==0 ) return SQLITE_NOMEM; + aTo = (WherePath*)pSpace; + aFrom = aTo+mxChoice; + memset(aFrom, 0, sizeof(aFrom[0])); + pX = (WhereLoop**)(aFrom+mxChoice); + for(ii=mxChoice*2, pFrom=aTo; ii>0; ii--, pFrom++, pX += nLoop){ + pFrom->aLoop = pX; + } + if( nOrderBy ){ + /* If there is an ORDER BY clause and it is not being ignored, set up + ** space for the aSortCost[] array. Each element of the aSortCost array + ** is either zero - meaning it has not yet been initialized - or the + ** cost of sorting nRowEst rows of data where the first X terms of + ** the ORDER BY clause are already in order, where X is the array + ** index. */ + aSortCost = (LogEst*)pX; + memset(aSortCost, 0, sizeof(LogEst) * nOrderBy); + } + assert( aSortCost==0 || &pSpace[nSpace]==(char*)&aSortCost[nOrderBy] ); + assert( aSortCost!=0 || &pSpace[nSpace]==(char*)pX ); + + /* Seed the search with a single WherePath containing zero WhereLoops. + ** + ** TUNING: Do not let the number of iterations go above 28. If the cost + ** of computing an automatic index is not paid back within the first 28 + ** rows, then do not use the automatic index. */ + aFrom[0].nRow = MIN(pParse->nQueryLoop, 48); assert( 48==sqlite3LogEst(28) ); + nFrom = 1; + assert( aFrom[0].isOrdered==0 ); + if( nOrderBy ){ + /* If nLoop is zero, then there are no FROM terms in the query. Since + ** in this case the query may return a maximum of one row, the results + ** are already in the requested order. Set isOrdered to nOrderBy to + ** indicate this. Or, if nLoop is greater than zero, set isOrdered to + ** -1, indicating that the result set may or may not be ordered, + ** depending on the loops added to the current plan. */ + aFrom[0].isOrdered = nLoop>0 ? -1 : nOrderBy; + } + + /* Compute successively longer WherePaths using the previous generation + ** of WherePaths as the basis for the next. Keep track of the mxChoice + ** best paths at each generation */ + for(iLoop=0; iLooppLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ + LogEst nOut; /* Rows visited by (pFrom+pWLoop) */ + LogEst rCost; /* Cost of path (pFrom+pWLoop) */ + LogEst rUnsorted; /* Unsorted cost of (pFrom+pWLoop) */ + i8 isOrdered = pFrom->isOrdered; /* isOrdered for (pFrom+pWLoop) */ + Bitmask maskNew; /* Mask of src visited by (..) */ + Bitmask revMask = 0; /* Mask of rev-order loops for (..) */ + + if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue; + if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue; + /* At this point, pWLoop is a candidate to be the next loop. + ** Compute its cost */ + rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow); + rUnsorted = sqlite3LogEstAdd(rUnsorted, pFrom->rUnsorted); + nOut = pFrom->nRow + pWLoop->nOut; + maskNew = pFrom->maskLoop | pWLoop->maskSelf; + if( isOrdered<0 ){ + isOrdered = wherePathSatisfiesOrderBy(pWInfo, + pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags, + iLoop, pWLoop, &revMask); + }else{ + revMask = pFrom->revLoop; + } + if( isOrdered>=0 && isOrderedisOrdered^isOrdered)&0x80)==0" is equivalent + ** to (pTo->isOrdered==(-1))==(isOrdered==(-1))" for the range + ** of legal values for isOrdered, -1..64. + */ + for(jj=0, pTo=aTo; jjmaskLoop==maskNew + && ((pTo->isOrdered^isOrdered)&0x80)==0 + ){ + testcase( jj==nTo-1 ); + break; + } + } + if( jj>=nTo ){ + /* None of the existing best-so-far paths match the candidate. */ + if( nTo>=mxChoice + && (rCost>mxCost || (rCost==mxCost && rUnsorted>=mxUnsorted)) + ){ + /* The current candidate is no better than any of the mxChoice + ** paths currently in the best-so-far buffer. So discard + ** this candidate as not viable. */ +#ifdef WHERETRACE_ENABLED /* 0x4 */ + if( sqlite3WhereTrace&0x4 ){ + sqlite3DebugPrintf("Skip %s cost=%-3d,%3d order=%c\n", + wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, + isOrdered>=0 ? isOrdered+'0' : '?'); + } +#endif + continue; + } + /* If we reach this points it means that the new candidate path + ** needs to be added to the set of best-so-far paths. */ + if( nTo=0 ? isOrdered+'0' : '?'); + } +#endif + }else{ + /* Control reaches here if best-so-far path pTo=aTo[jj] covers the + ** same set of loops and has the sam isOrdered setting as the + ** candidate path. Check to see if the candidate should replace + ** pTo or if the candidate should be skipped */ + if( pTo->rCostrCost==rCost && pTo->nRow<=nOut) ){ +#ifdef WHERETRACE_ENABLED /* 0x4 */ + if( sqlite3WhereTrace&0x4 ){ + sqlite3DebugPrintf( + "Skip %s cost=%-3d,%3d order=%c", + wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, + isOrdered>=0 ? isOrdered+'0' : '?'); + sqlite3DebugPrintf(" vs %s cost=%-3d,%d order=%c\n", + wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, + pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?'); + } +#endif + /* Discard the candidate path from further consideration */ + testcase( pTo->rCost==rCost ); + continue; + } + testcase( pTo->rCost==rCost+1 ); + /* Control reaches here if the candidate path is better than the + ** pTo path. Replace pTo with the candidate. */ +#ifdef WHERETRACE_ENABLED /* 0x4 */ + if( sqlite3WhereTrace&0x4 ){ + sqlite3DebugPrintf( + "Update %s cost=%-3d,%3d order=%c", + wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, + isOrdered>=0 ? isOrdered+'0' : '?'); + sqlite3DebugPrintf(" was %s cost=%-3d,%3d order=%c\n", + wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, + pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?'); + } +#endif + } + /* pWLoop is a winner. Add it to the set of best so far */ + pTo->maskLoop = pFrom->maskLoop | pWLoop->maskSelf; + pTo->revLoop = revMask; + pTo->nRow = nOut; + pTo->rCost = rCost; + pTo->rUnsorted = rUnsorted; + pTo->isOrdered = isOrdered; + memcpy(pTo->aLoop, pFrom->aLoop, sizeof(WhereLoop*)*iLoop); + pTo->aLoop[iLoop] = pWLoop; + if( nTo>=mxChoice ){ + mxI = 0; + mxCost = aTo[0].rCost; + mxUnsorted = aTo[0].nRow; + for(jj=1, pTo=&aTo[1]; jjrCost>mxCost + || (pTo->rCost==mxCost && pTo->rUnsorted>mxUnsorted) + ){ + mxCost = pTo->rCost; + mxUnsorted = pTo->rUnsorted; + mxI = jj; + } + } + } + } + } + +#ifdef WHERETRACE_ENABLED /* >=2 */ + if( sqlite3WhereTrace & 0x02 ){ + sqlite3DebugPrintf("---- after round %d ----\n", iLoop); + for(ii=0, pTo=aTo; iirCost, pTo->nRow, + pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?'); + if( pTo->isOrdered>0 ){ + sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop); + }else{ + sqlite3DebugPrintf("\n"); + } + } + } +#endif + + /* Swap the roles of aFrom and aTo for the next generation */ + pFrom = aTo; + aTo = aFrom; + aFrom = pFrom; + nFrom = nTo; + } + + if( nFrom==0 ){ + sqlite3ErrorMsg(pParse, "no query solution"); + sqlite3DbFree(db, pSpace); + return SQLITE_ERROR; + } + + /* Find the lowest cost path. pFrom will be left pointing to that path */ + pFrom = aFrom; + for(ii=1; iirCost>aFrom[ii].rCost ) pFrom = &aFrom[ii]; + } + assert( pWInfo->nLevel==nLoop ); + /* Load the lowest cost path into pWInfo */ + for(iLoop=0; iLoopa + iLoop; + pLevel->pWLoop = pWLoop = pFrom->aLoop[iLoop]; + pLevel->iFrom = pWLoop->iTab; + pLevel->iTabCur = pWInfo->pTabList->a[pLevel->iFrom].iCursor; + } + if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)!=0 + && (pWInfo->wctrlFlags & WHERE_DISTINCTBY)==0 + && pWInfo->eDistinct==WHERE_DISTINCT_NOOP + && nRowEst + ){ + Bitmask notUsed; + int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pResultSet, pFrom, + WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], ¬Used); + if( rc==pWInfo->pResultSet->nExpr ){ + pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; + } + } + if( pWInfo->pOrderBy ){ + if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){ + if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){ + pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; + } + }else{ + pWInfo->nOBSat = pFrom->isOrdered; + if( pWInfo->nOBSat<0 ) pWInfo->nOBSat = 0; + pWInfo->revMask = pFrom->revLoop; + } + if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP) + && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr && nLoop>0 + ){ + Bitmask revMask = 0; + int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, + pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &revMask + ); + assert( pWInfo->sorted==0 ); + if( nOrder==pWInfo->pOrderBy->nExpr ){ + pWInfo->sorted = 1; + pWInfo->revMask = revMask; + } + } + } + + + pWInfo->nRowOut = pFrom->nRow; + + /* Free temporary memory and return success */ + sqlite3DbFree(db, pSpace); + return SQLITE_OK; +} + +/* +** Most queries use only a single table (they are not joins) and have +** simple == constraints against indexed fields. This routine attempts +** to plan those simple cases using much less ceremony than the +** general-purpose query planner, and thereby yield faster sqlite3_prepare() +** times for the common case. +** +** Return non-zero on success, if this query can be handled by this +** no-frills query planner. Return zero if this query needs the +** general-purpose query planner. +*/ +static int whereShortCut(WhereLoopBuilder *pBuilder){ + WhereInfo *pWInfo; + struct SrcList_item *pItem; + WhereClause *pWC; + WhereTerm *pTerm; + WhereLoop *pLoop; + int iCur; + int j; + Table *pTab; + Index *pIdx; + + pWInfo = pBuilder->pWInfo; + if( pWInfo->wctrlFlags & WHERE_FORCE_TABLE ) return 0; + assert( pWInfo->pTabList->nSrc>=1 ); + pItem = pWInfo->pTabList->a; + pTab = pItem->pTab; + if( IsVirtual(pTab) ) return 0; + if( pItem->zIndex ) return 0; + iCur = pItem->iCursor; + pWC = &pWInfo->sWC; + pLoop = pBuilder->pNew; + pLoop->wsFlags = 0; + pLoop->nSkip = 0; + pTerm = findTerm(pWC, iCur, -1, 0, WO_EQ, 0); + if( pTerm ){ + pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW; + pLoop->aLTerm[0] = pTerm; + pLoop->nLTerm = 1; + pLoop->u.btree.nEq = 1; + /* TUNING: Cost of a rowid lookup is 10 */ + pLoop->rRun = 33; /* 33==sqlite3LogEst(10) */ + }else{ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + assert( pLoop->aLTermSpace==pLoop->aLTerm ); + if( !IsUniqueIndex(pIdx) + || pIdx->pPartIdxWhere!=0 + || pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace) + ) continue; + for(j=0; jnKeyCol; j++){ + pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx); + if( pTerm==0 ) break; + pLoop->aLTerm[j] = pTerm; + } + if( j!=pIdx->nKeyCol ) continue; + pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED; + if( pIdx->isCovering || (pItem->colUsed & ~columnsInIndex(pIdx))==0 ){ + pLoop->wsFlags |= WHERE_IDX_ONLY; + } + pLoop->nLTerm = j; + pLoop->u.btree.nEq = j; + pLoop->u.btree.pIndex = pIdx; + /* TUNING: Cost of a unique index lookup is 15 */ + pLoop->rRun = 39; /* 39==sqlite3LogEst(15) */ + break; + } + } + if( pLoop->wsFlags ){ + pLoop->nOut = (LogEst)1; + pWInfo->a[0].pWLoop = pLoop; + pLoop->maskSelf = getMask(&pWInfo->sMaskSet, iCur); + pWInfo->a[0].iTabCur = iCur; + pWInfo->nRowOut = 1; + if( pWInfo->pOrderBy ) pWInfo->nOBSat = pWInfo->pOrderBy->nExpr; + if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){ + pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; + } +#ifdef SQLITE_DEBUG + pLoop->cId = '0'; +#endif + return 1; + } + return 0; +} + +/* +** 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 +** in order to complete the WHERE clause processing. +** +** If an error occurs, this routine returns NULL. +** +** The basic idea is to do a nested loop, one loop for each table in +** the FROM clause of a select. (INSERT and UPDATE statements are the +** same as a SELECT with only a single table in the FROM clause.) For +** example, if the SQL is this: +** +** SELECT * FROM t1, t2, t3 WHERE ...; +** +** Then the code generated is conceptually like the following: +** +** foreach row1 in t1 do \ Code generated +** 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 +** to see if there are indices that can be used to speed up the loop. +** +** Terms of the WHERE clause are also used to limit which rows actually +** make it to the "..." in the middle of the loop. After each "foreach", +** terms of the WHERE clause that use only terms in that loop and outer +** loops are evaluated and if false a jump is made around all subsequent +** inner loops (or around the "..." if the test occurs within the inner- +** most loop) +** +** OUTER JOINS +** +** An outer join of tables t1 and t2 is conceptally coded as follows: +** +** foreach row1 in t1 do +** flag = 0 +** foreach row2 in t2 do +** start: +** ... +** flag = 1 +** end +** if flag==0 then +** move the row2 cursor to a null row +** goto start +** fi +** end +** +** ORDER BY CLAUSE PROCESSING +** +** pOrderBy is a pointer to the ORDER BY clause (or the GROUP BY clause +** if the WHERE_GROUPBY flag is set in wctrlFlags) of a SELECT statement +** if there is one. If there is no ORDER BY clause or if this routine +** is called from an UPDATE or DELETE statement, then pOrderBy is NULL. +** +** The iIdxCur parameter is the cursor number of an index. If +** WHERE_ONETABLE_ONLY is set, iIdxCur is the cursor number of an index +** to use for OR clause processing. The WHERE clause should use this +** specific cursor. If WHERE_ONEPASS_DESIRED is set, then iIdxCur is +** the first cursor in an array of cursors for all indices. iIdxCur should +** be used to compute the appropriate cursor depending on which index is +** used. +*/ +SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( + Parse *pParse, /* The parser context */ + SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */ + Expr *pWhere, /* The WHERE clause */ + ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */ + ExprList *pResultSet, /* Result set of the query */ + u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */ + int iIdxCur /* If WHERE_ONETABLE_ONLY is set, index cursor number */ +){ + int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */ + int nTabList; /* Number of elements in pTabList */ + WhereInfo *pWInfo; /* Will become the return value of this function */ + Vdbe *v = pParse->pVdbe; /* The virtual database engine */ + Bitmask notReady; /* Cursors that are not yet positioned */ + WhereLoopBuilder sWLB; /* The WhereLoop builder */ + WhereMaskSet *pMaskSet; /* The expression mask set */ + WhereLevel *pLevel; /* A single level in pWInfo->a[] */ + WhereLoop *pLoop; /* Pointer to a single WhereLoop object */ + int ii; /* Loop counter */ + sqlite3 *db; /* Database connection */ + int rc; /* Return code */ + + + /* Variable initialization */ + db = pParse->db; + memset(&sWLB, 0, sizeof(sWLB)); + + /* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */ + testcase( pOrderBy && pOrderBy->nExpr==BMS-1 ); + if( pOrderBy && pOrderBy->nExpr>=BMS ) pOrderBy = 0; + sWLB.pOrderBy = pOrderBy; + + /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via + ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ + if( OptimizationDisabled(db, SQLITE_DistinctOpt) ){ + wctrlFlags &= ~WHERE_WANT_DISTINCT; + } + + /* The number of tables in the FROM clause is limited by the number of + ** bits in a Bitmask + */ + testcase( pTabList->nSrc==BMS ); + if( pTabList->nSrc>BMS ){ + sqlite3ErrorMsg(pParse, "at most %d tables in a join", BMS); + return 0; + } + + /* This function normally generates a nested loop for all tables in + ** pTabList. But if the WHERE_ONETABLE_ONLY flag is set, then we should + ** only generate code for the first table in pTabList and assume that + ** any cursors associated with subsequent tables are uninitialized. + */ + nTabList = (wctrlFlags & WHERE_ONETABLE_ONLY) ? 1 : pTabList->nSrc; + + /* Allocate and initialize the WhereInfo structure that will become the + ** return value. A single allocation is used to store the WhereInfo + ** struct, the contents of WhereInfo.a[], the WhereClause structure + ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte + ** field (type Bitmask) it must be aligned on an 8-byte boundary on + ** some architectures. Hence the ROUND8() below. + */ + nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel)); + pWInfo = sqlite3DbMallocZero(db, nByteWInfo + sizeof(WhereLoop)); + if( db->mallocFailed ){ + sqlite3DbFree(db, pWInfo); + pWInfo = 0; + goto whereBeginError; + } + pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1; + pWInfo->nLevel = nTabList; + pWInfo->pParse = pParse; + pWInfo->pTabList = pTabList; + pWInfo->pOrderBy = pOrderBy; + pWInfo->pResultSet = pResultSet; + pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v); + pWInfo->wctrlFlags = wctrlFlags; + pWInfo->savedNQueryLoop = pParse->nQueryLoop; + pMaskSet = &pWInfo->sMaskSet; + sWLB.pWInfo = pWInfo; + sWLB.pWC = &pWInfo->sWC; + sWLB.pNew = (WhereLoop*)(((char*)pWInfo)+nByteWInfo); + assert( EIGHT_BYTE_ALIGNMENT(sWLB.pNew) ); + whereLoopInit(sWLB.pNew); +#ifdef SQLITE_DEBUG + sWLB.pNew->cId = '*'; +#endif + + /* Split the WHERE clause into separate subexpressions where each + ** subexpression is separated by an AND operator. + */ + initMaskSet(pMaskSet); + whereClauseInit(&pWInfo->sWC, pWInfo); + whereSplit(&pWInfo->sWC, pWhere, TK_AND); + + /* Special case: a WHERE clause that is constant. Evaluate the + ** expression and either jump over all of the code or fall thru. + */ + for(ii=0; iinTerm; ii++){ + if( nTabList==0 || sqlite3ExprIsConstantNotJoin(sWLB.pWC->a[ii].pExpr) ){ + sqlite3ExprIfFalse(pParse, sWLB.pWC->a[ii].pExpr, pWInfo->iBreak, + SQLITE_JUMPIFNULL); + sWLB.pWC->a[ii].wtFlags |= TERM_CODED; + } + } + + /* Special case: No FROM clause + */ + if( nTabList==0 ){ + if( pOrderBy ) pWInfo->nOBSat = pOrderBy->nExpr; + if( wctrlFlags & WHERE_WANT_DISTINCT ){ + pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; + } + } + + /* Assign a bit from the bitmask to every term in the FROM clause. + ** + ** When assigning bitmask values to FROM clause cursors, it must be + ** the case that if X is the bitmask for the N-th FROM clause term then + ** the bitmask for all FROM clause terms to the left of the N-th term + ** is (X-1). An expression from the ON clause of a LEFT JOIN can use + ** its Expr.iRightJoinTable value to find the bitmask of the right table + ** of the join. Subtracting one from the right table bitmask gives a + ** bitmask for all tables to the left of the join. Knowing the bitmask + ** for all tables to the left of a left join is important. Ticket #3015. + ** + ** Note that bitmasks are created for all pTabList->nSrc tables in + ** pTabList, not just the first nTabList tables. nTabList is normally + ** equal to pTabList->nSrc but might be shortened to 1 if the + ** WHERE_ONETABLE_ONLY flag is set. + */ + for(ii=0; iinSrc; ii++){ + createMask(pMaskSet, pTabList->a[ii].iCursor); + } +#ifndef NDEBUG + { + Bitmask toTheLeft = 0; + for(ii=0; iinSrc; ii++){ + Bitmask m = getMask(pMaskSet, pTabList->a[ii].iCursor); + assert( (m-1)==toTheLeft ); + toTheLeft |= m; + } + } +#endif + + /* 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. + */ + exprAnalyzeAll(pTabList, &pWInfo->sWC); + if( db->mallocFailed ){ + goto whereBeginError; + } + + if( wctrlFlags & WHERE_WANT_DISTINCT ){ + if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){ + /* The DISTINCT marking is pointless. Ignore it. */ + pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; + }else if( pOrderBy==0 ){ + /* Try to ORDER BY the result set to make distinct processing easier */ + pWInfo->wctrlFlags |= WHERE_DISTINCTBY; + pWInfo->pOrderBy = pResultSet; + } + } + + /* Construct the WhereLoop objects */ + WHERETRACE(0xffff,("*** Optimizer Start ***\n")); +#if defined(WHERETRACE_ENABLED) + /* Display all terms of the WHERE clause */ + if( sqlite3WhereTrace & 0x100 ){ + int i; + for(i=0; inTerm; i++){ + whereTermPrint(&sWLB.pWC->a[i], i); + } + } +#endif + + if( nTabList!=1 || whereShortCut(&sWLB)==0 ){ + rc = whereLoopAddAll(&sWLB); + if( rc ) goto whereBeginError; + + /* Display all of the WhereLoop objects if wheretrace is enabled */ +#ifdef WHERETRACE_ENABLED /* !=0 */ + if( sqlite3WhereTrace ){ + WhereLoop *p; + int i; + static char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz" + "ABCDEFGHIJKLMNOPQRSTUVWYXZ"; + for(p=pWInfo->pLoops, i=0; p; p=p->pNextLoop, i++){ + p->cId = zLabel[i%sizeof(zLabel)]; + whereLoopPrint(p, sWLB.pWC); + } + } +#endif + + wherePathSolver(pWInfo, 0); + if( db->mallocFailed ) goto whereBeginError; + if( pWInfo->pOrderBy ){ + wherePathSolver(pWInfo, pWInfo->nRowOut+1); + if( db->mallocFailed ) goto whereBeginError; + } + } + if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){ + pWInfo->revMask = (Bitmask)(-1); + } + if( pParse->nErr || NEVER(db->mallocFailed) ){ + goto whereBeginError; + } +#ifdef WHERETRACE_ENABLED /* !=0 */ + if( sqlite3WhereTrace ){ + sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut); + if( pWInfo->nOBSat>0 ){ + sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask); + } + switch( pWInfo->eDistinct ){ + case WHERE_DISTINCT_UNIQUE: { + sqlite3DebugPrintf(" DISTINCT=unique"); + break; + } + case WHERE_DISTINCT_ORDERED: { + sqlite3DebugPrintf(" DISTINCT=ordered"); + break; + } + case WHERE_DISTINCT_UNORDERED: { + sqlite3DebugPrintf(" DISTINCT=unordered"); + break; + } + } + sqlite3DebugPrintf("\n"); + for(ii=0; iinLevel; ii++){ + whereLoopPrint(pWInfo->a[ii].pWLoop, sWLB.pWC); + } + } +#endif + /* Attempt to omit tables from the join that do not effect the result */ + if( pWInfo->nLevel>=2 + && pResultSet!=0 + && OptimizationEnabled(db, SQLITE_OmitNoopJoin) + ){ + Bitmask tabUsed = exprListTableUsage(pMaskSet, pResultSet); + if( sWLB.pOrderBy ) tabUsed |= exprListTableUsage(pMaskSet, sWLB.pOrderBy); + while( pWInfo->nLevel>=2 ){ + WhereTerm *pTerm, *pEnd; + pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop; + if( (pWInfo->pTabList->a[pLoop->iTab].jointype & JT_LEFT)==0 ) break; + if( (wctrlFlags & WHERE_WANT_DISTINCT)==0 + && (pLoop->wsFlags & WHERE_ONEROW)==0 + ){ + break; + } + if( (tabUsed & pLoop->maskSelf)!=0 ) break; + pEnd = sWLB.pWC->a + sWLB.pWC->nTerm; + for(pTerm=sWLB.pWC->a; pTermprereqAll & pLoop->maskSelf)!=0 + && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) + ){ + break; + } + } + if( pTerm drop loop %c not used\n", pLoop->cId)); + pWInfo->nLevel--; + nTabList--; + } + } + WHERETRACE(0xffff,("*** Optimizer Finished ***\n")); + pWInfo->pParse->nQueryLoop += pWInfo->nRowOut; + + /* If the caller is an UPDATE or DELETE statement that is requesting + ** to use a one-pass algorithm, determine if this is appropriate. + ** The one-pass algorithm only works if the WHERE clause constrains + ** the statement to update a single row. + */ + assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 ); + if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 + && (pWInfo->a[0].pWLoop->wsFlags & WHERE_ONEROW)!=0 ){ + pWInfo->okOnePass = 1; + if( HasRowid(pTabList->a[0].pTab) ){ + pWInfo->a[0].pWLoop->wsFlags &= ~WHERE_IDX_ONLY; + } + } + + /* Open all tables in the pTabList and any indices selected for + ** searching those tables. + */ + notReady = ~(Bitmask)0; + for(ii=0, pLevel=pWInfo->a; iia[pLevel->iFrom]; + pTab = pTabItem->pTab; + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + pLoop = pLevel->pWLoop; + if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){ + /* Do nothing */ + }else +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){ + const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); + int iCur = pTabItem->iCursor; + sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB); + }else if( IsVirtual(pTab) ){ + /* noop */ + }else +#endif + if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 + && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){ + int op = OP_OpenRead; + if( pWInfo->okOnePass ){ + op = OP_OpenWrite; + pWInfo->aiCurOnePass[0] = pTabItem->iCursor; + }; + sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op); + assert( pTabItem->iCursor==pLevel->iTabCur ); + testcase( !pWInfo->okOnePass && pTab->nCol==BMS-1 ); + testcase( !pWInfo->okOnePass && pTab->nCol==BMS ); + if( !pWInfo->okOnePass && pTab->nColcolUsed; + int n = 0; + for(; b; b=b>>1, n++){} + sqlite3VdbeChangeP4(v, sqlite3VdbeCurrentAddr(v)-1, + SQLITE_INT_TO_PTR(n), P4_INT32); + assert( n<=pTab->nCol ); + } + }else{ + sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + } + if( pLoop->wsFlags & WHERE_INDEXED ){ + Index *pIx = pLoop->u.btree.pIndex; + int iIndexCur; + int op = OP_OpenRead; + /* iIdxCur is always set if to a positive value if ONEPASS is possible */ + assert( iIdxCur!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 ); + if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIx) + && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 + ){ + /* This is one term of an OR-optimization using the PRIMARY KEY of a + ** WITHOUT ROWID table. No need for a separate index */ + iIndexCur = pLevel->iTabCur; + op = 0; + }else if( pWInfo->okOnePass ){ + Index *pJ = pTabItem->pTab->pIndex; + iIndexCur = iIdxCur; + assert( wctrlFlags & WHERE_ONEPASS_DESIRED ); + while( ALWAYS(pJ) && pJ!=pIx ){ + iIndexCur++; + pJ = pJ->pNext; + } + op = OP_OpenWrite; + pWInfo->aiCurOnePass[1] = iIndexCur; + }else if( iIdxCur && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ){ + iIndexCur = iIdxCur; + if( wctrlFlags & WHERE_REOPEN_IDX ) op = OP_ReopenIdx; + }else{ + iIndexCur = pParse->nTab++; + } + pLevel->iIdxCur = iIndexCur; + assert( pIx->pSchema==pTab->pSchema ); + assert( iIndexCur>=0 ); + if( op ){ + sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIx); + if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0 + && (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0 + && (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 + ){ + sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); /* Hint to COMDB2 */ + } + VdbeComment((v, "%s", pIx->zName)); + } + } + if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb); + notReady &= ~getMask(&pWInfo->sMaskSet, pTabItem->iCursor); + } + pWInfo->iTop = sqlite3VdbeCurrentAddr(v); + if( db->mallocFailed ) goto whereBeginError; + + /* 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(ii=0; iia[ii]; + wsFlags = pLevel->pWLoop->wsFlags; +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX + if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){ + constructAutomaticIndex(pParse, &pWInfo->sWC, + &pTabList->a[pLevel->iFrom], notReady, pLevel); + if( db->mallocFailed ) goto whereBeginError; + } +#endif + addrExplain = explainOneScan( + pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags + ); + pLevel->addrBody = sqlite3VdbeCurrentAddr(v); + notReady = codeOneLoopStart(pWInfo, ii, notReady); + pWInfo->iContinue = pLevel->addrCont; + if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_ONETABLE_ONLY)==0 ){ + addScanStatus(v, pTabList, pLevel, addrExplain); + } + } + + /* Done. */ + VdbeModuleComment((v, "Begin WHERE-core")); + return pWInfo; + + /* Jump here if malloc fails */ +whereBeginError: + if( pWInfo ){ + pParse->nQueryLoop = pWInfo->savedNQueryLoop; + whereInfoFree(db, pWInfo); + } + return 0; +} + +/* +** Generate the end of the WHERE loop. See comments on +** sqlite3WhereBegin() for additional information. +*/ +SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ + Parse *pParse = pWInfo->pParse; + Vdbe *v = pParse->pVdbe; + int i; + WhereLevel *pLevel; + WhereLoop *pLoop; + SrcList *pTabList = pWInfo->pTabList; + sqlite3 *db = pParse->db; + + /* Generate loop termination code. + */ + VdbeModuleComment((v, "End WHERE-core")); + sqlite3ExprCacheClear(pParse); + for(i=pWInfo->nLevel-1; i>=0; i--){ + int addr; + pLevel = &pWInfo->a[i]; + pLoop = pLevel->pWLoop; + sqlite3VdbeResolveLabel(v, pLevel->addrCont); + if( pLevel->op!=OP_Noop ){ + sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3); + sqlite3VdbeChangeP5(v, pLevel->p5); + VdbeCoverage(v); + VdbeCoverageIf(v, pLevel->op==OP_Next); + VdbeCoverageIf(v, pLevel->op==OP_Prev); + VdbeCoverageIf(v, pLevel->op==OP_VNext); + } + if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){ + struct InLoop *pIn; + int j; + sqlite3VdbeResolveLabel(v, pLevel->addrNxt); + for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){ + sqlite3VdbeJumpHere(v, pIn->addrInTop+1); + sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop); + VdbeCoverage(v); + VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen); + VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen); + sqlite3VdbeJumpHere(v, pIn->addrInTop-1); + } + } + sqlite3VdbeResolveLabel(v, pLevel->addrBrk); + if( pLevel->addrSkip ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrSkip); + VdbeComment((v, "next skip-scan on %s", pLoop->u.btree.pIndex->zName)); + sqlite3VdbeJumpHere(v, pLevel->addrSkip); + sqlite3VdbeJumpHere(v, pLevel->addrSkip-2); + } + if( pLevel->addrLikeRep ){ + int op; + if( sqlite3VdbeGetOp(v, pLevel->addrLikeRep-1)->p1 ){ + op = OP_DecrJumpZero; + }else{ + op = OP_JumpZeroIncr; + } + sqlite3VdbeAddOp2(v, op, pLevel->iLikeRepCntr, pLevel->addrLikeRep); + VdbeCoverage(v); + } + if( pLevel->iLeftJoin ){ + addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v); + assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 + || (pLoop->wsFlags & WHERE_INDEXED)!=0 ); + if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 ){ + sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor); + } + if( pLoop->wsFlags & WHERE_INDEXED ){ + sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur); + } + if( pLevel->op==OP_Return ){ + sqlite3VdbeAddOp2(v, OP_Gosub, pLevel->p1, pLevel->addrFirst); + }else{ + sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrFirst); + } + sqlite3VdbeJumpHere(v, addr); + } + VdbeModuleComment((v, "End WHERE-loop%d: %s", i, + pWInfo->pTabList->a[pLevel->iFrom].pTab->zName)); + } + + /* The "break" point is here, just past the end of the outer loop. + ** Set it. + */ + sqlite3VdbeResolveLabel(v, pWInfo->iBreak); + + assert( pWInfo->nLevel<=pTabList->nSrc ); + for(i=0, pLevel=pWInfo->a; inLevel; i++, pLevel++){ + int k, last; + VdbeOp *pOp; + Index *pIdx = 0; + struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom]; + Table *pTab = pTabItem->pTab; + assert( pTab!=0 ); + pLoop = pLevel->pWLoop; + + /* For a co-routine, change all OP_Column references to the table of + ** the co-routine into OP_SCopy of result contained in a register. + ** OP_Rowid becomes OP_Null. + */ + if( pTabItem->viaCoroutine && !db->mallocFailed ){ + last = sqlite3VdbeCurrentAddr(v); + k = pLevel->addrBody; + pOp = sqlite3VdbeGetOp(v, k); + for(; kp1!=pLevel->iTabCur ) continue; + if( pOp->opcode==OP_Column ){ + pOp->opcode = OP_Copy; + pOp->p1 = pOp->p2 + pTabItem->regResult; + pOp->p2 = pOp->p3; + pOp->p3 = 0; + }else if( pOp->opcode==OP_Rowid ){ + pOp->opcode = OP_Null; + pOp->p1 = 0; + pOp->p3 = 0; + } + } + continue; + } + + /* Close all of the cursors that were opened by sqlite3WhereBegin. + ** Except, do not close cursors that will be reused by the OR optimization + ** (WHERE_OMIT_OPEN_CLOSE). And do not close the OP_OpenWrite cursors + ** created for the ONEPASS optimization. + */ + if( (pTab->tabFlags & TF_Ephemeral)==0 + && pTab->pSelect==0 + && (pWInfo->wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 + ){ + int ws = pLoop->wsFlags; + if( !pWInfo->okOnePass && (ws & WHERE_IDX_ONLY)==0 ){ + sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor); + } + if( (ws & WHERE_INDEXED)!=0 + && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0 + && pLevel->iIdxCur!=pWInfo->aiCurOnePass[1] + ){ + sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur); + } + } + + /* If this scan uses an index, make VDBE code substitutions to read data + ** from the index instead of from the table where possible. In some cases + ** this optimization prevents the table from ever being read, which can + ** yield a significant performance boost. + ** + ** 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( pLoop->wsFlags & (WHERE_INDEXED|WHERE_IDX_ONLY) ){ + pIdx = pLoop->u.btree.pIndex; + }else if( pLoop->wsFlags & WHERE_MULTI_OR ){ + pIdx = pLevel->u.pCovidx; + } + if( pIdx && !db->mallocFailed ){ + last = sqlite3VdbeCurrentAddr(v); + k = pLevel->addrBody; + pOp = sqlite3VdbeGetOp(v, k); + for(; kp1!=pLevel->iTabCur ) continue; + if( pOp->opcode==OP_Column ){ + int x = pOp->p2; + assert( pIdx->pTable==pTab ); + if( !HasRowid(pTab) ){ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + x = pPk->aiColumn[x]; + } + x = sqlite3ColumnOfIndex(pIdx, x); + if( x>=0 ){ + pOp->p2 = x; + pOp->p1 = pLevel->iIdxCur; + } + assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 ); + }else if( pOp->opcode==OP_Rowid ){ + pOp->p1 = pLevel->iIdxCur; + pOp->opcode = OP_IdxRowid; + } + } + } + } + + /* Final cleanup + */ + pParse->nQueryLoop = pWInfo->savedNQueryLoop; + whereInfoFree(db, pWInfo); + return; +} + +/************** End of where.c ***********************************************/ +/************** Begin file parse.c *******************************************/ +/* Driver template for the LEMON parser generator. +** The author disclaims copyright to this source code. +** +** This version of "lempar.c" is modified, slightly, for use by SQLite. +** The only modifications are the addition of a couple of NEVER() +** macros to disable tests that are needed in the case of a general +** LALR(1) grammar but which are always false in the +** specific grammar used by SQLite. +*/ +/* First off, code is included that follows the "include" declaration +** in the input grammar file. */ +/* #include */ + + +/* +** Disable all error recovery processing in the parser push-down +** automaton. +*/ +#define YYNOERRORRECOVERY 1 + +/* +** Make yytestcase() the same as testcase() +*/ +#define yytestcase(X) testcase(X) + +/* +** 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 eOperator; /* "like" or "glob" or "regexp" */ + int bNot; /* 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 +** +** UPDATE ON (a,b,c) +** +** Then the "b" IdList records the list "a,b,c". +*/ +struct TrigEvent { int a; IdList * b; }; + +/* +** An instance of this structure holds the ATTACH key and the key type. +*/ +struct AttachKey { int type; Token key; }; + + + /* + ** For a compound SELECT statement, make sure p->pPrior->pNext==p for + ** all elements in the list. And make sure list length does not exceed + ** SQLITE_LIMIT_COMPOUND_SELECT. + */ + static void parserDoubleLinkSelect(Parse *pParse, Select *p){ + if( p->pPrior ){ + Select *pNext = 0, *pLoop; + int mxSelect, cnt = 0; + for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){ + pLoop->pNext = pNext; + pLoop->selFlags |= SF_Compound; + } + if( (p->selFlags & SF_MultiValue)==0 && + (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 && + cnt>mxSelect + ){ + sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); + } + } + } + + /* This is a utility routine used to set the ExprSpan.zStart and + ** ExprSpan.zEnd values of pOut so that the span covers the complete + ** range of text beginning with pStart and going to the end of pEnd. + */ + static void spanSet(ExprSpan *pOut, Token *pStart, Token *pEnd){ + pOut->zStart = pStart->z; + pOut->zEnd = &pEnd->z[pEnd->n]; + } + + /* Construct a new Expr object from a single identifier. Use the + ** new Expr to populate pOut. Set the span of pOut to be the identifier + ** that created the expression. + */ + static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token *pValue){ + pOut->pExpr = sqlite3PExpr(pParse, op, 0, 0, pValue); + pOut->zStart = pValue->z; + pOut->zEnd = &pValue->z[pValue->n]; + } + + /* This routine constructs a binary expression node out of two ExprSpan + ** objects and uses the result to populate a new ExprSpan object. + */ + static void spanBinaryExpr( + ExprSpan *pOut, /* Write the result here */ + Parse *pParse, /* The parsing context. Errors accumulate here */ + int op, /* The binary operation */ + ExprSpan *pLeft, /* The left operand */ + ExprSpan *pRight /* The right operand */ + ){ + pOut->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr, 0); + pOut->zStart = pLeft->zStart; + pOut->zEnd = pRight->zEnd; + } + + /* Construct an expression node for a unary postfix operator + */ + static void spanUnaryPostfix( + ExprSpan *pOut, /* Write the new expression node here */ + Parse *pParse, /* Parsing context to record errors */ + int op, /* The operator */ + ExprSpan *pOperand, /* The operand */ + Token *pPostOp /* The operand token for setting the span */ + ){ + pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0); + pOut->zStart = pOperand->zStart; + pOut->zEnd = &pPostOp->z[pPostOp->n]; + } + + /* A routine to convert a binary TK_IS or TK_ISNOT expression into a + ** unary TK_ISNULL or TK_NOTNULL expression. */ + static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){ + sqlite3 *db = pParse->db; + if( pY && pA && pY->op==TK_NULL ){ + pA->op = (u8)op; + sqlite3ExprDelete(db, pA->pRight); + pA->pRight = 0; + } + } + + /* Construct an expression node for a unary prefix operator + */ + static void spanUnaryPrefix( + ExprSpan *pOut, /* Write the new expression node here */ + Parse *pParse, /* Parsing context to record errors */ + int op, /* The operator */ + ExprSpan *pOperand, /* The operand */ + Token *pPreOp /* The operand token for setting the span */ + ){ + pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0); + pOut->zStart = pPreOp->z; + pOut->zEnd = pOperand->zEnd; + } +/* Next is all token values, in a form suitable for use by makeheaders. +** This section will be null unless lemon is run with the -m switch. +*/ +/* +** These constants (all generated automatically by the parser generator) +** specify the various kinds of tokens (terminals) that the parser +** understands. +** +** Each symbol here is a terminal symbol in the grammar. +*/ +/* Make sure the INTERFACE macro is defined. +*/ +#ifndef INTERFACE +# define INTERFACE 1 +#endif +/* The next thing included is series of defines which control +** various aspects of the generated parser. +** YYCODETYPE is the data type used for storing terminal +** and nonterminal numbers. "unsigned char" is +** used if there are fewer than 250 terminals +** and nonterminals. "int" is used otherwise. +** YYNOCODE is a number of type YYCODETYPE which corresponds +** to no legal terminal or nonterminal number. This +** number is used to fill in empty slots of the hash +** table. +** YYFALLBACK If defined, this indicates that one or more tokens +** have fall-back values which should be used if the +** original value of the token will not parse. +** YYACTIONTYPE is the data type used for storing terminal +** and nonterminal numbers. "unsigned char" is +** used if there are fewer than 250 rules and +** states combined. "int" is used otherwise. +** sqlite3ParserTOKENTYPE is the data type used for minor tokens given +** directly to the parser from the tokenizer. +** YYMINORTYPE is the data type used for all minor tokens. +** This is typically a union of many types, one of +** which is sqlite3ParserTOKENTYPE. The entry in the union +** for base tokens is called "yy0". +** YYSTACKDEPTH is the maximum depth of the parser's stack. If +** zero the stack is dynamically sized using realloc() +** sqlite3ParserARG_SDECL A static variable declaration for the %extra_argument +** sqlite3ParserARG_PDECL A parameter declaration for the %extra_argument +** sqlite3ParserARG_STORE Code to store %extra_argument into yypParser +** 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 254 +#define YYACTIONTYPE unsigned short int +#define YYWILDCARD 70 +#define sqlite3ParserTOKENTYPE Token +typedef union { + int yyinit; + sqlite3ParserTOKENTYPE yy0; + Select* yy3; + ExprList* yy14; + With* yy59; + SrcList* yy65; + struct LikeOp yy96; + Expr* yy132; + u8 yy186; + int yy328; + ExprSpan yy346; + struct TrigEvent yy378; + u16 yy381; + IdList* yy408; + struct {int value; int mask;} yy429; + TriggerStep* yy473; + struct LimitVal yy476; +} YYMINORTYPE; +#ifndef YYSTACKDEPTH +#define YYSTACKDEPTH 100 +#endif +#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 642 +#define YYNRULE 327 +#define YYFALLBACK 1 +#define YY_NO_ACTION (YYNSTATE+YYNRULE+2) +#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) +#define YY_ERROR_ACTION (YYNSTATE+YYNRULE) + +/* The yyzerominor constant is used to initialize instances of +** YYMINORTYPE objects to zero. */ +static const YYMINORTYPE yyzerominor = { 0 }; + +/* Define the yytestcase() macro to be a no-op if is not already defined +** otherwise. +** +** Applications can choose to define yytestcase() in the %include section +** to a macro that can assist in verifying code coverage. For production +** code the yytestcase() macro should be turned off. But it is useful +** for testing. +*/ +#ifndef yytestcase +# define yytestcase(X) +#endif + + +/* Next are the tables used to determine what action to take based on the +** current state and lookahead token. These tables are used to implement +** functions that take a state number and lookahead value and return an +** action integer. +** +** Suppose the action integer is N. Then the action is determined as +** follows +** +** 0 <= N < YYNSTATE Shift N. That is, push the lookahead +** token onto the stack and goto state N. +** +** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE. +** +** N == YYNSTATE+YYNRULE A syntax error has occurred. +** +** N == YYNSTATE+YYNRULE+1 The parser accepts its input. +** +** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused +** slots in the yy_action[] table. +** +** The action table is constructed as a single large table named yy_action[]. +** Given state S and lookahead X, the action is computed as +** +** yy_action[ yy_shift_ofst[S] + X ] +** +** If the index value yy_shift_ofst[S]+X is out of range or if the value +** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] +** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table +** and that yy_default[S] should be used instead. +** +** The formula above is for computing the action when the lookahead is +** a terminal symbol. If the lookahead is a non-terminal (as occurs after +** a reduce action) then the yy_reduce_ofst[] array is used in place of +** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of +** YY_SHIFT_USE_DFLT. +** +** The following are the tables generated in this section: +** +** yy_action[] A single table containing all actions. +** yy_lookahead[] A table containing the lookahead for each entry in +** yy_action. Used to detect hash collisions. +** 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. +*/ +#define YY_ACTTAB_COUNT (1497) +static const YYACTIONTYPE yy_action[] = { + /* 0 */ 306, 212, 432, 955, 639, 191, 955, 295, 559, 88, + /* 10 */ 88, 88, 88, 81, 86, 86, 86, 86, 85, 85, + /* 20 */ 84, 84, 84, 83, 330, 185, 184, 183, 635, 635, + /* 30 */ 292, 606, 606, 88, 88, 88, 88, 683, 86, 86, + /* 40 */ 86, 86, 85, 85, 84, 84, 84, 83, 330, 16, + /* 50 */ 436, 597, 89, 90, 80, 600, 599, 601, 601, 87, + /* 60 */ 87, 88, 88, 88, 88, 684, 86, 86, 86, 86, + /* 70 */ 85, 85, 84, 84, 84, 83, 330, 306, 559, 84, + /* 80 */ 84, 84, 83, 330, 65, 86, 86, 86, 86, 85, + /* 90 */ 85, 84, 84, 84, 83, 330, 635, 635, 634, 633, + /* 100 */ 182, 682, 550, 379, 376, 375, 17, 322, 606, 606, + /* 110 */ 371, 198, 479, 91, 374, 82, 79, 165, 85, 85, + /* 120 */ 84, 84, 84, 83, 330, 598, 635, 635, 107, 89, + /* 130 */ 90, 80, 600, 599, 601, 601, 87, 87, 88, 88, + /* 140 */ 88, 88, 186, 86, 86, 86, 86, 85, 85, 84, + /* 150 */ 84, 84, 83, 330, 306, 594, 594, 142, 328, 327, + /* 160 */ 484, 249, 344, 238, 635, 635, 634, 633, 585, 448, + /* 170 */ 526, 525, 229, 388, 1, 394, 450, 584, 449, 635, + /* 180 */ 635, 635, 635, 319, 395, 606, 606, 199, 157, 273, + /* 190 */ 382, 268, 381, 187, 635, 635, 634, 633, 311, 555, + /* 200 */ 266, 593, 593, 266, 347, 588, 89, 90, 80, 600, + /* 210 */ 599, 601, 601, 87, 87, 88, 88, 88, 88, 478, + /* 220 */ 86, 86, 86, 86, 85, 85, 84, 84, 84, 83, + /* 230 */ 330, 306, 272, 536, 634, 633, 146, 610, 197, 310, + /* 240 */ 575, 182, 482, 271, 379, 376, 375, 506, 21, 634, + /* 250 */ 633, 634, 633, 635, 635, 374, 611, 574, 548, 440, + /* 260 */ 111, 563, 606, 606, 634, 633, 324, 479, 608, 608, + /* 270 */ 608, 300, 435, 573, 119, 407, 210, 162, 562, 883, + /* 280 */ 592, 592, 306, 89, 90, 80, 600, 599, 601, 601, + /* 290 */ 87, 87, 88, 88, 88, 88, 506, 86, 86, 86, + /* 300 */ 86, 85, 85, 84, 84, 84, 83, 330, 620, 111, + /* 310 */ 635, 635, 361, 606, 606, 358, 249, 349, 248, 433, + /* 320 */ 243, 479, 586, 634, 633, 195, 611, 93, 119, 221, + /* 330 */ 575, 497, 534, 534, 89, 90, 80, 600, 599, 601, + /* 340 */ 601, 87, 87, 88, 88, 88, 88, 574, 86, 86, + /* 350 */ 86, 86, 85, 85, 84, 84, 84, 83, 330, 306, + /* 360 */ 77, 429, 638, 573, 589, 530, 240, 230, 242, 105, + /* 370 */ 249, 349, 248, 515, 588, 208, 460, 529, 564, 173, + /* 380 */ 634, 633, 970, 144, 430, 2, 424, 228, 380, 557, + /* 390 */ 606, 606, 190, 153, 159, 158, 514, 51, 632, 631, + /* 400 */ 630, 71, 536, 432, 954, 196, 610, 954, 614, 45, + /* 410 */ 18, 89, 90, 80, 600, 599, 601, 601, 87, 87, + /* 420 */ 88, 88, 88, 88, 261, 86, 86, 86, 86, 85, + /* 430 */ 85, 84, 84, 84, 83, 330, 306, 608, 608, 608, + /* 440 */ 542, 424, 402, 385, 241, 506, 451, 320, 211, 543, + /* 450 */ 164, 436, 386, 293, 451, 587, 108, 496, 111, 334, + /* 460 */ 391, 591, 424, 614, 27, 452, 453, 606, 606, 72, + /* 470 */ 257, 70, 259, 452, 339, 342, 564, 582, 68, 415, + /* 480 */ 469, 328, 327, 62, 614, 45, 110, 393, 89, 90, + /* 490 */ 80, 600, 599, 601, 601, 87, 87, 88, 88, 88, + /* 500 */ 88, 152, 86, 86, 86, 86, 85, 85, 84, 84, + /* 510 */ 84, 83, 330, 306, 110, 499, 520, 538, 402, 389, + /* 520 */ 424, 110, 566, 500, 593, 593, 454, 82, 79, 165, + /* 530 */ 424, 591, 384, 564, 340, 615, 188, 162, 424, 350, + /* 540 */ 616, 424, 614, 44, 606, 606, 445, 582, 300, 434, + /* 550 */ 151, 19, 614, 9, 568, 580, 348, 615, 469, 567, + /* 560 */ 614, 26, 616, 614, 45, 89, 90, 80, 600, 599, + /* 570 */ 601, 601, 87, 87, 88, 88, 88, 88, 411, 86, + /* 580 */ 86, 86, 86, 85, 85, 84, 84, 84, 83, 330, + /* 590 */ 306, 579, 110, 578, 521, 282, 433, 398, 400, 255, + /* 600 */ 486, 82, 79, 165, 487, 164, 82, 79, 165, 488, + /* 610 */ 488, 364, 387, 424, 544, 544, 509, 350, 362, 155, + /* 620 */ 191, 606, 606, 559, 642, 640, 333, 82, 79, 165, + /* 630 */ 305, 564, 507, 312, 357, 614, 45, 329, 596, 595, + /* 640 */ 194, 337, 89, 90, 80, 600, 599, 601, 601, 87, + /* 650 */ 87, 88, 88, 88, 88, 424, 86, 86, 86, 86, + /* 660 */ 85, 85, 84, 84, 84, 83, 330, 306, 20, 323, + /* 670 */ 150, 263, 211, 543, 421, 596, 595, 614, 22, 424, + /* 680 */ 193, 424, 284, 424, 391, 424, 509, 424, 577, 424, + /* 690 */ 186, 335, 424, 559, 424, 313, 120, 546, 606, 606, + /* 700 */ 67, 614, 47, 614, 50, 614, 48, 614, 100, 614, + /* 710 */ 99, 614, 101, 576, 614, 102, 614, 109, 326, 89, + /* 720 */ 90, 80, 600, 599, 601, 601, 87, 87, 88, 88, + /* 730 */ 88, 88, 424, 86, 86, 86, 86, 85, 85, 84, + /* 740 */ 84, 84, 83, 330, 306, 424, 311, 424, 585, 54, + /* 750 */ 424, 516, 517, 590, 614, 112, 424, 584, 424, 572, + /* 760 */ 424, 195, 424, 571, 424, 67, 424, 614, 94, 614, + /* 770 */ 98, 424, 614, 97, 264, 606, 606, 195, 614, 46, + /* 780 */ 614, 96, 614, 30, 614, 49, 614, 115, 614, 114, + /* 790 */ 418, 229, 388, 614, 113, 306, 89, 90, 80, 600, + /* 800 */ 599, 601, 601, 87, 87, 88, 88, 88, 88, 424, + /* 810 */ 86, 86, 86, 86, 85, 85, 84, 84, 84, 83, + /* 820 */ 330, 119, 424, 590, 110, 372, 606, 606, 195, 53, + /* 830 */ 250, 614, 29, 195, 472, 438, 729, 190, 302, 498, + /* 840 */ 14, 523, 641, 2, 614, 43, 306, 89, 90, 80, + /* 850 */ 600, 599, 601, 601, 87, 87, 88, 88, 88, 88, + /* 860 */ 424, 86, 86, 86, 86, 85, 85, 84, 84, 84, + /* 870 */ 83, 330, 424, 613, 964, 964, 354, 606, 606, 420, + /* 880 */ 312, 64, 614, 42, 391, 355, 283, 437, 301, 255, + /* 890 */ 414, 410, 495, 492, 614, 28, 471, 306, 89, 90, + /* 900 */ 80, 600, 599, 601, 601, 87, 87, 88, 88, 88, + /* 910 */ 88, 424, 86, 86, 86, 86, 85, 85, 84, 84, + /* 920 */ 84, 83, 330, 424, 110, 110, 110, 110, 606, 606, + /* 930 */ 110, 254, 13, 614, 41, 532, 531, 283, 481, 531, + /* 940 */ 457, 284, 119, 561, 356, 614, 40, 284, 306, 89, + /* 950 */ 78, 80, 600, 599, 601, 601, 87, 87, 88, 88, + /* 960 */ 88, 88, 424, 86, 86, 86, 86, 85, 85, 84, + /* 970 */ 84, 84, 83, 330, 110, 424, 341, 220, 555, 606, + /* 980 */ 606, 351, 555, 318, 614, 95, 413, 255, 83, 330, + /* 990 */ 284, 284, 255, 640, 333, 356, 255, 614, 39, 306, + /* 1000 */ 356, 90, 80, 600, 599, 601, 601, 87, 87, 88, + /* 1010 */ 88, 88, 88, 424, 86, 86, 86, 86, 85, 85, + /* 1020 */ 84, 84, 84, 83, 330, 424, 317, 316, 141, 465, + /* 1030 */ 606, 606, 219, 619, 463, 614, 10, 417, 462, 255, + /* 1040 */ 189, 510, 553, 351, 207, 363, 161, 614, 38, 315, + /* 1050 */ 218, 255, 255, 80, 600, 599, 601, 601, 87, 87, + /* 1060 */ 88, 88, 88, 88, 424, 86, 86, 86, 86, 85, + /* 1070 */ 85, 84, 84, 84, 83, 330, 76, 419, 255, 3, + /* 1080 */ 878, 461, 424, 247, 331, 331, 614, 37, 217, 76, + /* 1090 */ 419, 390, 3, 216, 215, 422, 4, 331, 331, 424, + /* 1100 */ 547, 12, 424, 545, 614, 36, 424, 541, 422, 424, + /* 1110 */ 540, 424, 214, 424, 408, 424, 539, 403, 605, 605, + /* 1120 */ 237, 614, 25, 119, 614, 24, 588, 408, 614, 45, + /* 1130 */ 118, 614, 35, 614, 34, 614, 33, 614, 23, 588, + /* 1140 */ 60, 223, 603, 602, 513, 378, 73, 74, 140, 139, + /* 1150 */ 424, 110, 265, 75, 426, 425, 59, 424, 610, 73, + /* 1160 */ 74, 549, 402, 404, 424, 373, 75, 426, 425, 604, + /* 1170 */ 138, 610, 614, 11, 392, 76, 419, 181, 3, 614, + /* 1180 */ 32, 271, 369, 331, 331, 493, 614, 31, 149, 608, + /* 1190 */ 608, 608, 607, 15, 422, 365, 614, 8, 137, 489, + /* 1200 */ 136, 190, 608, 608, 608, 607, 15, 485, 176, 135, + /* 1210 */ 7, 252, 477, 408, 174, 133, 175, 474, 57, 56, + /* 1220 */ 132, 130, 119, 76, 419, 588, 3, 468, 245, 464, + /* 1230 */ 171, 331, 331, 125, 123, 456, 447, 122, 446, 104, + /* 1240 */ 336, 231, 422, 166, 154, 73, 74, 332, 116, 431, + /* 1250 */ 121, 309, 75, 426, 425, 222, 106, 610, 308, 637, + /* 1260 */ 204, 408, 629, 627, 628, 6, 200, 428, 427, 290, + /* 1270 */ 203, 622, 201, 588, 62, 63, 289, 66, 419, 399, + /* 1280 */ 3, 401, 288, 92, 143, 331, 331, 287, 608, 608, + /* 1290 */ 608, 607, 15, 73, 74, 227, 422, 325, 69, 416, + /* 1300 */ 75, 426, 425, 612, 412, 610, 192, 61, 569, 209, + /* 1310 */ 396, 226, 278, 225, 383, 408, 527, 558, 276, 533, + /* 1320 */ 552, 528, 321, 523, 370, 508, 180, 588, 494, 179, + /* 1330 */ 366, 117, 253, 269, 522, 503, 608, 608, 608, 607, + /* 1340 */ 15, 551, 502, 58, 274, 524, 178, 73, 74, 304, + /* 1350 */ 501, 368, 303, 206, 75, 426, 425, 491, 360, 610, + /* 1360 */ 213, 177, 483, 131, 345, 298, 297, 296, 202, 294, + /* 1370 */ 480, 490, 466, 134, 172, 129, 444, 346, 470, 128, + /* 1380 */ 314, 459, 103, 127, 126, 148, 124, 167, 443, 235, + /* 1390 */ 608, 608, 608, 607, 15, 442, 439, 623, 234, 299, + /* 1400 */ 145, 583, 291, 377, 581, 160, 119, 156, 270, 636, + /* 1410 */ 971, 169, 279, 626, 520, 625, 473, 624, 170, 621, + /* 1420 */ 618, 119, 168, 55, 409, 423, 537, 609, 286, 285, + /* 1430 */ 405, 570, 560, 556, 5, 52, 458, 554, 147, 267, + /* 1440 */ 519, 504, 518, 406, 262, 239, 260, 512, 343, 511, + /* 1450 */ 258, 353, 565, 256, 224, 251, 359, 277, 275, 476, + /* 1460 */ 475, 246, 352, 244, 467, 455, 236, 233, 232, 307, + /* 1470 */ 441, 281, 205, 163, 397, 280, 535, 505, 330, 617, + /* 1480 */ 971, 971, 971, 971, 367, 971, 971, 971, 971, 971, + /* 1490 */ 971, 971, 971, 971, 971, 971, 338, +}; +static const YYCODETYPE yy_lookahead[] = { + /* 0 */ 19, 22, 22, 23, 1, 24, 26, 15, 27, 80, + /* 10 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + /* 20 */ 91, 92, 93, 94, 95, 108, 109, 110, 27, 28, + /* 30 */ 23, 50, 51, 80, 81, 82, 83, 122, 85, 86, + /* 40 */ 87, 88, 89, 90, 91, 92, 93, 94, 95, 22, + /* 50 */ 70, 23, 71, 72, 73, 74, 75, 76, 77, 78, + /* 60 */ 79, 80, 81, 82, 83, 122, 85, 86, 87, 88, + /* 70 */ 89, 90, 91, 92, 93, 94, 95, 19, 97, 91, + /* 80 */ 92, 93, 94, 95, 26, 85, 86, 87, 88, 89, + /* 90 */ 90, 91, 92, 93, 94, 95, 27, 28, 97, 98, + /* 100 */ 99, 122, 211, 102, 103, 104, 79, 19, 50, 51, + /* 110 */ 19, 122, 59, 55, 113, 224, 225, 226, 89, 90, + /* 120 */ 91, 92, 93, 94, 95, 23, 27, 28, 26, 71, + /* 130 */ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + /* 140 */ 82, 83, 51, 85, 86, 87, 88, 89, 90, 91, + /* 150 */ 92, 93, 94, 95, 19, 132, 133, 58, 89, 90, + /* 160 */ 21, 108, 109, 110, 27, 28, 97, 98, 33, 100, + /* 170 */ 7, 8, 119, 120, 22, 19, 107, 42, 109, 27, + /* 180 */ 28, 27, 28, 95, 28, 50, 51, 99, 100, 101, + /* 190 */ 102, 103, 104, 105, 27, 28, 97, 98, 107, 152, + /* 200 */ 112, 132, 133, 112, 65, 69, 71, 72, 73, 74, + /* 210 */ 75, 76, 77, 78, 79, 80, 81, 82, 83, 11, + /* 220 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + /* 230 */ 95, 19, 101, 97, 97, 98, 24, 101, 122, 157, + /* 240 */ 12, 99, 103, 112, 102, 103, 104, 152, 22, 97, + /* 250 */ 98, 97, 98, 27, 28, 113, 27, 29, 91, 164, + /* 260 */ 165, 124, 50, 51, 97, 98, 219, 59, 132, 133, + /* 270 */ 134, 22, 23, 45, 66, 47, 212, 213, 124, 140, + /* 280 */ 132, 133, 19, 71, 72, 73, 74, 75, 76, 77, + /* 290 */ 78, 79, 80, 81, 82, 83, 152, 85, 86, 87, + /* 300 */ 88, 89, 90, 91, 92, 93, 94, 95, 164, 165, + /* 310 */ 27, 28, 230, 50, 51, 233, 108, 109, 110, 70, + /* 320 */ 16, 59, 23, 97, 98, 26, 97, 22, 66, 185, + /* 330 */ 12, 187, 27, 28, 71, 72, 73, 74, 75, 76, + /* 340 */ 77, 78, 79, 80, 81, 82, 83, 29, 85, 86, + /* 350 */ 87, 88, 89, 90, 91, 92, 93, 94, 95, 19, + /* 360 */ 22, 148, 149, 45, 23, 47, 62, 154, 64, 156, + /* 370 */ 108, 109, 110, 37, 69, 23, 163, 59, 26, 26, + /* 380 */ 97, 98, 144, 145, 146, 147, 152, 200, 52, 23, + /* 390 */ 50, 51, 26, 22, 89, 90, 60, 210, 7, 8, + /* 400 */ 9, 138, 97, 22, 23, 26, 101, 26, 174, 175, + /* 410 */ 197, 71, 72, 73, 74, 75, 76, 77, 78, 79, + /* 420 */ 80, 81, 82, 83, 16, 85, 86, 87, 88, 89, + /* 430 */ 90, 91, 92, 93, 94, 95, 19, 132, 133, 134, + /* 440 */ 23, 152, 208, 209, 140, 152, 152, 111, 195, 196, + /* 450 */ 98, 70, 163, 160, 152, 23, 22, 164, 165, 246, + /* 460 */ 207, 27, 152, 174, 175, 171, 172, 50, 51, 137, + /* 470 */ 62, 139, 64, 171, 172, 222, 124, 27, 138, 24, + /* 480 */ 163, 89, 90, 130, 174, 175, 197, 163, 71, 72, + /* 490 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + /* 500 */ 83, 22, 85, 86, 87, 88, 89, 90, 91, 92, + /* 510 */ 93, 94, 95, 19, 197, 181, 182, 23, 208, 209, + /* 520 */ 152, 197, 26, 189, 132, 133, 232, 224, 225, 226, + /* 530 */ 152, 97, 91, 26, 232, 116, 212, 213, 152, 222, + /* 540 */ 121, 152, 174, 175, 50, 51, 243, 97, 22, 23, + /* 550 */ 22, 234, 174, 175, 177, 23, 239, 116, 163, 177, + /* 560 */ 174, 175, 121, 174, 175, 71, 72, 73, 74, 75, + /* 570 */ 76, 77, 78, 79, 80, 81, 82, 83, 24, 85, + /* 580 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + /* 590 */ 19, 23, 197, 11, 23, 227, 70, 208, 220, 152, + /* 600 */ 31, 224, 225, 226, 35, 98, 224, 225, 226, 108, + /* 610 */ 109, 110, 115, 152, 117, 118, 27, 222, 49, 123, + /* 620 */ 24, 50, 51, 27, 0, 1, 2, 224, 225, 226, + /* 630 */ 166, 124, 168, 169, 239, 174, 175, 170, 171, 172, + /* 640 */ 22, 194, 71, 72, 73, 74, 75, 76, 77, 78, + /* 650 */ 79, 80, 81, 82, 83, 152, 85, 86, 87, 88, + /* 660 */ 89, 90, 91, 92, 93, 94, 95, 19, 22, 208, + /* 670 */ 24, 23, 195, 196, 170, 171, 172, 174, 175, 152, + /* 680 */ 26, 152, 152, 152, 207, 152, 97, 152, 23, 152, + /* 690 */ 51, 244, 152, 97, 152, 247, 248, 23, 50, 51, + /* 700 */ 26, 174, 175, 174, 175, 174, 175, 174, 175, 174, + /* 710 */ 175, 174, 175, 23, 174, 175, 174, 175, 188, 71, + /* 720 */ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + /* 730 */ 82, 83, 152, 85, 86, 87, 88, 89, 90, 91, + /* 740 */ 92, 93, 94, 95, 19, 152, 107, 152, 33, 24, + /* 750 */ 152, 100, 101, 27, 174, 175, 152, 42, 152, 23, + /* 760 */ 152, 26, 152, 23, 152, 26, 152, 174, 175, 174, + /* 770 */ 175, 152, 174, 175, 23, 50, 51, 26, 174, 175, + /* 780 */ 174, 175, 174, 175, 174, 175, 174, 175, 174, 175, + /* 790 */ 163, 119, 120, 174, 175, 19, 71, 72, 73, 74, + /* 800 */ 75, 76, 77, 78, 79, 80, 81, 82, 83, 152, + /* 810 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + /* 820 */ 95, 66, 152, 97, 197, 23, 50, 51, 26, 53, + /* 830 */ 23, 174, 175, 26, 23, 23, 23, 26, 26, 26, + /* 840 */ 36, 106, 146, 147, 174, 175, 19, 71, 72, 73, + /* 850 */ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + /* 860 */ 152, 85, 86, 87, 88, 89, 90, 91, 92, 93, + /* 870 */ 94, 95, 152, 196, 119, 120, 19, 50, 51, 168, + /* 880 */ 169, 26, 174, 175, 207, 28, 152, 249, 250, 152, + /* 890 */ 163, 163, 163, 163, 174, 175, 163, 19, 71, 72, + /* 900 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + /* 910 */ 83, 152, 85, 86, 87, 88, 89, 90, 91, 92, + /* 920 */ 93, 94, 95, 152, 197, 197, 197, 197, 50, 51, + /* 930 */ 197, 194, 36, 174, 175, 191, 192, 152, 191, 192, + /* 940 */ 163, 152, 66, 124, 152, 174, 175, 152, 19, 71, + /* 950 */ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + /* 960 */ 82, 83, 152, 85, 86, 87, 88, 89, 90, 91, + /* 970 */ 92, 93, 94, 95, 197, 152, 100, 188, 152, 50, + /* 980 */ 51, 152, 152, 188, 174, 175, 252, 152, 94, 95, + /* 990 */ 152, 152, 152, 1, 2, 152, 152, 174, 175, 19, + /* 1000 */ 152, 72, 73, 74, 75, 76, 77, 78, 79, 80, + /* 1010 */ 81, 82, 83, 152, 85, 86, 87, 88, 89, 90, + /* 1020 */ 91, 92, 93, 94, 95, 152, 188, 188, 22, 194, + /* 1030 */ 50, 51, 240, 173, 194, 174, 175, 252, 194, 152, + /* 1040 */ 36, 181, 28, 152, 23, 219, 122, 174, 175, 219, + /* 1050 */ 221, 152, 152, 73, 74, 75, 76, 77, 78, 79, + /* 1060 */ 80, 81, 82, 83, 152, 85, 86, 87, 88, 89, + /* 1070 */ 90, 91, 92, 93, 94, 95, 19, 20, 152, 22, + /* 1080 */ 23, 194, 152, 240, 27, 28, 174, 175, 240, 19, + /* 1090 */ 20, 26, 22, 194, 194, 38, 22, 27, 28, 152, + /* 1100 */ 23, 22, 152, 116, 174, 175, 152, 23, 38, 152, + /* 1110 */ 23, 152, 221, 152, 57, 152, 23, 163, 50, 51, + /* 1120 */ 194, 174, 175, 66, 174, 175, 69, 57, 174, 175, + /* 1130 */ 40, 174, 175, 174, 175, 174, 175, 174, 175, 69, + /* 1140 */ 22, 53, 74, 75, 30, 53, 89, 90, 22, 22, + /* 1150 */ 152, 197, 23, 96, 97, 98, 22, 152, 101, 89, + /* 1160 */ 90, 91, 208, 209, 152, 53, 96, 97, 98, 101, + /* 1170 */ 22, 101, 174, 175, 152, 19, 20, 105, 22, 174, + /* 1180 */ 175, 112, 19, 27, 28, 20, 174, 175, 24, 132, + /* 1190 */ 133, 134, 135, 136, 38, 44, 174, 175, 107, 61, + /* 1200 */ 54, 26, 132, 133, 134, 135, 136, 54, 107, 22, + /* 1210 */ 5, 140, 1, 57, 36, 111, 122, 28, 79, 79, + /* 1220 */ 131, 123, 66, 19, 20, 69, 22, 1, 16, 20, + /* 1230 */ 125, 27, 28, 123, 111, 120, 23, 131, 23, 16, + /* 1240 */ 68, 142, 38, 15, 22, 89, 90, 3, 167, 4, + /* 1250 */ 248, 251, 96, 97, 98, 180, 180, 101, 251, 151, + /* 1260 */ 6, 57, 151, 13, 151, 26, 25, 151, 161, 202, + /* 1270 */ 153, 162, 153, 69, 130, 128, 203, 19, 20, 127, + /* 1280 */ 22, 126, 204, 129, 22, 27, 28, 205, 132, 133, + /* 1290 */ 134, 135, 136, 89, 90, 231, 38, 95, 137, 179, + /* 1300 */ 96, 97, 98, 206, 179, 101, 122, 107, 159, 159, + /* 1310 */ 125, 231, 216, 228, 107, 57, 184, 217, 216, 176, + /* 1320 */ 217, 176, 48, 106, 18, 184, 158, 69, 159, 158, + /* 1330 */ 46, 71, 237, 176, 176, 176, 132, 133, 134, 135, + /* 1340 */ 136, 217, 176, 137, 216, 178, 158, 89, 90, 179, + /* 1350 */ 176, 159, 179, 159, 96, 97, 98, 159, 159, 101, + /* 1360 */ 5, 158, 202, 22, 18, 10, 11, 12, 13, 14, + /* 1370 */ 190, 238, 17, 190, 158, 193, 41, 159, 202, 193, + /* 1380 */ 159, 202, 245, 193, 193, 223, 190, 32, 159, 34, + /* 1390 */ 132, 133, 134, 135, 136, 159, 39, 155, 43, 150, + /* 1400 */ 223, 177, 201, 178, 177, 186, 66, 199, 177, 152, + /* 1410 */ 253, 56, 215, 152, 182, 152, 202, 152, 63, 152, + /* 1420 */ 152, 66, 67, 242, 229, 152, 174, 152, 152, 152, + /* 1430 */ 152, 152, 152, 152, 199, 242, 202, 152, 198, 152, + /* 1440 */ 152, 152, 183, 192, 152, 215, 152, 183, 215, 183, + /* 1450 */ 152, 241, 214, 152, 211, 152, 152, 211, 211, 152, + /* 1460 */ 152, 241, 152, 152, 152, 152, 152, 152, 152, 114, + /* 1470 */ 152, 152, 235, 152, 152, 152, 174, 187, 95, 174, + /* 1480 */ 253, 253, 253, 253, 236, 253, 253, 253, 253, 253, + /* 1490 */ 253, 253, 253, 253, 253, 253, 141, +}; +#define YY_SHIFT_USE_DFLT (-86) +#define YY_SHIFT_COUNT (429) +#define YY_SHIFT_MIN (-85) +#define YY_SHIFT_MAX (1383) +static const short yy_shift_ofst[] = { + /* 0 */ 992, 1057, 1355, 1156, 1204, 1204, 1, 262, -19, 135, + /* 10 */ 135, 776, 1204, 1204, 1204, 1204, 69, 69, 53, 208, + /* 20 */ 283, 755, 58, 725, 648, 571, 494, 417, 340, 263, + /* 30 */ 212, 827, 827, 827, 827, 827, 827, 827, 827, 827, + /* 40 */ 827, 827, 827, 827, 827, 827, 878, 827, 929, 980, + /* 50 */ 980, 1070, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, + /* 60 */ 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, + /* 70 */ 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, + /* 80 */ 1258, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, + /* 90 */ 1204, 1204, 1204, 1204, -71, -47, -47, -47, -47, -47, + /* 100 */ 0, 29, -12, 283, 283, 139, 91, 392, 392, 894, + /* 110 */ 672, 726, 1383, -86, -86, -86, 88, 318, 318, 99, + /* 120 */ 381, -20, 283, 283, 283, 283, 283, 283, 283, 283, + /* 130 */ 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, + /* 140 */ 283, 283, 283, 283, 624, 876, 726, 672, 1340, 1340, + /* 150 */ 1340, 1340, 1340, 1340, -86, -86, -86, 305, 136, 136, + /* 160 */ 142, 167, 226, 154, 137, 152, 283, 283, 283, 283, + /* 170 */ 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, + /* 180 */ 283, 283, 283, 336, 336, 336, 283, 283, 352, 283, + /* 190 */ 283, 283, 283, 283, 228, 283, 283, 283, 283, 283, + /* 200 */ 283, 283, 283, 283, 283, 501, 569, 596, 596, 596, + /* 210 */ 507, 497, 441, 391, 353, 156, 156, 857, 353, 857, + /* 220 */ 735, 813, 639, 715, 156, 332, 715, 715, 496, 419, + /* 230 */ 646, 1357, 1184, 1184, 1335, 1335, 1184, 1341, 1260, 1144, + /* 240 */ 1346, 1346, 1346, 1346, 1184, 1306, 1144, 1341, 1260, 1260, + /* 250 */ 1144, 1184, 1306, 1206, 1284, 1184, 1184, 1306, 1184, 1306, + /* 260 */ 1184, 1306, 1262, 1207, 1207, 1207, 1274, 1262, 1207, 1217, + /* 270 */ 1207, 1274, 1207, 1207, 1185, 1200, 1185, 1200, 1185, 1200, + /* 280 */ 1184, 1184, 1161, 1262, 1202, 1202, 1262, 1154, 1155, 1147, + /* 290 */ 1152, 1144, 1241, 1239, 1250, 1250, 1254, 1254, 1254, 1254, + /* 300 */ -86, -86, -86, -86, -86, -86, 1068, 304, 526, 249, + /* 310 */ 408, -83, 434, 812, 27, 811, 807, 802, 751, 589, + /* 320 */ 651, 163, 131, 674, 366, 450, 299, 148, 23, 102, + /* 330 */ 229, -21, 1245, 1244, 1222, 1099, 1228, 1172, 1223, 1215, + /* 340 */ 1213, 1115, 1106, 1123, 1110, 1209, 1105, 1212, 1226, 1098, + /* 350 */ 1089, 1140, 1139, 1104, 1189, 1178, 1094, 1211, 1205, 1187, + /* 360 */ 1101, 1071, 1153, 1175, 1146, 1138, 1151, 1091, 1164, 1165, + /* 370 */ 1163, 1069, 1072, 1148, 1112, 1134, 1127, 1129, 1126, 1092, + /* 380 */ 1114, 1118, 1088, 1090, 1093, 1087, 1084, 987, 1079, 1077, + /* 390 */ 1074, 1065, 924, 1021, 1014, 1004, 1006, 819, 739, 896, + /* 400 */ 855, 804, 739, 740, 736, 690, 654, 665, 618, 582, + /* 410 */ 568, 528, 554, 379, 532, 479, 455, 379, 432, 371, + /* 420 */ 341, 28, 338, 116, -11, -57, -85, 7, -8, 3, +}; +#define YY_REDUCE_USE_DFLT (-110) +#define YY_REDUCE_COUNT (305) +#define YY_REDUCE_MIN (-109) +#define YY_REDUCE_MAX (1323) +static const short yy_reduce_ofst[] = { + /* 0 */ 238, 954, 213, 289, 310, 234, 144, 317, -109, 382, + /* 10 */ 377, 303, 461, 389, 378, 368, 302, 294, 253, 395, + /* 20 */ 293, 324, 403, 403, 403, 403, 403, 403, 403, 403, + /* 30 */ 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, + /* 40 */ 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, + /* 50 */ 403, 1022, 1012, 1005, 998, 963, 961, 959, 957, 950, + /* 60 */ 947, 930, 912, 873, 861, 823, 810, 771, 759, 720, + /* 70 */ 708, 670, 657, 619, 614, 612, 610, 608, 606, 604, + /* 80 */ 598, 595, 593, 580, 542, 540, 537, 535, 533, 531, + /* 90 */ 529, 527, 503, 386, 403, 403, 403, 403, 403, 403, + /* 100 */ 403, 403, 403, 95, 447, 82, 334, 504, 467, 403, + /* 110 */ 477, 464, 403, 403, 403, 403, 860, 747, 744, 785, + /* 120 */ 638, 638, 926, 891, 900, 899, 887, 844, 840, 835, + /* 130 */ 848, 830, 843, 829, 792, 839, 826, 737, 838, 795, + /* 140 */ 789, 47, 734, 530, 696, 777, 711, 677, 733, 730, + /* 150 */ 729, 728, 727, 627, 448, 64, 187, 1305, 1302, 1252, + /* 160 */ 1290, 1273, 1323, 1322, 1321, 1319, 1318, 1316, 1315, 1314, + /* 170 */ 1313, 1312, 1311, 1310, 1308, 1307, 1304, 1303, 1301, 1298, + /* 180 */ 1294, 1292, 1289, 1266, 1264, 1259, 1288, 1287, 1238, 1285, + /* 190 */ 1281, 1280, 1279, 1278, 1251, 1277, 1276, 1275, 1273, 1268, + /* 200 */ 1267, 1265, 1263, 1261, 1257, 1248, 1237, 1247, 1246, 1243, + /* 210 */ 1238, 1240, 1235, 1249, 1234, 1233, 1230, 1220, 1214, 1210, + /* 220 */ 1225, 1219, 1232, 1231, 1197, 1195, 1227, 1224, 1201, 1208, + /* 230 */ 1242, 1137, 1236, 1229, 1193, 1181, 1221, 1177, 1196, 1179, + /* 240 */ 1191, 1190, 1186, 1182, 1218, 1216, 1176, 1162, 1183, 1180, + /* 250 */ 1160, 1199, 1203, 1133, 1095, 1198, 1194, 1188, 1192, 1171, + /* 260 */ 1169, 1168, 1173, 1174, 1166, 1159, 1141, 1170, 1158, 1167, + /* 270 */ 1157, 1132, 1145, 1143, 1124, 1128, 1103, 1102, 1100, 1096, + /* 280 */ 1150, 1149, 1085, 1125, 1080, 1064, 1120, 1097, 1082, 1078, + /* 290 */ 1073, 1067, 1109, 1107, 1119, 1117, 1116, 1113, 1111, 1108, + /* 300 */ 1007, 1000, 1002, 1076, 1075, 1081, +}; +static const YYACTIONTYPE yy_default[] = { + /* 0 */ 647, 964, 964, 964, 878, 878, 969, 964, 774, 802, + /* 10 */ 802, 938, 969, 969, 969, 876, 969, 969, 969, 964, + /* 20 */ 969, 778, 808, 969, 969, 969, 969, 969, 969, 969, + /* 30 */ 969, 937, 939, 816, 815, 918, 789, 813, 806, 810, + /* 40 */ 879, 872, 873, 871, 875, 880, 969, 809, 841, 856, + /* 50 */ 840, 969, 969, 969, 969, 969, 969, 969, 969, 969, + /* 60 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, + /* 70 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, + /* 80 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, + /* 90 */ 969, 969, 969, 969, 850, 855, 862, 854, 851, 843, + /* 100 */ 842, 844, 845, 969, 969, 673, 739, 969, 969, 846, + /* 110 */ 969, 685, 847, 859, 858, 857, 680, 969, 969, 969, + /* 120 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, + /* 130 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, + /* 140 */ 969, 969, 969, 969, 647, 964, 969, 969, 964, 964, + /* 150 */ 964, 964, 964, 964, 956, 778, 768, 969, 969, 969, + /* 160 */ 969, 969, 969, 969, 969, 969, 969, 944, 942, 969, + /* 170 */ 891, 969, 969, 969, 969, 969, 969, 969, 969, 969, + /* 180 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, + /* 190 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, + /* 200 */ 969, 969, 969, 969, 653, 969, 911, 774, 774, 774, + /* 210 */ 776, 754, 766, 655, 812, 791, 791, 923, 812, 923, + /* 220 */ 710, 733, 707, 802, 791, 874, 802, 802, 775, 766, + /* 230 */ 969, 949, 782, 782, 941, 941, 782, 821, 743, 812, + /* 240 */ 750, 750, 750, 750, 782, 670, 812, 821, 743, 743, + /* 250 */ 812, 782, 670, 917, 915, 782, 782, 670, 782, 670, + /* 260 */ 782, 670, 884, 741, 741, 741, 725, 884, 741, 710, + /* 270 */ 741, 725, 741, 741, 795, 790, 795, 790, 795, 790, + /* 280 */ 782, 782, 969, 884, 888, 888, 884, 807, 796, 805, + /* 290 */ 803, 812, 676, 728, 663, 663, 652, 652, 652, 652, + /* 300 */ 961, 961, 956, 712, 712, 695, 969, 969, 969, 969, + /* 310 */ 969, 969, 687, 969, 893, 969, 969, 969, 969, 969, + /* 320 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, + /* 330 */ 969, 828, 969, 648, 951, 969, 969, 948, 969, 969, + /* 340 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, + /* 350 */ 969, 969, 969, 969, 969, 969, 921, 969, 969, 969, + /* 360 */ 969, 969, 969, 914, 913, 969, 969, 969, 969, 969, + /* 370 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, + /* 380 */ 969, 969, 969, 969, 969, 969, 969, 757, 969, 969, + /* 390 */ 969, 761, 969, 969, 969, 969, 969, 969, 804, 969, + /* 400 */ 797, 969, 877, 969, 969, 969, 969, 969, 969, 969, + /* 410 */ 969, 969, 969, 966, 969, 969, 969, 965, 969, 969, + /* 420 */ 969, 969, 969, 830, 969, 829, 833, 969, 661, 969, + /* 430 */ 644, 649, 960, 963, 962, 959, 958, 957, 952, 950, + /* 440 */ 947, 946, 945, 943, 940, 936, 897, 895, 902, 901, + /* 450 */ 900, 899, 898, 896, 894, 892, 818, 817, 814, 811, + /* 460 */ 753, 935, 890, 752, 749, 748, 669, 953, 920, 929, + /* 470 */ 928, 927, 822, 926, 925, 924, 922, 919, 906, 820, + /* 480 */ 819, 744, 882, 881, 672, 910, 909, 908, 912, 916, + /* 490 */ 907, 784, 751, 671, 668, 675, 679, 731, 732, 740, + /* 500 */ 738, 737, 736, 735, 734, 730, 681, 686, 724, 709, + /* 510 */ 708, 717, 716, 722, 721, 720, 719, 718, 715, 714, + /* 520 */ 713, 706, 705, 711, 704, 727, 726, 723, 703, 747, + /* 530 */ 746, 745, 742, 702, 701, 700, 833, 699, 698, 838, + /* 540 */ 837, 866, 826, 755, 759, 758, 762, 763, 771, 770, + /* 550 */ 769, 780, 781, 793, 792, 824, 823, 794, 779, 773, + /* 560 */ 772, 788, 787, 786, 785, 777, 767, 799, 798, 868, + /* 570 */ 783, 867, 865, 934, 933, 932, 931, 930, 870, 967, + /* 580 */ 968, 887, 889, 886, 801, 800, 885, 869, 839, 836, + /* 590 */ 690, 691, 905, 904, 903, 693, 692, 689, 688, 863, + /* 600 */ 860, 852, 864, 861, 853, 849, 848, 834, 832, 831, + /* 610 */ 827, 835, 760, 756, 825, 765, 764, 697, 696, 694, + /* 620 */ 678, 677, 674, 667, 665, 664, 666, 662, 660, 659, + /* 630 */ 658, 657, 656, 684, 683, 682, 654, 651, 650, 646, + /* 640 */ 645, 643, +}; + +/* The next table maps tokens into fallback tokens. If a construct +** like the following: +** +** %fallback ID X Y Z. +** +** appears in the grammar, 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 */ + 27, /* EXPLAIN => ID */ + 27, /* QUERY => ID */ + 27, /* PLAN => ID */ + 27, /* BEGIN => ID */ + 0, /* TRANSACTION => nothing */ + 27, /* DEFERRED => ID */ + 27, /* IMMEDIATE => ID */ + 27, /* EXCLUSIVE => ID */ + 0, /* COMMIT => nothing */ + 27, /* END => ID */ + 27, /* ROLLBACK => ID */ + 27, /* SAVEPOINT => ID */ + 27, /* RELEASE => ID */ + 0, /* TO => nothing */ + 0, /* TABLE => nothing */ + 0, /* CREATE => nothing */ + 27, /* IF => ID */ + 0, /* NOT => nothing */ + 0, /* EXISTS => nothing */ + 27, /* TEMP => ID */ + 0, /* LP => nothing */ + 0, /* RP => nothing */ + 0, /* AS => nothing */ + 27, /* WITHOUT => ID */ + 0, /* COMMA => nothing */ + 0, /* ID => nothing */ + 0, /* INDEXED => nothing */ + 27, /* ABORT => ID */ + 27, /* ACTION => ID */ + 27, /* AFTER => ID */ + 27, /* ANALYZE => ID */ + 27, /* ASC => ID */ + 27, /* ATTACH => ID */ + 27, /* BEFORE => ID */ + 27, /* BY => ID */ + 27, /* CASCADE => ID */ + 27, /* CAST => ID */ + 27, /* COLUMNKW => ID */ + 27, /* CONFLICT => ID */ + 27, /* DATABASE => ID */ + 27, /* DESC => ID */ + 27, /* DETACH => ID */ + 27, /* EACH => ID */ + 27, /* FAIL => ID */ + 27, /* FOR => ID */ + 27, /* IGNORE => ID */ + 27, /* INITIALLY => ID */ + 27, /* INSTEAD => ID */ + 27, /* LIKE_KW => ID */ + 27, /* MATCH => ID */ + 27, /* NO => ID */ + 27, /* KEY => ID */ + 27, /* OF => ID */ + 27, /* OFFSET => ID */ + 27, /* PRAGMA => ID */ + 27, /* RAISE => ID */ + 27, /* RECURSIVE => ID */ + 27, /* REPLACE => ID */ + 27, /* RESTRICT => ID */ + 27, /* ROW => ID */ + 27, /* TRIGGER => ID */ + 27, /* VACUUM => ID */ + 27, /* VIEW => ID */ + 27, /* VIRTUAL => ID */ + 27, /* WITH => ID */ + 27, /* REINDEX => ID */ + 27, /* RENAME => ID */ + 27, /* CTIME_KW => ID */ +}; +#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. +** +** + The value of the token stored at this level of the stack. +** (In other words, the "major" token.) +** +** + The semantic value stored at this level of the stack. This is +** the information used by the action routines in the grammar. +** It is sometimes called the "minor" token. +*/ +struct yyStackEntry { + YYACTIONTYPE stateno; /* The state-number */ + YYCODETYPE major; /* The major token value. This is the code + ** number for the token at this stack level */ + YYMINORTYPE minor; /* The user-supplied minor token value. This + ** is the value of the token */ +}; +typedef struct yyStackEntry yyStackEntry; + +/* The state of the parser is completely contained in an instance of +** the following structure */ +struct yyParser { + int yyidx; /* Index of top element in stack */ +#ifdef YYTRACKMAXSTACKDEPTH + int yyidxMax; /* Maximum value of yyidx */ +#endif + int yyerrcnt; /* Shifts left before out of the error */ + sqlite3ParserARG_SDECL /* A place to hold %extra_argument */ +#if YYSTACKDEPTH<=0 + int yystksz; /* Current side of the stack */ + yyStackEntry *yystack; /* The parser's stack */ +#else + yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ +#endif +}; +typedef struct yyParser yyParser; + +#ifndef NDEBUG +/* #include */ +static FILE *yyTraceFILE = 0; +static char *yyTracePrompt = 0; +#endif /* NDEBUG */ + +#ifndef NDEBUG +/* +** Turn parser tracing on by giving a stream to which to write the trace +** and a prompt to preface each trace message. Tracing is turned off +** by making either argument NULL +** +** Inputs: +**
      +**
    • A FILE* to which trace output should be written. +** If NULL, then tracing is turned off. +**
    • A prefix string written at the beginning of every +** line of trace output. If NULL, then tracing is +** turned off. +**
    +** +** Outputs: +** None. +*/ +SQLITE_PRIVATE void sqlite3ParserTrace(FILE *TraceFILE, char *zTracePrompt){ + yyTraceFILE = TraceFILE; + yyTracePrompt = zTracePrompt; + if( yyTraceFILE==0 ) yyTracePrompt = 0; + else if( yyTracePrompt==0 ) yyTraceFILE = 0; +} +#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", "SAVEPOINT", "RELEASE", "TO", + "TABLE", "CREATE", "IF", "NOT", + "EXISTS", "TEMP", "LP", "RP", + "AS", "WITHOUT", "COMMA", "ID", + "INDEXED", "ABORT", "ACTION", "AFTER", + "ANALYZE", "ASC", "ATTACH", "BEFORE", + "BY", "CASCADE", "CAST", "COLUMNKW", + "CONFLICT", "DATABASE", "DESC", "DETACH", + "EACH", "FAIL", "FOR", "IGNORE", + "INITIALLY", "INSTEAD", "LIKE_KW", "MATCH", + "NO", "KEY", "OF", "OFFSET", + "PRAGMA", "RAISE", "RECURSIVE", "REPLACE", + "RESTRICT", "ROW", "TRIGGER", "VACUUM", + "VIEW", "VIRTUAL", "WITH", "REINDEX", + "RENAME", "CTIME_KW", "ANY", "OR", + "AND", "IS", "BETWEEN", "IN", + "ISNULL", "NOTNULL", "NE", "EQ", + "GT", "LE", "LT", "GE", + "ESCAPE", "BITAND", "BITOR", "LSHIFT", + "RSHIFT", "PLUS", "MINUS", "STAR", + "SLASH", "REM", "CONCAT", "COLLATE", + "BITNOT", "STRING", "JOIN_KW", "CONSTRAINT", + "DEFAULT", "NULL", "PRIMARY", "UNIQUE", + "CHECK", "REFERENCES", "AUTOINCR", "ON", + "INSERT", "DELETE", "UPDATE", "SET", + "DEFERRABLE", "FOREIGN", "DROP", "UNION", + "ALL", "EXCEPT", "INTERSECT", "SELECT", + "VALUES", "DISTINCT", "DOT", "FROM", + "JOIN", "USING", "ORDER", "GROUP", + "HAVING", "LIMIT", "WHERE", "INTO", + "INTEGER", "FLOAT", "BLOB", "VARIABLE", + "CASE", "WHEN", "THEN", "ELSE", + "INDEX", "ALTER", "ADD", "error", + "input", "cmdlist", "ecmd", "explain", + "cmdx", "cmd", "transtype", "trans_opt", + "nm", "savepoint_opt", "create_table", "create_table_args", + "createkw", "temp", "ifnotexists", "dbnm", + "columnlist", "conslist_opt", "table_options", "select", + "column", "columnid", "type", "carglist", + "typetoken", "typename", "signed", "plus_num", + "minus_num", "ccons", "term", "expr", + "onconf", "sortorder", "autoinc", "idxlist_opt", + "refargs", "defer_subclause", "refarg", "refact", + "init_deferred_pred_opt", "conslist", "tconscomma", "tcons", + "idxlist", "defer_subclause_opt", "orconf", "resolvetype", + "raisetype", "ifexists", "fullname", "selectnowith", + "oneselect", "with", "multiselect_op", "distinct", + "selcollist", "from", "where_opt", "groupby_opt", + "having_opt", "orderby_opt", "limit_opt", "values", + "nexprlist", "exprlist", "sclp", "as", + "seltablist", "stl_prefix", "joinop", "indexed_opt", + "on_opt", "using_opt", "joinop2", "idlist", + "sortlist", "setlist", "insert_cmd", "inscollist_opt", + "likeop", "between_op", "in_op", "case_operand", + "case_exprlist", "case_else", "uniqueflag", "collate", + "nmnum", "trigger_decl", "trigger_cmd_list", "trigger_time", + "trigger_event", "foreach_clause", "when_clause", "trigger_cmd", + "trnm", "tridxby", "database_kw_opt", "key_opt", + "add_column_fullname", "kwcolumn_opt", "create_vtab", "vtabarglist", + "vtabarg", "vtabargtoken", "lp", "anylist", + "wqlist", +}; +#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 */ "ecmd ::= SEMI", + /* 4 */ "ecmd ::= explain cmdx SEMI", + /* 5 */ "explain ::=", + /* 6 */ "explain ::= EXPLAIN", + /* 7 */ "explain ::= EXPLAIN QUERY PLAN", + /* 8 */ "cmdx ::= cmd", + /* 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 */ "savepoint_opt ::= SAVEPOINT", + /* 21 */ "savepoint_opt ::=", + /* 22 */ "cmd ::= SAVEPOINT nm", + /* 23 */ "cmd ::= RELEASE savepoint_opt nm", + /* 24 */ "cmd ::= ROLLBACK trans_opt TO savepoint_opt nm", + /* 25 */ "cmd ::= create_table create_table_args", + /* 26 */ "create_table ::= createkw temp TABLE ifnotexists nm dbnm", + /* 27 */ "createkw ::= CREATE", + /* 28 */ "ifnotexists ::=", + /* 29 */ "ifnotexists ::= IF NOT EXISTS", + /* 30 */ "temp ::= TEMP", + /* 31 */ "temp ::=", + /* 32 */ "create_table_args ::= LP columnlist conslist_opt RP table_options", + /* 33 */ "create_table_args ::= AS select", + /* 34 */ "table_options ::=", + /* 35 */ "table_options ::= WITHOUT nm", + /* 36 */ "columnlist ::= columnlist COMMA column", + /* 37 */ "columnlist ::= column", + /* 38 */ "column ::= columnid type carglist", + /* 39 */ "columnid ::= nm", + /* 40 */ "nm ::= ID|INDEXED", + /* 41 */ "nm ::= STRING", + /* 42 */ "nm ::= JOIN_KW", + /* 43 */ "type ::=", + /* 44 */ "type ::= typetoken", + /* 45 */ "typetoken ::= typename", + /* 46 */ "typetoken ::= typename LP signed RP", + /* 47 */ "typetoken ::= typename LP signed COMMA signed RP", + /* 48 */ "typename ::= ID|STRING", + /* 49 */ "typename ::= typename ID|STRING", + /* 50 */ "signed ::= plus_num", + /* 51 */ "signed ::= minus_num", + /* 52 */ "carglist ::= carglist ccons", + /* 53 */ "carglist ::=", + /* 54 */ "ccons ::= CONSTRAINT nm", + /* 55 */ "ccons ::= DEFAULT term", + /* 56 */ "ccons ::= DEFAULT LP expr RP", + /* 57 */ "ccons ::= DEFAULT PLUS term", + /* 58 */ "ccons ::= DEFAULT MINUS term", + /* 59 */ "ccons ::= DEFAULT ID|INDEXED", + /* 60 */ "ccons ::= NULL onconf", + /* 61 */ "ccons ::= NOT NULL onconf", + /* 62 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc", + /* 63 */ "ccons ::= UNIQUE onconf", + /* 64 */ "ccons ::= CHECK LP expr RP", + /* 65 */ "ccons ::= REFERENCES nm idxlist_opt refargs", + /* 66 */ "ccons ::= defer_subclause", + /* 67 */ "ccons ::= COLLATE ID|STRING", + /* 68 */ "autoinc ::=", + /* 69 */ "autoinc ::= AUTOINCR", + /* 70 */ "refargs ::=", + /* 71 */ "refargs ::= refargs refarg", + /* 72 */ "refarg ::= MATCH nm", + /* 73 */ "refarg ::= ON INSERT refact", + /* 74 */ "refarg ::= ON DELETE refact", + /* 75 */ "refarg ::= ON UPDATE refact", + /* 76 */ "refact ::= SET NULL", + /* 77 */ "refact ::= SET DEFAULT", + /* 78 */ "refact ::= CASCADE", + /* 79 */ "refact ::= RESTRICT", + /* 80 */ "refact ::= NO ACTION", + /* 81 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt", + /* 82 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt", + /* 83 */ "init_deferred_pred_opt ::=", + /* 84 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED", + /* 85 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE", + /* 86 */ "conslist_opt ::=", + /* 87 */ "conslist_opt ::= COMMA conslist", + /* 88 */ "conslist ::= conslist tconscomma tcons", + /* 89 */ "conslist ::= tcons", + /* 90 */ "tconscomma ::= COMMA", + /* 91 */ "tconscomma ::=", + /* 92 */ "tcons ::= CONSTRAINT nm", + /* 93 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf", + /* 94 */ "tcons ::= UNIQUE LP idxlist RP onconf", + /* 95 */ "tcons ::= CHECK LP expr RP onconf", + /* 96 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt", + /* 97 */ "defer_subclause_opt ::=", + /* 98 */ "defer_subclause_opt ::= defer_subclause", + /* 99 */ "onconf ::=", + /* 100 */ "onconf ::= ON CONFLICT resolvetype", + /* 101 */ "orconf ::=", + /* 102 */ "orconf ::= OR resolvetype", + /* 103 */ "resolvetype ::= raisetype", + /* 104 */ "resolvetype ::= IGNORE", + /* 105 */ "resolvetype ::= REPLACE", + /* 106 */ "cmd ::= DROP TABLE ifexists fullname", + /* 107 */ "ifexists ::= IF EXISTS", + /* 108 */ "ifexists ::=", + /* 109 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select", + /* 110 */ "cmd ::= DROP VIEW ifexists fullname", + /* 111 */ "cmd ::= select", + /* 112 */ "select ::= with selectnowith", + /* 113 */ "selectnowith ::= oneselect", + /* 114 */ "selectnowith ::= selectnowith multiselect_op oneselect", + /* 115 */ "multiselect_op ::= UNION", + /* 116 */ "multiselect_op ::= UNION ALL", + /* 117 */ "multiselect_op ::= EXCEPT|INTERSECT", + /* 118 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", + /* 119 */ "oneselect ::= values", + /* 120 */ "values ::= VALUES LP nexprlist RP", + /* 121 */ "values ::= values COMMA LP exprlist RP", + /* 122 */ "distinct ::= DISTINCT", + /* 123 */ "distinct ::= ALL", + /* 124 */ "distinct ::=", + /* 125 */ "sclp ::= selcollist COMMA", + /* 126 */ "sclp ::=", + /* 127 */ "selcollist ::= sclp expr as", + /* 128 */ "selcollist ::= sclp STAR", + /* 129 */ "selcollist ::= sclp nm DOT STAR", + /* 130 */ "as ::= AS nm", + /* 131 */ "as ::= ID|STRING", + /* 132 */ "as ::=", + /* 133 */ "from ::=", + /* 134 */ "from ::= FROM seltablist", + /* 135 */ "stl_prefix ::= seltablist joinop", + /* 136 */ "stl_prefix ::=", + /* 137 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt", + /* 138 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt", + /* 139 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt", + /* 140 */ "dbnm ::=", + /* 141 */ "dbnm ::= DOT nm", + /* 142 */ "fullname ::= nm dbnm", + /* 143 */ "joinop ::= COMMA|JOIN", + /* 144 */ "joinop ::= JOIN_KW JOIN", + /* 145 */ "joinop ::= JOIN_KW nm JOIN", + /* 146 */ "joinop ::= JOIN_KW nm nm JOIN", + /* 147 */ "on_opt ::= ON expr", + /* 148 */ "on_opt ::=", + /* 149 */ "indexed_opt ::=", + /* 150 */ "indexed_opt ::= INDEXED BY nm", + /* 151 */ "indexed_opt ::= NOT INDEXED", + /* 152 */ "using_opt ::= USING LP idlist RP", + /* 153 */ "using_opt ::=", + /* 154 */ "orderby_opt ::=", + /* 155 */ "orderby_opt ::= ORDER BY sortlist", + /* 156 */ "sortlist ::= sortlist COMMA expr sortorder", + /* 157 */ "sortlist ::= expr sortorder", + /* 158 */ "sortorder ::= ASC", + /* 159 */ "sortorder ::= DESC", + /* 160 */ "sortorder ::=", + /* 161 */ "groupby_opt ::=", + /* 162 */ "groupby_opt ::= GROUP BY nexprlist", + /* 163 */ "having_opt ::=", + /* 164 */ "having_opt ::= HAVING expr", + /* 165 */ "limit_opt ::=", + /* 166 */ "limit_opt ::= LIMIT expr", + /* 167 */ "limit_opt ::= LIMIT expr OFFSET expr", + /* 168 */ "limit_opt ::= LIMIT expr COMMA expr", + /* 169 */ "cmd ::= with DELETE FROM fullname indexed_opt where_opt", + /* 170 */ "where_opt ::=", + /* 171 */ "where_opt ::= WHERE expr", + /* 172 */ "cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt", + /* 173 */ "setlist ::= setlist COMMA nm EQ expr", + /* 174 */ "setlist ::= nm EQ expr", + /* 175 */ "cmd ::= with insert_cmd INTO fullname inscollist_opt select", + /* 176 */ "cmd ::= with insert_cmd INTO fullname inscollist_opt DEFAULT VALUES", + /* 177 */ "insert_cmd ::= INSERT orconf", + /* 178 */ "insert_cmd ::= REPLACE", + /* 179 */ "inscollist_opt ::=", + /* 180 */ "inscollist_opt ::= LP idlist RP", + /* 181 */ "idlist ::= idlist COMMA nm", + /* 182 */ "idlist ::= nm", + /* 183 */ "expr ::= term", + /* 184 */ "expr ::= LP expr RP", + /* 185 */ "term ::= NULL", + /* 186 */ "expr ::= ID|INDEXED", + /* 187 */ "expr ::= JOIN_KW", + /* 188 */ "expr ::= nm DOT nm", + /* 189 */ "expr ::= nm DOT nm DOT nm", + /* 190 */ "term ::= INTEGER|FLOAT|BLOB", + /* 191 */ "term ::= STRING", + /* 192 */ "expr ::= VARIABLE", + /* 193 */ "expr ::= expr COLLATE ID|STRING", + /* 194 */ "expr ::= CAST LP expr AS typetoken RP", + /* 195 */ "expr ::= ID|INDEXED LP distinct exprlist RP", + /* 196 */ "expr ::= ID|INDEXED LP STAR RP", + /* 197 */ "term ::= CTIME_KW", + /* 198 */ "expr ::= expr AND expr", + /* 199 */ "expr ::= expr OR expr", + /* 200 */ "expr ::= expr LT|GT|GE|LE expr", + /* 201 */ "expr ::= expr EQ|NE expr", + /* 202 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", + /* 203 */ "expr ::= expr PLUS|MINUS expr", + /* 204 */ "expr ::= expr STAR|SLASH|REM expr", + /* 205 */ "expr ::= expr CONCAT expr", + /* 206 */ "likeop ::= LIKE_KW|MATCH", + /* 207 */ "likeop ::= NOT LIKE_KW|MATCH", + /* 208 */ "expr ::= expr likeop expr", + /* 209 */ "expr ::= expr likeop expr ESCAPE expr", + /* 210 */ "expr ::= expr ISNULL|NOTNULL", + /* 211 */ "expr ::= expr NOT NULL", + /* 212 */ "expr ::= expr IS expr", + /* 213 */ "expr ::= expr IS NOT expr", + /* 214 */ "expr ::= NOT expr", + /* 215 */ "expr ::= BITNOT expr", + /* 216 */ "expr ::= MINUS expr", + /* 217 */ "expr ::= PLUS expr", + /* 218 */ "between_op ::= BETWEEN", + /* 219 */ "between_op ::= NOT BETWEEN", + /* 220 */ "expr ::= expr between_op expr AND expr", + /* 221 */ "in_op ::= IN", + /* 222 */ "in_op ::= NOT IN", + /* 223 */ "expr ::= expr in_op LP exprlist RP", + /* 224 */ "expr ::= LP select RP", + /* 225 */ "expr ::= expr in_op LP select RP", + /* 226 */ "expr ::= expr in_op nm dbnm", + /* 227 */ "expr ::= EXISTS LP select RP", + /* 228 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 229 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 230 */ "case_exprlist ::= WHEN expr THEN expr", + /* 231 */ "case_else ::= ELSE expr", + /* 232 */ "case_else ::=", + /* 233 */ "case_operand ::= expr", + /* 234 */ "case_operand ::=", + /* 235 */ "exprlist ::= nexprlist", + /* 236 */ "exprlist ::=", + /* 237 */ "nexprlist ::= nexprlist COMMA expr", + /* 238 */ "nexprlist ::= expr", + /* 239 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt", + /* 240 */ "uniqueflag ::= UNIQUE", + /* 241 */ "uniqueflag ::=", + /* 242 */ "idxlist_opt ::=", + /* 243 */ "idxlist_opt ::= LP idxlist RP", + /* 244 */ "idxlist ::= idxlist COMMA nm collate sortorder", + /* 245 */ "idxlist ::= nm collate sortorder", + /* 246 */ "collate ::=", + /* 247 */ "collate ::= COLLATE ID|STRING", + /* 248 */ "cmd ::= DROP INDEX ifexists fullname", + /* 249 */ "cmd ::= VACUUM", + /* 250 */ "cmd ::= VACUUM nm", + /* 251 */ "cmd ::= PRAGMA nm dbnm", + /* 252 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", + /* 253 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", + /* 254 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 255 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", + /* 256 */ "nmnum ::= plus_num", + /* 257 */ "nmnum ::= nm", + /* 258 */ "nmnum ::= ON", + /* 259 */ "nmnum ::= DELETE", + /* 260 */ "nmnum ::= DEFAULT", + /* 261 */ "plus_num ::= PLUS INTEGER|FLOAT", + /* 262 */ "plus_num ::= INTEGER|FLOAT", + /* 263 */ "minus_num ::= MINUS INTEGER|FLOAT", + /* 264 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", + /* 265 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 266 */ "trigger_time ::= BEFORE", + /* 267 */ "trigger_time ::= AFTER", + /* 268 */ "trigger_time ::= INSTEAD OF", + /* 269 */ "trigger_time ::=", + /* 270 */ "trigger_event ::= DELETE|INSERT", + /* 271 */ "trigger_event ::= UPDATE", + /* 272 */ "trigger_event ::= UPDATE OF idlist", + /* 273 */ "foreach_clause ::=", + /* 274 */ "foreach_clause ::= FOR EACH ROW", + /* 275 */ "when_clause ::=", + /* 276 */ "when_clause ::= WHEN expr", + /* 277 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", + /* 278 */ "trigger_cmd_list ::= trigger_cmd SEMI", + /* 279 */ "trnm ::= nm", + /* 280 */ "trnm ::= nm DOT nm", + /* 281 */ "tridxby ::=", + /* 282 */ "tridxby ::= INDEXED BY nm", + /* 283 */ "tridxby ::= NOT INDEXED", + /* 284 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt", + /* 285 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select", + /* 286 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt", + /* 287 */ "trigger_cmd ::= select", + /* 288 */ "expr ::= RAISE LP IGNORE RP", + /* 289 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 290 */ "raisetype ::= ROLLBACK", + /* 291 */ "raisetype ::= ABORT", + /* 292 */ "raisetype ::= FAIL", + /* 293 */ "cmd ::= DROP TRIGGER ifexists fullname", + /* 294 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", + /* 295 */ "cmd ::= DETACH database_kw_opt expr", + /* 296 */ "key_opt ::=", + /* 297 */ "key_opt ::= KEY expr", + /* 298 */ "database_kw_opt ::= DATABASE", + /* 299 */ "database_kw_opt ::=", + /* 300 */ "cmd ::= REINDEX", + /* 301 */ "cmd ::= REINDEX nm dbnm", + /* 302 */ "cmd ::= ANALYZE", + /* 303 */ "cmd ::= ANALYZE nm dbnm", + /* 304 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 305 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column", + /* 306 */ "add_column_fullname ::= fullname", + /* 307 */ "kwcolumn_opt ::=", + /* 308 */ "kwcolumn_opt ::= COLUMNKW", + /* 309 */ "cmd ::= create_vtab", + /* 310 */ "cmd ::= create_vtab LP vtabarglist RP", + /* 311 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", + /* 312 */ "vtabarglist ::= vtabarg", + /* 313 */ "vtabarglist ::= vtabarglist COMMA vtabarg", + /* 314 */ "vtabarg ::=", + /* 315 */ "vtabarg ::= vtabarg vtabargtoken", + /* 316 */ "vtabargtoken ::= ANY", + /* 317 */ "vtabargtoken ::= lp anylist RP", + /* 318 */ "lp ::= LP", + /* 319 */ "anylist ::=", + /* 320 */ "anylist ::= anylist LP anylist RP", + /* 321 */ "anylist ::= anylist ANY", + /* 322 */ "with ::=", + /* 323 */ "with ::= WITH wqlist", + /* 324 */ "with ::= WITH RECURSIVE wqlist", + /* 325 */ "wqlist ::= nm idxlist_opt AS LP select RP", + /* 326 */ "wqlist ::= wqlist COMMA nm idxlist_opt AS LP select RP", +}; +#endif /* NDEBUG */ + + +#if YYSTACKDEPTH<=0 +/* +** Try to increase the size of the parser stack. +*/ +static void yyGrowStack(yyParser *p){ + int newSize; + yyStackEntry *pNew; + + newSize = p->yystksz*2 + 100; + pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); + if( pNew ){ + p->yystack = pNew; + p->yystksz = newSize; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sStack grows to %d entries!\n", + yyTracePrompt, p->yystksz); + } +#endif + } +} +#endif + +/* +** This function allocates a new parser. +** The only argument is a pointer to a function which works like +** malloc. +** +** Inputs: +** A pointer to the function used to allocate memory. +** +** Outputs: +** A pointer to a parser. This pointer is used in subsequent calls +** to sqlite3Parser and sqlite3ParserFree. +*/ +SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(u64)){ + yyParser *pParser; + pParser = (yyParser*)(*mallocProc)( (u64)sizeof(yyParser) ); + if( pParser ){ + pParser->yyidx = -1; +#ifdef YYTRACKMAXSTACKDEPTH + pParser->yyidxMax = 0; +#endif +#if YYSTACKDEPTH<=0 + pParser->yystack = NULL; + pParser->yystksz = 0; + yyGrowStack(pParser); +#endif + } + return pParser; +} + +/* The following function deletes the value associated with a +** symbol. The symbol can be either a terminal or nonterminal. +** "yymajor" is the symbol code, and "yypminor" is a pointer to +** the value. +*/ +static void yy_destructor( + yyParser *yypParser, /* The parser */ + YYCODETYPE yymajor, /* Type code for object to destroy */ + YYMINORTYPE *yypminor /* The object to be destroyed */ +){ + sqlite3ParserARG_FETCH; + switch( yymajor ){ + /* Here is inserted the actions which take place when a + ** terminal or non-terminal is destroyed. This can happen + ** when the symbol is popped from the stack during a + ** 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 163: /* select */ + case 195: /* selectnowith */ + case 196: /* oneselect */ + case 207: /* values */ +{ +sqlite3SelectDelete(pParse->db, (yypminor->yy3)); +} + break; + case 174: /* term */ + case 175: /* expr */ +{ +sqlite3ExprDelete(pParse->db, (yypminor->yy346).pExpr); +} + break; + case 179: /* idxlist_opt */ + case 188: /* idxlist */ + case 200: /* selcollist */ + case 203: /* groupby_opt */ + case 205: /* orderby_opt */ + case 208: /* nexprlist */ + case 209: /* exprlist */ + case 210: /* sclp */ + case 220: /* sortlist */ + case 221: /* setlist */ + case 228: /* case_exprlist */ +{ +sqlite3ExprListDelete(pParse->db, (yypminor->yy14)); +} + break; + case 194: /* fullname */ + case 201: /* from */ + case 212: /* seltablist */ + case 213: /* stl_prefix */ +{ +sqlite3SrcListDelete(pParse->db, (yypminor->yy65)); +} + break; + case 197: /* with */ + case 252: /* wqlist */ +{ +sqlite3WithDelete(pParse->db, (yypminor->yy59)); +} + break; + case 202: /* where_opt */ + case 204: /* having_opt */ + case 216: /* on_opt */ + case 227: /* case_operand */ + case 229: /* case_else */ + case 238: /* when_clause */ + case 243: /* key_opt */ +{ +sqlite3ExprDelete(pParse->db, (yypminor->yy132)); +} + break; + case 217: /* using_opt */ + case 219: /* idlist */ + case 223: /* inscollist_opt */ +{ +sqlite3IdListDelete(pParse->db, (yypminor->yy408)); +} + break; + case 234: /* trigger_cmd_list */ + case 239: /* trigger_cmd */ +{ +sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy473)); +} + break; + case 236: /* trigger_event */ +{ +sqlite3IdListDelete(pParse->db, (yypminor->yy378).b); +} + break; + default: break; /* If no destructor action specified: do nothing */ + } +} + +/* +** Pop the parser's stack once. +** +** If there is a destructor routine associated with the token which +** is popped from the stack, then call it. +** +** Return the major token number for the symbol popped. +*/ +static int yy_pop_parser_stack(yyParser *pParser){ + YYCODETYPE yymajor; + yyStackEntry *yytos = &pParser->yystack[pParser->yyidx]; + + /* There is no mechanism by which the parser stack can be popped below + ** empty in SQLite. */ + if( NEVER(pParser->yyidx<0) ) return 0; +#ifndef NDEBUG + if( yyTraceFILE && pParser->yyidx>=0 ){ + fprintf(yyTraceFILE,"%sPopping %s\n", + yyTracePrompt, + yyTokenName[yytos->major]); + } +#endif + yymajor = yytos->major; + yy_destructor(pParser, yymajor, &yytos->minor); + pParser->yyidx--; + return yymajor; +} + +/* +** Deallocate and destroy a parser. Destructors are all called for +** all stack elements before shutting the parser down. +** +** Inputs: +**
      +**
    • A pointer to the parser. This should be a pointer +** obtained from sqlite3ParserAlloc. +**
    • A pointer to a function used to reclaim memory obtained +** from malloc. +**
    +*/ +SQLITE_PRIVATE void sqlite3ParserFree( + void *p, /* The parser to be deleted */ + void (*freeProc)(void*) /* Function used to reclaim memory */ +){ + yyParser *pParser = (yyParser*)p; + /* In SQLite, we never try to destroy a parser that was not successfully + ** created in the first place. */ + if( NEVER(pParser==0) ) return; + while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); +#if YYSTACKDEPTH<=0 + free(pParser->yystack); +#endif + (*freeProc)((void*)pParser); +} + +/* +** Return the peak depth of the stack for a parser. +*/ +#ifdef YYTRACKMAXSTACKDEPTH +SQLITE_PRIVATE int sqlite3ParserStackPeak(void *p){ + yyParser *pParser = (yyParser*)p; + return pParser->yyidxMax; +} +#endif + +/* +** Find the appropriate action for a parser given the terminal +** look-ahead token iLookAhead. +** +** If the look-ahead token is YYNOCODE, then check to see if the action is +** independent of the look-ahead. If it is, return the action, otherwise +** return YY_NO_ACTION. +*/ +static int yy_find_shift_action( + yyParser *pParser, /* The parser */ + YYCODETYPE iLookAhead /* The look-ahead token */ +){ + int i; + int stateno = pParser->yystack[pParser->yyidx].stateno; + + if( stateno>YY_SHIFT_COUNT + || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ + return yy_default[stateno]; + } + assert( iLookAhead!=YYNOCODE ); + i += iLookAhead; + if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){ + if( iLookAhead>0 ){ +#ifdef YYFALLBACK + YYCODETYPE iFallback; /* Fallback token */ + if( iLookAhead %s\n", + yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); + } +#endif + return yy_find_shift_action(pParser, iFallback); + } +#endif +#ifdef YYWILDCARD + { + int j = i - iLookAhead + YYWILDCARD; + if( +#if YY_SHIFT_MIN+YYWILDCARD<0 + j>=0 && +#endif +#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT + j %s\n", + yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]); + } +#endif /* NDEBUG */ + return yy_action[j]; + } + } +#endif /* YYWILDCARD */ + } + return yy_default[stateno]; + }else{ + return yy_action[i]; + } +} + +/* +** Find the appropriate action for a parser given the non-terminal +** look-ahead token iLookAhead. +** +** If the look-ahead token is YYNOCODE, then check to see if the action is +** independent of the look-ahead. If it is, return the action, otherwise +** return YY_NO_ACTION. +*/ +static int yy_find_reduce_action( + int stateno, /* Current state number */ + YYCODETYPE iLookAhead /* The look-ahead token */ +){ + int i; +#ifdef YYERRORSYMBOL + if( stateno>YY_REDUCE_COUNT ){ + return yy_default[stateno]; + } +#else + assert( stateno<=YY_REDUCE_COUNT ); +#endif + i = yy_reduce_ofst[stateno]; + assert( i!=YY_REDUCE_USE_DFLT ); + assert( iLookAhead!=YYNOCODE ); + i += iLookAhead; +#ifdef YYERRORSYMBOL + if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){ + return yy_default[stateno]; + } +#else + assert( i>=0 && iyyidx--; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); + } +#endif + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will execute if the parser + ** stack every overflows */ + + UNUSED_PARAMETER(yypMinor); /* Silence some compiler warnings */ + sqlite3ErrorMsg(pParse, "parser stack overflow"); + sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */ +} + +/* +** Perform a shift action. +*/ +static void yy_shift( + yyParser *yypParser, /* The parser to be shifted */ + int yyNewState, /* The new state to shift in */ + int yyMajor, /* The major token to shift in */ + YYMINORTYPE *yypMinor /* Pointer to the minor token to shift in */ +){ + yyStackEntry *yytos; + yypParser->yyidx++; +#ifdef YYTRACKMAXSTACKDEPTH + if( yypParser->yyidx>yypParser->yyidxMax ){ + yypParser->yyidxMax = yypParser->yyidx; + } +#endif +#if YYSTACKDEPTH>0 + if( yypParser->yyidx>=YYSTACKDEPTH ){ + yyStackOverflow(yypParser, yypMinor); + return; + } +#else + if( yypParser->yyidx>=yypParser->yystksz ){ + yyGrowStack(yypParser); + if( yypParser->yyidx>=yypParser->yystksz ){ + yyStackOverflow(yypParser, yypMinor); + return; + } + } +#endif + yytos = &yypParser->yystack[yypParser->yyidx]; + yytos->stateno = (YYACTIONTYPE)yyNewState; + yytos->major = (YYCODETYPE)yyMajor; + yytos->minor = *yypMinor; +#ifndef NDEBUG + if( yyTraceFILE && yypParser->yyidx>0 ){ + int i; + fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState); + fprintf(yyTraceFILE,"%sStack:",yyTracePrompt); + for(i=1; i<=yypParser->yyidx; i++) + fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]); + fprintf(yyTraceFILE,"\n"); + } +#endif +} + +/* 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[] = { + { 144, 1 }, + { 145, 2 }, + { 145, 1 }, + { 146, 1 }, + { 146, 3 }, + { 147, 0 }, + { 147, 1 }, + { 147, 3 }, + { 148, 1 }, + { 149, 3 }, + { 151, 0 }, + { 151, 1 }, + { 151, 2 }, + { 150, 0 }, + { 150, 1 }, + { 150, 1 }, + { 150, 1 }, + { 149, 2 }, + { 149, 2 }, + { 149, 2 }, + { 153, 1 }, + { 153, 0 }, + { 149, 2 }, + { 149, 3 }, + { 149, 5 }, + { 149, 2 }, + { 154, 6 }, + { 156, 1 }, + { 158, 0 }, + { 158, 3 }, + { 157, 1 }, + { 157, 0 }, + { 155, 5 }, + { 155, 2 }, + { 162, 0 }, + { 162, 2 }, + { 160, 3 }, + { 160, 1 }, + { 164, 3 }, + { 165, 1 }, + { 152, 1 }, + { 152, 1 }, + { 152, 1 }, + { 166, 0 }, + { 166, 1 }, + { 168, 1 }, + { 168, 4 }, + { 168, 6 }, + { 169, 1 }, + { 169, 2 }, + { 170, 1 }, + { 170, 1 }, + { 167, 2 }, + { 167, 0 }, + { 173, 2 }, + { 173, 2 }, + { 173, 4 }, + { 173, 3 }, + { 173, 3 }, + { 173, 2 }, + { 173, 2 }, + { 173, 3 }, + { 173, 5 }, + { 173, 2 }, + { 173, 4 }, + { 173, 4 }, + { 173, 1 }, + { 173, 2 }, + { 178, 0 }, + { 178, 1 }, + { 180, 0 }, + { 180, 2 }, + { 182, 2 }, + { 182, 3 }, + { 182, 3 }, + { 182, 3 }, + { 183, 2 }, + { 183, 2 }, + { 183, 1 }, + { 183, 1 }, + { 183, 2 }, + { 181, 3 }, + { 181, 2 }, + { 184, 0 }, + { 184, 2 }, + { 184, 2 }, + { 161, 0 }, + { 161, 2 }, + { 185, 3 }, + { 185, 1 }, + { 186, 1 }, + { 186, 0 }, + { 187, 2 }, + { 187, 7 }, + { 187, 5 }, + { 187, 5 }, + { 187, 10 }, + { 189, 0 }, + { 189, 1 }, + { 176, 0 }, + { 176, 3 }, + { 190, 0 }, + { 190, 2 }, + { 191, 1 }, + { 191, 1 }, + { 191, 1 }, + { 149, 4 }, + { 193, 2 }, + { 193, 0 }, + { 149, 8 }, + { 149, 4 }, + { 149, 1 }, + { 163, 2 }, + { 195, 1 }, + { 195, 3 }, + { 198, 1 }, + { 198, 2 }, + { 198, 1 }, + { 196, 9 }, + { 196, 1 }, + { 207, 4 }, + { 207, 5 }, + { 199, 1 }, + { 199, 1 }, + { 199, 0 }, + { 210, 2 }, + { 210, 0 }, + { 200, 3 }, + { 200, 2 }, + { 200, 4 }, + { 211, 2 }, + { 211, 1 }, + { 211, 0 }, + { 201, 0 }, + { 201, 2 }, + { 213, 2 }, + { 213, 0 }, + { 212, 7 }, + { 212, 7 }, + { 212, 7 }, + { 159, 0 }, + { 159, 2 }, + { 194, 2 }, + { 214, 1 }, + { 214, 2 }, + { 214, 3 }, + { 214, 4 }, + { 216, 2 }, + { 216, 0 }, + { 215, 0 }, + { 215, 3 }, + { 215, 2 }, + { 217, 4 }, + { 217, 0 }, + { 205, 0 }, + { 205, 3 }, + { 220, 4 }, + { 220, 2 }, + { 177, 1 }, + { 177, 1 }, + { 177, 0 }, + { 203, 0 }, + { 203, 3 }, + { 204, 0 }, + { 204, 2 }, + { 206, 0 }, + { 206, 2 }, + { 206, 4 }, + { 206, 4 }, + { 149, 6 }, + { 202, 0 }, + { 202, 2 }, + { 149, 8 }, + { 221, 5 }, + { 221, 3 }, + { 149, 6 }, + { 149, 7 }, + { 222, 2 }, + { 222, 1 }, + { 223, 0 }, + { 223, 3 }, + { 219, 3 }, + { 219, 1 }, + { 175, 1 }, + { 175, 3 }, + { 174, 1 }, + { 175, 1 }, + { 175, 1 }, + { 175, 3 }, + { 175, 5 }, + { 174, 1 }, + { 174, 1 }, + { 175, 1 }, + { 175, 3 }, + { 175, 6 }, + { 175, 5 }, + { 175, 4 }, + { 174, 1 }, + { 175, 3 }, + { 175, 3 }, + { 175, 3 }, + { 175, 3 }, + { 175, 3 }, + { 175, 3 }, + { 175, 3 }, + { 175, 3 }, + { 224, 1 }, + { 224, 2 }, + { 175, 3 }, + { 175, 5 }, + { 175, 2 }, + { 175, 3 }, + { 175, 3 }, + { 175, 4 }, + { 175, 2 }, + { 175, 2 }, + { 175, 2 }, + { 175, 2 }, + { 225, 1 }, + { 225, 2 }, + { 175, 5 }, + { 226, 1 }, + { 226, 2 }, + { 175, 5 }, + { 175, 3 }, + { 175, 5 }, + { 175, 4 }, + { 175, 4 }, + { 175, 5 }, + { 228, 5 }, + { 228, 4 }, + { 229, 2 }, + { 229, 0 }, + { 227, 1 }, + { 227, 0 }, + { 209, 1 }, + { 209, 0 }, + { 208, 3 }, + { 208, 1 }, + { 149, 12 }, + { 230, 1 }, + { 230, 0 }, + { 179, 0 }, + { 179, 3 }, + { 188, 5 }, + { 188, 3 }, + { 231, 0 }, + { 231, 2 }, + { 149, 4 }, + { 149, 1 }, + { 149, 2 }, + { 149, 3 }, + { 149, 5 }, + { 149, 6 }, + { 149, 5 }, + { 149, 6 }, + { 232, 1 }, + { 232, 1 }, + { 232, 1 }, + { 232, 1 }, + { 232, 1 }, + { 171, 2 }, + { 171, 1 }, + { 172, 2 }, + { 149, 5 }, + { 233, 11 }, + { 235, 1 }, + { 235, 1 }, + { 235, 2 }, + { 235, 0 }, + { 236, 1 }, + { 236, 1 }, + { 236, 3 }, + { 237, 0 }, + { 237, 3 }, + { 238, 0 }, + { 238, 2 }, + { 234, 3 }, + { 234, 2 }, + { 240, 1 }, + { 240, 3 }, + { 241, 0 }, + { 241, 3 }, + { 241, 2 }, + { 239, 7 }, + { 239, 5 }, + { 239, 5 }, + { 239, 1 }, + { 175, 4 }, + { 175, 6 }, + { 192, 1 }, + { 192, 1 }, + { 192, 1 }, + { 149, 4 }, + { 149, 6 }, + { 149, 3 }, + { 243, 0 }, + { 243, 2 }, + { 242, 1 }, + { 242, 0 }, + { 149, 1 }, + { 149, 3 }, + { 149, 1 }, + { 149, 3 }, + { 149, 6 }, + { 149, 6 }, + { 244, 1 }, + { 245, 0 }, + { 245, 1 }, + { 149, 1 }, + { 149, 4 }, + { 246, 8 }, + { 247, 1 }, + { 247, 3 }, + { 248, 0 }, + { 248, 2 }, + { 249, 1 }, + { 249, 3 }, + { 250, 1 }, + { 251, 0 }, + { 251, 4 }, + { 251, 2 }, + { 197, 0 }, + { 197, 2 }, + { 197, 3 }, + { 252, 6 }, + { 252, 8 }, +}; + +static void yy_accept(yyParser*); /* Forward Declaration */ + +/* +** Perform a reduce action and the shift that must immediately +** follow the reduce. +*/ +static void yy_reduce( + yyParser *yypParser, /* The parser */ + int yyruleno /* Number of the rule by which to reduce */ +){ + int yygoto; /* The next state */ + int yyact; /* The next action */ + YYMINORTYPE yygotominor; /* The LHS of the rule reduced */ + yyStackEntry *yymsp; /* The top of the parser's stack */ + int yysize; /* Amount to pop the stack */ + sqlite3ParserARG_FETCH; + yymsp = &yypParser->yystack[yypParser->yyidx]; +#ifndef NDEBUG + if( yyTraceFILE && yyruleno>=0 + && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ + fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, + yyRuleName[yyruleno]); + } +#endif /* NDEBUG */ + + /* Silence complaints from purify about yygotominor being uninitialized + ** in some cases when it is copied into the stack after the following + ** switch. yygotominor is uninitialized when a rule reduces that does + ** not set the value of its left-hand side nonterminal. Leaving the + ** value of the nonterminal uninitialized is utterly harmless as long + ** as the value is never used. So really the only thing this code + ** accomplishes is to quieten purify. + ** + ** 2007-01-16: The wireshark project (www.wireshark.org) reports that + ** without this code, their parser segfaults. I'm not sure what there + ** parser is doing to make this happen. This is the second bug report + ** from wireshark this week. Clearly they are stressing Lemon in ways + ** that it has not been previously stressed... (SQLite ticket #2172) + */ + /*memset(&yygotominor, 0, sizeof(yygotominor));*/ + yygotominor = yyzerominor; + + + switch( yyruleno ){ + /* Beginning here are the reduction cases. A typical example + ** follows: + ** case 0: + ** #line + ** { ... } // User supplied code + ** #line + ** break; + */ + case 5: /* explain ::= */ +{ sqlite3BeginParse(pParse, 0); } + break; + case 6: /* explain ::= EXPLAIN */ +{ sqlite3BeginParse(pParse, 1); } + break; + case 7: /* explain ::= EXPLAIN QUERY PLAN */ +{ sqlite3BeginParse(pParse, 2); } + break; + case 8: /* cmdx ::= cmd */ +{ sqlite3FinishCoding(pParse); } + break; + case 9: /* cmd ::= BEGIN transtype trans_opt */ +{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy328);} + break; + case 13: /* transtype ::= */ +{yygotominor.yy328 = TK_DEFERRED;} + break; + case 14: /* transtype ::= DEFERRED */ + case 15: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==15); + case 16: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==16); + case 115: /* multiselect_op ::= UNION */ yytestcase(yyruleno==115); + case 117: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==117); +{yygotominor.yy328 = yymsp[0].major;} + break; + case 17: /* cmd ::= COMMIT trans_opt */ + case 18: /* cmd ::= END trans_opt */ yytestcase(yyruleno==18); +{sqlite3CommitTransaction(pParse);} + break; + case 19: /* cmd ::= ROLLBACK trans_opt */ +{sqlite3RollbackTransaction(pParse);} + break; + case 22: /* cmd ::= SAVEPOINT nm */ +{ + sqlite3Savepoint(pParse, SAVEPOINT_BEGIN, &yymsp[0].minor.yy0); +} + break; + case 23: /* cmd ::= RELEASE savepoint_opt nm */ +{ + sqlite3Savepoint(pParse, SAVEPOINT_RELEASE, &yymsp[0].minor.yy0); +} + break; + case 24: /* cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ +{ + sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &yymsp[0].minor.yy0); +} + break; + case 26: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ +{ + sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy328,0,0,yymsp[-2].minor.yy328); +} + break; + case 27: /* createkw ::= CREATE */ +{ + pParse->db->lookaside.bEnabled = 0; + yygotominor.yy0 = yymsp[0].minor.yy0; +} + break; + case 28: /* ifnotexists ::= */ + case 31: /* temp ::= */ yytestcase(yyruleno==31); + case 68: /* autoinc ::= */ yytestcase(yyruleno==68); + case 81: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==81); + case 83: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==83); + case 85: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==85); + case 97: /* defer_subclause_opt ::= */ yytestcase(yyruleno==97); + case 108: /* ifexists ::= */ yytestcase(yyruleno==108); + case 218: /* between_op ::= BETWEEN */ yytestcase(yyruleno==218); + case 221: /* in_op ::= IN */ yytestcase(yyruleno==221); +{yygotominor.yy328 = 0;} + break; + case 29: /* ifnotexists ::= IF NOT EXISTS */ + case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30); + case 69: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==69); + case 84: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==84); + case 107: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==107); + case 219: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==219); + case 222: /* in_op ::= NOT IN */ yytestcase(yyruleno==222); +{yygotominor.yy328 = 1;} + break; + case 32: /* create_table_args ::= LP columnlist conslist_opt RP table_options */ +{ + sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy186,0); +} + break; + case 33: /* create_table_args ::= AS select */ +{ + sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy3); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy3); +} + break; + case 34: /* table_options ::= */ +{yygotominor.yy186 = 0;} + break; + case 35: /* table_options ::= WITHOUT nm */ +{ + if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){ + yygotominor.yy186 = TF_WithoutRowid; + }else{ + yygotominor.yy186 = 0; + sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); + } +} + break; + case 38: /* column ::= columnid type carglist */ +{ + yygotominor.yy0.z = yymsp[-2].minor.yy0.z; + yygotominor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-2].minor.yy0.z) + pParse->sLastToken.n; +} + break; + case 39: /* columnid ::= nm */ +{ + sqlite3AddColumn(pParse,&yymsp[0].minor.yy0); + yygotominor.yy0 = yymsp[0].minor.yy0; + pParse->constraintName.n = 0; +} + break; + case 40: /* nm ::= ID|INDEXED */ + case 41: /* nm ::= STRING */ yytestcase(yyruleno==41); + case 42: /* nm ::= JOIN_KW */ yytestcase(yyruleno==42); + case 45: /* typetoken ::= typename */ yytestcase(yyruleno==45); + case 48: /* typename ::= ID|STRING */ yytestcase(yyruleno==48); + case 130: /* as ::= AS nm */ yytestcase(yyruleno==130); + case 131: /* as ::= ID|STRING */ yytestcase(yyruleno==131); + case 141: /* dbnm ::= DOT nm */ yytestcase(yyruleno==141); + case 150: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==150); + case 247: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==247); + case 256: /* nmnum ::= plus_num */ yytestcase(yyruleno==256); + case 257: /* nmnum ::= nm */ yytestcase(yyruleno==257); + case 258: /* nmnum ::= ON */ yytestcase(yyruleno==258); + case 259: /* nmnum ::= DELETE */ yytestcase(yyruleno==259); + case 260: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==260); + case 261: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==261); + case 262: /* plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==262); + case 263: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==263); + case 279: /* trnm ::= nm */ yytestcase(yyruleno==279); +{yygotominor.yy0 = yymsp[0].minor.yy0;} + break; + case 44: /* type ::= typetoken */ +{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy0);} + break; + case 46: /* typetoken ::= typename LP signed RP */ +{ + yygotominor.yy0.z = yymsp[-3].minor.yy0.z; + yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z); +} + break; + case 47: /* typetoken ::= typename LP signed COMMA signed RP */ +{ + yygotominor.yy0.z = yymsp[-5].minor.yy0.z; + yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z); +} + break; + case 49: /* typename ::= typename ID|STRING */ +{yygotominor.yy0.z=yymsp[-1].minor.yy0.z; yygotominor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);} + break; + case 54: /* ccons ::= CONSTRAINT nm */ + case 92: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==92); +{pParse->constraintName = yymsp[0].minor.yy0;} + break; + case 55: /* ccons ::= DEFAULT term */ + case 57: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==57); +{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy346);} + break; + case 56: /* ccons ::= DEFAULT LP expr RP */ +{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy346);} + break; + case 58: /* ccons ::= DEFAULT MINUS term */ +{ + ExprSpan v; + v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy346.pExpr, 0, 0); + v.zStart = yymsp[-1].minor.yy0.z; + v.zEnd = yymsp[0].minor.yy346.zEnd; + sqlite3AddDefaultValue(pParse,&v); +} + break; + case 59: /* ccons ::= DEFAULT ID|INDEXED */ +{ + ExprSpan v; + spanExpr(&v, pParse, TK_STRING, &yymsp[0].minor.yy0); + sqlite3AddDefaultValue(pParse,&v); +} + break; + case 61: /* ccons ::= NOT NULL onconf */ +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy328);} + break; + case 62: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy328,yymsp[0].minor.yy328,yymsp[-2].minor.yy328);} + break; + case 63: /* ccons ::= UNIQUE onconf */ +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy328,0,0,0,0);} + break; + case 64: /* ccons ::= CHECK LP expr RP */ +{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy346.pExpr);} + break; + case 65: /* ccons ::= REFERENCES nm idxlist_opt refargs */ +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy14,yymsp[0].minor.yy328);} + break; + case 66: /* ccons ::= defer_subclause */ +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy328);} + break; + case 67: /* ccons ::= COLLATE ID|STRING */ +{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} + break; + case 70: /* refargs ::= */ +{ yygotominor.yy328 = OE_None*0x0101; /* EV: R-19803-45884 */} + break; + case 71: /* refargs ::= refargs refarg */ +{ yygotominor.yy328 = (yymsp[-1].minor.yy328 & ~yymsp[0].minor.yy429.mask) | yymsp[0].minor.yy429.value; } + break; + case 72: /* refarg ::= MATCH nm */ + case 73: /* refarg ::= ON INSERT refact */ yytestcase(yyruleno==73); +{ yygotominor.yy429.value = 0; yygotominor.yy429.mask = 0x000000; } + break; + case 74: /* refarg ::= ON DELETE refact */ +{ yygotominor.yy429.value = yymsp[0].minor.yy328; yygotominor.yy429.mask = 0x0000ff; } + break; + case 75: /* refarg ::= ON UPDATE refact */ +{ yygotominor.yy429.value = yymsp[0].minor.yy328<<8; yygotominor.yy429.mask = 0x00ff00; } + break; + case 76: /* refact ::= SET NULL */ +{ yygotominor.yy328 = OE_SetNull; /* EV: R-33326-45252 */} + break; + case 77: /* refact ::= SET DEFAULT */ +{ yygotominor.yy328 = OE_SetDflt; /* EV: R-33326-45252 */} + break; + case 78: /* refact ::= CASCADE */ +{ yygotominor.yy328 = OE_Cascade; /* EV: R-33326-45252 */} + break; + case 79: /* refact ::= RESTRICT */ +{ yygotominor.yy328 = OE_Restrict; /* EV: R-33326-45252 */} + break; + case 80: /* refact ::= NO ACTION */ +{ yygotominor.yy328 = OE_None; /* EV: R-33326-45252 */} + break; + case 82: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + case 98: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==98); + case 100: /* onconf ::= ON CONFLICT resolvetype */ yytestcase(yyruleno==100); + case 103: /* resolvetype ::= raisetype */ yytestcase(yyruleno==103); +{yygotominor.yy328 = yymsp[0].minor.yy328;} + break; + case 86: /* conslist_opt ::= */ +{yygotominor.yy0.n = 0; yygotominor.yy0.z = 0;} + break; + case 87: /* conslist_opt ::= COMMA conslist */ +{yygotominor.yy0 = yymsp[-1].minor.yy0;} + break; + case 90: /* tconscomma ::= COMMA */ +{pParse->constraintName.n = 0;} + break; + case 93: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */ +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy14,yymsp[0].minor.yy328,yymsp[-2].minor.yy328,0);} + break; + case 94: /* tcons ::= UNIQUE LP idxlist RP onconf */ +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy14,yymsp[0].minor.yy328,0,0,0,0);} + break; + case 95: /* tcons ::= CHECK LP expr RP onconf */ +{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy346.pExpr);} + break; + case 96: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */ +{ + sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy14, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[-1].minor.yy328); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy328); +} + break; + case 99: /* onconf ::= */ +{yygotominor.yy328 = OE_Default;} + break; + case 101: /* orconf ::= */ +{yygotominor.yy186 = OE_Default;} + break; + case 102: /* orconf ::= OR resolvetype */ +{yygotominor.yy186 = (u8)yymsp[0].minor.yy328;} + break; + case 104: /* resolvetype ::= IGNORE */ +{yygotominor.yy328 = OE_Ignore;} + break; + case 105: /* resolvetype ::= REPLACE */ +{yygotominor.yy328 = OE_Replace;} + break; + case 106: /* cmd ::= DROP TABLE ifexists fullname */ +{ + sqlite3DropTable(pParse, yymsp[0].minor.yy65, 0, yymsp[-1].minor.yy328); +} + break; + case 109: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select */ +{ + sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy3, yymsp[-6].minor.yy328, yymsp[-4].minor.yy328); +} + break; + case 110: /* cmd ::= DROP VIEW ifexists fullname */ +{ + sqlite3DropTable(pParse, yymsp[0].minor.yy65, 1, yymsp[-1].minor.yy328); +} + break; + case 111: /* cmd ::= select */ +{ + SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0}; + sqlite3Select(pParse, yymsp[0].minor.yy3, &dest); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy3); +} + break; + case 112: /* select ::= with selectnowith */ +{ + Select *p = yymsp[0].minor.yy3; + if( p ){ + p->pWith = yymsp[-1].minor.yy59; + parserDoubleLinkSelect(pParse, p); + }else{ + sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy59); + } + yygotominor.yy3 = p; +} + break; + case 113: /* selectnowith ::= oneselect */ + case 119: /* oneselect ::= values */ yytestcase(yyruleno==119); +{yygotominor.yy3 = yymsp[0].minor.yy3;} + break; + case 114: /* selectnowith ::= selectnowith multiselect_op oneselect */ +{ + Select *pRhs = yymsp[0].minor.yy3; + if( pRhs && pRhs->pPrior ){ + SrcList *pFrom; + Token x; + x.n = 0; + parserDoubleLinkSelect(pParse, pRhs); + pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0); + pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0); + } + if( pRhs ){ + pRhs->op = (u8)yymsp[-1].minor.yy328; + pRhs->pPrior = yymsp[-2].minor.yy3; + pRhs->selFlags &= ~SF_MultiValue; + if( yymsp[-1].minor.yy328!=TK_ALL ) pParse->hasCompound = 1; + }else{ + sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy3); + } + yygotominor.yy3 = pRhs; +} + break; + case 116: /* multiselect_op ::= UNION ALL */ +{yygotominor.yy328 = TK_ALL;} + break; + case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ +{ + yygotominor.yy3 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy14,yymsp[-5].minor.yy65,yymsp[-4].minor.yy132,yymsp[-3].minor.yy14,yymsp[-2].minor.yy132,yymsp[-1].minor.yy14,yymsp[-7].minor.yy381,yymsp[0].minor.yy476.pLimit,yymsp[0].minor.yy476.pOffset); +#if SELECTTRACE_ENABLED + /* Populate the Select.zSelName[] string that is used to help with + ** query planner debugging, to differentiate between multiple Select + ** objects in a complex query. + ** + ** If the SELECT keyword is immediately followed by a C-style comment + ** then extract the first few alphanumeric characters from within that + ** comment to be the zSelName value. Otherwise, the label is #N where + ** is an integer that is incremented with each SELECT statement seen. + */ + if( yygotominor.yy3!=0 ){ + const char *z = yymsp[-8].minor.yy0.z+6; + int i; + sqlite3_snprintf(sizeof(yygotominor.yy3->zSelName), yygotominor.yy3->zSelName, "#%d", + ++pParse->nSelect); + while( z[0]==' ' ) z++; + if( z[0]=='/' && z[1]=='*' ){ + z += 2; + while( z[0]==' ' ) z++; + for(i=0; sqlite3Isalnum(z[i]); i++){} + sqlite3_snprintf(sizeof(yygotominor.yy3->zSelName), yygotominor.yy3->zSelName, "%.*s", i, z); + } + } +#endif /* SELECTRACE_ENABLED */ +} + break; + case 120: /* values ::= VALUES LP nexprlist RP */ +{ + yygotominor.yy3 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0,0); +} + break; + case 121: /* values ::= values COMMA LP exprlist RP */ +{ + Select *pRight, *pLeft = yymsp[-4].minor.yy3; + pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values|SF_MultiValue,0,0); + if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue; + if( pRight ){ + pRight->op = TK_ALL; + pLeft = yymsp[-4].minor.yy3; + pRight->pPrior = pLeft; + yygotominor.yy3 = pRight; + }else{ + yygotominor.yy3 = pLeft; + } +} + break; + case 122: /* distinct ::= DISTINCT */ +{yygotominor.yy381 = SF_Distinct;} + break; + case 123: /* distinct ::= ALL */ + case 124: /* distinct ::= */ yytestcase(yyruleno==124); +{yygotominor.yy381 = 0;} + break; + case 125: /* sclp ::= selcollist COMMA */ + case 243: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==243); +{yygotominor.yy14 = yymsp[-1].minor.yy14;} + break; + case 126: /* sclp ::= */ + case 154: /* orderby_opt ::= */ yytestcase(yyruleno==154); + case 161: /* groupby_opt ::= */ yytestcase(yyruleno==161); + case 236: /* exprlist ::= */ yytestcase(yyruleno==236); + case 242: /* idxlist_opt ::= */ yytestcase(yyruleno==242); +{yygotominor.yy14 = 0;} + break; + case 127: /* selcollist ::= sclp expr as */ +{ + yygotominor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy14, yymsp[-1].minor.yy346.pExpr); + if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[0].minor.yy0, 1); + sqlite3ExprListSetSpan(pParse,yygotominor.yy14,&yymsp[-1].minor.yy346); +} + break; + case 128: /* selcollist ::= sclp STAR */ +{ + Expr *p = sqlite3Expr(pParse->db, TK_ALL, 0); + yygotominor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy14, p); +} + break; + case 129: /* selcollist ::= sclp nm DOT STAR */ +{ + Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, &yymsp[0].minor.yy0); + Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0); + Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0); + yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14, pDot); +} + break; + case 132: /* as ::= */ +{yygotominor.yy0.n = 0;} + break; + case 133: /* from ::= */ +{yygotominor.yy65 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy65));} + break; + case 134: /* from ::= FROM seltablist */ +{ + yygotominor.yy65 = yymsp[0].minor.yy65; + sqlite3SrcListShiftJoinType(yygotominor.yy65); +} + break; + case 135: /* stl_prefix ::= seltablist joinop */ +{ + yygotominor.yy65 = yymsp[-1].minor.yy65; + if( ALWAYS(yygotominor.yy65 && yygotominor.yy65->nSrc>0) ) yygotominor.yy65->a[yygotominor.yy65->nSrc-1].jointype = (u8)yymsp[0].minor.yy328; +} + break; + case 136: /* stl_prefix ::= */ +{yygotominor.yy65 = 0;} + break; + case 137: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ +{ + yygotominor.yy65 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy132,yymsp[0].minor.yy408); + sqlite3SrcListIndexedBy(pParse, yygotominor.yy65, &yymsp[-2].minor.yy0); +} + break; + case 138: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */ +{ + yygotominor.yy65 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy3,yymsp[-1].minor.yy132,yymsp[0].minor.yy408); + } + break; + case 139: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ +{ + if( yymsp[-6].minor.yy65==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy132==0 && yymsp[0].minor.yy408==0 ){ + yygotominor.yy65 = yymsp[-4].minor.yy65; + }else if( yymsp[-4].minor.yy65->nSrc==1 ){ + yygotominor.yy65 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy132,yymsp[0].minor.yy408); + if( yygotominor.yy65 ){ + struct SrcList_item *pNew = &yygotominor.yy65->a[yygotominor.yy65->nSrc-1]; + struct SrcList_item *pOld = yymsp[-4].minor.yy65->a; + pNew->zName = pOld->zName; + pNew->zDatabase = pOld->zDatabase; + pNew->pSelect = pOld->pSelect; + pOld->zName = pOld->zDatabase = 0; + pOld->pSelect = 0; + } + sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy65); + }else{ + Select *pSubquery; + sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy65); + pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy65,0,0,0,0,SF_NestedFrom,0,0); + yygotominor.yy65 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy132,yymsp[0].minor.yy408); + } + } + break; + case 140: /* dbnm ::= */ + case 149: /* indexed_opt ::= */ yytestcase(yyruleno==149); +{yygotominor.yy0.z=0; yygotominor.yy0.n=0;} + break; + case 142: /* fullname ::= nm dbnm */ +{yygotominor.yy65 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);} + break; + case 143: /* joinop ::= COMMA|JOIN */ +{ yygotominor.yy328 = JT_INNER; } + break; + case 144: /* joinop ::= JOIN_KW JOIN */ +{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); } + break; + case 145: /* joinop ::= JOIN_KW nm JOIN */ +{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); } + break; + case 146: /* joinop ::= JOIN_KW nm nm JOIN */ +{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); } + break; + case 147: /* on_opt ::= ON expr */ + case 164: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==164); + case 171: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==171); + case 231: /* case_else ::= ELSE expr */ yytestcase(yyruleno==231); + case 233: /* case_operand ::= expr */ yytestcase(yyruleno==233); +{yygotominor.yy132 = yymsp[0].minor.yy346.pExpr;} + break; + case 148: /* on_opt ::= */ + case 163: /* having_opt ::= */ yytestcase(yyruleno==163); + case 170: /* where_opt ::= */ yytestcase(yyruleno==170); + case 232: /* case_else ::= */ yytestcase(yyruleno==232); + case 234: /* case_operand ::= */ yytestcase(yyruleno==234); +{yygotominor.yy132 = 0;} + break; + case 151: /* indexed_opt ::= NOT INDEXED */ +{yygotominor.yy0.z=0; yygotominor.yy0.n=1;} + break; + case 152: /* using_opt ::= USING LP idlist RP */ + case 180: /* inscollist_opt ::= LP idlist RP */ yytestcase(yyruleno==180); +{yygotominor.yy408 = yymsp[-1].minor.yy408;} + break; + case 153: /* using_opt ::= */ + case 179: /* inscollist_opt ::= */ yytestcase(yyruleno==179); +{yygotominor.yy408 = 0;} + break; + case 155: /* orderby_opt ::= ORDER BY sortlist */ + case 162: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==162); + case 235: /* exprlist ::= nexprlist */ yytestcase(yyruleno==235); +{yygotominor.yy14 = yymsp[0].minor.yy14;} + break; + case 156: /* sortlist ::= sortlist COMMA expr sortorder */ +{ + yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14,yymsp[-1].minor.yy346.pExpr); + if( yygotominor.yy14 ) yygotominor.yy14->a[yygotominor.yy14->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy328; +} + break; + case 157: /* sortlist ::= expr sortorder */ +{ + yygotominor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy346.pExpr); + if( yygotominor.yy14 && ALWAYS(yygotominor.yy14->a) ) yygotominor.yy14->a[0].sortOrder = (u8)yymsp[0].minor.yy328; +} + break; + case 158: /* sortorder ::= ASC */ + case 160: /* sortorder ::= */ yytestcase(yyruleno==160); +{yygotominor.yy328 = SQLITE_SO_ASC;} + break; + case 159: /* sortorder ::= DESC */ +{yygotominor.yy328 = SQLITE_SO_DESC;} + break; + case 165: /* limit_opt ::= */ +{yygotominor.yy476.pLimit = 0; yygotominor.yy476.pOffset = 0;} + break; + case 166: /* limit_opt ::= LIMIT expr */ +{yygotominor.yy476.pLimit = yymsp[0].minor.yy346.pExpr; yygotominor.yy476.pOffset = 0;} + break; + case 167: /* limit_opt ::= LIMIT expr OFFSET expr */ +{yygotominor.yy476.pLimit = yymsp[-2].minor.yy346.pExpr; yygotominor.yy476.pOffset = yymsp[0].minor.yy346.pExpr;} + break; + case 168: /* limit_opt ::= LIMIT expr COMMA expr */ +{yygotominor.yy476.pOffset = yymsp[-2].minor.yy346.pExpr; yygotominor.yy476.pLimit = yymsp[0].minor.yy346.pExpr;} + break; + case 169: /* cmd ::= with DELETE FROM fullname indexed_opt where_opt */ +{ + sqlite3WithPush(pParse, yymsp[-5].minor.yy59, 1); + sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy65, &yymsp[-1].minor.yy0); + sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy65,yymsp[0].minor.yy132); +} + break; + case 172: /* cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt */ +{ + sqlite3WithPush(pParse, yymsp[-7].minor.yy59, 1); + sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy65, &yymsp[-3].minor.yy0); + sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy14,"set list"); + sqlite3Update(pParse,yymsp[-4].minor.yy65,yymsp[-1].minor.yy14,yymsp[0].minor.yy132,yymsp[-5].minor.yy186); +} + break; + case 173: /* setlist ::= setlist COMMA nm EQ expr */ +{ + yygotominor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[0].minor.yy346.pExpr); + sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1); +} + break; + case 174: /* setlist ::= nm EQ expr */ +{ + yygotominor.yy14 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy346.pExpr); + sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1); +} + break; + case 175: /* cmd ::= with insert_cmd INTO fullname inscollist_opt select */ +{ + sqlite3WithPush(pParse, yymsp[-5].minor.yy59, 1); + sqlite3Insert(pParse, yymsp[-2].minor.yy65, yymsp[0].minor.yy3, yymsp[-1].minor.yy408, yymsp[-4].minor.yy186); +} + break; + case 176: /* cmd ::= with insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */ +{ + sqlite3WithPush(pParse, yymsp[-6].minor.yy59, 1); + sqlite3Insert(pParse, yymsp[-3].minor.yy65, 0, yymsp[-2].minor.yy408, yymsp[-5].minor.yy186); +} + break; + case 177: /* insert_cmd ::= INSERT orconf */ +{yygotominor.yy186 = yymsp[0].minor.yy186;} + break; + case 178: /* insert_cmd ::= REPLACE */ +{yygotominor.yy186 = OE_Replace;} + break; + case 181: /* idlist ::= idlist COMMA nm */ +{yygotominor.yy408 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy408,&yymsp[0].minor.yy0);} + break; + case 182: /* idlist ::= nm */ +{yygotominor.yy408 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);} + break; + case 183: /* expr ::= term */ +{yygotominor.yy346 = yymsp[0].minor.yy346;} + break; + case 184: /* expr ::= LP expr RP */ +{yygotominor.yy346.pExpr = yymsp[-1].minor.yy346.pExpr; spanSet(&yygotominor.yy346,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);} + break; + case 185: /* term ::= NULL */ + case 190: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==190); + case 191: /* term ::= STRING */ yytestcase(yyruleno==191); +{spanExpr(&yygotominor.yy346, pParse, yymsp[0].major, &yymsp[0].minor.yy0);} + break; + case 186: /* expr ::= ID|INDEXED */ + case 187: /* expr ::= JOIN_KW */ yytestcase(yyruleno==187); +{spanExpr(&yygotominor.yy346, pParse, TK_ID, &yymsp[0].minor.yy0);} + break; + case 188: /* expr ::= nm DOT nm */ +{ + Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0); + Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0); + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0); + spanSet(&yygotominor.yy346,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); +} + break; + case 189: /* expr ::= nm DOT nm DOT nm */ +{ + Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-4].minor.yy0); + Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0); + Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0); + Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0); + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0); + spanSet(&yygotominor.yy346,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); +} + break; + case 192: /* expr ::= VARIABLE */ +{ + if( yymsp[0].minor.yy0.n>=2 && yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1]) ){ + /* When doing a nested parse, one can include terms in an expression + ** that look like this: #1 #2 ... These terms refer to registers + ** in the virtual machine. #N is the N-th register. */ + if( pParse->nested==0 ){ + sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &yymsp[0].minor.yy0); + yygotominor.yy346.pExpr = 0; + }else{ + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0); + if( yygotominor.yy346.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy346.pExpr->iTable); + } + }else{ + spanExpr(&yygotominor.yy346, pParse, TK_VARIABLE, &yymsp[0].minor.yy0); + sqlite3ExprAssignVarNumber(pParse, yygotominor.yy346.pExpr); + } + spanSet(&yygotominor.yy346, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); +} + break; + case 193: /* expr ::= expr COLLATE ID|STRING */ +{ + yygotominor.yy346.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy346.pExpr, &yymsp[0].minor.yy0, 1); + yygotominor.yy346.zStart = yymsp[-2].minor.yy346.zStart; + yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; +} + break; + case 194: /* expr ::= CAST LP expr AS typetoken RP */ +{ + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy346.pExpr, 0, &yymsp[-1].minor.yy0); + spanSet(&yygotominor.yy346,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); +} + break; + case 195: /* expr ::= ID|INDEXED LP distinct exprlist RP */ +{ + if( yymsp[-1].minor.yy14 && yymsp[-1].minor.yy14->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){ + sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0); + } + yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0); + spanSet(&yygotominor.yy346,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); + if( yymsp[-2].minor.yy381 && yygotominor.yy346.pExpr ){ + yygotominor.yy346.pExpr->flags |= EP_Distinct; + } +} + break; + case 196: /* expr ::= ID|INDEXED LP STAR RP */ +{ + yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0); + spanSet(&yygotominor.yy346,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); +} + break; + case 197: /* term ::= CTIME_KW */ +{ + yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0); + spanSet(&yygotominor.yy346, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); +} + break; + case 198: /* expr ::= expr AND expr */ + case 199: /* expr ::= expr OR expr */ yytestcase(yyruleno==199); + case 200: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==200); + case 201: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==201); + case 202: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==202); + case 203: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==203); + case 204: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==204); + case 205: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==205); +{spanBinaryExpr(&yygotominor.yy346,pParse,yymsp[-1].major,&yymsp[-2].minor.yy346,&yymsp[0].minor.yy346);} + break; + case 206: /* likeop ::= LIKE_KW|MATCH */ +{yygotominor.yy96.eOperator = yymsp[0].minor.yy0; yygotominor.yy96.bNot = 0;} + break; + case 207: /* likeop ::= NOT LIKE_KW|MATCH */ +{yygotominor.yy96.eOperator = yymsp[0].minor.yy0; yygotominor.yy96.bNot = 1;} + break; + case 208: /* expr ::= expr likeop expr */ +{ + ExprList *pList; + pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy346.pExpr); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy346.pExpr); + yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy96.eOperator); + if( yymsp[-1].minor.yy96.bNot ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0); + yygotominor.yy346.zStart = yymsp[-2].minor.yy346.zStart; + yygotominor.yy346.zEnd = yymsp[0].minor.yy346.zEnd; + if( yygotominor.yy346.pExpr ) yygotominor.yy346.pExpr->flags |= EP_InfixFunc; +} + break; + case 209: /* expr ::= expr likeop expr ESCAPE expr */ +{ + ExprList *pList; + pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy346.pExpr); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy346.pExpr); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy346.pExpr); + yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy96.eOperator); + if( yymsp[-3].minor.yy96.bNot ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0); + yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart; + yygotominor.yy346.zEnd = yymsp[0].minor.yy346.zEnd; + if( yygotominor.yy346.pExpr ) yygotominor.yy346.pExpr->flags |= EP_InfixFunc; +} + break; + case 210: /* expr ::= expr ISNULL|NOTNULL */ +{spanUnaryPostfix(&yygotominor.yy346,pParse,yymsp[0].major,&yymsp[-1].minor.yy346,&yymsp[0].minor.yy0);} + break; + case 211: /* expr ::= expr NOT NULL */ +{spanUnaryPostfix(&yygotominor.yy346,pParse,TK_NOTNULL,&yymsp[-2].minor.yy346,&yymsp[0].minor.yy0);} + break; + case 212: /* expr ::= expr IS expr */ +{ + spanBinaryExpr(&yygotominor.yy346,pParse,TK_IS,&yymsp[-2].minor.yy346,&yymsp[0].minor.yy346); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy346.pExpr, yygotominor.yy346.pExpr, TK_ISNULL); +} + break; + case 213: /* expr ::= expr IS NOT expr */ +{ + spanBinaryExpr(&yygotominor.yy346,pParse,TK_ISNOT,&yymsp[-3].minor.yy346,&yymsp[0].minor.yy346); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy346.pExpr, yygotominor.yy346.pExpr, TK_NOTNULL); +} + break; + case 214: /* expr ::= NOT expr */ + case 215: /* expr ::= BITNOT expr */ yytestcase(yyruleno==215); +{spanUnaryPrefix(&yygotominor.yy346,pParse,yymsp[-1].major,&yymsp[0].minor.yy346,&yymsp[-1].minor.yy0);} + break; + case 216: /* expr ::= MINUS expr */ +{spanUnaryPrefix(&yygotominor.yy346,pParse,TK_UMINUS,&yymsp[0].minor.yy346,&yymsp[-1].minor.yy0);} + break; + case 217: /* expr ::= PLUS expr */ +{spanUnaryPrefix(&yygotominor.yy346,pParse,TK_UPLUS,&yymsp[0].minor.yy346,&yymsp[-1].minor.yy0);} + break; + case 220: /* expr ::= expr between_op expr AND expr */ +{ + ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy346.pExpr); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy346.pExpr); + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy346.pExpr, 0, 0); + if( yygotominor.yy346.pExpr ){ + yygotominor.yy346.pExpr->x.pList = pList; + }else{ + sqlite3ExprListDelete(pParse->db, pList); + } + if( yymsp[-3].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0); + yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart; + yygotominor.yy346.zEnd = yymsp[0].minor.yy346.zEnd; +} + break; + case 223: /* expr ::= expr in_op LP exprlist RP */ +{ + if( yymsp[-1].minor.yy14==0 ){ + /* Expressions of the form + ** + ** expr1 IN () + ** expr1 NOT IN () + ** + ** simplify to constants 0 (false) and 1 (true), respectively, + ** regardless of the value of expr1. + */ + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[yymsp[-3].minor.yy328]); + sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy346.pExpr); + }else if( yymsp[-1].minor.yy14->nExpr==1 ){ + /* Expressions of the form: + ** + ** expr1 IN (?1) + ** expr1 NOT IN (?2) + ** + ** with exactly one value on the RHS can be simplified to something + ** like this: + ** + ** expr1 == ?1 + ** expr1 <> ?2 + ** + ** But, the RHS of the == or <> is marked with the EP_Generic flag + ** so that it may not contribute to the computation of comparison + ** affinity or the collating sequence to use for comparison. Otherwise, + ** the semantics would be subtly different from IN or NOT IN. + */ + Expr *pRHS = yymsp[-1].minor.yy14->a[0].pExpr; + yymsp[-1].minor.yy14->a[0].pExpr = 0; + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14); + /* pRHS cannot be NULL because a malloc error would have been detected + ** before now and control would have never reached this point */ + if( ALWAYS(pRHS) ){ + pRHS->flags &= ~EP_Collate; + pRHS->flags |= EP_Generic; + } + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, yymsp[-3].minor.yy328 ? TK_NE : TK_EQ, yymsp[-4].minor.yy346.pExpr, pRHS, 0); + }else{ + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy346.pExpr, 0, 0); + if( yygotominor.yy346.pExpr ){ + yygotominor.yy346.pExpr->x.pList = yymsp[-1].minor.yy14; + sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr); + }else{ + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14); + } + if( yymsp[-3].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0); + } + yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart; + yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + } + break; + case 224: /* expr ::= LP select RP */ +{ + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0); + if( yygotominor.yy346.pExpr ){ + yygotominor.yy346.pExpr->x.pSelect = yymsp[-1].minor.yy3; + ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect|EP_Subquery); + sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr); + }else{ + sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3); + } + yygotominor.yy346.zStart = yymsp[-2].minor.yy0.z; + yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + } + break; + case 225: /* expr ::= expr in_op LP select RP */ +{ + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy346.pExpr, 0, 0); + if( yygotominor.yy346.pExpr ){ + yygotominor.yy346.pExpr->x.pSelect = yymsp[-1].minor.yy3; + ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect|EP_Subquery); + sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr); + }else{ + sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3); + } + if( yymsp[-3].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0); + yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart; + yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + } + break; + case 226: /* expr ::= expr in_op nm dbnm */ +{ + SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy346.pExpr, 0, 0); + if( yygotominor.yy346.pExpr ){ + yygotominor.yy346.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); + ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect|EP_Subquery); + sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr); + }else{ + sqlite3SrcListDelete(pParse->db, pSrc); + } + if( yymsp[-2].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0); + yygotominor.yy346.zStart = yymsp[-3].minor.yy346.zStart; + yygotominor.yy346.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]; + } + break; + case 227: /* expr ::= EXISTS LP select RP */ +{ + Expr *p = yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0); + if( p ){ + p->x.pSelect = yymsp[-1].minor.yy3; + ExprSetProperty(p, EP_xIsSelect|EP_Subquery); + sqlite3ExprSetHeightAndFlags(pParse, p); + }else{ + sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3); + } + yygotominor.yy346.zStart = yymsp[-3].minor.yy0.z; + yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + } + break; + case 228: /* expr ::= CASE case_operand case_exprlist case_else END */ +{ + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy132, 0, 0); + if( yygotominor.yy346.pExpr ){ + yygotominor.yy346.pExpr->x.pList = yymsp[-1].minor.yy132 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[-1].minor.yy132) : yymsp[-2].minor.yy14; + sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr); + }else{ + sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy14); + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy132); + } + yygotominor.yy346.zStart = yymsp[-4].minor.yy0.z; + yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; +} + break; + case 229: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ +{ + yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[-2].minor.yy346.pExpr); + yygotominor.yy14 = sqlite3ExprListAppend(pParse,yygotominor.yy14, yymsp[0].minor.yy346.pExpr); +} + break; + case 230: /* case_exprlist ::= WHEN expr THEN expr */ +{ + yygotominor.yy14 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy346.pExpr); + yygotominor.yy14 = sqlite3ExprListAppend(pParse,yygotominor.yy14, yymsp[0].minor.yy346.pExpr); +} + break; + case 237: /* nexprlist ::= nexprlist COMMA expr */ +{yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[0].minor.yy346.pExpr);} + break; + case 238: /* nexprlist ::= expr */ +{yygotominor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy346.pExpr);} + break; + case 239: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt */ +{ + sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, + sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy14, yymsp[-10].minor.yy328, + &yymsp[-11].minor.yy0, yymsp[0].minor.yy132, SQLITE_SO_ASC, yymsp[-8].minor.yy328); +} + break; + case 240: /* uniqueflag ::= UNIQUE */ + case 291: /* raisetype ::= ABORT */ yytestcase(yyruleno==291); +{yygotominor.yy328 = OE_Abort;} + break; + case 241: /* uniqueflag ::= */ +{yygotominor.yy328 = OE_None;} + break; + case 244: /* idxlist ::= idxlist COMMA nm collate sortorder */ +{ + Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0, 1); + yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, p); + sqlite3ExprListSetName(pParse,yygotominor.yy14,&yymsp[-2].minor.yy0,1); + sqlite3ExprListCheckLength(pParse, yygotominor.yy14, "index"); + if( yygotominor.yy14 ) yygotominor.yy14->a[yygotominor.yy14->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy328; +} + break; + case 245: /* idxlist ::= nm collate sortorder */ +{ + Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0, 1); + yygotominor.yy14 = sqlite3ExprListAppend(pParse,0, p); + sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1); + sqlite3ExprListCheckLength(pParse, yygotominor.yy14, "index"); + if( yygotominor.yy14 ) yygotominor.yy14->a[yygotominor.yy14->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy328; +} + break; + case 246: /* collate ::= */ +{yygotominor.yy0.z = 0; yygotominor.yy0.n = 0;} + break; + case 248: /* cmd ::= DROP INDEX ifexists fullname */ +{sqlite3DropIndex(pParse, yymsp[0].minor.yy65, yymsp[-1].minor.yy328);} + break; + case 249: /* cmd ::= VACUUM */ + case 250: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==250); +{sqlite3Vacuum(pParse);} + break; + case 251: /* cmd ::= PRAGMA nm dbnm */ +{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} + break; + case 252: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ +{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} + break; + case 253: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ +{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} + break; + case 254: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ +{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} + break; + case 255: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ +{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} + break; + case 264: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ +{ + Token all; + all.z = yymsp[-3].minor.yy0.z; + all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n; + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy473, &all); +} + break; + case 265: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ +{ + sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy328, yymsp[-4].minor.yy378.a, yymsp[-4].minor.yy378.b, yymsp[-2].minor.yy65, yymsp[0].minor.yy132, yymsp[-10].minor.yy328, yymsp[-8].minor.yy328); + yygotominor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); +} + break; + case 266: /* trigger_time ::= BEFORE */ + case 269: /* trigger_time ::= */ yytestcase(yyruleno==269); +{ yygotominor.yy328 = TK_BEFORE; } + break; + case 267: /* trigger_time ::= AFTER */ +{ yygotominor.yy328 = TK_AFTER; } + break; + case 268: /* trigger_time ::= INSTEAD OF */ +{ yygotominor.yy328 = TK_INSTEAD;} + break; + case 270: /* trigger_event ::= DELETE|INSERT */ + case 271: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==271); +{yygotominor.yy378.a = yymsp[0].major; yygotominor.yy378.b = 0;} + break; + case 272: /* trigger_event ::= UPDATE OF idlist */ +{yygotominor.yy378.a = TK_UPDATE; yygotominor.yy378.b = yymsp[0].minor.yy408;} + break; + case 275: /* when_clause ::= */ + case 296: /* key_opt ::= */ yytestcase(yyruleno==296); +{ yygotominor.yy132 = 0; } + break; + case 276: /* when_clause ::= WHEN expr */ + case 297: /* key_opt ::= KEY expr */ yytestcase(yyruleno==297); +{ yygotominor.yy132 = yymsp[0].minor.yy346.pExpr; } + break; + case 277: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ +{ + assert( yymsp[-2].minor.yy473!=0 ); + yymsp[-2].minor.yy473->pLast->pNext = yymsp[-1].minor.yy473; + yymsp[-2].minor.yy473->pLast = yymsp[-1].minor.yy473; + yygotominor.yy473 = yymsp[-2].minor.yy473; +} + break; + case 278: /* trigger_cmd_list ::= trigger_cmd SEMI */ +{ + assert( yymsp[-1].minor.yy473!=0 ); + yymsp[-1].minor.yy473->pLast = yymsp[-1].minor.yy473; + yygotominor.yy473 = yymsp[-1].minor.yy473; +} + break; + case 280: /* trnm ::= nm DOT nm */ +{ + yygotominor.yy0 = yymsp[0].minor.yy0; + sqlite3ErrorMsg(pParse, + "qualified table names are not allowed on INSERT, UPDATE, and DELETE " + "statements within triggers"); +} + break; + case 282: /* tridxby ::= INDEXED BY nm */ +{ + sqlite3ErrorMsg(pParse, + "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " + "within triggers"); +} + break; + case 283: /* tridxby ::= NOT INDEXED */ +{ + sqlite3ErrorMsg(pParse, + "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " + "within triggers"); +} + break; + case 284: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */ +{ yygotominor.yy473 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy14, yymsp[0].minor.yy132, yymsp[-5].minor.yy186); } + break; + case 285: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select */ +{yygotominor.yy473 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy408, yymsp[0].minor.yy3, yymsp[-4].minor.yy186);} + break; + case 286: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */ +{yygotominor.yy473 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy132);} + break; + case 287: /* trigger_cmd ::= select */ +{yygotominor.yy473 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy3); } + break; + case 288: /* expr ::= RAISE LP IGNORE RP */ +{ + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0); + if( yygotominor.yy346.pExpr ){ + yygotominor.yy346.pExpr->affinity = OE_Ignore; + } + yygotominor.yy346.zStart = yymsp[-3].minor.yy0.z; + yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; +} + break; + case 289: /* expr ::= RAISE LP raisetype COMMA nm RP */ +{ + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0); + if( yygotominor.yy346.pExpr ) { + yygotominor.yy346.pExpr->affinity = (char)yymsp[-3].minor.yy328; + } + yygotominor.yy346.zStart = yymsp[-5].minor.yy0.z; + yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; +} + break; + case 290: /* raisetype ::= ROLLBACK */ +{yygotominor.yy328 = OE_Rollback;} + break; + case 292: /* raisetype ::= FAIL */ +{yygotominor.yy328 = OE_Fail;} + break; + case 293: /* cmd ::= DROP TRIGGER ifexists fullname */ +{ + sqlite3DropTrigger(pParse,yymsp[0].minor.yy65,yymsp[-1].minor.yy328); +} + break; + case 294: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ +{ + sqlite3Attach(pParse, yymsp[-3].minor.yy346.pExpr, yymsp[-1].minor.yy346.pExpr, yymsp[0].minor.yy132); +} + break; + case 295: /* cmd ::= DETACH database_kw_opt expr */ +{ + sqlite3Detach(pParse, yymsp[0].minor.yy346.pExpr); +} + break; + case 300: /* cmd ::= REINDEX */ +{sqlite3Reindex(pParse, 0, 0);} + break; + case 301: /* cmd ::= REINDEX nm dbnm */ +{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} + break; + case 302: /* cmd ::= ANALYZE */ +{sqlite3Analyze(pParse, 0, 0);} + break; + case 303: /* cmd ::= ANALYZE nm dbnm */ +{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} + break; + case 304: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ +{ + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy65,&yymsp[0].minor.yy0); +} + break; + case 305: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */ +{ + sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0); +} + break; + case 306: /* add_column_fullname ::= fullname */ +{ + pParse->db->lookaside.bEnabled = 0; + sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy65); +} + break; + case 309: /* cmd ::= create_vtab */ +{sqlite3VtabFinishParse(pParse,0);} + break; + case 310: /* cmd ::= create_vtab LP vtabarglist RP */ +{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} + break; + case 311: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ +{ + sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy328); +} + break; + case 314: /* vtabarg ::= */ +{sqlite3VtabArgInit(pParse);} + break; + case 316: /* vtabargtoken ::= ANY */ + case 317: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==317); + case 318: /* lp ::= LP */ yytestcase(yyruleno==318); +{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} + break; + case 322: /* with ::= */ +{yygotominor.yy59 = 0;} + break; + case 323: /* with ::= WITH wqlist */ + case 324: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==324); +{ yygotominor.yy59 = yymsp[0].minor.yy59; } + break; + case 325: /* wqlist ::= nm idxlist_opt AS LP select RP */ +{ + yygotominor.yy59 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy14, yymsp[-1].minor.yy3); +} + break; + case 326: /* wqlist ::= wqlist COMMA nm idxlist_opt AS LP select RP */ +{ + yygotominor.yy59 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy59, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy14, yymsp[-1].minor.yy3); +} + break; + default: + /* (0) input ::= cmdlist */ yytestcase(yyruleno==0); + /* (1) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==1); + /* (2) cmdlist ::= ecmd */ yytestcase(yyruleno==2); + /* (3) ecmd ::= SEMI */ yytestcase(yyruleno==3); + /* (4) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==4); + /* (10) trans_opt ::= */ yytestcase(yyruleno==10); + /* (11) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==11); + /* (12) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==12); + /* (20) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==20); + /* (21) savepoint_opt ::= */ yytestcase(yyruleno==21); + /* (25) cmd ::= create_table create_table_args */ yytestcase(yyruleno==25); + /* (36) columnlist ::= columnlist COMMA column */ yytestcase(yyruleno==36); + /* (37) columnlist ::= column */ yytestcase(yyruleno==37); + /* (43) type ::= */ yytestcase(yyruleno==43); + /* (50) signed ::= plus_num */ yytestcase(yyruleno==50); + /* (51) signed ::= minus_num */ yytestcase(yyruleno==51); + /* (52) carglist ::= carglist ccons */ yytestcase(yyruleno==52); + /* (53) carglist ::= */ yytestcase(yyruleno==53); + /* (60) ccons ::= NULL onconf */ yytestcase(yyruleno==60); + /* (88) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==88); + /* (89) conslist ::= tcons */ yytestcase(yyruleno==89); + /* (91) tconscomma ::= */ yytestcase(yyruleno==91); + /* (273) foreach_clause ::= */ yytestcase(yyruleno==273); + /* (274) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==274); + /* (281) tridxby ::= */ yytestcase(yyruleno==281); + /* (298) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==298); + /* (299) database_kw_opt ::= */ yytestcase(yyruleno==299); + /* (307) kwcolumn_opt ::= */ yytestcase(yyruleno==307); + /* (308) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==308); + /* (312) vtabarglist ::= vtabarg */ yytestcase(yyruleno==312); + /* (313) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==313); + /* (315) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==315); + /* (319) anylist ::= */ yytestcase(yyruleno==319); + /* (320) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==320); + /* (321) anylist ::= anylist ANY */ yytestcase(yyruleno==321); + break; + }; + assert( yyruleno>=0 && yyrulenoyyidx -= yysize; + yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto); + if( yyact < YYNSTATE ){ +#ifdef NDEBUG + /* If we are not debugging and the reduce action popped at least + ** one element off the stack, then we can push the new element back + ** onto the stack here, and skip the stack overflow test in yy_shift(). + ** That gives a significant speed improvement. */ + if( yysize ){ + yypParser->yyidx++; + yymsp -= yysize-1; + yymsp->stateno = (YYACTIONTYPE)yyact; + yymsp->major = (YYCODETYPE)yygoto; + yymsp->minor = yygotominor; + }else +#endif + { + yy_shift(yypParser,yyact,yygoto,&yygotominor); + } + }else{ + assert( yyact == YYNSTATE + YYNRULE + 1 ); + yy_accept(yypParser); + } +} + +/* +** The following code executes when the parse fails +*/ +#ifndef YYNOERRORRECOVERY +static void yy_parse_failed( + yyParser *yypParser /* The parser */ +){ + sqlite3ParserARG_FETCH; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); + } +#endif + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will be executed whenever the + ** parser fails */ + sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ +} +#endif /* YYNOERRORRECOVERY */ + +/* +** The following code executes when a syntax error first occurs. +*/ +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) + + UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */ + assert( TOKEN.z[0] ); /* The tokenizer always gives us a token */ + sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); + sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ +} + +/* +** The following is executed when the parser accepts +*/ +static void yy_accept( + yyParser *yypParser /* The parser */ +){ + sqlite3ParserARG_FETCH; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); + } +#endif + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will be executed whenever the + ** parser accepts */ + sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ +} + +/* The main parser program. +** The first argument is a pointer to a structure obtained from +** "sqlite3ParserAlloc" which describes the current state of the parser. +** The second argument is the major token number. The third is +** the minor token. The fourth optional argument is whatever the +** user wants (and specified in the grammar) and is available for +** use by the action routines. +** +** Inputs: +**
      +**
    • A pointer to the parser (an opaque structure.) +**
    • The major token number. +**
    • The minor token number. +**
    • An option argument of a grammar-specified type. +**
    +** +** Outputs: +** None. +*/ +SQLITE_PRIVATE void sqlite3Parser( + void *yyp, /* The parser */ + int yymajor, /* The major token code number */ + sqlite3ParserTOKENTYPE yyminor /* The value for the token */ + sqlite3ParserARG_PDECL /* Optional %extra_argument parameter */ +){ + YYMINORTYPE yyminorunion; + int yyact; /* The parser action. */ +#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) + int yyendofinput; /* True if we are at the end of input */ +#endif +#ifdef YYERRORSYMBOL + int yyerrorhit = 0; /* True if yymajor has invoked an error */ +#endif + yyParser *yypParser; /* The parser */ + + /* (re)initialize the parser, if necessary */ + yypParser = (yyParser*)yyp; + if( yypParser->yyidx<0 ){ +#if YYSTACKDEPTH<=0 + if( yypParser->yystksz <=0 ){ + /*memset(&yyminorunion, 0, sizeof(yyminorunion));*/ + yyminorunion = yyzerominor; + yyStackOverflow(yypParser, &yyminorunion); + return; + } +#endif + yypParser->yyidx = 0; + yypParser->yyerrcnt = -1; + yypParser->yystack[0].stateno = 0; + yypParser->yystack[0].major = 0; + } + yyminorunion.yy0 = yyminor; +#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) + yyendofinput = (yymajor==0); +#endif + sqlite3ParserARG_STORE; + +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]); + } +#endif + + do{ + yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor); + if( yyactyyerrcnt--; + yymajor = YYNOCODE; + }else if( yyact < YYNSTATE + YYNRULE ){ + yy_reduce(yypParser,yyact-YYNSTATE); + }else{ + assert( yyact == YY_ERROR_ACTION ); +#ifdef YYERRORSYMBOL + int yymx; +#endif +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); + } +#endif +#ifdef YYERRORSYMBOL + /* A syntax error has occurred. + ** The response to an error depends upon whether or not the + ** grammar defines an error token "ERROR". + ** + ** This is what we do if the grammar does define ERROR: + ** + ** * Call the %syntax_error function. + ** + ** * Begin popping the stack until we enter a state where + ** it is legal to shift the error symbol, then shift + ** the error symbol. + ** + ** * Set the error count to three. + ** + ** * Begin accepting and shifting new tokens. No new error + ** processing will occur until three tokens have been + ** shifted successfully. + ** + */ + if( yypParser->yyerrcnt<0 ){ + yy_syntax_error(yypParser,yymajor,yyminorunion); + } + yymx = yypParser->yystack[yypParser->yyidx].major; + if( yymx==YYERRORSYMBOL || yyerrorhit ){ +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sDiscard input token %s\n", + yyTracePrompt,yyTokenName[yymajor]); + } +#endif + yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion); + yymajor = YYNOCODE; + }else{ + while( + yypParser->yyidx >= 0 && + yymx != YYERRORSYMBOL && + (yyact = yy_find_reduce_action( + yypParser->yystack[yypParser->yyidx].stateno, + YYERRORSYMBOL)) >= YYNSTATE + ){ + yy_pop_parser_stack(yypParser); + } + if( yypParser->yyidx < 0 || yymajor==0 ){ + yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); + yy_parse_failed(yypParser); + yymajor = YYNOCODE; + }else if( yymx!=YYERRORSYMBOL ){ + YYMINORTYPE u2; + u2.YYERRSYMDT = 0; + yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2); + } + } + yypParser->yyerrcnt = 3; + yyerrorhit = 1; +#elif defined(YYNOERRORRECOVERY) + /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to + ** do any kind of error recovery. Instead, simply invoke the syntax + ** error routine and continue going as if nothing had happened. + ** + ** Applications can set this macro (for example inside %include) if + ** they intend to abandon the parse upon the first syntax error seen. + */ + yy_syntax_error(yypParser,yymajor,yyminorunion); + yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); + yymajor = YYNOCODE; + +#else /* YYERRORSYMBOL is not defined */ + /* This is what we do if the grammar does not define ERROR: + ** + ** * Report an error message, and throw away the input token. + ** + ** * If the input token is $, then fail the parse. + ** + ** As before, subsequent error messages are suppressed until + ** three input tokens have been successfully shifted. + */ + if( yypParser->yyerrcnt<=0 ){ + yy_syntax_error(yypParser,yymajor,yyminorunion); + } + yypParser->yyerrcnt = 3; + yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); + if( yyendofinput ){ + yy_parse_failed(yypParser); + } + yymajor = YYNOCODE; +#endif + } + }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); + return; +} + +/************** End of parse.c ***********************************************/ +/************** Begin file tokenize.c ****************************************/ +/* +** 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 splits an SQL input string up into +** individual tokens and sends those tokens one-by-one over to the +** parser for analysis. +*/ +/* #include */ + +/* +** The charMap() macro maps alphabetic characters into their +** lower-case ASCII equivalent. On ASCII machines, this is just +** an upper-to-lower case map. On EBCDIC machines we also need +** to adjust the encoding. Only alphabetic characters and underscores +** need to be translated. +*/ +#ifdef SQLITE_ASCII +# define charMap(X) sqlite3UpperToLower[(unsigned char)X] +#endif +#ifdef SQLITE_EBCDIC +# define charMap(X) ebcdicToAscii[(unsigned char)X] +const unsigned char ebcdicToAscii[] = { +/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, /* 6x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7x */ + 0, 97, 98, 99,100,101,102,103,104,105, 0, 0, 0, 0, 0, 0, /* 8x */ + 0,106,107,108,109,110,111,112,113,114, 0, 0, 0, 0, 0, 0, /* 9x */ + 0, 0,115,116,117,118,119,120,121,122, 0, 0, 0, 0, 0, 0, /* Ax */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Bx */ + 0, 97, 98, 99,100,101,102,103,104,105, 0, 0, 0, 0, 0, 0, /* Cx */ + 0,106,107,108,109,110,111,112,113,114, 0, 0, 0, 0, 0, 0, /* Dx */ + 0, 0,115,116,117,118,119,120,121,122, 0, 0, 0, 0, 0, 0, /* Ex */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Fx */ +}; +#endif + +/* +** The sqlite3KeywordCode function looks up an identifier to determine if +** it is a keyword. If it is a keyword, the token code of that keyword is +** returned. If the input is not a keyword, TK_ID is returned. +** +** The implementation of this routine was generated by a program, +** mkkeywordhash.h, located in the tool subdirectory of the distribution. +** The output of the mkkeywordhash.c program is written into a file +** named keywordhash.h and then included into this source file by +** the #include below. +*/ +/************** Include keywordhash.h in the middle of tokenize.c ************/ +/************** Begin file keywordhash.h *************************************/ +/***** This file contains automatically generated code ****** +** +** The code in this file has been automatically generated by +** +** sqlite/tool/mkkeywordhash.c +** +** The code in this file implements a function that determines whether +** or not a given identifier is really an SQL keyword. The same thing +** might be implemented more directly using a hand-written hash table. +** But by using this automatically generated code, the size of the code +** is substantially reduced. This is important for embedded applications +** on platforms with limited memory. +*/ +/* Hash score: 182 */ +static int keywordCode(const char *z, int n){ + /* zText[] encodes 834 bytes of keywords in 554 bytes */ + /* REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT */ + /* ABLEFTHENDEFERRABLELSEXCEPTRANSACTIONATURALTERAISEXCLUSIVE */ + /* XISTSAVEPOINTERSECTRIGGEREFERENCESCONSTRAINTOFFSETEMPORARY */ + /* UNIQUERYWITHOUTERELEASEATTACHAVINGROUPDATEBEGINNERECURSIVE */ + /* BETWEENOTNULLIKECASCADELETECASECOLLATECREATECURRENT_DATEDETACH */ + /* IMMEDIATEJOINSERTMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMITWHEN */ + /* WHERENAMEAFTEREPLACEANDEFAULTAUTOINCREMENTCASTCOLUMNCOMMIT */ + /* CONFLICTCROSSCURRENT_TIMESTAMPRIMARYDEFERREDISTINCTDROPFAIL */ + /* FROMFULLGLOBYIFISNULLORDERESTRICTRIGHTROLLBACKROWUNIONUSING */ + /* VACUUMVIEWINITIALLY */ + static const char zText[553] = { + 'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H', + 'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G', + 'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A', + 'S','E','L','E','C','T','A','B','L','E','F','T','H','E','N','D','E','F', + 'E','R','R','A','B','L','E','L','S','E','X','C','E','P','T','R','A','N', + 'S','A','C','T','I','O','N','A','T','U','R','A','L','T','E','R','A','I', + 'S','E','X','C','L','U','S','I','V','E','X','I','S','T','S','A','V','E', + 'P','O','I','N','T','E','R','S','E','C','T','R','I','G','G','E','R','E', + 'F','E','R','E','N','C','E','S','C','O','N','S','T','R','A','I','N','T', + 'O','F','F','S','E','T','E','M','P','O','R','A','R','Y','U','N','I','Q', + 'U','E','R','Y','W','I','T','H','O','U','T','E','R','E','L','E','A','S', + 'E','A','T','T','A','C','H','A','V','I','N','G','R','O','U','P','D','A', + 'T','E','B','E','G','I','N','N','E','R','E','C','U','R','S','I','V','E', + 'B','E','T','W','E','E','N','O','T','N','U','L','L','I','K','E','C','A', + 'S','C','A','D','E','L','E','T','E','C','A','S','E','C','O','L','L','A', + 'T','E','C','R','E','A','T','E','C','U','R','R','E','N','T','_','D','A', + 'T','E','D','E','T','A','C','H','I','M','M','E','D','I','A','T','E','J', + 'O','I','N','S','E','R','T','M','A','T','C','H','P','L','A','N','A','L', + 'Y','Z','E','P','R','A','G','M','A','B','O','R','T','V','A','L','U','E', + 'S','V','I','R','T','U','A','L','I','M','I','T','W','H','E','N','W','H', + 'E','R','E','N','A','M','E','A','F','T','E','R','E','P','L','A','C','E', + 'A','N','D','E','F','A','U','L','T','A','U','T','O','I','N','C','R','E', + 'M','E','N','T','C','A','S','T','C','O','L','U','M','N','C','O','M','M', + 'I','T','C','O','N','F','L','I','C','T','C','R','O','S','S','C','U','R', + 'R','E','N','T','_','T','I','M','E','S','T','A','M','P','R','I','M','A', + 'R','Y','D','E','F','E','R','R','E','D','I','S','T','I','N','C','T','D', + 'R','O','P','F','A','I','L','F','R','O','M','F','U','L','L','G','L','O', + 'B','Y','I','F','I','S','N','U','L','L','O','R','D','E','R','E','S','T', + 'R','I','C','T','R','I','G','H','T','R','O','L','L','B','A','C','K','R', + 'O','W','U','N','I','O','N','U','S','I','N','G','V','A','C','U','U','M', + 'V','I','E','W','I','N','I','T','I','A','L','L','Y', + }; + static const unsigned char aHash[127] = { + 76, 105, 117, 74, 0, 45, 0, 0, 82, 0, 77, 0, 0, + 42, 12, 78, 15, 0, 116, 85, 54, 112, 0, 19, 0, 0, + 121, 0, 119, 115, 0, 22, 93, 0, 9, 0, 0, 70, 71, + 0, 69, 6, 0, 48, 90, 102, 0, 118, 101, 0, 0, 44, + 0, 103, 24, 0, 17, 0, 122, 53, 23, 0, 5, 110, 25, + 96, 0, 0, 124, 106, 60, 123, 57, 28, 55, 0, 91, 0, + 100, 26, 0, 99, 0, 0, 0, 95, 92, 97, 88, 109, 14, + 39, 108, 0, 81, 0, 18, 89, 111, 32, 0, 120, 80, 113, + 62, 46, 84, 0, 0, 94, 40, 59, 114, 0, 36, 0, 0, + 29, 0, 86, 63, 64, 0, 20, 61, 0, 56, + }; + static const unsigned char aNext[124] = { + 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, + 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 33, 0, 21, 0, 0, 0, 0, 0, 50, + 0, 43, 3, 47, 0, 0, 0, 0, 30, 0, 58, 0, 38, + 0, 0, 0, 1, 66, 0, 0, 67, 0, 41, 0, 0, 0, + 0, 0, 0, 49, 65, 0, 0, 0, 0, 31, 52, 16, 34, + 10, 0, 0, 0, 0, 0, 0, 0, 11, 72, 79, 0, 8, + 0, 104, 98, 0, 107, 0, 87, 0, 75, 51, 0, 27, 37, + 73, 83, 0, 35, 68, 0, 0, + }; + static const unsigned char aLen[124] = { + 7, 7, 5, 4, 6, 4, 5, 3, 6, 7, 3, 6, 6, + 7, 7, 3, 8, 2, 6, 5, 4, 4, 3, 10, 4, 6, + 11, 6, 2, 7, 5, 5, 9, 6, 9, 9, 7, 10, 10, + 4, 6, 2, 3, 9, 4, 2, 6, 5, 7, 4, 5, 7, + 6, 6, 5, 6, 5, 5, 9, 7, 7, 3, 2, 4, 4, + 7, 3, 6, 4, 7, 6, 12, 6, 9, 4, 6, 5, 4, + 7, 6, 5, 6, 7, 5, 4, 5, 6, 5, 7, 3, 7, + 13, 2, 2, 4, 6, 6, 8, 5, 17, 12, 7, 8, 8, + 2, 4, 4, 4, 4, 4, 2, 2, 6, 5, 8, 5, 8, + 3, 5, 5, 6, 4, 9, 3, + }; + static const unsigned short int aOffset[124] = { + 0, 2, 2, 8, 9, 14, 16, 20, 23, 25, 25, 29, 33, + 36, 41, 46, 48, 53, 54, 59, 62, 65, 67, 69, 78, 81, + 86, 91, 95, 96, 101, 105, 109, 117, 122, 128, 136, 142, 152, + 159, 162, 162, 165, 167, 167, 171, 176, 179, 184, 184, 188, 192, + 199, 204, 209, 212, 218, 221, 225, 234, 240, 240, 240, 243, 246, + 250, 251, 255, 261, 265, 272, 278, 290, 296, 305, 307, 313, 318, + 320, 327, 332, 337, 343, 349, 354, 358, 361, 367, 371, 378, 380, + 387, 389, 391, 400, 404, 410, 416, 424, 429, 429, 445, 452, 459, + 460, 467, 471, 475, 479, 483, 486, 488, 490, 496, 500, 508, 513, + 521, 524, 529, 534, 540, 544, 549, + }; + static const unsigned char aCode[124] = { + TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE, + TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN, + TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD, + TK_ADD, TK_DATABASE, TK_AS, TK_SELECT, TK_TABLE, + TK_JOIN_KW, TK_THEN, TK_END, TK_DEFERRABLE, TK_ELSE, + TK_EXCEPT, TK_TRANSACTION,TK_ACTION, TK_ON, TK_JOIN_KW, + TK_ALTER, TK_RAISE, TK_EXCLUSIVE, TK_EXISTS, TK_SAVEPOINT, + TK_INTERSECT, TK_TRIGGER, TK_REFERENCES, TK_CONSTRAINT, TK_INTO, + TK_OFFSET, TK_OF, TK_SET, TK_TEMP, TK_TEMP, + TK_OR, TK_UNIQUE, TK_QUERY, TK_WITHOUT, TK_WITH, + TK_JOIN_KW, TK_RELEASE, TK_ATTACH, TK_HAVING, TK_GROUP, + TK_UPDATE, TK_BEGIN, TK_JOIN_KW, TK_RECURSIVE, TK_BETWEEN, + TK_NOTNULL, TK_NOT, TK_NO, TK_NULL, TK_LIKE_KW, + TK_CASCADE, TK_ASC, TK_DELETE, TK_CASE, TK_COLLATE, + TK_CREATE, TK_CTIME_KW, TK_DETACH, TK_IMMEDIATE, TK_JOIN, + TK_INSERT, TK_MATCH, TK_PLAN, TK_ANALYZE, TK_PRAGMA, + TK_ABORT, TK_VALUES, TK_VIRTUAL, TK_LIMIT, TK_WHEN, + TK_WHERE, TK_RENAME, TK_AFTER, TK_REPLACE, TK_AND, + TK_DEFAULT, TK_AUTOINCR, TK_TO, TK_IN, TK_CAST, + TK_COLUMNKW, TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, + TK_CTIME_KW, TK_PRIMARY, TK_DEFERRED, TK_DISTINCT, TK_IS, + TK_DROP, TK_FAIL, TK_FROM, TK_JOIN_KW, TK_LIKE_KW, + TK_BY, TK_IF, TK_ISNULL, TK_ORDER, TK_RESTRICT, + TK_JOIN_KW, TK_ROLLBACK, TK_ROW, TK_UNION, TK_USING, + TK_VACUUM, TK_VIEW, TK_INITIALLY, TK_ALL, + }; + int h, i; + if( n<2 ) return TK_ID; + h = ((charMap(z[0])*4) ^ + (charMap(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 ){ + testcase( i==0 ); /* REINDEX */ + testcase( i==1 ); /* INDEXED */ + testcase( i==2 ); /* INDEX */ + testcase( i==3 ); /* DESC */ + testcase( i==4 ); /* ESCAPE */ + testcase( i==5 ); /* EACH */ + testcase( i==6 ); /* CHECK */ + testcase( i==7 ); /* KEY */ + testcase( i==8 ); /* BEFORE */ + testcase( i==9 ); /* FOREIGN */ + testcase( i==10 ); /* FOR */ + testcase( i==11 ); /* IGNORE */ + testcase( i==12 ); /* REGEXP */ + testcase( i==13 ); /* EXPLAIN */ + testcase( i==14 ); /* INSTEAD */ + testcase( i==15 ); /* ADD */ + testcase( i==16 ); /* DATABASE */ + testcase( i==17 ); /* AS */ + testcase( i==18 ); /* SELECT */ + testcase( i==19 ); /* TABLE */ + testcase( i==20 ); /* LEFT */ + testcase( i==21 ); /* THEN */ + testcase( i==22 ); /* END */ + testcase( i==23 ); /* DEFERRABLE */ + testcase( i==24 ); /* ELSE */ + testcase( i==25 ); /* EXCEPT */ + testcase( i==26 ); /* TRANSACTION */ + testcase( i==27 ); /* ACTION */ + testcase( i==28 ); /* ON */ + testcase( i==29 ); /* NATURAL */ + testcase( i==30 ); /* ALTER */ + testcase( i==31 ); /* RAISE */ + testcase( i==32 ); /* EXCLUSIVE */ + testcase( i==33 ); /* EXISTS */ + testcase( i==34 ); /* SAVEPOINT */ + testcase( i==35 ); /* INTERSECT */ + testcase( i==36 ); /* TRIGGER */ + testcase( i==37 ); /* REFERENCES */ + testcase( i==38 ); /* CONSTRAINT */ + testcase( i==39 ); /* INTO */ + testcase( i==40 ); /* OFFSET */ + testcase( i==41 ); /* OF */ + testcase( i==42 ); /* SET */ + testcase( i==43 ); /* TEMPORARY */ + testcase( i==44 ); /* TEMP */ + testcase( i==45 ); /* OR */ + testcase( i==46 ); /* UNIQUE */ + testcase( i==47 ); /* QUERY */ + testcase( i==48 ); /* WITHOUT */ + testcase( i==49 ); /* WITH */ + testcase( i==50 ); /* OUTER */ + testcase( i==51 ); /* RELEASE */ + testcase( i==52 ); /* ATTACH */ + testcase( i==53 ); /* HAVING */ + testcase( i==54 ); /* GROUP */ + testcase( i==55 ); /* UPDATE */ + testcase( i==56 ); /* BEGIN */ + testcase( i==57 ); /* INNER */ + testcase( i==58 ); /* RECURSIVE */ + testcase( i==59 ); /* BETWEEN */ + testcase( i==60 ); /* NOTNULL */ + testcase( i==61 ); /* NOT */ + testcase( i==62 ); /* NO */ + testcase( i==63 ); /* NULL */ + testcase( i==64 ); /* LIKE */ + testcase( i==65 ); /* CASCADE */ + testcase( i==66 ); /* ASC */ + testcase( i==67 ); /* DELETE */ + testcase( i==68 ); /* CASE */ + testcase( i==69 ); /* COLLATE */ + testcase( i==70 ); /* CREATE */ + testcase( i==71 ); /* CURRENT_DATE */ + testcase( i==72 ); /* DETACH */ + testcase( i==73 ); /* IMMEDIATE */ + testcase( i==74 ); /* JOIN */ + testcase( i==75 ); /* INSERT */ + testcase( i==76 ); /* MATCH */ + testcase( i==77 ); /* PLAN */ + testcase( i==78 ); /* ANALYZE */ + testcase( i==79 ); /* PRAGMA */ + testcase( i==80 ); /* ABORT */ + testcase( i==81 ); /* VALUES */ + testcase( i==82 ); /* VIRTUAL */ + testcase( i==83 ); /* LIMIT */ + testcase( i==84 ); /* WHEN */ + testcase( i==85 ); /* WHERE */ + testcase( i==86 ); /* RENAME */ + testcase( i==87 ); /* AFTER */ + testcase( i==88 ); /* REPLACE */ + testcase( i==89 ); /* AND */ + testcase( i==90 ); /* DEFAULT */ + testcase( i==91 ); /* AUTOINCREMENT */ + testcase( i==92 ); /* TO */ + testcase( i==93 ); /* IN */ + testcase( i==94 ); /* CAST */ + testcase( i==95 ); /* COLUMN */ + testcase( i==96 ); /* COMMIT */ + testcase( i==97 ); /* CONFLICT */ + testcase( i==98 ); /* CROSS */ + testcase( i==99 ); /* CURRENT_TIMESTAMP */ + testcase( i==100 ); /* CURRENT_TIME */ + testcase( i==101 ); /* PRIMARY */ + testcase( i==102 ); /* DEFERRED */ + testcase( i==103 ); /* DISTINCT */ + testcase( i==104 ); /* IS */ + testcase( i==105 ); /* DROP */ + testcase( i==106 ); /* FAIL */ + testcase( i==107 ); /* FROM */ + testcase( i==108 ); /* FULL */ + testcase( i==109 ); /* GLOB */ + testcase( i==110 ); /* BY */ + testcase( i==111 ); /* IF */ + testcase( i==112 ); /* ISNULL */ + testcase( i==113 ); /* ORDER */ + testcase( i==114 ); /* RESTRICT */ + testcase( i==115 ); /* RIGHT */ + testcase( i==116 ); /* ROLLBACK */ + testcase( i==117 ); /* ROW */ + testcase( i==118 ); /* UNION */ + testcase( i==119 ); /* USING */ + testcase( i==120 ); /* VACUUM */ + testcase( i==121 ); /* VIEW */ + testcase( i==122 ); /* INITIALLY */ + testcase( i==123 ); /* ALL */ + return aCode[i]; + } + } + return TK_ID; +} +SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){ + return keywordCode((char*)z, n); +} +#define SQLITE_N_KEYWORD 124 + +/************** End of keywordhash.h *****************************************/ +/************** Continuing where we left off in tokenize.c *******************/ + + +/* +** If X is a character that can be used in an identifier then +** IdChar(X) will be true. Otherwise it is false. +** +** For ASCII, any character with the high-order bit set is +** allowed in an identifier. For 7-bit characters, +** sqlite3IsIdChar[X] must be 1. +** +** For EBCDIC, the rules are more complex but have the same +** end result. +** +** Ticket #1066. the SQL standard does not allow '$' in the +** middle of identifiers. But many SQL implementations do. +** SQLite will allow '$' in identifiers for compatibility. +** But the feature is undocumented. +*/ +#ifdef SQLITE_ASCII +#define IdChar(C) ((sqlite3CtypeMap[(unsigned char)C]&0x46)!=0) +#endif +#ifdef SQLITE_EBCDIC +SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[] = { +/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 4x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, /* 5x */ + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, /* 6x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, /* 7x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, /* 8x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, /* 9x */ + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, /* Ax */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Bx */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Cx */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Dx */ + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Ex */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, /* Fx */ +}; +#define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40])) +#endif +SQLITE_PRIVATE int sqlite3IsIdChar(u8 c){ return IdChar(c); } + + +/* +** Return the length of the token that begins at z[0]. +** Store the token type in *tokenType before returning. +*/ +SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ + int i, c; + switch( *z ){ + case ' ': case '\t': case '\n': case '\f': case '\r': { + testcase( z[0]==' ' ); + testcase( z[0]=='\t' ); + testcase( z[0]=='\n' ); + testcase( z[0]=='\f' ); + testcase( z[0]=='\r' ); + for(i=1; sqlite3Isspace(z[i]); i++){} + *tokenType = TK_SPACE; + return i; + } + case '-': { + if( z[1]=='-' ){ + for(i=2; (c=z[i])!=0 && c!='\n'; i++){} + *tokenType = TK_SPACE; /* IMP: R-22934-25134 */ + return i; + } + *tokenType = TK_MINUS; + return 1; + } + case '(': { + *tokenType = TK_LP; + return 1; + } + case ')': { + *tokenType = TK_RP; + return 1; + } + case ';': { + *tokenType = TK_SEMI; + return 1; + } + case '+': { + *tokenType = TK_PLUS; + return 1; + } + case '*': { + *tokenType = TK_STAR; + return 1; + } + case '/': { + if( z[1]!='*' || z[2]==0 ){ + *tokenType = TK_SLASH; + return 1; + } + for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){} + if( c ) i++; + *tokenType = TK_SPACE; /* IMP: R-22934-25134 */ + return i; + } + case '%': { + *tokenType = TK_REM; + return 1; + } + case '=': { + *tokenType = TK_EQ; + return 1 + (z[1]=='='); + } + case '<': { + if( (c=z[1])=='=' ){ + *tokenType = TK_LE; + return 2; + }else if( c=='>' ){ + *tokenType = TK_NE; + return 2; + }else if( c=='<' ){ + *tokenType = TK_LSHIFT; + return 2; + }else{ + *tokenType = TK_LT; + return 1; + } + } + case '>': { + if( (c=z[1])=='=' ){ + *tokenType = TK_GE; + return 2; + }else if( c=='>' ){ + *tokenType = TK_RSHIFT; + return 2; + }else{ + *tokenType = TK_GT; + return 1; + } + } + case '!': { + if( z[1]!='=' ){ + *tokenType = TK_ILLEGAL; + return 2; + }else{ + *tokenType = TK_NE; + return 2; + } + } + case '|': { + if( z[1]!='|' ){ + *tokenType = TK_BITOR; + return 1; + }else{ + *tokenType = TK_CONCAT; + return 2; + } + } + case ',': { + *tokenType = TK_COMMA; + return 1; + } + case '&': { + *tokenType = TK_BITAND; + return 1; + } + case '~': { + *tokenType = TK_BITNOT; + return 1; + } + case '`': + case '\'': + case '"': { + int delim = z[0]; + testcase( delim=='`' ); + testcase( delim=='\'' ); + testcase( delim=='"' ); + 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 if( c!=0 ){ + *tokenType = TK_ID; + return i+1; + }else{ + *tokenType = TK_ILLEGAL; + return i; + } + } + case '.': { +#ifndef SQLITE_OMIT_FLOATING_POINT + if( !sqlite3Isdigit(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': { + testcase( z[0]=='0' ); testcase( z[0]=='1' ); testcase( z[0]=='2' ); + testcase( z[0]=='3' ); testcase( z[0]=='4' ); testcase( z[0]=='5' ); + testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' ); + testcase( z[0]=='9' ); + *tokenType = TK_INTEGER; +#ifndef SQLITE_OMIT_HEX_INTEGER + if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){ + for(i=3; sqlite3Isxdigit(z[i]); i++){} + return i; + } +#endif + for(i=0; sqlite3Isdigit(z[i]); i++){} +#ifndef SQLITE_OMIT_FLOATING_POINT + if( z[i]=='.' ){ + i++; + while( sqlite3Isdigit(z[i]) ){ i++; } + *tokenType = TK_FLOAT; + } + if( (z[i]=='e' || z[i]=='E') && + ( sqlite3Isdigit(z[i+1]) + || ((z[i+1]=='+' || z[i+1]=='-') && sqlite3Isdigit(z[i+2])) + ) + ){ + i += 2; + while( sqlite3Isdigit(z[i]) ){ i++; } + *tokenType = TK_FLOAT; + } +#endif + while( IdChar(z[i]) ){ + *tokenType = TK_ILLEGAL; + i++; + } + return i; + } + case '[': { + for(i=1, c=z[0]; c!=']' && (c=z[i])!=0; i++){} + *tokenType = c==']' ? TK_ID : TK_ILLEGAL; + return i; + } + case '?': { + *tokenType = TK_VARIABLE; + for(i=1; sqlite3Isdigit(z[i]); i++){} + return i; + } +#ifndef SQLITE_OMIT_TCL_VARIABLE + case '$': +#endif + case '@': /* For compatibility with MS SQL Server */ + case '#': + case ':': { + int n = 0; + testcase( z[0]=='$' ); testcase( z[0]=='@' ); + testcase( z[0]==':' ); testcase( z[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 && !sqlite3Isspace(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': { + testcase( z[0]=='x' ); testcase( z[0]=='X' ); + if( z[1]=='\'' ){ + *tokenType = TK_BLOB; + for(i=2; sqlite3Isxdigit(z[i]); i++){} + if( z[i]!='\'' || i%2 ){ + *tokenType = TK_ILLEGAL; + while( z[i] && z[i]!='\'' ){ i++; } + } + if( z[i] ) i++; + return i; + } + /* Otherwise fall through to the next case */ + } +#endif + default: { + if( !IdChar(*z) ){ + break; + } + for(i=1; IdChar(z[i]); i++){} + *tokenType = keywordCode((char*)z, i); + return i; + } + } + *tokenType = TK_ILLEGAL; + return 1; +} + +/* +** Run the parser on the given SQL string. The parser structure is +** passed in. An SQLITE_ status code is returned. If an error occurs +** then an and attempt is made to write an error message into +** memory obtained from sqlite3_malloc() and to make *pzErrMsg point to that +** error message. +*/ +SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ + int nErr = 0; /* Number of errors encountered */ + int i; /* Loop counter */ + void *pEngine; /* The LEMON-generated LALR(1) parser */ + int tokenType; /* type of the next token */ + int lastTokenParsed = -1; /* type of the previous token */ + u8 enableLookaside; /* Saved value of db->lookaside.bEnabled */ + sqlite3 *db = pParse->db; /* The database connection */ + int mxSqlLen; /* Max length of an SQL string */ + + assert( zSql!=0 ); + mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; + if( db->nVdbeActive==0 ){ + db->u1.isInterrupted = 0; + } + pParse->rc = SQLITE_OK; + pParse->zTail = zSql; + i = 0; + assert( pzErrMsg!=0 ); + pEngine = sqlite3ParserAlloc(sqlite3Malloc); + if( pEngine==0 ){ + db->mallocFailed = 1; + return SQLITE_NOMEM; + } + assert( pParse->pNewTable==0 ); + assert( pParse->pNewTrigger==0 ); + assert( pParse->nVar==0 ); + assert( pParse->nzVar==0 ); + assert( pParse->azVar==0 ); + enableLookaside = db->lookaside.bEnabled; + if( db->lookaside.pStart ) db->lookaside.bEnabled = 1; + while( !db->mallocFailed && zSql[i]!=0 ){ + assert( i>=0 ); + pParse->sLastToken.z = &zSql[i]; + pParse->sLastToken.n = sqlite3GetToken((unsigned char*)&zSql[i],&tokenType); + i += pParse->sLastToken.n; + if( i>mxSqlLen ){ + pParse->rc = SQLITE_TOOBIG; + break; + } + switch( tokenType ){ + case TK_SPACE: { + if( db->u1.isInterrupted ){ + sqlite3ErrorMsg(pParse, "interrupt"); + pParse->rc = SQLITE_INTERRUPT; + goto abort_parse; + } + break; + } + case TK_ILLEGAL: { + sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"", + &pParse->sLastToken); + goto abort_parse; + } + case TK_SEMI: { + pParse->zTail = &zSql[i]; + /* Fall thru into the default case */ + } + default: { + sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse); + lastTokenParsed = tokenType; + if( pParse->rc!=SQLITE_OK ){ + goto abort_parse; + } + break; + } + } + } +abort_parse: + assert( nErr==0 ); + if( zSql[i]==0 && pParse->rc==SQLITE_OK && db->mallocFailed==0 ){ + if( lastTokenParsed!=TK_SEMI ){ + sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse); + pParse->zTail = &zSql[i]; + } + if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){ + sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse); + } + } +#ifdef YYTRACKMAXSTACKDEPTH + sqlite3_mutex_enter(sqlite3MallocMutex()); + sqlite3StatusSet(SQLITE_STATUS_PARSER_STACK, + sqlite3ParserStackPeak(pEngine) + ); + sqlite3_mutex_leave(sqlite3MallocMutex()); +#endif /* YYDEBUG */ + sqlite3ParserFree(pEngine, sqlite3_free); + db->lookaside.bEnabled = enableLookaside; + if( db->mallocFailed ){ + pParse->rc = SQLITE_NOMEM; + } + if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){ + sqlite3SetString(&pParse->zErrMsg, db, "%s", sqlite3ErrStr(pParse->rc)); + } + assert( pzErrMsg!=0 ); + if( pParse->zErrMsg ){ + *pzErrMsg = pParse->zErrMsg; + sqlite3_log(pParse->rc, "%s", *pzErrMsg); + pParse->zErrMsg = 0; + 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 ){ + sqlite3DbFree(db, pParse->aTableLock); + pParse->aTableLock = 0; + pParse->nTableLock = 0; + } +#endif +#ifndef SQLITE_OMIT_VIRTUALTABLE + sqlite3_free(pParse->apVtabLock); +#endif + + if( !IN_DECLARE_VTAB ){ + /* If the pParse->declareVtab flag is set, do not delete any table + ** structure built up in pParse->pNewTable. The calling code (see vtab.c) + ** will take responsibility for freeing the Table structure. + */ + sqlite3DeleteTable(db, pParse->pNewTable); + } + + if( pParse->bFreeWith ) sqlite3WithDelete(db, pParse->pWith); + sqlite3DeleteTrigger(db, pParse->pNewTrigger); + for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]); + sqlite3DbFree(db, pParse->azVar); + while( pParse->pAinc ){ + AutoincInfo *p = pParse->pAinc; + pParse->pAinc = p->pNext; + sqlite3DbFree(db, p); + } + while( pParse->pZombieTab ){ + Table *p = pParse->pZombieTab; + pParse->pZombieTab = p->pNextZombie; + sqlite3DeleteTable(db, p); + } + assert( nErr==0 || pParse->rc!=SQLITE_OK ); + return nErr; +} + +/************** End of tokenize.c ********************************************/ +/************** Begin file complete.c ****************************************/ +/* +** 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. +*/ +#ifndef SQLITE_OMIT_COMPLETE + +/* +** This is defined in tokenize.c. We just have to import the definition. +*/ +#ifndef SQLITE_AMALGAMATION +#ifdef SQLITE_ASCII +#define IdChar(C) ((sqlite3CtypeMap[(unsigned char)C]&0x46)!=0) +#endif +#ifdef SQLITE_EBCDIC +SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[]; +#define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40])) +#endif +#endif /* SQLITE_AMALGAMATION */ + + +/* +** 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 +#ifndef SQLITE_OMIT_TRIGGER +#define tkEXPLAIN 3 +#define tkCREATE 4 +#define tkTEMP 5 +#define tkTRIGGER 6 +#define tkEND 7 +#endif + +/* +** 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 8 states: +** +** (0) INVALID We have not yet seen a non-whitespace character. +** +** (1) 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. +** +** (2) NORMAL We are in the middle of statement which ends with a single +** semicolon. +** +** (3) EXPLAIN The keyword EXPLAIN has been seen at the beginning of +** a statement. +** +** (4) CREATE The keyword CREATE has been seen at the beginning of a +** statement, possibly preceded by EXPLAIN and/or followed by +** TEMP or TEMPORARY +** +** (5) TRIGGER We are in the middle of a trigger definition that must be +** ended by a semicolon, the keyword END, and another semicolon. +** +** (6) SEMI We've seen the first semicolon in the ";END;" that occurs at +** the end of a trigger definition. +** +** (7) END We've seen the ";END" of the ";END;" that occurs at the end +** of a trigger definition. +** +** 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. +** This means that a SQL string of all whitespace is invalid. +** +** 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. +*/ +SQLITE_API int SQLITE_STDCALL 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[8][8] = { + /* Token: */ + /* State: ** SEMI WS OTHER EXPLAIN CREATE TEMP TRIGGER END */ + /* 0 INVALID: */ { 1, 0, 2, 3, 4, 2, 2, 2, }, + /* 1 START: */ { 1, 1, 2, 3, 4, 2, 2, 2, }, + /* 2 NORMAL: */ { 1, 2, 2, 2, 2, 2, 2, 2, }, + /* 3 EXPLAIN: */ { 1, 3, 3, 2, 4, 2, 2, 2, }, + /* 4 CREATE: */ { 1, 4, 2, 2, 2, 4, 5, 2, }, + /* 5 TRIGGER: */ { 6, 5, 5, 5, 5, 5, 5, 5, }, + /* 6 SEMI: */ { 6, 6, 5, 5, 5, 5, 5, 7, }, + /* 7 END: */ { 1, 7, 5, 5, 5, 5, 5, 5, }, + }; +#else + /* If triggers are not supported by this compile then the statement machine + ** used to detect the end of a statement is much simpler + */ + static const u8 trans[3][3] = { + /* Token: */ + /* State: ** SEMI WS OTHER */ + /* 0 INVALID: */ { 1, 0, 2, }, + /* 1 START: */ { 1, 1, 2, }, + /* 2 NORMAL: */ { 1, 2, 2, }, + }; +#endif /* SQLITE_OMIT_TRIGGER */ + +#ifdef SQLITE_ENABLE_API_ARMOR + if( zSql==0 ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + + 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==1; + 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: { +#ifdef SQLITE_EBCDIC + unsigned char c; +#endif + 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==1; +} + +#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. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *zSql){ + sqlite3_value *pVal; + char const *zSql8; + int rc; + +#ifndef SQLITE_OMIT_AUTOINIT + rc = sqlite3_initialize(); + if( rc ) return rc; +#endif + pVal = sqlite3ValueNew(0); + sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC); + zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8); + if( zSql8 ){ + rc = sqlite3_complete(zSql8); + }else{ + rc = SQLITE_NOMEM; + } + sqlite3ValueFree(pVal); + return sqlite3ApiExit(0, rc); +} +#endif /* SQLITE_OMIT_UTF16 */ +#endif /* SQLITE_OMIT_COMPLETE */ + +/************** End of complete.c ********************************************/ +/************** Begin file main.c ********************************************/ +/* +** 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. +** +************************************************************************* +** 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. +*/ + +#ifdef SQLITE_ENABLE_FTS3 +/************** Include fts3.h in the middle of main.c ***********************/ +/************** Begin file fts3.h ********************************************/ +/* +** 2006 Oct 10 +** +** 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 is used by programs that want to link against the +** FTS3 library. All it does is declare the sqlite3Fts3Init() interface. +*/ + +#if 0 +extern "C" { +#endif /* __cplusplus */ + +SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db); + +#if 0 +} /* extern "C" */ +#endif /* __cplusplus */ + +/************** End of fts3.h ************************************************/ +/************** Continuing where we left off in main.c ***********************/ +#endif +#ifdef SQLITE_ENABLE_RTREE +/************** Include rtree.h in the middle of main.c **********************/ +/************** Begin file rtree.h *******************************************/ +/* +** 2008 May 26 +** +** 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 is used by programs that want to link against the +** RTREE library. All it does is declare the sqlite3RtreeInit() interface. +*/ + +#if 0 +extern "C" { +#endif /* __cplusplus */ + +SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db); + +#if 0 +} /* extern "C" */ +#endif /* __cplusplus */ + +/************** End of rtree.h ***********************************************/ +/************** Continuing where we left off in main.c ***********************/ +#endif +#ifdef SQLITE_ENABLE_ICU +/************** Include sqliteicu.h in the middle of main.c ******************/ +/************** Begin file sqliteicu.h ***************************************/ +/* +** 2008 May 26 +** +** 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 is used by programs that want to link against the +** ICU extension. All it does is declare the sqlite3IcuInit() interface. +*/ + +#if 0 +extern "C" { +#endif /* __cplusplus */ + +SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db); + +#if 0 +} /* extern "C" */ +#endif /* __cplusplus */ + + +/************** End of sqliteicu.h *******************************************/ +/************** Continuing where we left off in main.c ***********************/ +#endif + +#ifndef SQLITE_AMALGAMATION +/* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant +** contains the text of SQLITE_VERSION macro. +*/ +SQLITE_API const char sqlite3_version[] = SQLITE_VERSION; +#endif + +/* IMPLEMENTATION-OF: R-53536-42575 The sqlite3_libversion() function returns +** a pointer to the to the sqlite3_version[] string constant. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_libversion(void){ return sqlite3_version; } + +/* IMPLEMENTATION-OF: R-63124-39300 The sqlite3_sourceid() function returns a +** pointer to a string constant whose value is the same as the +** SQLITE_SOURCE_ID C preprocessor macro. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } + +/* IMPLEMENTATION-OF: R-35210-63508 The sqlite3_libversion_number() function +** returns an integer equal to SQLITE_VERSION_NUMBER. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; } + +/* IMPLEMENTATION-OF: R-20790-14025 The sqlite3_threadsafe() function returns +** zero if and only if SQLite was compiled with mutexing code omitted due to +** the SQLITE_THREADSAFE compile-time option being set to 0. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; } + +/* +** When compiling the test fixture or with debugging enabled (on Win32), +** this variable being set to non-zero will cause OSTRACE macros to emit +** extra diagnostic information. +*/ +#ifdef SQLITE_HAVE_OS_TRACE +# ifndef SQLITE_DEBUG_OS_TRACE +# define SQLITE_DEBUG_OS_TRACE 0 +# endif + int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; +#endif + +#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE) +/* +** If the following function pointer is not NULL and if +** SQLITE_ENABLE_IOTRACE is enabled, then messages describing +** I/O active are written using this function. These messages +** are intended for debugging activity only. +*/ +SQLITE_API void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...) = 0; +#endif + +/* +** 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. +*/ +SQLITE_API char *sqlite3_temp_directory = 0; + +/* +** If the following global variable points to a string which is the +** name of a directory, then that directory will be used to store +** all database files specified with a relative pathname. +** +** See also the "PRAGMA data_store_directory" SQL command. +*/ +SQLITE_API char *sqlite3_data_directory = 0; + +/* +** Initialize SQLite. +** +** This routine must be called to initialize the memory allocation, +** VFS, and mutex subsystems prior to doing any serious work with +** SQLite. But as long as you do not compile with SQLITE_OMIT_AUTOINIT +** this routine will be called automatically by key routines such as +** sqlite3_open(). +** +** This routine is a no-op except on its very first call for the process, +** or for the first call after a call to sqlite3_shutdown. +** +** The first thread to call this routine runs the initialization to +** completion. If subsequent threads call this routine before the first +** thread has finished the initialization process, then the subsequent +** threads must block until the first thread finishes with the initialization. +** +** The first thread might call this routine recursively. Recursive +** calls to this routine should not block, of course. Otherwise the +** initialization process would never complete. +** +** Let X be the first thread to enter this routine. Let Y be some other +** thread. Then while the initial invocation of this routine by X is +** incomplete, it is required that: +** +** * Calls to this routine from Y must block until the outer-most +** call by X completes. +** +** * Recursive calls to this routine from thread X return immediately +** without blocking. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void){ + MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */ + int rc; /* Result code */ +#ifdef SQLITE_EXTRA_INIT + int bRunExtraInit = 0; /* Extra initialization needed */ +#endif + +#ifdef SQLITE_OMIT_WSD + rc = sqlite3_wsd_init(4096, 24); + if( rc!=SQLITE_OK ){ + return rc; + } +#endif + + /* If the following assert() fails on some obscure processor/compiler + ** combination, the work-around is to set the correct pointer + ** size at compile-time using -DSQLITE_PTRSIZE=n compile-time option */ + assert( SQLITE_PTRSIZE==sizeof(char*) ); + + /* If SQLite is already completely initialized, then this call + ** to sqlite3_initialize() should be a no-op. But the initialization + ** must be complete. So isInit must not be set until the very end + ** of this routine. + */ + if( sqlite3GlobalConfig.isInit ) return SQLITE_OK; + + /* Make sure the mutex subsystem is initialized. If unable to + ** initialize the mutex subsystem, return early with the error. + ** If the system is so sick that we are unable to allocate a mutex, + ** there is not much SQLite is going to be able to do. + ** + ** The mutex subsystem must take care of serializing its own + ** initialization. + */ + rc = sqlite3MutexInit(); + if( rc ) return rc; + + /* Initialize the malloc() system and the recursive pInitMutex mutex. + ** This operation is protected by the STATIC_MASTER mutex. Note that + ** MutexAlloc() is called for a static mutex prior to initializing the + ** malloc subsystem - this implies that the allocation of a static + ** mutex must not require support from the malloc subsystem. + */ + MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) + sqlite3_mutex_enter(pMaster); + sqlite3GlobalConfig.isMutexInit = 1; + if( !sqlite3GlobalConfig.isMallocInit ){ + rc = sqlite3MallocInit(); + } + if( rc==SQLITE_OK ){ + sqlite3GlobalConfig.isMallocInit = 1; + if( !sqlite3GlobalConfig.pInitMutex ){ + sqlite3GlobalConfig.pInitMutex = + sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); + if( sqlite3GlobalConfig.bCoreMutex && !sqlite3GlobalConfig.pInitMutex ){ + rc = SQLITE_NOMEM; + } + } + } + if( rc==SQLITE_OK ){ + sqlite3GlobalConfig.nRefInitMutex++; + } + sqlite3_mutex_leave(pMaster); + + /* If rc is not SQLITE_OK at this point, then either the malloc + ** subsystem could not be initialized or the system failed to allocate + ** the pInitMutex mutex. Return an error in either case. */ + if( rc!=SQLITE_OK ){ + return rc; + } + + /* Do the rest of the initialization under the recursive mutex so + ** that we will be able to handle recursive calls into + ** sqlite3_initialize(). The recursive calls normally come through + ** sqlite3_os_init() when it invokes sqlite3_vfs_register(), but other + ** recursive calls might also be possible. + ** + ** IMPLEMENTATION-OF: R-00140-37445 SQLite automatically serializes calls + ** to the xInit method, so the xInit method need not be threadsafe. + ** + ** The following mutex is what serializes access to the appdef pcache xInit + ** methods. The sqlite3_pcache_methods.xInit() all is embedded in the + ** call to sqlite3PcacheInitialize(). + */ + sqlite3_mutex_enter(sqlite3GlobalConfig.pInitMutex); + if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){ + FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions); + sqlite3GlobalConfig.inProgress = 1; + memset(pHash, 0, sizeof(sqlite3GlobalFunctions)); + sqlite3RegisterGlobalFunctions(); + if( sqlite3GlobalConfig.isPCacheInit==0 ){ + rc = sqlite3PcacheInitialize(); + } + if( rc==SQLITE_OK ){ + sqlite3GlobalConfig.isPCacheInit = 1; + rc = sqlite3OsInit(); + } + if( rc==SQLITE_OK ){ + sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, + sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage); + sqlite3GlobalConfig.isInit = 1; +#ifdef SQLITE_EXTRA_INIT + bRunExtraInit = 1; +#endif + } + sqlite3GlobalConfig.inProgress = 0; + } + sqlite3_mutex_leave(sqlite3GlobalConfig.pInitMutex); + + /* Go back under the static mutex and clean up the recursive + ** mutex to prevent a resource leak. + */ + sqlite3_mutex_enter(pMaster); + sqlite3GlobalConfig.nRefInitMutex--; + if( sqlite3GlobalConfig.nRefInitMutex<=0 ){ + assert( sqlite3GlobalConfig.nRefInitMutex==0 ); + sqlite3_mutex_free(sqlite3GlobalConfig.pInitMutex); + sqlite3GlobalConfig.pInitMutex = 0; + } + sqlite3_mutex_leave(pMaster); + + /* The following is just a sanity check to make sure SQLite has + ** been compiled correctly. It is important to run this code, but + ** we don't want to run it too often and soak up CPU cycles for no + ** reason. So we run it once during initialization. + */ +#ifndef NDEBUG +#ifndef SQLITE_OMIT_FLOATING_POINT + /* This section of code's only "output" is via assert() statements. */ + if ( rc==SQLITE_OK ){ + u64 x = (((u64)1)<<63)-1; + double y; + assert(sizeof(x)==8); + assert(sizeof(x)==sizeof(y)); + memcpy(&y, &x, 8); + assert( sqlite3IsNaN(y) ); + } +#endif +#endif + + /* Do extra initialization steps requested by the SQLITE_EXTRA_INIT + ** compile-time option. + */ +#ifdef SQLITE_EXTRA_INIT + if( bRunExtraInit ){ + int SQLITE_EXTRA_INIT(const char*); + rc = SQLITE_EXTRA_INIT(0); + } +#endif + + return rc; +} + +/* +** Undo the effects of sqlite3_initialize(). Must not be called while +** there are outstanding database connections or memory allocations or +** while any part of SQLite is otherwise in use in any thread. This +** routine is not threadsafe. But it is safe to invoke this routine +** on when SQLite is already shut down. If SQLite is already shut down +** when this routine is invoked, then this routine is a harmless no-op. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void){ +#ifdef SQLITE_OMIT_WSD + int rc = sqlite3_wsd_init(4096, 24); + if( rc!=SQLITE_OK ){ + return rc; + } +#endif + + if( sqlite3GlobalConfig.isInit ){ +#ifdef SQLITE_EXTRA_SHUTDOWN + void SQLITE_EXTRA_SHUTDOWN(void); + SQLITE_EXTRA_SHUTDOWN(); +#endif + sqlite3_os_end(); + sqlite3_reset_auto_extension(); + sqlite3GlobalConfig.isInit = 0; + } + if( sqlite3GlobalConfig.isPCacheInit ){ + sqlite3PcacheShutdown(); + sqlite3GlobalConfig.isPCacheInit = 0; + } + if( sqlite3GlobalConfig.isMallocInit ){ + sqlite3MallocEnd(); + sqlite3GlobalConfig.isMallocInit = 0; + +#ifndef SQLITE_OMIT_SHUTDOWN_DIRECTORIES + /* The heap subsystem has now been shutdown and these values are supposed + ** to be NULL or point to memory that was obtained from sqlite3_malloc(), + ** which would rely on that heap subsystem; therefore, make sure these + ** values cannot refer to heap memory that was just invalidated when the + ** heap subsystem was shutdown. This is only done if the current call to + ** this function resulted in the heap subsystem actually being shutdown. + */ + sqlite3_data_directory = 0; + sqlite3_temp_directory = 0; +#endif + } + if( sqlite3GlobalConfig.isMutexInit ){ + sqlite3MutexEnd(); + sqlite3GlobalConfig.isMutexInit = 0; + } + + return SQLITE_OK; +} + +/* +** This API allows applications to modify the global configuration of +** the SQLite library at run-time. +** +** This routine should only be called when there are no outstanding +** database connections or memory allocations. This routine is not +** threadsafe. Failure to heed these warnings can lead to unpredictable +** behavior. +*/ +SQLITE_API int SQLITE_CDECL sqlite3_config(int op, ...){ + va_list ap; + int rc = SQLITE_OK; + + /* sqlite3_config() shall return SQLITE_MISUSE if it is invoked while + ** the SQLite library is in use. */ + if( sqlite3GlobalConfig.isInit ) return SQLITE_MISUSE_BKPT; + + va_start(ap, op); + switch( op ){ + + /* Mutex configuration options are only available in a threadsafe + ** compile. + */ +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-54466-46756 */ + case SQLITE_CONFIG_SINGLETHREAD: { + /* EVIDENCE-OF: R-02748-19096 This option sets the threading mode to + ** Single-thread. */ + sqlite3GlobalConfig.bCoreMutex = 0; /* Disable mutex on core */ + sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */ + break; + } +#endif +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-20520-54086 */ + case SQLITE_CONFIG_MULTITHREAD: { + /* EVIDENCE-OF: R-14374-42468 This option sets the threading mode to + ** Multi-thread. */ + sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */ + sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */ + break; + } +#endif +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-59593-21810 */ + case SQLITE_CONFIG_SERIALIZED: { + /* EVIDENCE-OF: R-41220-51800 This option sets the threading mode to + ** Serialized. */ + sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */ + sqlite3GlobalConfig.bFullMutex = 1; /* Enable mutex on connections */ + break; + } +#endif +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-63666-48755 */ + case SQLITE_CONFIG_MUTEX: { + /* Specify an alternative mutex implementation */ + sqlite3GlobalConfig.mutex = *va_arg(ap, sqlite3_mutex_methods*); + break; + } +#endif +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-14450-37597 */ + case SQLITE_CONFIG_GETMUTEX: { + /* Retrieve the current mutex implementation */ + *va_arg(ap, sqlite3_mutex_methods*) = sqlite3GlobalConfig.mutex; + break; + } +#endif + + case SQLITE_CONFIG_MALLOC: { + /* EVIDENCE-OF: R-55594-21030 The SQLITE_CONFIG_MALLOC option takes a + ** single argument which is a pointer to an instance of the + ** sqlite3_mem_methods structure. The argument specifies alternative + ** low-level memory allocation routines to be used in place of the memory + ** allocation routines built into SQLite. */ + sqlite3GlobalConfig.m = *va_arg(ap, sqlite3_mem_methods*); + break; + } + case SQLITE_CONFIG_GETMALLOC: { + /* EVIDENCE-OF: R-51213-46414 The SQLITE_CONFIG_GETMALLOC option takes a + ** single argument which is a pointer to an instance of the + ** sqlite3_mem_methods structure. The sqlite3_mem_methods structure is + ** filled with the currently defined memory allocation routines. */ + if( sqlite3GlobalConfig.m.xMalloc==0 ) sqlite3MemSetDefault(); + *va_arg(ap, sqlite3_mem_methods*) = sqlite3GlobalConfig.m; + break; + } + case SQLITE_CONFIG_MEMSTATUS: { + /* EVIDENCE-OF: R-61275-35157 The SQLITE_CONFIG_MEMSTATUS option takes + ** single argument of type int, interpreted as a boolean, which enables + ** or disables the collection of memory allocation statistics. */ + sqlite3GlobalConfig.bMemstat = va_arg(ap, int); + break; + } + case SQLITE_CONFIG_SCRATCH: { + /* EVIDENCE-OF: R-08404-60887 There are three arguments to + ** SQLITE_CONFIG_SCRATCH: A pointer an 8-byte aligned memory buffer from + ** which the scratch allocations will be drawn, the size of each scratch + ** allocation (sz), and the maximum number of scratch allocations (N). */ + sqlite3GlobalConfig.pScratch = va_arg(ap, void*); + sqlite3GlobalConfig.szScratch = va_arg(ap, int); + sqlite3GlobalConfig.nScratch = va_arg(ap, int); + break; + } + case SQLITE_CONFIG_PAGECACHE: { + /* EVIDENCE-OF: R-31408-40510 There are three arguments to + ** SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned memory, the size + ** of each page buffer (sz), and the number of pages (N). */ + sqlite3GlobalConfig.pPage = va_arg(ap, void*); + sqlite3GlobalConfig.szPage = va_arg(ap, int); + sqlite3GlobalConfig.nPage = va_arg(ap, int); + break; + } + case SQLITE_CONFIG_PCACHE_HDRSZ: { + /* EVIDENCE-OF: R-39100-27317 The SQLITE_CONFIG_PCACHE_HDRSZ option takes + ** a single parameter which is a pointer to an integer and writes into + ** that integer the number of extra bytes per page required for each page + ** in SQLITE_CONFIG_PAGECACHE. */ + *va_arg(ap, int*) = + sqlite3HeaderSizeBtree() + + sqlite3HeaderSizePcache() + + sqlite3HeaderSizePcache1(); + break; + } + + case SQLITE_CONFIG_PCACHE: { + /* no-op */ + break; + } + case SQLITE_CONFIG_GETPCACHE: { + /* now an error */ + rc = SQLITE_ERROR; + break; + } + + case SQLITE_CONFIG_PCACHE2: { + /* EVIDENCE-OF: R-63325-48378 The SQLITE_CONFIG_PCACHE2 option takes a + ** single argument which is a pointer to an sqlite3_pcache_methods2 + ** object. This object specifies the interface to a custom page cache + ** implementation. */ + sqlite3GlobalConfig.pcache2 = *va_arg(ap, sqlite3_pcache_methods2*); + break; + } + case SQLITE_CONFIG_GETPCACHE2: { + /* EVIDENCE-OF: R-22035-46182 The SQLITE_CONFIG_GETPCACHE2 option takes a + ** single argument which is a pointer to an sqlite3_pcache_methods2 + ** object. SQLite copies of the current page cache implementation into + ** that object. */ + if( sqlite3GlobalConfig.pcache2.xInit==0 ){ + sqlite3PCacheSetDefault(); + } + *va_arg(ap, sqlite3_pcache_methods2*) = sqlite3GlobalConfig.pcache2; + break; + } + +/* EVIDENCE-OF: R-06626-12911 The SQLITE_CONFIG_HEAP option is only +** available if SQLite is compiled with either SQLITE_ENABLE_MEMSYS3 or +** SQLITE_ENABLE_MEMSYS5 and returns SQLITE_ERROR if invoked otherwise. */ +#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) + case SQLITE_CONFIG_HEAP: { + /* EVIDENCE-OF: R-19854-42126 There are three arguments to + ** SQLITE_CONFIG_HEAP: An 8-byte aligned pointer to the memory, the + ** number of bytes in the memory buffer, and the minimum allocation size. + */ + sqlite3GlobalConfig.pHeap = va_arg(ap, void*); + sqlite3GlobalConfig.nHeap = va_arg(ap, int); + sqlite3GlobalConfig.mnReq = va_arg(ap, int); + + if( sqlite3GlobalConfig.mnReq<1 ){ + sqlite3GlobalConfig.mnReq = 1; + }else if( sqlite3GlobalConfig.mnReq>(1<<12) ){ + /* cap min request size at 2^12 */ + sqlite3GlobalConfig.mnReq = (1<<12); + } + + if( sqlite3GlobalConfig.pHeap==0 ){ + /* EVIDENCE-OF: R-49920-60189 If the first pointer (the memory pointer) + ** is NULL, then SQLite reverts to using its default memory allocator + ** (the system malloc() implementation), undoing any prior invocation of + ** SQLITE_CONFIG_MALLOC. + ** + ** Setting sqlite3GlobalConfig.m to all zeros will cause malloc to + ** revert to its default implementation when sqlite3_initialize() is run + */ + memset(&sqlite3GlobalConfig.m, 0, sizeof(sqlite3GlobalConfig.m)); + }else{ + /* EVIDENCE-OF: R-61006-08918 If the memory pointer is not NULL then the + ** alternative memory allocator is engaged to handle all of SQLites + ** memory allocation needs. */ +#ifdef SQLITE_ENABLE_MEMSYS3 + sqlite3GlobalConfig.m = *sqlite3MemGetMemsys3(); +#endif +#ifdef SQLITE_ENABLE_MEMSYS5 + sqlite3GlobalConfig.m = *sqlite3MemGetMemsys5(); +#endif + } + break; + } +#endif + + case SQLITE_CONFIG_LOOKASIDE: { + sqlite3GlobalConfig.szLookaside = va_arg(ap, int); + sqlite3GlobalConfig.nLookaside = va_arg(ap, int); + break; + } + + /* Record a pointer to the logger function and its first argument. + ** The default is NULL. Logging is disabled if the function pointer is + ** NULL. + */ + case SQLITE_CONFIG_LOG: { + /* MSVC is picky about pulling func ptrs from va lists. + ** http://support.microsoft.com/kb/47961 + ** sqlite3GlobalConfig.xLog = va_arg(ap, void(*)(void*,int,const char*)); + */ + typedef void(*LOGFUNC_t)(void*,int,const char*); + sqlite3GlobalConfig.xLog = va_arg(ap, LOGFUNC_t); + sqlite3GlobalConfig.pLogArg = va_arg(ap, void*); + break; + } + + /* EVIDENCE-OF: R-55548-33817 The compile-time setting for URI filenames + ** can be changed at start-time using the + ** sqlite3_config(SQLITE_CONFIG_URI,1) or + ** sqlite3_config(SQLITE_CONFIG_URI,0) configuration calls. + */ + case SQLITE_CONFIG_URI: { + /* EVIDENCE-OF: R-25451-61125 The SQLITE_CONFIG_URI option takes a single + ** argument of type int. If non-zero, then URI handling is globally + ** enabled. If the parameter is zero, then URI handling is globally + ** disabled. */ + sqlite3GlobalConfig.bOpenUri = va_arg(ap, int); + break; + } + + case SQLITE_CONFIG_COVERING_INDEX_SCAN: { + /* EVIDENCE-OF: R-36592-02772 The SQLITE_CONFIG_COVERING_INDEX_SCAN + ** option takes a single integer argument which is interpreted as a + ** boolean in order to enable or disable the use of covering indices for + ** full table scans in the query optimizer. */ + sqlite3GlobalConfig.bUseCis = va_arg(ap, int); + break; + } + +#ifdef SQLITE_ENABLE_SQLLOG + case SQLITE_CONFIG_SQLLOG: { + typedef void(*SQLLOGFUNC_t)(void*, sqlite3*, const char*, int); + sqlite3GlobalConfig.xSqllog = va_arg(ap, SQLLOGFUNC_t); + sqlite3GlobalConfig.pSqllogArg = va_arg(ap, void *); + break; + } +#endif + + case SQLITE_CONFIG_MMAP_SIZE: { + /* EVIDENCE-OF: R-58063-38258 SQLITE_CONFIG_MMAP_SIZE takes two 64-bit + ** integer (sqlite3_int64) values that are the default mmap size limit + ** (the default setting for PRAGMA mmap_size) and the maximum allowed + ** mmap size limit. */ + sqlite3_int64 szMmap = va_arg(ap, sqlite3_int64); + sqlite3_int64 mxMmap = va_arg(ap, sqlite3_int64); + /* EVIDENCE-OF: R-53367-43190 If either argument to this option is + ** negative, then that argument is changed to its compile-time default. + ** + ** EVIDENCE-OF: R-34993-45031 The maximum allowed mmap size will be + ** silently truncated if necessary so that it does not exceed the + ** compile-time maximum mmap size set by the SQLITE_MAX_MMAP_SIZE + ** compile-time option. + */ + if( mxMmap<0 || mxMmap>SQLITE_MAX_MMAP_SIZE ){ + mxMmap = SQLITE_MAX_MMAP_SIZE; + } + if( szMmap<0 ) szMmap = SQLITE_DEFAULT_MMAP_SIZE; + if( szMmap>mxMmap) szMmap = mxMmap; + sqlite3GlobalConfig.mxMmap = mxMmap; + sqlite3GlobalConfig.szMmap = szMmap; + break; + } + +#if SQLITE_OS_WIN && defined(SQLITE_WIN32_MALLOC) /* IMP: R-04780-55815 */ + case SQLITE_CONFIG_WIN32_HEAPSIZE: { + /* EVIDENCE-OF: R-34926-03360 SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit + ** unsigned integer value that specifies the maximum size of the created + ** heap. */ + sqlite3GlobalConfig.nHeap = va_arg(ap, int); + break; + } +#endif + + case SQLITE_CONFIG_PMASZ: { + sqlite3GlobalConfig.szPma = va_arg(ap, unsigned int); + break; + } + + default: { + rc = SQLITE_ERROR; + break; + } + } + va_end(ap); + return rc; +} + +/* +** Set up the lookaside buffers for a database connection. +** Return SQLITE_OK on success. +** If lookaside is already active, return SQLITE_BUSY. +** +** The sz parameter is the number of bytes in each lookaside slot. +** The cnt parameter is the number of slots. If pStart is NULL the +** space for the lookaside memory is obtained from sqlite3_malloc(). +** If pStart is not NULL then it is sz*cnt bytes of memory to use for +** the lookaside memory. +*/ +static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ + void *pStart; + if( db->lookaside.nOut ){ + return SQLITE_BUSY; + } + /* Free any existing lookaside buffer for this handle before + ** allocating a new one so we don't have to have space for + ** both at the same time. + */ + if( db->lookaside.bMalloced ){ + sqlite3_free(db->lookaside.pStart); + } + /* The size of a lookaside slot after ROUNDDOWN8 needs to be larger + ** than a pointer to be useful. + */ + sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */ + if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0; + if( cnt<0 ) cnt = 0; + if( sz==0 || cnt==0 ){ + sz = 0; + pStart = 0; + }else if( pBuf==0 ){ + sqlite3BeginBenignMalloc(); + pStart = sqlite3Malloc( sz*cnt ); /* IMP: R-61949-35727 */ + sqlite3EndBenignMalloc(); + if( pStart ) cnt = sqlite3MallocSize(pStart)/sz; + }else{ + pStart = pBuf; + } + db->lookaside.pStart = pStart; + db->lookaside.pFree = 0; + db->lookaside.sz = (u16)sz; + if( pStart ){ + int i; + LookasideSlot *p; + assert( sz > (int)sizeof(LookasideSlot*) ); + p = (LookasideSlot*)pStart; + for(i=cnt-1; i>=0; i--){ + p->pNext = db->lookaside.pFree; + db->lookaside.pFree = p; + p = (LookasideSlot*)&((u8*)p)[sz]; + } + db->lookaside.pEnd = p; + db->lookaside.bEnabled = 1; + db->lookaside.bMalloced = pBuf==0 ?1:0; + }else{ + db->lookaside.pStart = db; + db->lookaside.pEnd = db; + db->lookaside.bEnabled = 0; + db->lookaside.bMalloced = 0; + } + return SQLITE_OK; +} + +/* +** Return the mutex associated with a database connection. +*/ +SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3 *db){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + return db->mutex; +} + +/* +** Free up as much memory as we can from the given database +** connection. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3 *db){ + int i; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); + for(i=0; inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + Pager *pPager = sqlite3BtreePager(pBt); + sqlite3PagerShrink(pPager); + } + } + sqlite3BtreeLeaveAll(db); + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +/* +** Configuration settings for an individual database connection +*/ +SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3 *db, int op, ...){ + va_list ap; + int rc; + va_start(ap, op); + switch( op ){ + case SQLITE_DBCONFIG_LOOKASIDE: { + void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */ + int sz = va_arg(ap, int); /* IMP: R-47871-25994 */ + int cnt = va_arg(ap, int); /* IMP: R-04460-53386 */ + rc = setupLookaside(db, pBuf, sz, cnt); + break; + } + default: { + static const struct { + int op; /* The opcode */ + u32 mask; /* Mask of the bit in sqlite3.flags to set/clear */ + } aFlagOp[] = { + { SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys }, + { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger }, + }; + unsigned int i; + rc = SQLITE_ERROR; /* IMP: R-42790-23372 */ + for(i=0; iflags; + if( onoff>0 ){ + db->flags |= aFlagOp[i].mask; + }else if( onoff==0 ){ + db->flags &= ~aFlagOp[i].mask; + } + if( oldFlags!=db->flags ){ + sqlite3ExpirePreparedStatements(db); + } + if( pRes ){ + *pRes = (db->flags & aFlagOp[i].mask)!=0; + } + rc = SQLITE_OK; + break; + } + } + break; + } + } + va_end(ap); + return rc; +} + + +/* +** Return true if the buffer z[0..n-1] contains all spaces. +*/ +static int allSpaces(const char *z, int n){ + while( n>0 && z[n-1]==' ' ){ n--; } + return n==0; +} + +/* +** This is the default collating function named "BINARY" which is always +** available. +** +** If the padFlag argument is not NULL then space padding at the end +** of strings is ignored. This implements the RTRIM collation. +*/ +static int binCollFunc( + void *padFlag, + int nKey1, const void *pKey1, + int nKey2, const void *pKey2 +){ + int rc, n; + n = nKey1lastRowid; +} + +/* +** Return the number of changes in the most recent call to sqlite3_exec(). +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3 *db){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + return db->nChange; +} + +/* +** Return the number of changes since the database handle was opened. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3 *db){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + return db->nTotalChange; +} + +/* +** Close all open savepoints. This function only manipulates fields of the +** database handle object, it does not close any savepoints that may be open +** at the b-tree/pager level. +*/ +SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *db){ + while( db->pSavepoint ){ + Savepoint *pTmp = db->pSavepoint; + db->pSavepoint = pTmp->pNext; + sqlite3DbFree(db, pTmp); + } + db->nSavepoint = 0; + db->nStatement = 0; + db->isTransactionSavepoint = 0; +} + +/* +** Invoke the destructor function associated with FuncDef p, if any. Except, +** if this is not the last copy of the function, do not invoke it. Multiple +** copies of a single function are created when create_function() is called +** with SQLITE_ANY as the encoding. +*/ +static void functionDestroy(sqlite3 *db, FuncDef *p){ + FuncDestructor *pDestructor = p->pDestructor; + if( pDestructor ){ + pDestructor->nRef--; + if( pDestructor->nRef==0 ){ + pDestructor->xDestroy(pDestructor->pUserData); + sqlite3DbFree(db, pDestructor); + } + } +} + +/* +** Disconnect all sqlite3_vtab objects that belong to database connection +** db. This is called when db is being closed. +*/ +static void disconnectAllVtab(sqlite3 *db){ +#ifndef SQLITE_OMIT_VIRTUALTABLE + int i; + sqlite3BtreeEnterAll(db); + for(i=0; inDb; i++){ + Schema *pSchema = db->aDb[i].pSchema; + if( db->aDb[i].pSchema ){ + HashElem *p; + for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){ + Table *pTab = (Table *)sqliteHashData(p); + if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab); + } + } + } + sqlite3VtabUnlockList(db); + sqlite3BtreeLeaveAll(db); +#else + UNUSED_PARAMETER(db); +#endif +} + +/* +** Return TRUE if database connection db has unfinalized prepared +** statements or unfinished sqlite3_backup objects. +*/ +static int connectionIsBusy(sqlite3 *db){ + int j; + assert( sqlite3_mutex_held(db->mutex) ); + if( db->pVdbe ) return 1; + for(j=0; jnDb; j++){ + Btree *pBt = db->aDb[j].pBt; + if( pBt && sqlite3BtreeIsInBackup(pBt) ) return 1; + } + return 0; +} + +/* +** Close an existing SQLite database +*/ +static int sqlite3Close(sqlite3 *db, int forceZombie){ + if( !db ){ + /* EVIDENCE-OF: R-63257-11740 Calling sqlite3_close() or + ** sqlite3_close_v2() with a NULL pointer argument is a harmless no-op. */ + return SQLITE_OK; + } + if( !sqlite3SafetyCheckSickOrOk(db) ){ + return SQLITE_MISUSE_BKPT; + } + sqlite3_mutex_enter(db->mutex); + + /* Force xDisconnect calls on all virtual tables */ + disconnectAllVtab(db); + + /* If a transaction is open, the disconnectAllVtab() call above + ** will not have called the xDisconnect() method on any virtual + ** tables in the db->aVTrans[] array. The following sqlite3VtabRollback() + ** call will do so. We need to do this before the check for active + ** SQL statements below, as the v-table implementation may be storing + ** some prepared statements internally. + */ + sqlite3VtabRollback(db); + + /* Legacy behavior (sqlite3_close() behavior) is to return + ** SQLITE_BUSY if the connection can not be closed immediately. + */ + if( !forceZombie && connectionIsBusy(db) ){ + sqlite3ErrorWithMsg(db, SQLITE_BUSY, "unable to close due to unfinalized " + "statements or unfinished backups"); + sqlite3_mutex_leave(db->mutex); + return SQLITE_BUSY; + } + +#ifdef SQLITE_ENABLE_SQLLOG + if( sqlite3GlobalConfig.xSqllog ){ + /* Closing the handle. Fourth parameter is passed the value 2. */ + sqlite3GlobalConfig.xSqllog(sqlite3GlobalConfig.pSqllogArg, db, 0, 2); + } +#endif + + /* Convert the connection into a zombie and then close it. + */ + db->magic = SQLITE_MAGIC_ZOMBIE; + sqlite3LeaveMutexAndCloseZombie(db); + return SQLITE_OK; +} + +/* +** Two variations on the public interface for closing a database +** connection. The sqlite3_close() version returns SQLITE_BUSY and +** leaves the connection option if there are unfinalized prepared +** statements or unfinished sqlite3_backups. The sqlite3_close_v2() +** version forces the connection to become a zombie if there are +** unclosed resources, and arranges for deallocation when the last +** prepare statement or sqlite3_backup closes. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); } +SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); } + + +/* +** Close the mutex on database connection db. +** +** Furthermore, if database connection db is a zombie (meaning that there +** has been a prior call to sqlite3_close(db) or sqlite3_close_v2(db)) and +** every sqlite3_stmt has now been finalized and every sqlite3_backup has +** finished, then free all resources. +*/ +SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ + HashElem *i; /* Hash table iterator */ + int j; + + /* If there are outstanding sqlite3_stmt or sqlite3_backup objects + ** or if the connection has not yet been closed by sqlite3_close_v2(), + ** then just leave the mutex and return. + */ + if( db->magic!=SQLITE_MAGIC_ZOMBIE || connectionIsBusy(db) ){ + sqlite3_mutex_leave(db->mutex); + return; + } + + /* If we reach this point, it means that the database connection has + ** closed all sqlite3_stmt and sqlite3_backup objects and has been + ** passed to sqlite3_close (meaning that it is a zombie). Therefore, + ** go ahead and free all resources. + */ + + /* If a transaction is open, roll it back. This also ensures that if + ** any database schemas have been modified by an uncommitted transaction + ** they are reset. And that the required b-tree mutex is held to make + ** the pager rollback and schema reset an atomic operation. */ + sqlite3RollbackAll(db, SQLITE_OK); + + /* Free any outstanding Savepoint structures. */ + sqlite3CloseSavepoints(db); + + /* Close all database connections */ + for(j=0; jnDb; j++){ + struct Db *pDb = &db->aDb[j]; + if( pDb->pBt ){ + sqlite3BtreeClose(pDb->pBt); + pDb->pBt = 0; + if( j!=1 ){ + pDb->pSchema = 0; + } + } + } + /* Clear the TEMP schema separately and last */ + if( db->aDb[1].pSchema ){ + sqlite3SchemaClear(db->aDb[1].pSchema); + } + sqlite3VtabUnlockList(db); + + /* Free up the array of auxiliary databases */ + sqlite3CollapseDatabaseArray(db); + assert( db->nDb<=2 ); + assert( db->aDb==db->aDbStatic ); + + /* Tell the code in notify.c that the connection no longer holds any + ** locks and does not require any further unlock-notify callbacks. + */ + sqlite3ConnectionClosed(db); + + for(j=0; jaFunc.a); j++){ + FuncDef *pNext, *pHash, *p; + for(p=db->aFunc.a[j]; p; p=pHash){ + pHash = p->pHash; + while( p ){ + functionDestroy(db, p); + pNext = p->pNext; + sqlite3DbFree(db, p); + p = pNext; + } + } + } + for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){ + CollSeq *pColl = (CollSeq *)sqliteHashData(i); + /* Invoke any destructors registered for collation sequence user data. */ + for(j=0; j<3; j++){ + if( pColl[j].xDel ){ + pColl[j].xDel(pColl[j].pUser); + } + } + sqlite3DbFree(db, pColl); + } + sqlite3HashClear(&db->aCollSeq); +#ifndef SQLITE_OMIT_VIRTUALTABLE + for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){ + Module *pMod = (Module *)sqliteHashData(i); + if( pMod->xDestroy ){ + pMod->xDestroy(pMod->pAux); + } + sqlite3DbFree(db, pMod); + } + sqlite3HashClear(&db->aModule); +#endif + + sqlite3Error(db, SQLITE_OK); /* Deallocates any cached error strings. */ + sqlite3ValueFree(db->pErr); + sqlite3CloseExtensions(db); +#if SQLITE_USER_AUTHENTICATION + sqlite3_free(db->auth.zAuthUser); + sqlite3_free(db->auth.zAuthPW); +#endif + + 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? + */ + sqlite3DbFree(db, db->aDb[1].pSchema); + sqlite3_mutex_leave(db->mutex); + db->magic = SQLITE_MAGIC_CLOSED; + sqlite3_mutex_free(db->mutex); + assert( db->lookaside.nOut==0 ); /* Fails on a lookaside memory leak */ + if( db->lookaside.bMalloced ){ + sqlite3_free(db->lookaside.pStart); + } + sqlite3_free(db); +} + +/* +** Rollback all database files. If tripCode is not SQLITE_OK, then +** any write cursors are invalidated ("tripped" - as in "tripping a circuit +** breaker") and made to return tripCode if there are any further +** attempts to use that cursor. Read cursors remain open and valid +** but are "saved" in case the table pages are moved around. +*/ +SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){ + int i; + int inTrans = 0; + int schemaChange; + assert( sqlite3_mutex_held(db->mutex) ); + sqlite3BeginBenignMalloc(); + + /* Obtain all b-tree mutexes before making any calls to BtreeRollback(). + ** This is important in case the transaction being rolled back has + ** modified the database schema. If the b-tree mutexes are not taken + ** here, then another shared-cache connection might sneak in between + ** the database rollback and schema reset, which can cause false + ** corruption reports in some cases. */ + sqlite3BtreeEnterAll(db); + schemaChange = (db->flags & SQLITE_InternChanges)!=0 && db->init.busy==0; + + for(i=0; inDb; i++){ + Btree *p = db->aDb[i].pBt; + if( p ){ + if( sqlite3BtreeIsInTrans(p) ){ + inTrans = 1; + } + sqlite3BtreeRollback(p, tripCode, !schemaChange); + } + } + sqlite3VtabRollback(db); + sqlite3EndBenignMalloc(); + + if( (db->flags&SQLITE_InternChanges)!=0 && db->init.busy==0 ){ + sqlite3ExpirePreparedStatements(db); + sqlite3ResetAllSchemasOfConnection(db); + } + sqlite3BtreeLeaveAll(db); + + /* Any deferred constraint violations have now been resolved. */ + db->nDeferredCons = 0; + db->nDeferredImmCons = 0; + db->flags &= ~SQLITE_DeferFKs; + + /* If one has been configured, invoke the rollback-hook callback */ + if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){ + db->xRollbackCallback(db->pRollbackArg); + } +} + +/* +** Return a static string containing the name corresponding to the error code +** specified in the argument. +*/ +#if defined(SQLITE_NEED_ERR_NAME) +SQLITE_PRIVATE const char *sqlite3ErrName(int rc){ + const char *zName = 0; + int i, origRc = rc; + for(i=0; i<2 && zName==0; i++, rc &= 0xff){ + switch( rc ){ + case SQLITE_OK: zName = "SQLITE_OK"; break; + case SQLITE_ERROR: zName = "SQLITE_ERROR"; break; + case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break; + case SQLITE_PERM: zName = "SQLITE_PERM"; break; + case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; + case SQLITE_ABORT_ROLLBACK: zName = "SQLITE_ABORT_ROLLBACK"; break; + case SQLITE_BUSY: zName = "SQLITE_BUSY"; break; + case SQLITE_BUSY_RECOVERY: zName = "SQLITE_BUSY_RECOVERY"; break; + case SQLITE_BUSY_SNAPSHOT: zName = "SQLITE_BUSY_SNAPSHOT"; break; + case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break; + case SQLITE_LOCKED_SHAREDCACHE: zName = "SQLITE_LOCKED_SHAREDCACHE";break; + case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; + case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; + case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break; + case SQLITE_READONLY_CANTLOCK: zName = "SQLITE_READONLY_CANTLOCK"; break; + case SQLITE_READONLY_ROLLBACK: zName = "SQLITE_READONLY_ROLLBACK"; break; + case SQLITE_READONLY_DBMOVED: zName = "SQLITE_READONLY_DBMOVED"; break; + case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; + case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; + case SQLITE_IOERR_READ: zName = "SQLITE_IOERR_READ"; break; + case SQLITE_IOERR_SHORT_READ: zName = "SQLITE_IOERR_SHORT_READ"; break; + case SQLITE_IOERR_WRITE: zName = "SQLITE_IOERR_WRITE"; break; + case SQLITE_IOERR_FSYNC: zName = "SQLITE_IOERR_FSYNC"; break; + case SQLITE_IOERR_DIR_FSYNC: zName = "SQLITE_IOERR_DIR_FSYNC"; break; + case SQLITE_IOERR_TRUNCATE: zName = "SQLITE_IOERR_TRUNCATE"; break; + case SQLITE_IOERR_FSTAT: zName = "SQLITE_IOERR_FSTAT"; break; + case SQLITE_IOERR_UNLOCK: zName = "SQLITE_IOERR_UNLOCK"; break; + case SQLITE_IOERR_RDLOCK: zName = "SQLITE_IOERR_RDLOCK"; break; + case SQLITE_IOERR_DELETE: zName = "SQLITE_IOERR_DELETE"; break; + case SQLITE_IOERR_NOMEM: zName = "SQLITE_IOERR_NOMEM"; break; + case SQLITE_IOERR_ACCESS: zName = "SQLITE_IOERR_ACCESS"; break; + case SQLITE_IOERR_CHECKRESERVEDLOCK: + zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break; + case SQLITE_IOERR_LOCK: zName = "SQLITE_IOERR_LOCK"; break; + case SQLITE_IOERR_CLOSE: zName = "SQLITE_IOERR_CLOSE"; break; + case SQLITE_IOERR_DIR_CLOSE: zName = "SQLITE_IOERR_DIR_CLOSE"; break; + case SQLITE_IOERR_SHMOPEN: zName = "SQLITE_IOERR_SHMOPEN"; break; + case SQLITE_IOERR_SHMSIZE: zName = "SQLITE_IOERR_SHMSIZE"; break; + case SQLITE_IOERR_SHMLOCK: zName = "SQLITE_IOERR_SHMLOCK"; break; + case SQLITE_IOERR_SHMMAP: zName = "SQLITE_IOERR_SHMMAP"; break; + case SQLITE_IOERR_SEEK: zName = "SQLITE_IOERR_SEEK"; break; + case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break; + case SQLITE_IOERR_MMAP: zName = "SQLITE_IOERR_MMAP"; break; + case SQLITE_IOERR_GETTEMPPATH: zName = "SQLITE_IOERR_GETTEMPPATH"; break; + case SQLITE_IOERR_CONVPATH: zName = "SQLITE_IOERR_CONVPATH"; break; + case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; + case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break; + case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break; + case SQLITE_FULL: zName = "SQLITE_FULL"; break; + case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; + case SQLITE_CANTOPEN_NOTEMPDIR: zName = "SQLITE_CANTOPEN_NOTEMPDIR";break; + case SQLITE_CANTOPEN_ISDIR: zName = "SQLITE_CANTOPEN_ISDIR"; break; + case SQLITE_CANTOPEN_FULLPATH: zName = "SQLITE_CANTOPEN_FULLPATH"; break; + case SQLITE_CANTOPEN_CONVPATH: zName = "SQLITE_CANTOPEN_CONVPATH"; break; + case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; + case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; + case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break; + case SQLITE_TOOBIG: zName = "SQLITE_TOOBIG"; break; + case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break; + case SQLITE_CONSTRAINT_UNIQUE: zName = "SQLITE_CONSTRAINT_UNIQUE"; break; + case SQLITE_CONSTRAINT_TRIGGER: zName = "SQLITE_CONSTRAINT_TRIGGER";break; + case SQLITE_CONSTRAINT_FOREIGNKEY: + zName = "SQLITE_CONSTRAINT_FOREIGNKEY"; break; + case SQLITE_CONSTRAINT_CHECK: zName = "SQLITE_CONSTRAINT_CHECK"; break; + case SQLITE_CONSTRAINT_PRIMARYKEY: + zName = "SQLITE_CONSTRAINT_PRIMARYKEY"; break; + case SQLITE_CONSTRAINT_NOTNULL: zName = "SQLITE_CONSTRAINT_NOTNULL";break; + case SQLITE_CONSTRAINT_COMMITHOOK: + zName = "SQLITE_CONSTRAINT_COMMITHOOK"; break; + case SQLITE_CONSTRAINT_VTAB: zName = "SQLITE_CONSTRAINT_VTAB"; break; + case SQLITE_CONSTRAINT_FUNCTION: + zName = "SQLITE_CONSTRAINT_FUNCTION"; break; + case SQLITE_CONSTRAINT_ROWID: zName = "SQLITE_CONSTRAINT_ROWID"; break; + case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break; + case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break; + case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break; + case SQLITE_AUTH: zName = "SQLITE_AUTH"; break; + case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break; + case SQLITE_RANGE: zName = "SQLITE_RANGE"; break; + case SQLITE_NOTADB: zName = "SQLITE_NOTADB"; break; + case SQLITE_ROW: zName = "SQLITE_ROW"; break; + case SQLITE_NOTICE: zName = "SQLITE_NOTICE"; break; + case SQLITE_NOTICE_RECOVER_WAL: zName = "SQLITE_NOTICE_RECOVER_WAL";break; + case SQLITE_NOTICE_RECOVER_ROLLBACK: + zName = "SQLITE_NOTICE_RECOVER_ROLLBACK"; break; + case SQLITE_WARNING: zName = "SQLITE_WARNING"; break; + case SQLITE_WARNING_AUTOINDEX: zName = "SQLITE_WARNING_AUTOINDEX"; break; + case SQLITE_DONE: zName = "SQLITE_DONE"; break; + } + } + if( zName==0 ){ + static char zBuf[50]; + sqlite3_snprintf(sizeof(zBuf), zBuf, "SQLITE_UNKNOWN(%d)", origRc); + zName = zBuf; + } + return zName; +} +#endif + +/* +** Return a static string that describes the kind of error specified in the +** argument. +*/ +SQLITE_PRIVATE const char *sqlite3ErrStr(int rc){ + static const char* const aMsg[] = { + /* SQLITE_OK */ "not an error", + /* SQLITE_ERROR */ "SQL logic error or missing database", + /* SQLITE_INTERNAL */ 0, + /* SQLITE_PERM */ "access permission denied", + /* SQLITE_ABORT */ "callback requested query abort", + /* SQLITE_BUSY */ "database is locked", + /* SQLITE_LOCKED */ "database table is locked", + /* SQLITE_NOMEM */ "out of memory", + /* SQLITE_READONLY */ "attempt to write a readonly database", + /* SQLITE_INTERRUPT */ "interrupted", + /* SQLITE_IOERR */ "disk I/O error", + /* SQLITE_CORRUPT */ "database disk image is malformed", + /* SQLITE_NOTFOUND */ "unknown operation", + /* SQLITE_FULL */ "database or disk is full", + /* SQLITE_CANTOPEN */ "unable to open database file", + /* SQLITE_PROTOCOL */ "locking protocol", + /* SQLITE_EMPTY */ "table contains no data", + /* SQLITE_SCHEMA */ "database schema has changed", + /* SQLITE_TOOBIG */ "string or blob too big", + /* SQLITE_CONSTRAINT */ "constraint failed", + /* SQLITE_MISMATCH */ "datatype mismatch", + /* SQLITE_MISUSE */ "library routine called out of sequence", + /* SQLITE_NOLFS */ "large file support is disabled", + /* SQLITE_AUTH */ "authorization denied", + /* SQLITE_FORMAT */ "auxiliary database format error", + /* SQLITE_RANGE */ "bind or column index out of range", + /* SQLITE_NOTADB */ "file is encrypted or is not a database", + }; + const char *zErr = "unknown error"; + switch( rc ){ + case SQLITE_ABORT_ROLLBACK: { + zErr = "abort due to ROLLBACK"; + break; + } + default: { + rc &= 0xff; + if( ALWAYS(rc>=0) && rcbusyTimeout; + 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(db->pVfs, delay*1000); + return 1; +#else + sqlite3 *db = (sqlite3 *)ptr; + int timeout = ((sqlite3 *)ptr)->busyTimeout; + if( (count+1)*1000 > timeout ){ + return 0; + } + sqlite3OsSleep(db->pVfs, 1000000); + 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. +*/ +SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p){ + int rc; + if( NEVER(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. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler( + sqlite3 *db, + int (*xBusy)(void*,int), + void *pArg +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + db->busyHandler.xFunc = xBusy; + db->busyHandler.pArg = pArg; + db->busyHandler.nBusy = 0; + db->busyTimeout = 0; + sqlite3_mutex_leave(db->mutex); + 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 +** be invoked every nOps opcodes. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler( + sqlite3 *db, + int nOps, + int (*xProgress)(void*), + void *pArg +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return; + } +#endif + sqlite3_mutex_enter(db->mutex); + if( nOps>0 ){ + db->xProgress = xProgress; + db->nProgressOps = (unsigned)nOps; + db->pProgressArg = pArg; + }else{ + db->xProgress = 0; + db->nProgressOps = 0; + db->pProgressArg = 0; + } + sqlite3_mutex_leave(db->mutex); +} +#endif + + +/* +** This routine installs a default busy handler that waits for the +** specified number of milliseconds before returning 0. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3 *db, int ms){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + if( ms>0 ){ + sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db); + db->busyTimeout = ms; + }else{ + sqlite3_busy_handler(db, 0, 0); + } + return SQLITE_OK; +} + +/* +** Cause any pending operation to stop at its earliest opportunity. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3 *db){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return; + } +#endif + db->u1.isInterrupted = 1; +} + + +/* +** This function is exactly the same as sqlite3_create_function(), except +** that it is designed to be called by internal code. The difference is +** that if a malloc() fails in sqlite3_create_function(), an error code +** is returned and the mallocFailed flag cleared. +*/ +SQLITE_PRIVATE int sqlite3CreateFunc( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int enc, + void *pUserData, + void (*xFunc)(sqlite3_context*,int,sqlite3_value **), + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*), + FuncDestructor *pDestructor +){ + FuncDef *p; + int nName; + int extraFlags; + + assert( sqlite3_mutex_held(db->mutex) ); + if( zFunctionName==0 || + (xFunc && (xFinal || xStep)) || + (!xFunc && (xFinal && !xStep)) || + (!xFunc && (!xFinal && xStep)) || + (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) || + (255<(nName = sqlite3Strlen30( zFunctionName))) ){ + return SQLITE_MISUSE_BKPT; + } + + assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); + extraFlags = enc & SQLITE_DETERMINISTIC; + enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); + +#ifndef SQLITE_OMIT_UTF16 + /* If SQLITE_UTF16 is specified as the encoding type, transform this + ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the + ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally. + ** + ** If SQLITE_ANY is specified, add three versions of the function + ** to the hash table. + */ + if( enc==SQLITE_UTF16 ){ + enc = SQLITE_UTF16NATIVE; + }else if( enc==SQLITE_ANY ){ + int rc; + rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8|extraFlags, + pUserData, xFunc, xStep, xFinal, pDestructor); + if( rc==SQLITE_OK ){ + rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE|extraFlags, + pUserData, xFunc, xStep, xFinal, pDestructor); + } + if( rc!=SQLITE_OK ){ + return rc; + } + enc = SQLITE_UTF16BE; + } +#else + enc = SQLITE_UTF8; +#endif + + /* Check if an existing function is being overridden or deleted. If so, + ** and there are active VMs, then return SQLITE_BUSY. If a function + ** is being overridden/deleted but there are no active VMs, allow the + ** operation to continue but invalidate all precompiled statements. + */ + p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0); + if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){ + if( db->nVdbeActive ){ + sqlite3ErrorWithMsg(db, SQLITE_BUSY, + "unable to delete/modify user-function due to active statements"); + assert( !db->mallocFailed ); + return SQLITE_BUSY; + }else{ + sqlite3ExpirePreparedStatements(db); + } + } + + p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 1); + assert(p || db->mallocFailed); + if( !p ){ + return SQLITE_NOMEM; + } + + /* If an older version of the function with a configured destructor is + ** being replaced invoke the destructor function here. */ + functionDestroy(db, p); + + if( pDestructor ){ + pDestructor->nRef++; + } + p->pDestructor = pDestructor; + p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags; + testcase( p->funcFlags & SQLITE_DETERMINISTIC ); + p->xFunc = xFunc; + p->xStep = xStep; + p->xFinalize = xFinal; + p->pUserData = pUserData; + p->nArg = (u16)nArg; + return SQLITE_OK; +} + +/* +** Create new user functions. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_create_function( + sqlite3 *db, + const char *zFunc, + int nArg, + int enc, + void *p, + void (*xFunc)(sqlite3_context*,int,sqlite3_value **), + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*) +){ + return sqlite3_create_function_v2(db, zFunc, nArg, enc, p, xFunc, xStep, + xFinal, 0); +} + +SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2( + sqlite3 *db, + const char *zFunc, + int nArg, + int enc, + void *p, + void (*xFunc)(sqlite3_context*,int,sqlite3_value **), + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*), + void (*xDestroy)(void *) +){ + int rc = SQLITE_ERROR; + FuncDestructor *pArg = 0; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + return SQLITE_MISUSE_BKPT; + } +#endif + sqlite3_mutex_enter(db->mutex); + if( xDestroy ){ + pArg = (FuncDestructor *)sqlite3DbMallocZero(db, sizeof(FuncDestructor)); + if( !pArg ){ + xDestroy(p); + goto out; + } + pArg->xDestroy = xDestroy; + pArg->pUserData = p; + } + rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, xFunc, xStep, xFinal, pArg); + if( pArg && pArg->nRef==0 ){ + assert( rc!=SQLITE_OK ); + xDestroy(p); + sqlite3DbFree(db, pArg); + } + + out: + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API int SQLITE_STDCALL sqlite3_create_function16( + sqlite3 *db, + const void *zFunctionName, + int nArg, + int eTextRep, + void *p, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +){ + int rc; + char *zFunc8; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zFunctionName==0 ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + assert( !db->mallocFailed ); + zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE); + rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal,0); + sqlite3DbFree(db, zFunc8); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} +#endif + + +/* +** Declare that a function has been overloaded by a virtual table. +** +** If the function already exists as a regular global function, then +** this routine is a no-op. If the function does not exist, then create +** a new one that always throws a run-time error. +** +** When virtual tables intend to provide an overloaded function, they +** should call this routine to make sure the global function exists. +** A global function must exist in order for name resolution to work +** properly. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_overload_function( + sqlite3 *db, + const char *zName, + int nArg +){ + int nName = sqlite3Strlen30(zName); + int rc = SQLITE_OK; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zName==0 || nArg<-2 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + sqlite3_mutex_enter(db->mutex); + if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){ + rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8, + 0, sqlite3InvalidFunction, 0, 0, 0); + } + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +#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. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){ + void *pOld; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + pOld = db->pTraceArg; + db->xTrace = xTrace; + db->pTraceArg = pArg; + sqlite3_mutex_leave(db->mutex); + 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. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_profile( + sqlite3 *db, + void (*xProfile)(void*,const char*,sqlite_uint64), + void *pArg +){ + void *pOld; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + pOld = db->pProfileArg; + db->xProfile = xProfile; + db->pProfileArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pOld; +} +#endif /* SQLITE_OMIT_TRACE */ + +/* +** Register a function to be invoked when a transaction commits. +** If the invoked function returns non-zero, then the commit becomes a +** rollback. +*/ +SQLITE_API void *SQLITE_STDCALL 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; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + pOld = db->pCommitArg; + db->xCommitCallback = xCallback; + db->pCommitArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pOld; +} + +/* +** Register a callback to be invoked each time a row is updated, +** inserted or deleted using this database connection. +*/ +SQLITE_API void *SQLITE_STDCALL 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; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + pRet = db->pUpdateArg; + db->xUpdateCallback = xCallback; + db->pUpdateArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pRet; +} + +/* +** Register a callback to be invoked each time a transaction is rolled +** back by this database connection. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook( + sqlite3 *db, /* Attach the hook to this database */ + void (*xCallback)(void*), /* Callback function */ + void *pArg /* Argument to the function */ +){ + void *pRet; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + pRet = db->pRollbackArg; + db->xRollbackCallback = xCallback; + db->pRollbackArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pRet; +} + +#ifndef SQLITE_OMIT_WAL +/* +** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint(). +** Invoke sqlite3_wal_checkpoint if the number of frames in the log file +** is greater than sqlite3.pWalArg cast to an integer (the value configured by +** wal_autocheckpoint()). +*/ +SQLITE_PRIVATE int sqlite3WalDefaultHook( + void *pClientData, /* Argument */ + sqlite3 *db, /* Connection */ + const char *zDb, /* Database */ + int nFrame /* Size of WAL */ +){ + if( nFrame>=SQLITE_PTR_TO_INT(pClientData) ){ + sqlite3BeginBenignMalloc(); + sqlite3_wal_checkpoint(db, zDb); + sqlite3EndBenignMalloc(); + } + return SQLITE_OK; +} +#endif /* SQLITE_OMIT_WAL */ + +/* +** Configure an sqlite3_wal_hook() callback to automatically checkpoint +** a database after committing a transaction if there are nFrame or +** more frames in the log file. Passing zero or a negative value as the +** nFrame parameter disables automatic checkpoints entirely. +** +** The callback registered by this function replaces any existing callback +** registered using sqlite3_wal_hook(). Likewise, registering a callback +** using sqlite3_wal_hook() disables the automatic checkpoint mechanism +** configured by this function. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){ +#ifdef SQLITE_OMIT_WAL + UNUSED_PARAMETER(db); + UNUSED_PARAMETER(nFrame); +#else +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + if( nFrame>0 ){ + sqlite3_wal_hook(db, sqlite3WalDefaultHook, SQLITE_INT_TO_PTR(nFrame)); + }else{ + sqlite3_wal_hook(db, 0, 0); + } +#endif + return SQLITE_OK; +} + +/* +** Register a callback to be invoked each time a transaction is written +** into the write-ahead-log by this database connection. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook( + sqlite3 *db, /* Attach the hook to this db handle */ + int(*xCallback)(void *, sqlite3*, const char*, int), + void *pArg /* First argument passed to xCallback() */ +){ +#ifndef SQLITE_OMIT_WAL + void *pRet; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + pRet = db->pWalArg; + db->xWalCallback = xCallback; + db->pWalArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pRet; +#else + return 0; +#endif +} + +/* +** Checkpoint database zDb. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Name of attached database (or NULL) */ + int eMode, /* SQLITE_CHECKPOINT_* value */ + int *pnLog, /* OUT: Size of WAL log in frames */ + int *pnCkpt /* OUT: Total number of frames checkpointed */ +){ +#ifdef SQLITE_OMIT_WAL + return SQLITE_OK; +#else + int rc; /* Return code */ + int iDb = SQLITE_MAX_ATTACHED; /* sqlite3.aDb[] index of db to checkpoint */ + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + + /* Initialize the output variables to -1 in case an error occurs. */ + if( pnLog ) *pnLog = -1; + if( pnCkpt ) *pnCkpt = -1; + + assert( SQLITE_CHECKPOINT_PASSIVE==0 ); + assert( SQLITE_CHECKPOINT_FULL==1 ); + assert( SQLITE_CHECKPOINT_RESTART==2 ); + assert( SQLITE_CHECKPOINT_TRUNCATE==3 ); + if( eModeSQLITE_CHECKPOINT_TRUNCATE ){ + /* EVIDENCE-OF: R-03996-12088 The M parameter must be a valid checkpoint + ** mode: */ + return SQLITE_MISUSE; + } + + sqlite3_mutex_enter(db->mutex); + if( zDb && zDb[0] ){ + iDb = sqlite3FindDbName(db, zDb); + } + if( iDb<0 ){ + rc = SQLITE_ERROR; + sqlite3ErrorWithMsg(db, SQLITE_ERROR, "unknown database: %s", zDb); + }else{ + db->busyHandler.nBusy = 0; + rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt); + sqlite3Error(db, rc); + } + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +#endif +} + + +/* +** Checkpoint database zDb. If zDb is NULL, or if the buffer zDb points +** to contains a zero-length string, all attached databases are +** checkpointed. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){ + /* EVIDENCE-OF: R-41613-20553 The sqlite3_wal_checkpoint(D,X) is equivalent to + ** sqlite3_wal_checkpoint_v2(D,X,SQLITE_CHECKPOINT_PASSIVE,0,0). */ + return sqlite3_wal_checkpoint_v2(db,zDb,SQLITE_CHECKPOINT_PASSIVE,0,0); +} + +#ifndef SQLITE_OMIT_WAL +/* +** Run a checkpoint on database iDb. This is a no-op if database iDb is +** not currently open in WAL mode. +** +** If a transaction is open on the database being checkpointed, this +** function returns SQLITE_LOCKED and a checkpoint is not attempted. If +** an error occurs while running the checkpoint, an SQLite error code is +** returned (i.e. SQLITE_IOERR). Otherwise, SQLITE_OK. +** +** The mutex on database handle db should be held by the caller. The mutex +** associated with the specific b-tree being checkpointed is taken by +** this function while the checkpoint is running. +** +** If iDb is passed SQLITE_MAX_ATTACHED, then all attached databases are +** checkpointed. If an error is encountered it is returned immediately - +** no attempt is made to checkpoint any remaining databases. +** +** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. +*/ +SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3 *db, int iDb, int eMode, int *pnLog, int *pnCkpt){ + int rc = SQLITE_OK; /* Return code */ + int i; /* Used to iterate through attached dbs */ + int bBusy = 0; /* True if SQLITE_BUSY has been encountered */ + + assert( sqlite3_mutex_held(db->mutex) ); + assert( !pnLog || *pnLog==-1 ); + assert( !pnCkpt || *pnCkpt==-1 ); + + for(i=0; inDb && rc==SQLITE_OK; i++){ + if( i==iDb || iDb==SQLITE_MAX_ATTACHED ){ + rc = sqlite3BtreeCheckpoint(db->aDb[i].pBt, eMode, pnLog, pnCkpt); + pnLog = 0; + pnCkpt = 0; + if( rc==SQLITE_BUSY ){ + bBusy = 1; + rc = SQLITE_OK; + } + } + } + + return (rc==SQLITE_OK && bBusy) ? SQLITE_BUSY : rc; +} +#endif /* SQLITE_OMIT_WAL */ + +/* +** This function returns true if main-memory should be used instead of +** a temporary file for transient pager files and statement journals. +** The value returned depends on the value of db->temp_store (runtime +** parameter) and the compile time value of SQLITE_TEMP_STORE. The +** following table describes the relationship between these two values +** and this functions return value. +** +** SQLITE_TEMP_STORE db->temp_store Location of temporary database +** ----------------- -------------- ------------------------------ +** 0 any file (return 0) +** 1 1 file (return 0) +** 1 2 memory (return 1) +** 1 0 file (return 0) +** 2 1 file (return 0) +** 2 2 memory (return 1) +** 2 0 memory (return 1) +** 3 any memory (return 1) +*/ +SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3 *db){ +#if SQLITE_TEMP_STORE==1 + return ( db->temp_store==2 ); +#endif +#if SQLITE_TEMP_STORE==2 + return ( db->temp_store!=1 ); +#endif +#if SQLITE_TEMP_STORE==3 + return 1; +#endif +#if SQLITE_TEMP_STORE<1 || SQLITE_TEMP_STORE>3 + return 0; +#endif +} + +/* +** Return UTF-8 encoded English language explanation of the most recent +** error. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3 *db){ + const char *z; + if( !db ){ + return sqlite3ErrStr(SQLITE_NOMEM); + } + if( !sqlite3SafetyCheckSickOrOk(db) ){ + return sqlite3ErrStr(SQLITE_MISUSE_BKPT); + } + sqlite3_mutex_enter(db->mutex); + if( db->mallocFailed ){ + z = sqlite3ErrStr(SQLITE_NOMEM); + }else{ + testcase( db->pErr==0 ); + z = (char*)sqlite3_value_text(db->pErr); + assert( !db->mallocFailed ); + if( z==0 ){ + z = sqlite3ErrStr(db->errCode); + } + } + sqlite3_mutex_leave(db->mutex); + return z; +} + +#ifndef SQLITE_OMIT_UTF16 +/* +** Return UTF-16 encoded English language explanation of the most recent +** error. +*/ +SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3 *db){ + static const u16 outOfMem[] = { + 'o', 'u', 't', ' ', 'o', 'f', ' ', 'm', 'e', 'm', 'o', 'r', 'y', 0 + }; + static const u16 misuse[] = { + 'l', 'i', 'b', 'r', 'a', 'r', 'y', ' ', + 'r', 'o', 'u', 't', 'i', 'n', 'e', ' ', + 'c', 'a', 'l', 'l', 'e', 'd', ' ', + 'o', 'u', 't', ' ', + 'o', 'f', ' ', + 's', 'e', 'q', 'u', 'e', 'n', 'c', 'e', 0 + }; + + const void *z; + if( !db ){ + return (void *)outOfMem; + } + if( !sqlite3SafetyCheckSickOrOk(db) ){ + return (void *)misuse; + } + sqlite3_mutex_enter(db->mutex); + if( db->mallocFailed ){ + z = (void *)outOfMem; + }else{ + z = sqlite3_value_text16(db->pErr); + if( z==0 ){ + sqlite3ErrorWithMsg(db, db->errCode, sqlite3ErrStr(db->errCode)); + z = sqlite3_value_text16(db->pErr); + } + /* A malloc() may have failed within the call to sqlite3_value_text16() + ** above. If this is the case, then the db->mallocFailed flag needs to + ** be cleared before returning. Do this directly, instead of via + ** sqlite3ApiExit(), to avoid setting the database handle error message. + */ + db->mallocFailed = 0; + } + sqlite3_mutex_leave(db->mutex); + 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(). +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db){ + if( db && !sqlite3SafetyCheckSickOrOk(db) ){ + return SQLITE_MISUSE_BKPT; + } + if( !db || db->mallocFailed ){ + return SQLITE_NOMEM; + } + return db->errCode & db->errMask; +} +SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db){ + if( db && !sqlite3SafetyCheckSickOrOk(db) ){ + return SQLITE_MISUSE_BKPT; + } + if( !db || db->mallocFailed ){ + return SQLITE_NOMEM; + } + return db->errCode; +} + +/* +** Return a string that describes the kind of error specified in the +** argument. For now, this simply calls the internal sqlite3ErrStr() +** function. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_errstr(int rc){ + return sqlite3ErrStr(rc); +} + +/* +** Create a new collating function for database "db". The name is zName +** and the encoding is enc. +*/ +static int createCollation( + sqlite3* db, + const char *zName, + u8 enc, + void* pCtx, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDel)(void*) +){ + CollSeq *pColl; + int enc2; + + assert( sqlite3_mutex_held(db->mutex) ); + + /* If SQLITE_UTF16 is specified as the encoding type, transform this + ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the + ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally. + */ + enc2 = enc; + testcase( enc2==SQLITE_UTF16 ); + testcase( enc2==SQLITE_UTF16_ALIGNED ); + if( enc2==SQLITE_UTF16 || enc2==SQLITE_UTF16_ALIGNED ){ + enc2 = SQLITE_UTF16NATIVE; + } + if( enc2SQLITE_UTF16BE ){ + return SQLITE_MISUSE_BKPT; + } + + /* Check if this call is removing or replacing an existing collation + ** sequence. If so, and there are active VMs, return busy. If there + ** are no active VMs, invalidate any pre-compiled statements. + */ + pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0); + if( pColl && pColl->xCmp ){ + if( db->nVdbeActive ){ + sqlite3ErrorWithMsg(db, SQLITE_BUSY, + "unable to delete/modify collation sequence due to active statements"); + return SQLITE_BUSY; + } + sqlite3ExpirePreparedStatements(db); + + /* If collation sequence pColl was created directly by a call to + ** sqlite3_create_collation, and not generated by synthCollSeq(), + ** then any copies made by synthCollSeq() need to be invalidated. + ** Also, collation destructor - CollSeq.xDel() - function may need + ** to be called. + */ + if( (pColl->enc & ~SQLITE_UTF16_ALIGNED)==enc2 ){ + CollSeq *aColl = sqlite3HashFind(&db->aCollSeq, zName); + int j; + for(j=0; j<3; j++){ + CollSeq *p = &aColl[j]; + if( p->enc==pColl->enc ){ + if( p->xDel ){ + p->xDel(p->pUser); + } + p->xCmp = 0; + } + } + } + } + + pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 1); + if( pColl==0 ) return SQLITE_NOMEM; + pColl->xCmp = xCompare; + pColl->pUser = pCtx; + pColl->xDel = xDel; + pColl->enc = (u8)(enc2 | (enc & SQLITE_UTF16_ALIGNED)); + sqlite3Error(db, SQLITE_OK); + return SQLITE_OK; +} + + +/* +** This array defines hard upper bounds on limit values. The +** initializer must be kept in sync with the SQLITE_LIMIT_* +** #defines in sqlite3.h. +*/ +static const int aHardLimit[] = { + SQLITE_MAX_LENGTH, + SQLITE_MAX_SQL_LENGTH, + SQLITE_MAX_COLUMN, + SQLITE_MAX_EXPR_DEPTH, + SQLITE_MAX_COMPOUND_SELECT, + SQLITE_MAX_VDBE_OP, + SQLITE_MAX_FUNCTION_ARG, + SQLITE_MAX_ATTACHED, + SQLITE_MAX_LIKE_PATTERN_LENGTH, + SQLITE_MAX_VARIABLE_NUMBER, /* IMP: R-38091-32352 */ + SQLITE_MAX_TRIGGER_DEPTH, + SQLITE_MAX_WORKER_THREADS, +}; + +/* +** Make sure the hard limits are set to reasonable values +*/ +#if SQLITE_MAX_LENGTH<100 +# error SQLITE_MAX_LENGTH must be at least 100 +#endif +#if SQLITE_MAX_SQL_LENGTH<100 +# error SQLITE_MAX_SQL_LENGTH must be at least 100 +#endif +#if SQLITE_MAX_SQL_LENGTH>SQLITE_MAX_LENGTH +# error SQLITE_MAX_SQL_LENGTH must not be greater than SQLITE_MAX_LENGTH +#endif +#if SQLITE_MAX_COMPOUND_SELECT<2 +# error SQLITE_MAX_COMPOUND_SELECT must be at least 2 +#endif +#if SQLITE_MAX_VDBE_OP<40 +# error SQLITE_MAX_VDBE_OP must be at least 40 +#endif +#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000 +# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000 +#endif +#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125 +# error SQLITE_MAX_ATTACHED must be between 0 and 125 +#endif +#if SQLITE_MAX_LIKE_PATTERN_LENGTH<1 +# error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1 +#endif +#if SQLITE_MAX_COLUMN>32767 +# error SQLITE_MAX_COLUMN must not exceed 32767 +#endif +#if SQLITE_MAX_TRIGGER_DEPTH<1 +# error SQLITE_MAX_TRIGGER_DEPTH must be at least 1 +#endif +#if SQLITE_MAX_WORKER_THREADS<0 || SQLITE_MAX_WORKER_THREADS>50 +# error SQLITE_MAX_WORKER_THREADS must be between 0 and 50 +#endif + + +/* +** Change the value of a limit. Report the old value. +** If an invalid limit index is supplied, report -1. +** Make no changes but still report the old value if the +** new limit is negative. +** +** A new lower limit does not shrink existing constructs. +** It merely prevents new constructs that exceed the limit +** from forming. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ + int oldLimit; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return -1; + } +#endif + + /* EVIDENCE-OF: R-30189-54097 For each limit category SQLITE_LIMIT_NAME + ** there is a hard upper bound set at compile-time by a C preprocessor + ** macro called SQLITE_MAX_NAME. (The "_LIMIT_" in the name is changed to + ** "_MAX_".) + */ + assert( aHardLimit[SQLITE_LIMIT_LENGTH]==SQLITE_MAX_LENGTH ); + assert( aHardLimit[SQLITE_LIMIT_SQL_LENGTH]==SQLITE_MAX_SQL_LENGTH ); + assert( aHardLimit[SQLITE_LIMIT_COLUMN]==SQLITE_MAX_COLUMN ); + assert( aHardLimit[SQLITE_LIMIT_EXPR_DEPTH]==SQLITE_MAX_EXPR_DEPTH ); + assert( aHardLimit[SQLITE_LIMIT_COMPOUND_SELECT]==SQLITE_MAX_COMPOUND_SELECT); + assert( aHardLimit[SQLITE_LIMIT_VDBE_OP]==SQLITE_MAX_VDBE_OP ); + assert( aHardLimit[SQLITE_LIMIT_FUNCTION_ARG]==SQLITE_MAX_FUNCTION_ARG ); + assert( aHardLimit[SQLITE_LIMIT_ATTACHED]==SQLITE_MAX_ATTACHED ); + assert( aHardLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]== + SQLITE_MAX_LIKE_PATTERN_LENGTH ); + assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER); + assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH ); + assert( aHardLimit[SQLITE_LIMIT_WORKER_THREADS]==SQLITE_MAX_WORKER_THREADS ); + assert( SQLITE_LIMIT_WORKER_THREADS==(SQLITE_N_LIMIT-1) ); + + + if( limitId<0 || limitId>=SQLITE_N_LIMIT ){ + return -1; + } + oldLimit = db->aLimit[limitId]; + if( newLimit>=0 ){ /* IMP: R-52476-28732 */ + if( newLimit>aHardLimit[limitId] ){ + newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */ + } + db->aLimit[limitId] = newLimit; + } + return oldLimit; /* IMP: R-53341-35419 */ +} + +/* +** This function is used to parse both URIs and non-URI filenames passed by the +** user to API functions sqlite3_open() or sqlite3_open_v2(), and for database +** URIs specified as part of ATTACH statements. +** +** The first argument to this function is the name of the VFS to use (or +** a NULL to signify the default VFS) if the URI does not contain a "vfs=xxx" +** query parameter. The second argument contains the URI (or non-URI filename) +** itself. When this function is called the *pFlags variable should contain +** the default flags to open the database handle with. The value stored in +** *pFlags may be updated before returning if the URI filename contains +** "cache=xxx" or "mode=xxx" query parameters. +** +** If successful, SQLITE_OK is returned. In this case *ppVfs is set to point to +** the VFS that should be used to open the database file. *pzFile is set to +** point to a buffer containing the name of the file to open. It is the +** responsibility of the caller to eventually call sqlite3_free() to release +** this buffer. +** +** If an error occurs, then an SQLite error code is returned and *pzErrMsg +** may be set to point to a buffer containing an English language error +** message. It is the responsibility of the caller to eventually release +** this buffer by calling sqlite3_free(). +*/ +SQLITE_PRIVATE int sqlite3ParseUri( + const char *zDefaultVfs, /* VFS to use if no "vfs=xxx" query option */ + const char *zUri, /* Nul-terminated URI to parse */ + unsigned int *pFlags, /* IN/OUT: SQLITE_OPEN_XXX flags */ + sqlite3_vfs **ppVfs, /* OUT: VFS to use */ + char **pzFile, /* OUT: Filename component of URI */ + char **pzErrMsg /* OUT: Error message (if rc!=SQLITE_OK) */ +){ + int rc = SQLITE_OK; + unsigned int flags = *pFlags; + const char *zVfs = zDefaultVfs; + char *zFile; + char c; + int nUri = sqlite3Strlen30(zUri); + + assert( *pzErrMsg==0 ); + + if( ((flags & SQLITE_OPEN_URI) /* IMP: R-48725-32206 */ + || sqlite3GlobalConfig.bOpenUri) /* IMP: R-51689-46548 */ + && nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */ + ){ + char *zOpt; + int eState; /* Parser state when parsing URI */ + int iIn; /* Input character index */ + int iOut = 0; /* Output character index */ + u64 nByte = nUri+2; /* Bytes of space to allocate */ + + /* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen + ** method that there may be extra parameters following the file-name. */ + flags |= SQLITE_OPEN_URI; + + for(iIn=0; iIn=0 && octet<256 ); + if( octet==0 ){ + /* This branch is taken when "%00" appears within the URI. In this + ** case we ignore all text in the remainder of the path, name or + ** value currently being parsed. So ignore the current character + ** and skip to the next "?", "=" or "&", as appropriate. */ + while( (c = zUri[iIn])!=0 && c!='#' + && (eState!=0 || c!='?') + && (eState!=1 || (c!='=' && c!='&')) + && (eState!=2 || c!='&') + ){ + iIn++; + } + continue; + } + c = octet; + }else if( eState==1 && (c=='&' || c=='=') ){ + if( zFile[iOut-1]==0 ){ + /* An empty option name. Ignore this option altogether. */ + while( zUri[iIn] && zUri[iIn]!='#' && zUri[iIn-1]!='&' ) iIn++; + continue; + } + if( c=='&' ){ + zFile[iOut++] = '\0'; + }else{ + eState = 2; + } + c = 0; + }else if( (eState==0 && c=='?') || (eState==2 && c=='&') ){ + c = 0; + eState = 1; + } + zFile[iOut++] = c; + } + if( eState==1 ) zFile[iOut++] = '\0'; + zFile[iOut++] = '\0'; + zFile[iOut++] = '\0'; + + /* Check if there were any options specified that should be interpreted + ** here. Options that are interpreted here include "vfs" and those that + ** correspond to flags that may be passed to the sqlite3_open_v2() + ** method. */ + zOpt = &zFile[sqlite3Strlen30(zFile)+1]; + while( zOpt[0] ){ + int nOpt = sqlite3Strlen30(zOpt); + char *zVal = &zOpt[nOpt+1]; + int nVal = sqlite3Strlen30(zVal); + + if( nOpt==3 && memcmp("vfs", zOpt, 3)==0 ){ + zVfs = zVal; + }else{ + struct OpenMode { + const char *z; + int mode; + } *aMode = 0; + char *zModeType = 0; + int mask = 0; + int limit = 0; + + if( nOpt==5 && memcmp("cache", zOpt, 5)==0 ){ + static struct OpenMode aCacheMode[] = { + { "shared", SQLITE_OPEN_SHAREDCACHE }, + { "private", SQLITE_OPEN_PRIVATECACHE }, + { 0, 0 } + }; + + mask = SQLITE_OPEN_SHAREDCACHE|SQLITE_OPEN_PRIVATECACHE; + aMode = aCacheMode; + limit = mask; + zModeType = "cache"; + } + if( nOpt==4 && memcmp("mode", zOpt, 4)==0 ){ + static struct OpenMode aOpenMode[] = { + { "ro", SQLITE_OPEN_READONLY }, + { "rw", SQLITE_OPEN_READWRITE }, + { "rwc", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE }, + { "memory", SQLITE_OPEN_MEMORY }, + { 0, 0 } + }; + + mask = SQLITE_OPEN_READONLY | SQLITE_OPEN_READWRITE + | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY; + aMode = aOpenMode; + limit = mask & flags; + zModeType = "access"; + } + + if( aMode ){ + int i; + int mode = 0; + for(i=0; aMode[i].z; i++){ + const char *z = aMode[i].z; + if( nVal==sqlite3Strlen30(z) && 0==memcmp(zVal, z, nVal) ){ + mode = aMode[i].mode; + break; + } + } + if( mode==0 ){ + *pzErrMsg = sqlite3_mprintf("no such %s mode: %s", zModeType, zVal); + rc = SQLITE_ERROR; + goto parse_uri_out; + } + if( (mode & ~SQLITE_OPEN_MEMORY)>limit ){ + *pzErrMsg = sqlite3_mprintf("%s mode not allowed: %s", + zModeType, zVal); + rc = SQLITE_PERM; + goto parse_uri_out; + } + flags = (flags & ~mask) | mode; + } + } + + zOpt = &zVal[nVal+1]; + } + + }else{ + zFile = sqlite3_malloc64(nUri+2); + if( !zFile ) return SQLITE_NOMEM; + memcpy(zFile, zUri, nUri); + zFile[nUri] = '\0'; + zFile[nUri+1] = '\0'; + flags &= ~SQLITE_OPEN_URI; + } + + *ppVfs = sqlite3_vfs_find(zVfs); + if( *ppVfs==0 ){ + *pzErrMsg = sqlite3_mprintf("no such vfs: %s", zVfs); + rc = SQLITE_ERROR; + } + parse_uri_out: + if( rc!=SQLITE_OK ){ + sqlite3_free(zFile); + zFile = 0; + } + *pFlags = flags; + *pzFile = zFile; + return rc; +} + + +/* +** 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 */ + unsigned int flags, /* Operational flags */ + const char *zVfs /* Name of the VFS to use */ +){ + sqlite3 *db; /* Store allocated handle here */ + int rc; /* Return code */ + int isThreadsafe; /* True for threadsafe connections */ + char *zOpen = 0; /* Filename argument to pass to BtreeOpen() */ + char *zErrMsg = 0; /* Error message from sqlite3ParseUri() */ + +#ifdef SQLITE_ENABLE_API_ARMOR + if( ppDb==0 ) return SQLITE_MISUSE_BKPT; +#endif + *ppDb = 0; +#ifndef SQLITE_OMIT_AUTOINIT + rc = sqlite3_initialize(); + if( rc ) return rc; +#endif + + /* Only allow sensible combinations of bits in the flags argument. + ** Throw an error if any non-sense combination is used. If we + ** do not block illegal combinations here, it could trigger + ** assert() statements in deeper layers. Sensible combinations + ** are: + ** + ** 1: SQLITE_OPEN_READONLY + ** 2: SQLITE_OPEN_READWRITE + ** 6: SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE + */ + assert( SQLITE_OPEN_READONLY == 0x01 ); + assert( SQLITE_OPEN_READWRITE == 0x02 ); + assert( SQLITE_OPEN_CREATE == 0x04 ); + testcase( (1<<(flags&7))==0x02 ); /* READONLY */ + testcase( (1<<(flags&7))==0x04 ); /* READWRITE */ + testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */ + if( ((1<<(flags&7)) & 0x46)==0 ){ + return SQLITE_MISUSE_BKPT; /* IMP: R-65497-44594 */ + } + + if( sqlite3GlobalConfig.bCoreMutex==0 ){ + isThreadsafe = 0; + }else if( flags & SQLITE_OPEN_NOMUTEX ){ + isThreadsafe = 0; + }else if( flags & SQLITE_OPEN_FULLMUTEX ){ + isThreadsafe = 1; + }else{ + isThreadsafe = sqlite3GlobalConfig.bFullMutex; + } + if( flags & SQLITE_OPEN_PRIVATECACHE ){ + flags &= ~SQLITE_OPEN_SHAREDCACHE; + }else if( sqlite3GlobalConfig.sharedCacheEnabled ){ + flags |= SQLITE_OPEN_SHAREDCACHE; + } + + /* Remove harmful bits from the flags parameter + ** + ** The SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_FULLMUTEX flags were + ** dealt with in the previous code block. Besides these, the only + ** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY, + ** SQLITE_OPEN_READWRITE, SQLITE_OPEN_CREATE, SQLITE_OPEN_SHAREDCACHE, + ** SQLITE_OPEN_PRIVATECACHE, and some reserved bits. Silently mask + ** off all other flags. + */ + flags &= ~( SQLITE_OPEN_DELETEONCLOSE | + SQLITE_OPEN_EXCLUSIVE | + SQLITE_OPEN_MAIN_DB | + SQLITE_OPEN_TEMP_DB | + SQLITE_OPEN_TRANSIENT_DB | + SQLITE_OPEN_MAIN_JOURNAL | + SQLITE_OPEN_TEMP_JOURNAL | + SQLITE_OPEN_SUBJOURNAL | + SQLITE_OPEN_MASTER_JOURNAL | + SQLITE_OPEN_NOMUTEX | + SQLITE_OPEN_FULLMUTEX | + SQLITE_OPEN_WAL + ); + + /* Allocate the sqlite data structure */ + db = sqlite3MallocZero( sizeof(sqlite3) ); + if( db==0 ) goto opendb_out; + if( isThreadsafe ){ + db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); + if( db->mutex==0 ){ + sqlite3_free(db); + db = 0; + goto opendb_out; + } + } + sqlite3_mutex_enter(db->mutex); + db->errMask = 0xff; + db->nDb = 2; + db->magic = SQLITE_MAGIC_BUSY; + db->aDb = db->aDbStatic; + + assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); + memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); + db->aLimit[SQLITE_LIMIT_WORKER_THREADS] = SQLITE_DEFAULT_WORKER_THREADS; + db->autoCommit = 1; + db->nextAutovac = -1; + db->szMmap = sqlite3GlobalConfig.szMmap; + db->nextPagesize = 0; + db->nMaxSorterMmap = 0x7FFFFFFF; + db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill +#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX + | SQLITE_AutoIndex +#endif +#if SQLITE_DEFAULT_CKPTFULLFSYNC + | SQLITE_CkptFullFSync +#endif +#if SQLITE_DEFAULT_FILE_FORMAT<4 + | SQLITE_LegacyFileFmt +#endif +#ifdef SQLITE_ENABLE_LOAD_EXTENSION + | SQLITE_LoadExtension +#endif +#if SQLITE_DEFAULT_RECURSIVE_TRIGGERS + | SQLITE_RecTriggers +#endif +#if defined(SQLITE_DEFAULT_FOREIGN_KEYS) && SQLITE_DEFAULT_FOREIGN_KEYS + | SQLITE_ForeignKeys +#endif +#if defined(SQLITE_REVERSE_UNORDERED_SELECTS) + | SQLITE_ReverseOrder +#endif + ; + sqlite3HashInit(&db->aCollSeq); +#ifndef SQLITE_OMIT_VIRTUALTABLE + sqlite3HashInit(&db->aModule); +#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. + ** + ** EVIDENCE-OF: R-52786-44878 SQLite defines three built-in collating + ** functions: + */ + createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0); + createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0); + createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0); + createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0); + createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0); + if( db->mallocFailed ){ + goto opendb_out; + } + /* EVIDENCE-OF: R-08308-17224 The default collating function for all + ** strings is BINARY. + */ + db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0); + assert( db->pDfltColl!=0 ); + + /* Parse the filename/URI argument. */ + db->openFlags = flags; + rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; + sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg); + sqlite3_free(zErrMsg); + goto opendb_out; + } + + /* Open the backend database driver */ + rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0, + flags | SQLITE_OPEN_MAIN_DB); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_IOERR_NOMEM ){ + rc = SQLITE_NOMEM; + } + sqlite3Error(db, rc); + goto opendb_out; + } + sqlite3BtreeEnter(db->aDb[0].pBt); + db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt); + if( !db->mallocFailed ) ENC(db) = SCHEMA_ENC(db); + sqlite3BtreeLeave(db->aDb[0].pBt); + db->aDb[1].pSchema = sqlite3SchemaGet(db, 0); + + /* 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; + db->aDb[1].zName = "temp"; + db->aDb[1].safety_level = 1; + + db->magic = SQLITE_MAGIC_OPEN; + if( db->mallocFailed ){ + goto opendb_out; + } + + /* 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. + */ + sqlite3Error(db, SQLITE_OK); + sqlite3RegisterBuiltinFunctions(db); + + /* Load automatic extensions - extensions that have been registered + ** using the sqlite3_automatic_extension() API. + */ + rc = sqlite3_errcode(db); + if( rc==SQLITE_OK ){ + sqlite3AutoLoadExtensions(db); + rc = sqlite3_errcode(db); + if( rc!=SQLITE_OK ){ + goto opendb_out; + } + } + +#ifdef SQLITE_ENABLE_FTS1 + if( !db->mallocFailed ){ + extern int sqlite3Fts1Init(sqlite3*); + rc = sqlite3Fts1Init(db); + } +#endif + +#ifdef SQLITE_ENABLE_FTS2 + if( !db->mallocFailed && rc==SQLITE_OK ){ + extern int sqlite3Fts2Init(sqlite3*); + rc = sqlite3Fts2Init(db); + } +#endif + +#ifdef SQLITE_ENABLE_FTS3 + if( !db->mallocFailed && rc==SQLITE_OK ){ + rc = sqlite3Fts3Init(db); + } +#endif + +#ifdef SQLITE_ENABLE_ICU + if( !db->mallocFailed && rc==SQLITE_OK ){ + rc = sqlite3IcuInit(db); + } +#endif + +#ifdef SQLITE_ENABLE_RTREE + if( !db->mallocFailed && rc==SQLITE_OK){ + rc = sqlite3RtreeInit(db); + } +#endif + +#ifdef SQLITE_ENABLE_DBSTAT_VTAB + if( !db->mallocFailed && rc==SQLITE_OK){ + int sqlite3_dbstat_register(sqlite3*); + rc = sqlite3_dbstat_register(db); + } +#endif + + /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking + ** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking + ** mode. Doing nothing at all also makes NORMAL the default. + */ +#ifdef SQLITE_DEFAULT_LOCKING_MODE + db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE; + sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt), + SQLITE_DEFAULT_LOCKING_MODE); +#endif + + if( rc ) sqlite3Error(db, rc); + + /* Enable the lookaside-malloc subsystem */ + setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside, + sqlite3GlobalConfig.nLookaside); + + sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT); + +opendb_out: + sqlite3_free(zOpen); + if( db ){ + assert( db->mutex!=0 || isThreadsafe==0 + || sqlite3GlobalConfig.bFullMutex==0 ); + sqlite3_mutex_leave(db->mutex); + } + rc = sqlite3_errcode(db); + assert( db!=0 || rc==SQLITE_NOMEM ); + if( rc==SQLITE_NOMEM ){ + sqlite3_close(db); + db = 0; + }else if( rc!=SQLITE_OK ){ + db->magic = SQLITE_MAGIC_SICK; + } + *ppDb = db; +#ifdef SQLITE_ENABLE_SQLLOG + if( sqlite3GlobalConfig.xSqllog ){ + /* Opening a db handle. Fourth parameter is passed 0. */ + void *pArg = sqlite3GlobalConfig.pSqllogArg; + sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0); + } +#endif + return sqlite3ApiExit(0, rc); +} + +/* +** Open a new database handle. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_open( + const char *zFilename, + sqlite3 **ppDb +){ + return openDatabase(zFilename, ppDb, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); +} +SQLITE_API int SQLITE_STDCALL sqlite3_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs /* Name of VFS module to use */ +){ + return openDatabase(filename, ppDb, (unsigned int)flags, zVfs); +} + +#ifndef SQLITE_OMIT_UTF16 +/* +** Open a new database handle. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_open16( + const void *zFilename, + sqlite3 **ppDb +){ + char const *zFilename8; /* zFilename encoded in UTF-8 instead of UTF-16 */ + sqlite3_value *pVal; + int rc; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( ppDb==0 ) return SQLITE_MISUSE_BKPT; +#endif + *ppDb = 0; +#ifndef SQLITE_OMIT_AUTOINIT + rc = sqlite3_initialize(); + if( rc ) return rc; +#endif + if( zFilename==0 ) zFilename = "\000\000"; + pVal = sqlite3ValueNew(0); + sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC); + zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8); + if( zFilename8 ){ + rc = openDatabase(zFilename8, ppDb, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); + assert( *ppDb || rc==SQLITE_NOMEM ); + if( rc==SQLITE_OK && !DbHasProperty(*ppDb, 0, DB_SchemaLoaded) ){ + SCHEMA_ENC(*ppDb) = ENC(*ppDb) = SQLITE_UTF16NATIVE; + } + }else{ + rc = SQLITE_NOMEM; + } + sqlite3ValueFree(pVal); + + return sqlite3ApiExit(0, rc); +} +#endif /* SQLITE_OMIT_UTF16 */ + +/* +** Register a new collation sequence with the database handle db. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_create_collation( + sqlite3* db, + const char *zName, + int enc, + void* pCtx, + int(*xCompare)(void*,int,const void*,int,const void*) +){ + return sqlite3_create_collation_v2(db, zName, enc, pCtx, xCompare, 0); +} + +/* +** Register a new collation sequence with the database handle db. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2( + sqlite3* db, + const char *zName, + int enc, + void* pCtx, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDel)(void*) +){ + int rc; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + assert( !db->mallocFailed ); + rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, xDel); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +#ifndef SQLITE_OMIT_UTF16 +/* +** Register a new collation sequence with the database handle db. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16( + sqlite3* db, + const void *zName, + int enc, + void* pCtx, + int(*xCompare)(void*,int,const void*,int,const void*) +){ + int rc = SQLITE_OK; + char *zName8; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + assert( !db->mallocFailed ); + zName8 = sqlite3Utf16to8(db, zName, -1, SQLITE_UTF16NATIVE); + if( zName8 ){ + rc = createCollation(db, zName8, (u8)enc, pCtx, xCompare, 0); + sqlite3DbFree(db, zName8); + } + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} +#endif /* SQLITE_OMIT_UTF16 */ + +/* +** Register a collation sequence factory callback with the database handle +** db. Replace any previously installed collation sequence factory. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed( + sqlite3 *db, + void *pCollNeededArg, + void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*) +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + db->xCollNeeded = xCollNeeded; + db->xCollNeeded16 = 0; + db->pCollNeededArg = pCollNeededArg; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_UTF16 +/* +** Register a collation sequence factory callback with the database handle +** db. Replace any previously installed collation sequence factory. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16( + sqlite3 *db, + void *pCollNeededArg, + void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*) +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + db->xCollNeeded = 0; + db->xCollNeeded16 = xCollNeeded16; + db->pCollNeededArg = pCollNeededArg; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} +#endif /* SQLITE_OMIT_UTF16 */ + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** This function is now an anachronism. It used to be used to recover from a +** malloc() failure, but SQLite now does this automatically. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_global_recover(void){ + 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. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3 *db){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + return db->autoCommit; +} + +/* +** The following routines are substitutes for constants SQLITE_CORRUPT, +** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_IOERR and possibly other error +** constants. They serve two purposes: +** +** 1. Serve as a convenient place to set a breakpoint in a debugger +** to detect when version error conditions occurs. +** +** 2. Invoke sqlite3_log() to provide the source code location where +** a low-level error is first detected. +*/ +SQLITE_PRIVATE int sqlite3CorruptError(int lineno){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_CORRUPT, + "database corruption at line %d of [%.10s]", + lineno, 20+sqlite3_sourceid()); + return SQLITE_CORRUPT; +} +SQLITE_PRIVATE int sqlite3MisuseError(int lineno){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_MISUSE, + "misuse at line %d of [%.10s]", + lineno, 20+sqlite3_sourceid()); + return SQLITE_MISUSE; +} +SQLITE_PRIVATE int sqlite3CantopenError(int lineno){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_CANTOPEN, + "cannot open file at line %d of [%.10s]", + lineno, 20+sqlite3_sourceid()); + return SQLITE_CANTOPEN; +} + + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** This is a convenience routine that makes sure that all thread-specific +** data for this thread has been deallocated. +** +** SQLite no longer uses thread-specific data so this routine is now a +** no-op. It is retained for historical compatibility. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_thread_cleanup(void){ +} +#endif + +/* +** Return meta information about a specific column of a database table. +** See comment in sqlite3.h (sqlite.h.in) for details. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata( + sqlite3 *db, /* Connection handle */ + const char *zDbName, /* Database name or NULL */ + const char *zTableName, /* Table name */ + const char *zColumnName, /* Column name */ + char const **pzDataType, /* OUTPUT: Declared data type */ + char const **pzCollSeq, /* OUTPUT: Collation sequence name */ + int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ + int *pPrimaryKey, /* OUTPUT: True if column part of PK */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ +){ + int rc; + char *zErrMsg = 0; + Table *pTab = 0; + Column *pCol = 0; + int iCol = 0; + char const *zDataType = 0; + char const *zCollSeq = 0; + int notnull = 0; + int primarykey = 0; + int autoinc = 0; + + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zTableName==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + + /* Ensure the database schema has been loaded */ + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); + rc = sqlite3Init(db, &zErrMsg); + if( SQLITE_OK!=rc ){ + goto error_out; + } + + /* Locate the table in question */ + pTab = sqlite3FindTable(db, zTableName, zDbName); + if( !pTab || pTab->pSelect ){ + pTab = 0; + goto error_out; + } + + /* Find the column for which info is requested */ + if( zColumnName==0 ){ + /* Query for existance of table only */ + }else{ + for(iCol=0; iColnCol; iCol++){ + pCol = &pTab->aCol[iCol]; + if( 0==sqlite3StrICmp(pCol->zName, zColumnName) ){ + break; + } + } + if( iCol==pTab->nCol ){ + if( HasRowid(pTab) && sqlite3IsRowid(zColumnName) ){ + iCol = pTab->iPKey; + pCol = iCol>=0 ? &pTab->aCol[iCol] : 0; + }else{ + pTab = 0; + goto error_out; + } + } + } + + /* The following block stores the meta information that will be returned + ** to the caller in local variables zDataType, zCollSeq, notnull, primarykey + ** and autoinc. At this point there are two possibilities: + ** + ** 1. The specified column name was rowid", "oid" or "_rowid_" + ** and there is no explicitly declared IPK column. + ** + ** 2. The table is not a view and the column name identified an + ** explicitly declared column. Copy meta information from *pCol. + */ + if( pCol ){ + zDataType = pCol->zType; + zCollSeq = pCol->zColl; + notnull = pCol->notNull!=0; + primarykey = (pCol->colFlags & COLFLAG_PRIMKEY)!=0; + autoinc = pTab->iPKey==iCol && (pTab->tabFlags & TF_Autoincrement)!=0; + }else{ + zDataType = "INTEGER"; + primarykey = 1; + } + if( !zCollSeq ){ + zCollSeq = "BINARY"; + } + +error_out: + sqlite3BtreeLeaveAll(db); + + /* Whether the function call succeeded or failed, set the output parameters + ** to whatever their local counterparts contain. If an error did occur, + ** this has the effect of zeroing all output parameters. + */ + if( pzDataType ) *pzDataType = zDataType; + if( pzCollSeq ) *pzCollSeq = zCollSeq; + if( pNotNull ) *pNotNull = notnull; + if( pPrimaryKey ) *pPrimaryKey = primarykey; + if( pAutoinc ) *pAutoinc = autoinc; + + if( SQLITE_OK==rc && !pTab ){ + sqlite3DbFree(db, zErrMsg); + zErrMsg = sqlite3MPrintf(db, "no such table column: %s.%s", zTableName, + zColumnName); + rc = SQLITE_ERROR; + } + sqlite3ErrorWithMsg(db, rc, (zErrMsg?"%s":0), zErrMsg); + sqlite3DbFree(db, zErrMsg); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Sleep for a little while. Return the amount of time slept. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int ms){ + sqlite3_vfs *pVfs; + int rc; + pVfs = sqlite3_vfs_find(0); + if( pVfs==0 ) return 0; + + /* This function works in milliseconds, but the underlying OsSleep() + ** API uses microseconds. Hence the 1000's. + */ + rc = (sqlite3OsSleep(pVfs, 1000*ms)/1000); + return rc; +} + +/* +** Enable or disable the extended result codes. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3 *db, int onoff){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + db->errMask = onoff ? 0xffffffff : 0xff; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +/* +** Invoke the xFileControl method on a particular database. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){ + int rc = SQLITE_ERROR; + Btree *pBtree; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + pBtree = sqlite3DbNameToBtree(db, zDbName); + if( pBtree ){ + Pager *pPager; + sqlite3_file *fd; + sqlite3BtreeEnter(pBtree); + pPager = sqlite3BtreePager(pBtree); + assert( pPager!=0 ); + fd = sqlite3PagerFile(pPager); + assert( fd!=0 ); + if( op==SQLITE_FCNTL_FILE_POINTER ){ + *(sqlite3_file**)pArg = fd; + rc = SQLITE_OK; + }else if( fd->pMethods ){ + rc = sqlite3OsFileControl(fd, op, pArg); + }else{ + rc = SQLITE_NOTFOUND; + } + sqlite3BtreeLeave(pBtree); + } + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Interface to the testing logic. +*/ +SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...){ + int rc = 0; +#ifndef SQLITE_OMIT_BUILTIN_TEST + va_list ap; + va_start(ap, op); + switch( op ){ + + /* + ** Save the current state of the PRNG. + */ + case SQLITE_TESTCTRL_PRNG_SAVE: { + sqlite3PrngSaveState(); + break; + } + + /* + ** Restore the state of the PRNG to the last state saved using + ** PRNG_SAVE. If PRNG_SAVE has never before been called, then + ** this verb acts like PRNG_RESET. + */ + case SQLITE_TESTCTRL_PRNG_RESTORE: { + sqlite3PrngRestoreState(); + break; + } + + /* + ** Reset the PRNG back to its uninitialized state. The next call + ** to sqlite3_randomness() will reseed the PRNG using a single call + ** to the xRandomness method of the default VFS. + */ + case SQLITE_TESTCTRL_PRNG_RESET: { + sqlite3_randomness(0,0); + break; + } + + /* + ** sqlite3_test_control(BITVEC_TEST, size, program) + ** + ** Run a test against a Bitvec object of size. The program argument + ** is an array of integers that defines the test. Return -1 on a + ** memory allocation error, 0 on success, or non-zero for an error. + ** See the sqlite3BitvecBuiltinTest() for additional information. + */ + case SQLITE_TESTCTRL_BITVEC_TEST: { + int sz = va_arg(ap, int); + int *aProg = va_arg(ap, int*); + rc = sqlite3BitvecBuiltinTest(sz, aProg); + break; + } + + /* + ** sqlite3_test_control(FAULT_INSTALL, xCallback) + ** + ** Arrange to invoke xCallback() whenever sqlite3FaultSim() is called, + ** if xCallback is not NULL. + ** + ** As a test of the fault simulator mechanism itself, sqlite3FaultSim(0) + ** is called immediately after installing the new callback and the return + ** value from sqlite3FaultSim(0) becomes the return from + ** sqlite3_test_control(). + */ + case SQLITE_TESTCTRL_FAULT_INSTALL: { + /* MSVC is picky about pulling func ptrs from va lists. + ** http://support.microsoft.com/kb/47961 + ** sqlite3GlobalConfig.xTestCallback = va_arg(ap, int(*)(int)); + */ + typedef int(*TESTCALLBACKFUNC_t)(int); + sqlite3GlobalConfig.xTestCallback = va_arg(ap, TESTCALLBACKFUNC_t); + rc = sqlite3FaultSim(0); + break; + } + + /* + ** sqlite3_test_control(BENIGN_MALLOC_HOOKS, xBegin, xEnd) + ** + ** Register hooks to call to indicate which malloc() failures + ** are benign. + */ + case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: { + typedef void (*void_function)(void); + void_function xBenignBegin; + void_function xBenignEnd; + xBenignBegin = va_arg(ap, void_function); + xBenignEnd = va_arg(ap, void_function); + sqlite3BenignMallocHooks(xBenignBegin, xBenignEnd); + break; + } + + /* + ** sqlite3_test_control(SQLITE_TESTCTRL_PENDING_BYTE, unsigned int X) + ** + ** Set the PENDING byte to the value in the argument, if X>0. + ** Make no changes if X==0. Return the value of the pending byte + ** as it existing before this routine was called. + ** + ** IMPORTANT: Changing the PENDING byte from 0x40000000 results in + ** an incompatible database file format. Changing the PENDING byte + ** while any database connection is open results in undefined and + ** deleterious behavior. + */ + case SQLITE_TESTCTRL_PENDING_BYTE: { + rc = PENDING_BYTE; +#ifndef SQLITE_OMIT_WSD + { + unsigned int newVal = va_arg(ap, unsigned int); + if( newVal ) sqlite3PendingByte = newVal; + } +#endif + break; + } + + /* + ** sqlite3_test_control(SQLITE_TESTCTRL_ASSERT, int X) + ** + ** This action provides a run-time test to see whether or not + ** assert() was enabled at compile-time. If X is true and assert() + ** is enabled, then the return value is true. If X is true and + ** assert() is disabled, then the return value is zero. If X is + ** false and assert() is enabled, then the assertion fires and the + ** process aborts. If X is false and assert() is disabled, then the + ** return value is zero. + */ + case SQLITE_TESTCTRL_ASSERT: { + volatile int x = 0; + assert( (x = va_arg(ap,int))!=0 ); + rc = x; + break; + } + + + /* + ** sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, int X) + ** + ** This action provides a run-time test to see how the ALWAYS and + ** NEVER macros were defined at compile-time. + ** + ** The return value is ALWAYS(X). + ** + ** The recommended test is X==2. If the return value is 2, that means + ** ALWAYS() and NEVER() are both no-op pass-through macros, which is the + ** default setting. If the return value is 1, then ALWAYS() is either + ** hard-coded to true or else it asserts if its argument is false. + ** The first behavior (hard-coded to true) is the case if + ** SQLITE_TESTCTRL_ASSERT shows that assert() is disabled and the second + ** behavior (assert if the argument to ALWAYS() is false) is the case if + ** SQLITE_TESTCTRL_ASSERT shows that assert() is enabled. + ** + ** The run-time test procedure might look something like this: + ** + ** if( sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, 2)==2 ){ + ** // ALWAYS() and NEVER() are no-op pass-through macros + ** }else if( sqlite3_test_control(SQLITE_TESTCTRL_ASSERT, 1) ){ + ** // ALWAYS(x) asserts that x is true. NEVER(x) asserts x is false. + ** }else{ + ** // ALWAYS(x) is a constant 1. NEVER(x) is a constant 0. + ** } + */ + case SQLITE_TESTCTRL_ALWAYS: { + int x = va_arg(ap,int); + rc = ALWAYS(x); + break; + } + + /* + ** sqlite3_test_control(SQLITE_TESTCTRL_BYTEORDER); + ** + ** The integer returned reveals the byte-order of the computer on which + ** SQLite is running: + ** + ** 1 big-endian, determined at run-time + ** 10 little-endian, determined at run-time + ** 432101 big-endian, determined at compile-time + ** 123410 little-endian, determined at compile-time + */ + case SQLITE_TESTCTRL_BYTEORDER: { + rc = SQLITE_BYTEORDER*100 + SQLITE_LITTLEENDIAN*10 + SQLITE_BIGENDIAN; + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_RESERVE, sqlite3 *db, int N) + ** + ** Set the nReserve size to N for the main database on the database + ** connection db. + */ + case SQLITE_TESTCTRL_RESERVE: { + sqlite3 *db = va_arg(ap, sqlite3*); + int x = va_arg(ap,int); + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeSetPageSize(db->aDb[0].pBt, 0, x, 0); + sqlite3_mutex_leave(db->mutex); + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, sqlite3 *db, int N) + ** + ** Enable or disable various optimizations for testing purposes. The + ** argument N is a bitmask of optimizations to be disabled. For normal + ** operation N should be 0. The idea is that a test program (like the + ** SQL Logic Test or SLT test module) can run the same SQL multiple times + ** with various optimizations disabled to verify that the same answer + ** is obtained in every case. + */ + case SQLITE_TESTCTRL_OPTIMIZATIONS: { + sqlite3 *db = va_arg(ap, sqlite3*); + db->dbOptFlags = (u16)(va_arg(ap, int) & 0xffff); + break; + } + +#ifdef SQLITE_N_KEYWORD + /* sqlite3_test_control(SQLITE_TESTCTRL_ISKEYWORD, const char *zWord) + ** + ** If zWord is a keyword recognized by the parser, then return the + ** number of keywords. Or if zWord is not a keyword, return 0. + ** + ** This test feature is only available in the amalgamation since + ** the SQLITE_N_KEYWORD macro is not defined in this file if SQLite + ** is built using separate source files. + */ + case SQLITE_TESTCTRL_ISKEYWORD: { + const char *zWord = va_arg(ap, const char*); + int n = sqlite3Strlen30(zWord); + rc = (sqlite3KeywordCode((u8*)zWord, n)!=TK_ID) ? SQLITE_N_KEYWORD : 0; + break; + } +#endif + + /* sqlite3_test_control(SQLITE_TESTCTRL_SCRATCHMALLOC, sz, &pNew, pFree); + ** + ** Pass pFree into sqlite3ScratchFree(). + ** If sz>0 then allocate a scratch buffer into pNew. + */ + case SQLITE_TESTCTRL_SCRATCHMALLOC: { + void *pFree, **ppNew; + int sz; + sz = va_arg(ap, int); + ppNew = va_arg(ap, void**); + pFree = va_arg(ap, void*); + if( sz ) *ppNew = sqlite3ScratchMalloc(sz); + sqlite3ScratchFree(pFree); + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff); + ** + ** If parameter onoff is non-zero, configure the wrappers so that all + ** subsequent calls to localtime() and variants fail. If onoff is zero, + ** undo this setting. + */ + case SQLITE_TESTCTRL_LOCALTIME_FAULT: { + sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int); + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int); + ** + ** Set or clear a flag that indicates that the database file is always well- + ** formed and never corrupt. This flag is clear by default, indicating that + ** database files might have arbitrary corruption. Setting the flag during + ** testing causes certain assert() statements in the code to be activated + ** that demonstrat invariants on well-formed database files. + */ + case SQLITE_TESTCTRL_NEVER_CORRUPT: { + sqlite3GlobalConfig.neverCorrupt = va_arg(ap, int); + break; + } + + + /* sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, xCallback, ptr); + ** + ** Set the VDBE coverage callback function to xCallback with context + ** pointer ptr. + */ + case SQLITE_TESTCTRL_VDBE_COVERAGE: { +#ifdef SQLITE_VDBE_COVERAGE + typedef void (*branch_callback)(void*,int,u8,u8); + sqlite3GlobalConfig.xVdbeBranch = va_arg(ap,branch_callback); + sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*); +#endif + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, nMax); */ + case SQLITE_TESTCTRL_SORTER_MMAP: { + sqlite3 *db = va_arg(ap, sqlite3*); + db->nMaxSorterMmap = va_arg(ap, int); + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_ISINIT); + ** + ** Return SQLITE_OK if SQLite has been initialized and SQLITE_ERROR if + ** not. + */ + case SQLITE_TESTCTRL_ISINIT: { + if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR; + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, dbName, onOff, tnum); + ** + ** This test control is used to create imposter tables. "db" is a pointer + ** to the database connection. dbName is the database name (ex: "main" or + ** "temp") which will receive the imposter. "onOff" turns imposter mode on + ** or off. "tnum" is the root page of the b-tree to which the imposter + ** table should connect. + ** + ** Enable imposter mode only when the schema has already been parsed. Then + ** run a single CREATE TABLE statement to construct the imposter table in + ** the parsed schema. Then turn imposter mode back off again. + ** + ** If onOff==0 and tnum>0 then reset the schema for all databases, causing + ** the schema to be reparsed the next time it is needed. This has the + ** effect of erasing all imposter tables. + */ + case SQLITE_TESTCTRL_IMPOSTER: { + sqlite3 *db = va_arg(ap, sqlite3*); + sqlite3_mutex_enter(db->mutex); + db->init.iDb = sqlite3FindDbName(db, va_arg(ap,const char*)); + db->init.busy = db->init.imposterTable = va_arg(ap,int); + db->init.newTnum = va_arg(ap,int); + if( db->init.busy==0 && db->init.newTnum>0 ){ + sqlite3ResetAllSchemasOfConnection(db); + } + sqlite3_mutex_leave(db->mutex); + break; + } + } + va_end(ap); +#endif /* SQLITE_OMIT_BUILTIN_TEST */ + return rc; +} + +/* +** This is a utility routine, useful to VFS implementations, that checks +** to see if a database file was a URI that contained a specific query +** parameter, and if so obtains the value of the query parameter. +** +** The zFilename argument is the filename pointer passed into the xOpen() +** method of a VFS implementation. The zParam argument is the name of the +** query parameter we seek. This routine returns the value of the zParam +** parameter if it exists. If the parameter does not exist, this routine +** returns a NULL pointer. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam){ + if( zFilename==0 || zParam==0 ) return 0; + zFilename += sqlite3Strlen30(zFilename) + 1; + while( zFilename[0] ){ + int x = strcmp(zFilename, zParam); + zFilename += sqlite3Strlen30(zFilename) + 1; + if( x==0 ) return zFilename; + zFilename += sqlite3Strlen30(zFilename) + 1; + } + return 0; +} + +/* +** Return a boolean value for a query parameter. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){ + const char *z = sqlite3_uri_parameter(zFilename, zParam); + bDflt = bDflt!=0; + return z ? sqlite3GetBoolean(z, bDflt) : bDflt; +} + +/* +** Return a 64-bit integer value for a query parameter. +*/ +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64( + const char *zFilename, /* Filename as passed to xOpen */ + const char *zParam, /* URI parameter sought */ + sqlite3_int64 bDflt /* return if parameter is missing */ +){ + const char *z = sqlite3_uri_parameter(zFilename, zParam); + sqlite3_int64 v; + if( z && sqlite3DecOrHexToI64(z, &v)==SQLITE_OK ){ + bDflt = v; + } + return bDflt; +} + +/* +** Return the Btree pointer identified by zDbName. Return NULL if not found. +*/ +SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){ + int i; + for(i=0; inDb; i++){ + if( db->aDb[i].pBt + && (zDbName==0 || sqlite3StrICmp(zDbName, db->aDb[i].zName)==0) + ){ + return db->aDb[i].pBt; + } + } + return 0; +} + +/* +** Return the filename of the database associated with a database +** connection. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *zDbName){ + Btree *pBt; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + pBt = sqlite3DbNameToBtree(db, zDbName); + return pBt ? sqlite3BtreeGetFilename(pBt) : 0; +} + +/* +** Return 1 if database is read-only or 0 if read/write. Return -1 if +** no such database exists. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbName){ + Btree *pBt; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return -1; + } +#endif + pBt = sqlite3DbNameToBtree(db, zDbName); + return pBt ? sqlite3BtreeIsReadonly(pBt) : -1; +} + +/************** End of main.c ************************************************/ +/************** Begin file notify.c ******************************************/ +/* +** 2009 March 3 +** +** 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_unlock_notify() +** API method and its associated functionality. +*/ + +/* Omit this entire file if SQLITE_ENABLE_UNLOCK_NOTIFY is not defined. */ +#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY + +/* +** Public interfaces: +** +** sqlite3ConnectionBlocked() +** sqlite3ConnectionUnlocked() +** sqlite3ConnectionClosed() +** sqlite3_unlock_notify() +*/ + +#define assertMutexHeld() \ + assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) ) + +/* +** Head of a linked list of all sqlite3 objects created by this process +** for which either sqlite3.pBlockingConnection or sqlite3.pUnlockConnection +** is not NULL. This variable may only accessed while the STATIC_MASTER +** mutex is held. +*/ +static sqlite3 *SQLITE_WSD sqlite3BlockedList = 0; + +#ifndef NDEBUG +/* +** This function is a complex assert() that verifies the following +** properties of the blocked connections list: +** +** 1) Each entry in the list has a non-NULL value for either +** pUnlockConnection or pBlockingConnection, or both. +** +** 2) All entries in the list that share a common value for +** xUnlockNotify are grouped together. +** +** 3) If the argument db is not NULL, then none of the entries in the +** blocked connections list have pUnlockConnection or pBlockingConnection +** set to db. This is used when closing connection db. +*/ +static void checkListProperties(sqlite3 *db){ + sqlite3 *p; + for(p=sqlite3BlockedList; p; p=p->pNextBlocked){ + int seen = 0; + sqlite3 *p2; + + /* Verify property (1) */ + assert( p->pUnlockConnection || p->pBlockingConnection ); + + /* Verify property (2) */ + for(p2=sqlite3BlockedList; p2!=p; p2=p2->pNextBlocked){ + if( p2->xUnlockNotify==p->xUnlockNotify ) seen = 1; + assert( p2->xUnlockNotify==p->xUnlockNotify || !seen ); + assert( db==0 || p->pUnlockConnection!=db ); + assert( db==0 || p->pBlockingConnection!=db ); + } + } +} +#else +# define checkListProperties(x) +#endif + +/* +** Remove connection db from the blocked connections list. If connection +** db is not currently a part of the list, this function is a no-op. +*/ +static void removeFromBlockedList(sqlite3 *db){ + sqlite3 **pp; + assertMutexHeld(); + for(pp=&sqlite3BlockedList; *pp; pp = &(*pp)->pNextBlocked){ + if( *pp==db ){ + *pp = (*pp)->pNextBlocked; + break; + } + } +} + +/* +** Add connection db to the blocked connections list. It is assumed +** that it is not already a part of the list. +*/ +static void addToBlockedList(sqlite3 *db){ + sqlite3 **pp; + assertMutexHeld(); + for( + pp=&sqlite3BlockedList; + *pp && (*pp)->xUnlockNotify!=db->xUnlockNotify; + pp=&(*pp)->pNextBlocked + ); + db->pNextBlocked = *pp; + *pp = db; +} + +/* +** Obtain the STATIC_MASTER mutex. +*/ +static void enterMutex(void){ + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); + checkListProperties(0); +} + +/* +** Release the STATIC_MASTER mutex. +*/ +static void leaveMutex(void){ + assertMutexHeld(); + checkListProperties(0); + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +} + +/* +** Register an unlock-notify callback. +** +** This is called after connection "db" has attempted some operation +** but has received an SQLITE_LOCKED error because another connection +** (call it pOther) in the same process was busy using the same shared +** cache. pOther is found by looking at db->pBlockingConnection. +** +** If there is no blocking connection, the callback is invoked immediately, +** before this routine returns. +** +** If pOther is already blocked on db, then report SQLITE_LOCKED, to indicate +** a deadlock. +** +** Otherwise, make arrangements to invoke xNotify when pOther drops +** its locks. +** +** Each call to this routine overrides any prior callbacks registered +** on the same "db". If xNotify==0 then any prior callbacks are immediately +** cancelled. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify( + sqlite3 *db, + void (*xNotify)(void **, int), + void *pArg +){ + int rc = SQLITE_OK; + + sqlite3_mutex_enter(db->mutex); + enterMutex(); + + if( xNotify==0 ){ + removeFromBlockedList(db); + db->pBlockingConnection = 0; + db->pUnlockConnection = 0; + db->xUnlockNotify = 0; + db->pUnlockArg = 0; + }else if( 0==db->pBlockingConnection ){ + /* The blocking transaction has been concluded. Or there never was a + ** blocking transaction. In either case, invoke the notify callback + ** immediately. + */ + xNotify(&pArg, 1); + }else{ + sqlite3 *p; + + for(p=db->pBlockingConnection; p && p!=db; p=p->pUnlockConnection){} + if( p ){ + rc = SQLITE_LOCKED; /* Deadlock detected. */ + }else{ + db->pUnlockConnection = db->pBlockingConnection; + db->xUnlockNotify = xNotify; + db->pUnlockArg = pArg; + removeFromBlockedList(db); + addToBlockedList(db); + } + } + + leaveMutex(); + assert( !db->mallocFailed ); + sqlite3ErrorWithMsg(db, rc, (rc?"database is deadlocked":0)); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** This function is called while stepping or preparing a statement +** associated with connection db. The operation will return SQLITE_LOCKED +** to the user because it requires a lock that will not be available +** until connection pBlocker concludes its current transaction. +*/ +SQLITE_PRIVATE void sqlite3ConnectionBlocked(sqlite3 *db, sqlite3 *pBlocker){ + enterMutex(); + if( db->pBlockingConnection==0 && db->pUnlockConnection==0 ){ + addToBlockedList(db); + } + db->pBlockingConnection = pBlocker; + leaveMutex(); +} + +/* +** This function is called when +** the transaction opened by database db has just finished. Locks held +** by database connection db have been released. +** +** This function loops through each entry in the blocked connections +** list and does the following: +** +** 1) If the sqlite3.pBlockingConnection member of a list entry is +** set to db, then set pBlockingConnection=0. +** +** 2) If the sqlite3.pUnlockConnection member of a list entry is +** set to db, then invoke the configured unlock-notify callback and +** set pUnlockConnection=0. +** +** 3) If the two steps above mean that pBlockingConnection==0 and +** pUnlockConnection==0, remove the entry from the blocked connections +** list. +*/ +SQLITE_PRIVATE void sqlite3ConnectionUnlocked(sqlite3 *db){ + void (*xUnlockNotify)(void **, int) = 0; /* Unlock-notify cb to invoke */ + int nArg = 0; /* Number of entries in aArg[] */ + sqlite3 **pp; /* Iterator variable */ + void **aArg; /* Arguments to the unlock callback */ + void **aDyn = 0; /* Dynamically allocated space for aArg[] */ + void *aStatic[16]; /* Starter space for aArg[]. No malloc required */ + + aArg = aStatic; + enterMutex(); /* Enter STATIC_MASTER mutex */ + + /* This loop runs once for each entry in the blocked-connections list. */ + for(pp=&sqlite3BlockedList; *pp; /* no-op */ ){ + sqlite3 *p = *pp; + + /* Step 1. */ + if( p->pBlockingConnection==db ){ + p->pBlockingConnection = 0; + } + + /* Step 2. */ + if( p->pUnlockConnection==db ){ + assert( p->xUnlockNotify ); + if( p->xUnlockNotify!=xUnlockNotify && nArg!=0 ){ + xUnlockNotify(aArg, nArg); + nArg = 0; + } + + sqlite3BeginBenignMalloc(); + assert( aArg==aDyn || (aDyn==0 && aArg==aStatic) ); + assert( nArg<=(int)ArraySize(aStatic) || aArg==aDyn ); + if( (!aDyn && nArg==(int)ArraySize(aStatic)) + || (aDyn && nArg==(int)(sqlite3MallocSize(aDyn)/sizeof(void*))) + ){ + /* The aArg[] array needs to grow. */ + void **pNew = (void **)sqlite3Malloc(nArg*sizeof(void *)*2); + if( pNew ){ + memcpy(pNew, aArg, nArg*sizeof(void *)); + sqlite3_free(aDyn); + aDyn = aArg = pNew; + }else{ + /* This occurs when the array of context pointers that need to + ** be passed to the unlock-notify callback is larger than the + ** aStatic[] array allocated on the stack and the attempt to + ** allocate a larger array from the heap has failed. + ** + ** This is a difficult situation to handle. Returning an error + ** code to the caller is insufficient, as even if an error code + ** is returned the transaction on connection db will still be + ** closed and the unlock-notify callbacks on blocked connections + ** will go unissued. This might cause the application to wait + ** indefinitely for an unlock-notify callback that will never + ** arrive. + ** + ** Instead, invoke the unlock-notify callback with the context + ** array already accumulated. We can then clear the array and + ** begin accumulating any further context pointers without + ** requiring any dynamic allocation. This is sub-optimal because + ** it means that instead of one callback with a large array of + ** context pointers the application will receive two or more + ** callbacks with smaller arrays of context pointers, which will + ** reduce the applications ability to prioritize multiple + ** connections. But it is the best that can be done under the + ** circumstances. + */ + xUnlockNotify(aArg, nArg); + nArg = 0; + } + } + sqlite3EndBenignMalloc(); + + aArg[nArg++] = p->pUnlockArg; + xUnlockNotify = p->xUnlockNotify; + p->pUnlockConnection = 0; + p->xUnlockNotify = 0; + p->pUnlockArg = 0; + } + + /* Step 3. */ + if( p->pBlockingConnection==0 && p->pUnlockConnection==0 ){ + /* Remove connection p from the blocked connections list. */ + *pp = p->pNextBlocked; + p->pNextBlocked = 0; + }else{ + pp = &p->pNextBlocked; + } + } + + if( nArg!=0 ){ + xUnlockNotify(aArg, nArg); + } + sqlite3_free(aDyn); + leaveMutex(); /* Leave STATIC_MASTER mutex */ +} + +/* +** This is called when the database connection passed as an argument is +** being closed. The connection is removed from the blocked list. +*/ +SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){ + sqlite3ConnectionUnlocked(db); + enterMutex(); + removeFromBlockedList(db); + checkListProperties(db); + leaveMutex(); +} +#endif + +/************** End of notify.c **********************************************/ +/************** Begin file fts3.c ********************************************/ +/* +** 2006 Oct 10 +** +** 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 is an SQLite module implementing full-text search. +*/ + +/* +** The code in this file is only compiled if: +** +** * The FTS3 module is being built as an extension +** (in which case SQLITE_CORE is not defined), or +** +** * The FTS3 module is being built into the core of +** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). +*/ + +/* The full-text index is stored in a series of b+tree (-like) +** structures called segments which map terms to doclists. The +** structures are like b+trees in layout, but are constructed from the +** bottom up in optimal fashion and are not updatable. Since trees +** are built from the bottom up, things will be described from the +** bottom up. +** +** +**** Varints **** +** The basic unit of encoding is a variable-length integer called a +** varint. We encode variable-length integers in little-endian order +** using seven bits * per byte as follows: +** +** KEY: +** A = 0xxxxxxx 7 bits of data and one flag bit +** B = 1xxxxxxx 7 bits of data and one flag bit +** +** 7 bits - A +** 14 bits - BA +** 21 bits - BBA +** and so on. +** +** This is similar in concept to how sqlite encodes "varints" but +** the encoding is not the same. SQLite varints are big-endian +** are are limited to 9 bytes in length whereas FTS3 varints are +** little-endian and can be up to 10 bytes in length (in theory). +** +** Example encodings: +** +** 1: 0x01 +** 127: 0x7f +** 128: 0x81 0x00 +** +** +**** Document lists **** +** A doclist (document list) holds a docid-sorted list of hits for a +** given term. Doclists hold docids and associated token positions. +** A docid is the unique integer identifier for a single document. +** A position is the index of a word within the document. The first +** word of the document has a position of 0. +** +** FTS3 used to optionally store character offsets using a compile-time +** option. But that functionality is no longer supported. +** +** A doclist is stored like this: +** +** array { +** varint docid; (delta from previous doclist) +** array { (position list for column 0) +** varint position; (2 more than the delta from previous position) +** } +** array { +** varint POS_COLUMN; (marks start of position list for new column) +** varint column; (index of new column) +** array { +** varint position; (2 more than the delta from previous position) +** } +** } +** varint POS_END; (marks end of positions for this document. +** } +** +** Here, array { X } means zero or more occurrences of X, adjacent in +** memory. A "position" is an index of a token in the token stream +** generated by the tokenizer. Note that POS_END and POS_COLUMN occur +** in the same logical place as the position element, and act as sentinals +** ending a position list array. POS_END is 0. POS_COLUMN is 1. +** The positions numbers are not stored literally but rather as two more +** than the difference from the prior position, or the just the position plus +** 2 for the first position. Example: +** +** label: A B C D E F G H I J K +** value: 123 5 9 1 1 14 35 0 234 72 0 +** +** The 123 value is the first docid. For column zero in this document +** there are two matches at positions 3 and 10 (5-2 and 9-2+3). The 1 +** at D signals the start of a new column; the 1 at E indicates that the +** new column is column number 1. There are two positions at 12 and 45 +** (14-2 and 35-2+12). The 0 at H indicate the end-of-document. The +** 234 at I is the delta to next docid (357). It has one position 70 +** (72-2) and then terminates with the 0 at K. +** +** A "position-list" is the list of positions for multiple columns for +** a single docid. A "column-list" is the set of positions for a single +** column. Hence, a position-list consists of one or more column-lists, +** a document record consists of a docid followed by a position-list and +** a doclist consists of one or more document records. +** +** A bare doclist omits the position information, becoming an +** array of varint-encoded docids. +** +**** Segment leaf nodes **** +** Segment leaf nodes store terms and doclists, ordered by term. Leaf +** nodes are written using LeafWriter, and read using LeafReader (to +** iterate through a single leaf node's data) and LeavesReader (to +** iterate through a segment's entire leaf layer). Leaf nodes have +** the format: +** +** varint iHeight; (height from leaf level, always 0) +** varint nTerm; (length of first term) +** char pTerm[nTerm]; (content of first term) +** varint nDoclist; (length of term's associated doclist) +** char pDoclist[nDoclist]; (content of doclist) +** array { +** (further terms are delta-encoded) +** varint nPrefix; (length of prefix shared with previous term) +** varint nSuffix; (length of unshared suffix) +** char pTermSuffix[nSuffix];(unshared suffix of next term) +** varint nDoclist; (length of term's associated doclist) +** char pDoclist[nDoclist]; (content of doclist) +** } +** +** Here, array { X } means zero or more occurrences of X, adjacent in +** memory. +** +** Leaf nodes are broken into blocks which are stored contiguously in +** the %_segments table in sorted order. This means that when the end +** of a node is reached, the next term is in the node with the next +** greater node id. +** +** New data is spilled to a new leaf node when the current node +** exceeds LEAF_MAX bytes (default 2048). New data which itself is +** larger than STANDALONE_MIN (default 1024) is placed in a standalone +** node (a leaf node with a single term and doclist). The goal of +** these settings is to pack together groups of small doclists while +** making it efficient to directly access large doclists. The +** assumption is that large doclists represent terms which are more +** likely to be query targets. +** +** TODO(shess) It may be useful for blocking decisions to be more +** dynamic. For instance, it may make more sense to have a 2.5k leaf +** node rather than splitting into 2k and .5k nodes. My intuition is +** that this might extend through 2x or 4x the pagesize. +** +** +**** Segment interior nodes **** +** Segment interior nodes store blockids for subtree nodes and terms +** to describe what data is stored by the each subtree. Interior +** nodes are written using InteriorWriter, and read using +** InteriorReader. InteriorWriters are created as needed when +** SegmentWriter creates new leaf nodes, or when an interior node +** itself grows too big and must be split. The format of interior +** nodes: +** +** varint iHeight; (height from leaf level, always >0) +** varint iBlockid; (block id of node's leftmost subtree) +** optional { +** varint nTerm; (length of first term) +** char pTerm[nTerm]; (content of first term) +** array { +** (further terms are delta-encoded) +** varint nPrefix; (length of shared prefix with previous term) +** varint nSuffix; (length of unshared suffix) +** char pTermSuffix[nSuffix]; (unshared suffix of next term) +** } +** } +** +** Here, optional { X } means an optional element, while array { X } +** means zero or more occurrences of X, adjacent in memory. +** +** An interior node encodes n terms separating n+1 subtrees. The +** subtree blocks are contiguous, so only the first subtree's blockid +** is encoded. The subtree at iBlockid will contain all terms less +** than the first term encoded (or all terms if no term is encoded). +** Otherwise, for terms greater than or equal to pTerm[i] but less +** than pTerm[i+1], the subtree for that term will be rooted at +** iBlockid+i. Interior nodes only store enough term data to +** distinguish adjacent children (if the rightmost term of the left +** child is "something", and the leftmost term of the right child is +** "wicked", only "w" is stored). +** +** New data is spilled to a new interior node at the same height when +** the current node exceeds INTERIOR_MAX bytes (default 2048). +** INTERIOR_MIN_TERMS (default 7) keeps large terms from monopolizing +** interior nodes and making the tree too skinny. The interior nodes +** at a given height are naturally tracked by interior nodes at +** height+1, and so on. +** +** +**** Segment directory **** +** The segment directory in table %_segdir stores meta-information for +** merging and deleting segments, and also the root node of the +** segment's tree. +** +** The root node is the top node of the segment's tree after encoding +** the entire segment, restricted to ROOT_MAX bytes (default 1024). +** This could be either a leaf node or an interior node. If the top +** node requires more than ROOT_MAX bytes, it is flushed to %_segments +** and a new root interior node is generated (which should always fit +** within ROOT_MAX because it only needs space for 2 varints, the +** height and the blockid of the previous root). +** +** The meta-information in the segment directory is: +** level - segment level (see below) +** idx - index within level +** - (level,idx uniquely identify a segment) +** start_block - first leaf node +** leaves_end_block - last leaf node +** end_block - last block (including interior nodes) +** root - contents of root node +** +** If the root node is a leaf node, then start_block, +** leaves_end_block, and end_block are all 0. +** +** +**** Segment merging **** +** To amortize update costs, segments are grouped into levels and +** merged in batches. Each increase in level represents exponentially +** more documents. +** +** New documents (actually, document updates) are tokenized and +** written individually (using LeafWriter) to a level 0 segment, with +** incrementing idx. When idx reaches MERGE_COUNT (default 16), all +** level 0 segments are merged into a single level 1 segment. Level 1 +** is populated like level 0, and eventually MERGE_COUNT level 1 +** segments are merged to a single level 2 segment (representing +** MERGE_COUNT^2 updates), and so on. +** +** A segment merge traverses all segments at a given level in +** parallel, performing a straightforward sorted merge. Since segment +** leaf nodes are written in to the %_segments table in order, this +** merge traverses the underlying sqlite disk structures efficiently. +** After the merge, all segment blocks from the merged level are +** deleted. +** +** MERGE_COUNT controls how often we merge segments. 16 seems to be +** somewhat of a sweet spot for insertion performance. 32 and 64 show +** very similar performance numbers to 16 on insertion, though they're +** a tiny bit slower (perhaps due to more overhead in merge-time +** sorting). 8 is about 20% slower than 16, 4 about 50% slower than +** 16, 2 about 66% slower than 16. +** +** At query time, high MERGE_COUNT increases the number of segments +** which need to be scanned and merged. For instance, with 100k docs +** inserted: +** +** MERGE_COUNT segments +** 16 25 +** 8 12 +** 4 10 +** 2 6 +** +** This appears to have only a moderate impact on queries for very +** frequent terms (which are somewhat dominated by segment merge +** costs), and infrequent and non-existent terms still seem to be fast +** even with many segments. +** +** TODO(shess) That said, it would be nice to have a better query-side +** argument for MERGE_COUNT of 16. Also, it is possible/likely that +** optimizations to things like doclist merging will swing the sweet +** spot around. +** +** +** +**** Handling of deletions and updates **** +** Since we're using a segmented structure, with no docid-oriented +** index into the term index, we clearly cannot simply update the term +** index when a document is deleted or updated. For deletions, we +** write an empty doclist (varint(docid) varint(POS_END)), for updates +** we simply write the new doclist. Segment merges overwrite older +** data for a particular docid with newer data, so deletes or updates +** will eventually overtake the earlier data and knock it out. The +** query logic likewise merges doclists so that newer data knocks out +** older data. +*/ + +/************** Include fts3Int.h in the middle of fts3.c ********************/ +/************** Begin file fts3Int.h *****************************************/ +/* +** 2009 Nov 12 +** +** 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. +** +****************************************************************************** +** +*/ +#ifndef _FTSINT_H +#define _FTSINT_H + +#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) +# define NDEBUG 1 +#endif + +/* +** FTS4 is really an extension for FTS3. It is enabled using the +** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also all +** the SQLITE_ENABLE_FTS4 macro to serve as an alisse for SQLITE_ENABLE_FTS3. +*/ +#if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3) +# define SQLITE_ENABLE_FTS3 +#endif + +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* If not building as part of the core, include sqlite3ext.h. */ +#ifndef SQLITE_CORE +SQLITE_EXTENSION_INIT3 +#endif + +/************** Include fts3_tokenizer.h in the middle of fts3Int.h **********/ +/************** Begin file fts3_tokenizer.h **********************************/ +/* +** 2006 July 10 +** +** The author disclaims copyright to this source code. +** +************************************************************************* +** Defines the interface to tokenizers used by fulltext-search. There +** are three basic components: +** +** sqlite3_tokenizer_module is a singleton defining the tokenizer +** interface functions. This is essentially the class structure for +** tokenizers. +** +** sqlite3_tokenizer is used to define a particular tokenizer, perhaps +** including customization information defined at creation time. +** +** sqlite3_tokenizer_cursor is generated by a tokenizer to generate +** tokens from a particular input. +*/ +#ifndef _FTS3_TOKENIZER_H_ +#define _FTS3_TOKENIZER_H_ + +/* TODO(shess) Only used for SQLITE_OK and SQLITE_DONE at this time. +** If tokenizers are to be allowed to call sqlite3_*() functions, then +** we will need a way to register the API consistently. +*/ + +/* +** Structures used by the tokenizer interface. When a new tokenizer +** implementation is registered, the caller provides a pointer to +** an sqlite3_tokenizer_module containing pointers to the callback +** functions that make up an implementation. +** +** When an fts3 table is created, it passes any arguments passed to +** the tokenizer clause of the CREATE VIRTUAL TABLE statement to the +** sqlite3_tokenizer_module.xCreate() function of the requested tokenizer +** implementation. The xCreate() function in turn returns an +** sqlite3_tokenizer structure representing the specific tokenizer to +** be used for the fts3 table (customized by the tokenizer clause arguments). +** +** To tokenize an input buffer, the sqlite3_tokenizer_module.xOpen() +** method is called. It returns an sqlite3_tokenizer_cursor object +** that may be used to tokenize a specific input buffer based on +** the tokenization rules supplied by a specific sqlite3_tokenizer +** object. +*/ +typedef struct sqlite3_tokenizer_module sqlite3_tokenizer_module; +typedef struct sqlite3_tokenizer sqlite3_tokenizer; +typedef struct sqlite3_tokenizer_cursor sqlite3_tokenizer_cursor; + +struct sqlite3_tokenizer_module { + + /* + ** Structure version. Should always be set to 0 or 1. + */ + int iVersion; + + /* + ** Create a new tokenizer. The values in the argv[] array are the + ** arguments passed to the "tokenizer" clause of the CREATE VIRTUAL + ** TABLE statement that created the fts3 table. For example, if + ** the following SQL is executed: + ** + ** CREATE .. USING fts3( ... , tokenizer arg1 arg2) + ** + ** then argc is set to 2, and the argv[] array contains pointers + ** to the strings "arg1" and "arg2". + ** + ** This method should return either SQLITE_OK (0), or an SQLite error + ** code. If SQLITE_OK is returned, then *ppTokenizer should be set + ** to point at the newly created tokenizer structure. The generic + ** sqlite3_tokenizer.pModule variable should not be initialized by + ** this callback. The caller will do so. + */ + int (*xCreate)( + int argc, /* Size of argv array */ + const char *const*argv, /* Tokenizer argument strings */ + sqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */ + ); + + /* + ** Destroy an existing tokenizer. The fts3 module calls this method + ** exactly once for each successful call to xCreate(). + */ + int (*xDestroy)(sqlite3_tokenizer *pTokenizer); + + /* + ** Create a tokenizer cursor to tokenize an input buffer. The caller + ** is responsible for ensuring that the input buffer remains valid + ** until the cursor is closed (using the xClose() method). + */ + int (*xOpen)( + sqlite3_tokenizer *pTokenizer, /* Tokenizer object */ + const char *pInput, int nBytes, /* Input buffer */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Created tokenizer cursor */ + ); + + /* + ** Destroy an existing tokenizer cursor. The fts3 module calls this + ** method exactly once for each successful call to xOpen(). + */ + int (*xClose)(sqlite3_tokenizer_cursor *pCursor); + + /* + ** Retrieve the next token from the tokenizer cursor pCursor. This + ** method should either return SQLITE_OK and set the values of the + ** "OUT" variables identified below, or SQLITE_DONE to indicate that + ** the end of the buffer has been reached, or an SQLite error code. + ** + ** *ppToken should be set to point at a buffer containing the + ** normalized version of the token (i.e. after any case-folding and/or + ** stemming has been performed). *pnBytes should be set to the length + ** of this buffer in bytes. The input text that generated the token is + ** identified by the byte offsets returned in *piStartOffset and + ** *piEndOffset. *piStartOffset should be set to the index of the first + ** byte of the token in the input buffer. *piEndOffset should be set + ** to the index of the first byte just past the end of the token in + ** the input buffer. + ** + ** The buffer *ppToken is set to point at is managed by the tokenizer + ** implementation. It is only required to be valid until the next call + ** to xNext() or xClose(). + */ + /* TODO(shess) current implementation requires pInput to be + ** nul-terminated. This should either be fixed, or pInput/nBytes + ** should be converted to zInput. + */ + int (*xNext)( + sqlite3_tokenizer_cursor *pCursor, /* Tokenizer cursor */ + const char **ppToken, int *pnBytes, /* OUT: Normalized text for token */ + int *piStartOffset, /* OUT: Byte offset of token in input buffer */ + int *piEndOffset, /* OUT: Byte offset of end of token in input buffer */ + int *piPosition /* OUT: Number of tokens returned before this one */ + ); + + /*********************************************************************** + ** Methods below this point are only available if iVersion>=1. + */ + + /* + ** Configure the language id of a tokenizer cursor. + */ + int (*xLanguageid)(sqlite3_tokenizer_cursor *pCsr, int iLangid); +}; + +struct sqlite3_tokenizer { + const sqlite3_tokenizer_module *pModule; /* The module for this tokenizer */ + /* Tokenizer implementations will typically add additional fields */ +}; + +struct sqlite3_tokenizer_cursor { + sqlite3_tokenizer *pTokenizer; /* Tokenizer for this cursor. */ + /* Tokenizer implementations will typically add additional fields */ +}; + +int fts3_global_term_cnt(int iTerm, int iCol); +int fts3_term_cnt(int iTerm, int iCol); + + +#endif /* _FTS3_TOKENIZER_H_ */ + +/************** End of fts3_tokenizer.h **************************************/ +/************** Continuing where we left off in fts3Int.h ********************/ +/************** Include fts3_hash.h in the middle of fts3Int.h ***************/ +/************** Begin file fts3_hash.h ***************************************/ +/* +** 2001 September 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 is the header file for the generic hash-table implementation +** used in SQLite. We've modified it slightly to serve as a standalone +** hash table implementation for the full-text indexing module. +** +*/ +#ifndef _FTS3_HASH_H_ +#define _FTS3_HASH_H_ + +/* Forward declarations of structures. */ +typedef struct Fts3Hash Fts3Hash; +typedef struct Fts3HashElem Fts3HashElem; + +/* A complete hash table is an instance of the following structure. +** The internals of this structure are intended to be opaque -- client +** code should not attempt to access or modify the fields of this structure +** directly. Change this structure only by using the routines below. +** However, many of the "procedures" and "functions" for modifying and +** accessing this structure are really macros, so we can't really make +** this structure opaque. +*/ +struct Fts3Hash { + char keyClass; /* HASH_INT, _POINTER, _STRING, _BINARY */ + char copyKey; /* True if copy of key made on insert */ + int count; /* Number of entries in this table */ + Fts3HashElem *first; /* The first element of the array */ + int htsize; /* Number of buckets in the hash table */ + struct _fts3ht { /* the hash table */ + int count; /* Number of entries with this hash */ + Fts3HashElem *chain; /* Pointer to first entry with this hash */ + } *ht; +}; + +/* Each element in the hash table is an instance of the following +** structure. All elements are stored on a single doubly-linked list. +** +** Again, this structure is intended to be opaque, but it can't really +** be opaque because it is used by macros. +*/ +struct Fts3HashElem { + Fts3HashElem *next, *prev; /* Next and previous elements in the table */ + void *data; /* Data associated with this element */ + void *pKey; int nKey; /* Key associated with this element */ +}; + +/* +** There are 2 different modes of operation for a hash table: +** +** FTS3_HASH_STRING pKey points to a string that is nKey bytes long +** (including the null-terminator, if any). Case +** is respected in comparisons. +** +** FTS3_HASH_BINARY pKey points to binary data nKey bytes long. +** memcmp() is used to compare keys. +** +** A copy of the key is made if the copyKey parameter to fts3HashInit is 1. +*/ +#define FTS3_HASH_STRING 1 +#define FTS3_HASH_BINARY 2 + +/* +** Access routines. To delete, insert a NULL pointer. +*/ +SQLITE_PRIVATE void sqlite3Fts3HashInit(Fts3Hash *pNew, char keyClass, char copyKey); +SQLITE_PRIVATE void *sqlite3Fts3HashInsert(Fts3Hash*, const void *pKey, int nKey, void *pData); +SQLITE_PRIVATE void *sqlite3Fts3HashFind(const Fts3Hash*, const void *pKey, int nKey); +SQLITE_PRIVATE void sqlite3Fts3HashClear(Fts3Hash*); +SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const void *, int); + +/* +** Shorthand for the functions above +*/ +#define fts3HashInit sqlite3Fts3HashInit +#define fts3HashInsert sqlite3Fts3HashInsert +#define fts3HashFind sqlite3Fts3HashFind +#define fts3HashClear sqlite3Fts3HashClear +#define fts3HashFindElem sqlite3Fts3HashFindElem + +/* +** Macros for looping over all elements of a hash table. The idiom is +** like this: +** +** Fts3Hash h; +** Fts3HashElem *p; +** ... +** for(p=fts3HashFirst(&h); p; p=fts3HashNext(p)){ +** SomeStructure *pData = fts3HashData(p); +** // do something with pData +** } +*/ +#define fts3HashFirst(H) ((H)->first) +#define fts3HashNext(E) ((E)->next) +#define fts3HashData(E) ((E)->data) +#define fts3HashKey(E) ((E)->pKey) +#define fts3HashKeysize(E) ((E)->nKey) + +/* +** Number of entries in a hash table +*/ +#define fts3HashCount(H) ((H)->count) + +#endif /* _FTS3_HASH_H_ */ + +/************** End of fts3_hash.h *******************************************/ +/************** Continuing where we left off in fts3Int.h ********************/ + +/* +** This constant determines the maximum depth of an FTS expression tree +** that the library will create and use. FTS uses recursion to perform +** various operations on the query tree, so the disadvantage of a large +** limit is that it may allow very large queries to use large amounts +** of stack space (perhaps causing a stack overflow). +*/ +#ifndef SQLITE_FTS3_MAX_EXPR_DEPTH +# define SQLITE_FTS3_MAX_EXPR_DEPTH 12 +#endif + + +/* +** This constant controls how often segments are merged. Once there are +** FTS3_MERGE_COUNT segments of level N, they are merged into a single +** segment of level N+1. +*/ +#define FTS3_MERGE_COUNT 16 + +/* +** This is the maximum amount of data (in bytes) to store in the +** Fts3Table.pendingTerms hash table. Normally, the hash table is +** populated as documents are inserted/updated/deleted in a transaction +** and used to create a new segment when the transaction is committed. +** However if this limit is reached midway through a transaction, a new +** segment is created and the hash table cleared immediately. +*/ +#define FTS3_MAX_PENDING_DATA (1*1024*1024) + +/* +** Macro to return the number of elements in an array. SQLite has a +** similar macro called ArraySize(). Use a different name to avoid +** a collision when building an amalgamation with built-in FTS3. +*/ +#define SizeofArray(X) ((int)(sizeof(X)/sizeof(X[0]))) + + +#ifndef MIN +# define MIN(x,y) ((x)<(y)?(x):(y)) +#endif +#ifndef MAX +# define MAX(x,y) ((x)>(y)?(x):(y)) +#endif + +/* +** Maximum length of a varint encoded integer. The varint format is different +** from that used by SQLite, so the maximum length is 10, not 9. +*/ +#define FTS3_VARINT_MAX 10 + +/* +** FTS4 virtual tables may maintain multiple indexes - one index of all terms +** in the document set and zero or more prefix indexes. All indexes are stored +** as one or more b+-trees in the %_segments and %_segdir tables. +** +** It is possible to determine which index a b+-tree belongs to based on the +** value stored in the "%_segdir.level" column. Given this value L, the index +** that the b+-tree belongs to is (L<<10). In other words, all b+-trees with +** level values between 0 and 1023 (inclusive) belong to index 0, all levels +** between 1024 and 2047 to index 1, and so on. +** +** It is considered impossible for an index to use more than 1024 levels. In +** theory though this may happen, but only after at least +** (FTS3_MERGE_COUNT^1024) separate flushes of the pending-terms tables. +*/ +#define FTS3_SEGDIR_MAXLEVEL 1024 +#define FTS3_SEGDIR_MAXLEVEL_STR "1024" + +/* +** The testcase() macro is only used by the amalgamation. If undefined, +** make it a no-op. +*/ +#ifndef testcase +# define testcase(X) +#endif + +/* +** Terminator values for position-lists and column-lists. +*/ +#define POS_COLUMN (1) /* Column-list terminator */ +#define POS_END (0) /* Position-list terminator */ + +/* +** This section provides definitions to allow the +** FTS3 extension to be compiled outside of the +** amalgamation. +*/ +#ifndef SQLITE_AMALGAMATION +/* +** Macros indicating that conditional expressions are always true or +** false. +*/ +#ifdef SQLITE_COVERAGE_TEST +# define ALWAYS(x) (1) +# define NEVER(X) (0) +#elif defined(SQLITE_DEBUG) +# define ALWAYS(x) sqlite3Fts3Always((x)!=0) +# define NEVER(x) sqlite3Fts3Never((x)!=0) +SQLITE_PRIVATE int sqlite3Fts3Always(int b); +SQLITE_PRIVATE int sqlite3Fts3Never(int b); +#else +# define ALWAYS(x) (x) +# define NEVER(x) (x) +#endif + +/* +** Internal types used by SQLite. +*/ +typedef unsigned char u8; /* 1-byte (or larger) unsigned integer */ +typedef short int i16; /* 2-byte (or larger) signed integer */ +typedef unsigned int u32; /* 4-byte unsigned integer */ +typedef sqlite3_uint64 u64; /* 8-byte unsigned integer */ +typedef sqlite3_int64 i64; /* 8-byte signed integer */ + +/* +** Macro used to suppress compiler warnings for unused parameters. +*/ +#define UNUSED_PARAMETER(x) (void)(x) + +/* +** Activate assert() only if SQLITE_TEST is enabled. +*/ +#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) +# define NDEBUG 1 +#endif + +/* +** The TESTONLY macro is used to enclose variable declarations or +** other bits of code that are needed to support the arguments +** within testcase() and assert() macros. +*/ +#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) +# define TESTONLY(X) X +#else +# define TESTONLY(X) +#endif + +#endif /* SQLITE_AMALGAMATION */ + +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3Fts3Corrupt(void); +# define FTS_CORRUPT_VTAB sqlite3Fts3Corrupt() +#else +# define FTS_CORRUPT_VTAB SQLITE_CORRUPT_VTAB +#endif + +typedef struct Fts3Table Fts3Table; +typedef struct Fts3Cursor Fts3Cursor; +typedef struct Fts3Expr Fts3Expr; +typedef struct Fts3Phrase Fts3Phrase; +typedef struct Fts3PhraseToken Fts3PhraseToken; + +typedef struct Fts3Doclist Fts3Doclist; +typedef struct Fts3SegFilter Fts3SegFilter; +typedef struct Fts3DeferredToken Fts3DeferredToken; +typedef struct Fts3SegReader Fts3SegReader; +typedef struct Fts3MultiSegReader Fts3MultiSegReader; + +/* +** A connection to a fulltext index is an instance of the following +** structure. The xCreate and xConnect methods create an instance +** of this structure and xDestroy and xDisconnect free that instance. +** All other methods receive a pointer to the structure as one of their +** arguments. +*/ +struct Fts3Table { + sqlite3_vtab base; /* Base class used by SQLite core */ + sqlite3 *db; /* The database connection */ + const char *zDb; /* logical database name */ + const char *zName; /* virtual table name */ + int nColumn; /* number of named columns in virtual table */ + char **azColumn; /* column names. malloced */ + u8 *abNotindexed; /* True for 'notindexed' columns */ + sqlite3_tokenizer *pTokenizer; /* tokenizer for inserts and queries */ + char *zContentTbl; /* content=xxx option, or NULL */ + char *zLanguageid; /* languageid=xxx option, or NULL */ + int nAutoincrmerge; /* Value configured by 'automerge' */ + u32 nLeafAdd; /* Number of leaf blocks added this trans */ + + /* Precompiled statements used by the implementation. Each of these + ** statements is run and reset within a single virtual table API call. + */ + sqlite3_stmt *aStmt[40]; + + char *zReadExprlist; + char *zWriteExprlist; + + int nNodeSize; /* Soft limit for node size */ + u8 bFts4; /* True for FTS4, false for FTS3 */ + u8 bHasStat; /* True if %_stat table exists (2==unknown) */ + u8 bHasDocsize; /* True if %_docsize table exists */ + u8 bDescIdx; /* True if doclists are in reverse order */ + u8 bIgnoreSavepoint; /* True to ignore xSavepoint invocations */ + int nPgsz; /* Page size for host database */ + char *zSegmentsTbl; /* Name of %_segments table */ + sqlite3_blob *pSegments; /* Blob handle open on %_segments table */ + + /* + ** The following array of hash tables is used to buffer pending index + ** updates during transactions. All pending updates buffered at any one + ** time must share a common language-id (see the FTS4 langid= feature). + ** The current language id is stored in variable iPrevLangid. + ** + ** A single FTS4 table may have multiple full-text indexes. For each index + ** there is an entry in the aIndex[] array. Index 0 is an index of all the + ** terms that appear in the document set. Each subsequent index in aIndex[] + ** is an index of prefixes of a specific length. + ** + ** Variable nPendingData contains an estimate the memory consumed by the + ** pending data structures, including hash table overhead, but not including + ** malloc overhead. When nPendingData exceeds nMaxPendingData, all hash + ** tables are flushed to disk. Variable iPrevDocid is the docid of the most + ** recently inserted record. + */ + int nIndex; /* Size of aIndex[] */ + struct Fts3Index { + int nPrefix; /* Prefix length (0 for main terms index) */ + Fts3Hash hPending; /* Pending terms table for this index */ + } *aIndex; + int nMaxPendingData; /* Max pending data before flush to disk */ + int nPendingData; /* Current bytes of pending data */ + sqlite_int64 iPrevDocid; /* Docid of most recently inserted document */ + int iPrevLangid; /* Langid of recently inserted document */ + +#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) + /* State variables used for validating that the transaction control + ** methods of the virtual table are called at appropriate times. These + ** values do not contribute to FTS functionality; they are used for + ** verifying the operation of the SQLite core. + */ + int inTransaction; /* True after xBegin but before xCommit/xRollback */ + int mxSavepoint; /* Largest valid xSavepoint integer */ +#endif + +#ifdef SQLITE_TEST + /* True to disable the incremental doclist optimization. This is controled + ** by special insert command 'test-no-incr-doclist'. */ + int bNoIncrDoclist; +#endif +}; + +/* +** When the core wants to read from the virtual table, it creates a +** virtual table cursor (an instance of the following structure) using +** the xOpen method. Cursors are destroyed using the xClose method. +*/ +struct Fts3Cursor { + sqlite3_vtab_cursor base; /* Base class used by SQLite core */ + i16 eSearch; /* Search strategy (see below) */ + u8 isEof; /* True if at End Of Results */ + u8 isRequireSeek; /* True if must seek pStmt to %_content row */ + sqlite3_stmt *pStmt; /* Prepared statement in use by the cursor */ + Fts3Expr *pExpr; /* Parsed MATCH query string */ + int iLangid; /* Language being queried for */ + int nPhrase; /* Number of matchable phrases in query */ + Fts3DeferredToken *pDeferred; /* Deferred search tokens, if any */ + sqlite3_int64 iPrevId; /* Previous id read from aDoclist */ + char *pNextId; /* Pointer into the body of aDoclist */ + char *aDoclist; /* List of docids for full-text queries */ + int nDoclist; /* Size of buffer at aDoclist */ + u8 bDesc; /* True to sort in descending order */ + int eEvalmode; /* An FTS3_EVAL_XX constant */ + int nRowAvg; /* Average size of database rows, in pages */ + sqlite3_int64 nDoc; /* Documents in table */ + i64 iMinDocid; /* Minimum docid to return */ + i64 iMaxDocid; /* Maximum docid to return */ + int isMatchinfoNeeded; /* True when aMatchinfo[] needs filling in */ + u32 *aMatchinfo; /* Information about most recent match */ + int nMatchinfo; /* Number of elements in aMatchinfo[] */ + char *zMatchinfo; /* Matchinfo specification */ +}; + +#define FTS3_EVAL_FILTER 0 +#define FTS3_EVAL_NEXT 1 +#define FTS3_EVAL_MATCHINFO 2 + +/* +** The Fts3Cursor.eSearch member is always set to one of the following. +** Actualy, Fts3Cursor.eSearch can be greater than or equal to +** FTS3_FULLTEXT_SEARCH. If so, then Fts3Cursor.eSearch - 2 is the index +** of the column to be searched. For example, in +** +** CREATE VIRTUAL TABLE ex1 USING fts3(a,b,c,d); +** SELECT docid FROM ex1 WHERE b MATCH 'one two three'; +** +** Because the LHS of the MATCH operator is 2nd column "b", +** Fts3Cursor.eSearch will be set to FTS3_FULLTEXT_SEARCH+1. (+0 for a, +** +1 for b, +2 for c, +3 for d.) If the LHS of MATCH were "ex1" +** indicating that all columns should be searched, +** then eSearch would be set to FTS3_FULLTEXT_SEARCH+4. +*/ +#define FTS3_FULLSCAN_SEARCH 0 /* Linear scan of %_content table */ +#define FTS3_DOCID_SEARCH 1 /* Lookup by rowid on %_content table */ +#define FTS3_FULLTEXT_SEARCH 2 /* Full-text index search */ + +/* +** The lower 16-bits of the sqlite3_index_info.idxNum value set by +** the xBestIndex() method contains the Fts3Cursor.eSearch value described +** above. The upper 16-bits contain a combination of the following +** bits, used to describe extra constraints on full-text searches. +*/ +#define FTS3_HAVE_LANGID 0x00010000 /* languageid=? */ +#define FTS3_HAVE_DOCID_GE 0x00020000 /* docid>=? */ +#define FTS3_HAVE_DOCID_LE 0x00040000 /* docid<=? */ + +struct Fts3Doclist { + char *aAll; /* Array containing doclist (or NULL) */ + int nAll; /* Size of a[] in bytes */ + char *pNextDocid; /* Pointer to next docid */ + + sqlite3_int64 iDocid; /* Current docid (if pList!=0) */ + int bFreeList; /* True if pList should be sqlite3_free()d */ + char *pList; /* Pointer to position list following iDocid */ + int nList; /* Length of position list */ +}; + +/* +** A "phrase" is a sequence of one or more tokens that must match in +** sequence. A single token is the base case and the most common case. +** For a sequence of tokens contained in double-quotes (i.e. "one two three") +** nToken will be the number of tokens in the string. +*/ +struct Fts3PhraseToken { + char *z; /* Text of the token */ + int n; /* Number of bytes in buffer z */ + int isPrefix; /* True if token ends with a "*" character */ + int bFirst; /* True if token must appear at position 0 */ + + /* Variables above this point are populated when the expression is + ** parsed (by code in fts3_expr.c). Below this point the variables are + ** used when evaluating the expression. */ + Fts3DeferredToken *pDeferred; /* Deferred token object for this token */ + Fts3MultiSegReader *pSegcsr; /* Segment-reader for this token */ +}; + +struct Fts3Phrase { + /* Cache of doclist for this phrase. */ + Fts3Doclist doclist; + int bIncr; /* True if doclist is loaded incrementally */ + int iDoclistToken; + + /* Used by sqlite3Fts3EvalPhrasePoslist() if this is a descendent of an + ** OR condition. */ + char *pOrPoslist; + i64 iOrDocid; + + /* Variables below this point are populated by fts3_expr.c when parsing + ** a MATCH expression. Everything above is part of the evaluation phase. + */ + int nToken; /* Number of tokens in the phrase */ + int iColumn; /* Index of column this phrase must match */ + Fts3PhraseToken aToken[1]; /* One entry for each token in the phrase */ +}; + +/* +** A tree of these objects forms the RHS of a MATCH operator. +** +** If Fts3Expr.eType is FTSQUERY_PHRASE and isLoaded is true, then aDoclist +** points to a malloced buffer, size nDoclist bytes, containing the results +** of this phrase query in FTS3 doclist format. As usual, the initial +** "Length" field found in doclists stored on disk is omitted from this +** buffer. +** +** Variable aMI is used only for FTSQUERY_NEAR nodes to store the global +** matchinfo data. If it is not NULL, it points to an array of size nCol*3, +** where nCol is the number of columns in the queried FTS table. The array +** is populated as follows: +** +** aMI[iCol*3 + 0] = Undefined +** aMI[iCol*3 + 1] = Number of occurrences +** aMI[iCol*3 + 2] = Number of rows containing at least one instance +** +** The aMI array is allocated using sqlite3_malloc(). It should be freed +** when the expression node is. +*/ +struct Fts3Expr { + int eType; /* One of the FTSQUERY_XXX values defined below */ + int nNear; /* Valid if eType==FTSQUERY_NEAR */ + Fts3Expr *pParent; /* pParent->pLeft==this or pParent->pRight==this */ + Fts3Expr *pLeft; /* Left operand */ + Fts3Expr *pRight; /* Right operand */ + Fts3Phrase *pPhrase; /* Valid if eType==FTSQUERY_PHRASE */ + + /* The following are used by the fts3_eval.c module. */ + sqlite3_int64 iDocid; /* Current docid */ + u8 bEof; /* True this expression is at EOF already */ + u8 bStart; /* True if iDocid is valid */ + u8 bDeferred; /* True if this expression is entirely deferred */ + + u32 *aMI; +}; + +/* +** Candidate values for Fts3Query.eType. Note that the order of the first +** four values is in order of precedence when parsing expressions. For +** example, the following: +** +** "a OR b AND c NOT d NEAR e" +** +** is equivalent to: +** +** "a OR (b AND (c NOT (d NEAR e)))" +*/ +#define FTSQUERY_NEAR 1 +#define FTSQUERY_NOT 2 +#define FTSQUERY_AND 3 +#define FTSQUERY_OR 4 +#define FTSQUERY_PHRASE 5 + + +/* fts3_write.c */ +SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(sqlite3_vtab*,int,sqlite3_value**,sqlite3_int64*); +SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *); +SQLITE_PRIVATE void sqlite3Fts3PendingTermsClear(Fts3Table *); +SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *); +SQLITE_PRIVATE int sqlite3Fts3SegReaderNew(int, int, sqlite3_int64, + sqlite3_int64, sqlite3_int64, const char *, int, Fts3SegReader**); +SQLITE_PRIVATE int sqlite3Fts3SegReaderPending( + Fts3Table*,int,const char*,int,int,Fts3SegReader**); +SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *); +SQLITE_PRIVATE int sqlite3Fts3AllSegdirs(Fts3Table*, int, int, int, sqlite3_stmt **); +SQLITE_PRIVATE int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char **, int*, int*); + +SQLITE_PRIVATE int sqlite3Fts3SelectDoctotal(Fts3Table *, sqlite3_stmt **); +SQLITE_PRIVATE int sqlite3Fts3SelectDocsize(Fts3Table *, sqlite3_int64, sqlite3_stmt **); + +#ifndef SQLITE_DISABLE_FTS4_DEFERRED +SQLITE_PRIVATE void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *); +SQLITE_PRIVATE int sqlite3Fts3DeferToken(Fts3Cursor *, Fts3PhraseToken *, int); +SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *); +SQLITE_PRIVATE void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *); +SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *); +#else +# define sqlite3Fts3FreeDeferredTokens(x) +# define sqlite3Fts3DeferToken(x,y,z) SQLITE_OK +# define sqlite3Fts3CacheDeferredDoclists(x) SQLITE_OK +# define sqlite3Fts3FreeDeferredDoclists(x) +# define sqlite3Fts3DeferredTokenList(x,y,z) SQLITE_OK +#endif + +SQLITE_PRIVATE void sqlite3Fts3SegmentsClose(Fts3Table *); +SQLITE_PRIVATE int sqlite3Fts3MaxLevel(Fts3Table *, int *); + +/* Special values interpreted by sqlite3SegReaderCursor() */ +#define FTS3_SEGCURSOR_PENDING -1 +#define FTS3_SEGCURSOR_ALL -2 + +SQLITE_PRIVATE int sqlite3Fts3SegReaderStart(Fts3Table*, Fts3MultiSegReader*, Fts3SegFilter*); +SQLITE_PRIVATE int sqlite3Fts3SegReaderStep(Fts3Table *, Fts3MultiSegReader *); +SQLITE_PRIVATE void sqlite3Fts3SegReaderFinish(Fts3MultiSegReader *); + +SQLITE_PRIVATE int sqlite3Fts3SegReaderCursor(Fts3Table *, + int, int, int, const char *, int, int, int, Fts3MultiSegReader *); + +/* Flags allowed as part of the 4th argument to SegmentReaderIterate() */ +#define FTS3_SEGMENT_REQUIRE_POS 0x00000001 +#define FTS3_SEGMENT_IGNORE_EMPTY 0x00000002 +#define FTS3_SEGMENT_COLUMN_FILTER 0x00000004 +#define FTS3_SEGMENT_PREFIX 0x00000008 +#define FTS3_SEGMENT_SCAN 0x00000010 +#define FTS3_SEGMENT_FIRST 0x00000020 + +/* Type passed as 4th argument to SegmentReaderIterate() */ +struct Fts3SegFilter { + const char *zTerm; + int nTerm; + int iCol; + int flags; +}; + +struct Fts3MultiSegReader { + /* Used internally by sqlite3Fts3SegReaderXXX() calls */ + Fts3SegReader **apSegment; /* Array of Fts3SegReader objects */ + int nSegment; /* Size of apSegment array */ + int nAdvance; /* How many seg-readers to advance */ + Fts3SegFilter *pFilter; /* Pointer to filter object */ + char *aBuffer; /* Buffer to merge doclists in */ + int nBuffer; /* Allocated size of aBuffer[] in bytes */ + + int iColFilter; /* If >=0, filter for this column */ + int bRestart; + + /* Used by fts3.c only. */ + int nCost; /* Cost of running iterator */ + int bLookup; /* True if a lookup of a single entry. */ + + /* Output values. Valid only after Fts3SegReaderStep() returns SQLITE_ROW. */ + char *zTerm; /* Pointer to term buffer */ + int nTerm; /* Size of zTerm in bytes */ + char *aDoclist; /* Pointer to doclist buffer */ + int nDoclist; /* Size of aDoclist[] in bytes */ +}; + +SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table*,int,int); + +#define fts3GetVarint32(p, piVal) ( \ + (*(u8*)(p)&0x80) ? sqlite3Fts3GetVarint32(p, piVal) : (*piVal=*(u8*)(p), 1) \ +) + +/* fts3.c */ +SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char**,const char*,...); +SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *, sqlite3_int64); +SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *, sqlite_int64 *); +SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *, int *); +SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64); +SQLITE_PRIVATE void sqlite3Fts3Dequote(char *); +SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*); +SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *); +SQLITE_PRIVATE int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *); +SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int*, Fts3Table*); + +/* fts3_tokenizer.c */ +SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *, int *); +SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *); +SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *, + sqlite3_tokenizer **, char ** +); +SQLITE_PRIVATE int sqlite3Fts3IsIdChar(char); + +/* fts3_snippet.c */ +SQLITE_PRIVATE void sqlite3Fts3Offsets(sqlite3_context*, Fts3Cursor*); +SQLITE_PRIVATE void sqlite3Fts3Snippet(sqlite3_context *, Fts3Cursor *, const char *, + const char *, const char *, int, int +); +SQLITE_PRIVATE void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *, const char *); + +/* fts3_expr.c */ +SQLITE_PRIVATE int sqlite3Fts3ExprParse(sqlite3_tokenizer *, int, + char **, int, int, int, const char *, int, Fts3Expr **, char ** +); +SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *); +#ifdef SQLITE_TEST +SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db); +SQLITE_PRIVATE int sqlite3Fts3InitTerm(sqlite3 *db); +#endif + +SQLITE_PRIVATE int sqlite3Fts3OpenTokenizer(sqlite3_tokenizer *, int, const char *, int, + sqlite3_tokenizer_cursor ** +); + +/* fts3_aux.c */ +SQLITE_PRIVATE int sqlite3Fts3InitAux(sqlite3 *db); + +SQLITE_PRIVATE void sqlite3Fts3EvalPhraseCleanup(Fts3Phrase *); + +SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart( + Fts3Table*, Fts3MultiSegReader*, int, const char*, int); +SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext( + Fts3Table *, Fts3MultiSegReader *, sqlite3_int64 *, char **, int *); +SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol, char **); +SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *); +SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr); + +/* fts3_tokenize_vtab.c */ +SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *); + +/* fts3_unicode2.c (functions generated by parsing unicode text files) */ +#ifndef SQLITE_DISABLE_FTS3_UNICODE +SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int); +SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int); +SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); +#endif + +#endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */ +#endif /* _FTSINT_H */ + +/************** End of fts3Int.h *********************************************/ +/************** Continuing where we left off in fts3.c ***********************/ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +#if defined(SQLITE_ENABLE_FTS3) && !defined(SQLITE_CORE) +# define SQLITE_CORE 1 +#endif + +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ + +#ifndef SQLITE_CORE + SQLITE_EXTENSION_INIT1 +#endif + +static int fts3EvalNext(Fts3Cursor *pCsr); +static int fts3EvalStart(Fts3Cursor *pCsr); +static int fts3TermSegReaderCursor( + Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **); + +#ifndef SQLITE_AMALGAMATION +# if defined(SQLITE_DEBUG) +SQLITE_PRIVATE int sqlite3Fts3Always(int b) { assert( b ); return b; } +SQLITE_PRIVATE int sqlite3Fts3Never(int b) { assert( !b ); return b; } +# endif +#endif + +/* +** Write a 64-bit variable-length integer to memory starting at p[0]. +** The length of data written will be between 1 and FTS3_VARINT_MAX bytes. +** The number of bytes written is returned. +*/ +SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){ + unsigned char *q = (unsigned char *) p; + sqlite_uint64 vu = v; + do{ + *q++ = (unsigned char) ((vu & 0x7f) | 0x80); + vu >>= 7; + }while( vu!=0 ); + q[-1] &= 0x7f; /* turn off high bit in final byte */ + assert( q - (unsigned char *)p <= FTS3_VARINT_MAX ); + return (int) (q - (unsigned char *)p); +} + +#define GETVARINT_STEP(v, ptr, shift, mask1, mask2, var, ret) \ + v = (v & mask1) | ( (*ptr++) << shift ); \ + if( (v & mask2)==0 ){ var = v; return ret; } +#define GETVARINT_INIT(v, ptr, shift, mask1, mask2, var, ret) \ + v = (*ptr++); \ + if( (v & mask2)==0 ){ var = v; return ret; } + +/* +** Read a 64-bit variable-length integer from memory starting at p[0]. +** Return the number of bytes read, or 0 on error. +** The value is stored in *v. +*/ +SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *p, sqlite_int64 *v){ + const char *pStart = p; + u32 a; + u64 b; + int shift; + + GETVARINT_INIT(a, p, 0, 0x00, 0x80, *v, 1); + GETVARINT_STEP(a, p, 7, 0x7F, 0x4000, *v, 2); + GETVARINT_STEP(a, p, 14, 0x3FFF, 0x200000, *v, 3); + GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *v, 4); + b = (a & 0x0FFFFFFF ); + + for(shift=28; shift<=63; shift+=7){ + u64 c = *p++; + b += (c&0x7F) << shift; + if( (c & 0x80)==0 ) break; + } + *v = b; + return (int)(p - pStart); +} + +/* +** Similar to sqlite3Fts3GetVarint(), except that the output is truncated to a +** 32-bit integer before it is returned. +*/ +SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *p, int *pi){ + u32 a; + +#ifndef fts3GetVarint32 + GETVARINT_INIT(a, p, 0, 0x00, 0x80, *pi, 1); +#else + a = (*p++); + assert( a & 0x80 ); +#endif + + GETVARINT_STEP(a, p, 7, 0x7F, 0x4000, *pi, 2); + GETVARINT_STEP(a, p, 14, 0x3FFF, 0x200000, *pi, 3); + GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *pi, 4); + a = (a & 0x0FFFFFFF ); + *pi = (int)(a | ((u32)(*p & 0x0F) << 28)); + return 5; +} + +/* +** Return the number of bytes required to encode v as a varint +*/ +SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64 v){ + int i = 0; + do{ + i++; + v >>= 7; + }while( v!=0 ); + return i; +} + +/* +** 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. +** +** Examples: +** +** "abc" becomes abc +** 'xyz' becomes xyz +** [pqr] becomes pqr +** `mno` becomes mno +** +*/ +SQLITE_PRIVATE void sqlite3Fts3Dequote(char *z){ + char quote; /* Quote character (if any ) */ + + quote = z[0]; + if( quote=='[' || quote=='\'' || quote=='"' || quote=='`' ){ + int iIn = 1; /* Index of next byte to read from input */ + int iOut = 0; /* Index of next byte to write to output */ + + /* If the first byte was a '[', then the close-quote character is a ']' */ + if( quote=='[' ) quote = ']'; + + while( z[iIn] ){ + if( z[iIn]==quote ){ + if( z[iIn+1]!=quote ) break; + z[iOut++] = quote; + iIn += 2; + }else{ + z[iOut++] = z[iIn++]; + } + } + z[iOut] = '\0'; + } +} + +/* +** Read a single varint from the doclist at *pp and advance *pp to point +** to the first byte past the end of the varint. Add the value of the varint +** to *pVal. +*/ +static void fts3GetDeltaVarint(char **pp, sqlite3_int64 *pVal){ + sqlite3_int64 iVal; + *pp += sqlite3Fts3GetVarint(*pp, &iVal); + *pVal += iVal; +} + +/* +** When this function is called, *pp points to the first byte following a +** varint that is part of a doclist (or position-list, or any other list +** of varints). This function moves *pp to point to the start of that varint, +** and sets *pVal by the varint value. +** +** Argument pStart points to the first byte of the doclist that the +** varint is part of. +*/ +static void fts3GetReverseVarint( + char **pp, + char *pStart, + sqlite3_int64 *pVal +){ + sqlite3_int64 iVal; + char *p; + + /* Pointer p now points at the first byte past the varint we are + ** interested in. So, unless the doclist is corrupt, the 0x80 bit is + ** clear on character p[-1]. */ + for(p = (*pp)-2; p>=pStart && *p&0x80; p--); + p++; + *pp = p; + + sqlite3Fts3GetVarint(p, &iVal); + *pVal = iVal; +} + +/* +** The xDisconnect() virtual table method. +*/ +static int fts3DisconnectMethod(sqlite3_vtab *pVtab){ + Fts3Table *p = (Fts3Table *)pVtab; + int i; + + assert( p->nPendingData==0 ); + assert( p->pSegments==0 ); + + /* Free any prepared statements held */ + for(i=0; iaStmt); i++){ + sqlite3_finalize(p->aStmt[i]); + } + sqlite3_free(p->zSegmentsTbl); + sqlite3_free(p->zReadExprlist); + sqlite3_free(p->zWriteExprlist); + sqlite3_free(p->zContentTbl); + sqlite3_free(p->zLanguageid); + + /* Invoke the tokenizer destructor to free the tokenizer. */ + p->pTokenizer->pModule->xDestroy(p->pTokenizer); + + sqlite3_free(p); + return SQLITE_OK; +} + +/* +** Write an error message into *pzErr +*/ +SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char **pzErr, const char *zFormat, ...){ + va_list ap; + sqlite3_free(*pzErr); + va_start(ap, zFormat); + *pzErr = sqlite3_vmprintf(zFormat, ap); + va_end(ap); +} + +/* +** Construct one or more SQL statements from the format string given +** and then evaluate those statements. The success code is written +** into *pRc. +** +** If *pRc is initially non-zero then this routine is a no-op. +*/ +static void fts3DbExec( + int *pRc, /* Success code */ + sqlite3 *db, /* Database in which to run SQL */ + const char *zFormat, /* Format string for SQL */ + ... /* Arguments to the format string */ +){ + va_list ap; + char *zSql; + if( *pRc ) return; + va_start(ap, zFormat); + zSql = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + if( zSql==0 ){ + *pRc = SQLITE_NOMEM; + }else{ + *pRc = sqlite3_exec(db, zSql, 0, 0, 0); + sqlite3_free(zSql); + } +} + +/* +** The xDestroy() virtual table method. +*/ +static int fts3DestroyMethod(sqlite3_vtab *pVtab){ + Fts3Table *p = (Fts3Table *)pVtab; + int rc = SQLITE_OK; /* Return code */ + const char *zDb = p->zDb; /* Name of database (e.g. "main", "temp") */ + sqlite3 *db = p->db; /* Database handle */ + + /* Drop the shadow tables */ + if( p->zContentTbl==0 ){ + fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_content'", zDb, p->zName); + } + fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segments'", zDb,p->zName); + fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segdir'", zDb, p->zName); + fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_docsize'", zDb, p->zName); + fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_stat'", zDb, p->zName); + + /* If everything has worked, invoke fts3DisconnectMethod() to free the + ** memory associated with the Fts3Table structure and return SQLITE_OK. + ** Otherwise, return an SQLite error code. + */ + return (rc==SQLITE_OK ? fts3DisconnectMethod(pVtab) : rc); +} + + +/* +** Invoke sqlite3_declare_vtab() to declare the schema for the FTS3 table +** passed as the first argument. This is done as part of the xConnect() +** and xCreate() methods. +** +** If *pRc is non-zero when this function is called, it is a no-op. +** Otherwise, if an error occurs, an SQLite error code is stored in *pRc +** before returning. +*/ +static void fts3DeclareVtab(int *pRc, Fts3Table *p){ + if( *pRc==SQLITE_OK ){ + int i; /* Iterator variable */ + int rc; /* Return code */ + char *zSql; /* SQL statement passed to declare_vtab() */ + char *zCols; /* List of user defined columns */ + const char *zLanguageid; + + zLanguageid = (p->zLanguageid ? p->zLanguageid : "__langid"); + sqlite3_vtab_config(p->db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + + /* Create a list of user columns for the virtual table */ + zCols = sqlite3_mprintf("%Q, ", p->azColumn[0]); + for(i=1; zCols && inColumn; i++){ + zCols = sqlite3_mprintf("%z%Q, ", zCols, p->azColumn[i]); + } + + /* Create the whole "CREATE TABLE" statement to pass to SQLite */ + zSql = sqlite3_mprintf( + "CREATE TABLE x(%s %Q HIDDEN, docid HIDDEN, %Q HIDDEN)", + zCols, p->zName, zLanguageid + ); + if( !zCols || !zSql ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_declare_vtab(p->db, zSql); + } + + sqlite3_free(zSql); + sqlite3_free(zCols); + *pRc = rc; + } +} + +/* +** Create the %_stat table if it does not already exist. +*/ +SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int *pRc, Fts3Table *p){ + fts3DbExec(pRc, p->db, + "CREATE TABLE IF NOT EXISTS %Q.'%q_stat'" + "(id INTEGER PRIMARY KEY, value BLOB);", + p->zDb, p->zName + ); + if( (*pRc)==SQLITE_OK ) p->bHasStat = 1; +} + +/* +** Create the backing store tables (%_content, %_segments and %_segdir) +** required by the FTS3 table passed as the only argument. This is done +** as part of the vtab xCreate() method. +** +** If the p->bHasDocsize boolean is true (indicating that this is an +** FTS4 table, not an FTS3 table) then also create the %_docsize and +** %_stat tables required by FTS4. +*/ +static int fts3CreateTables(Fts3Table *p){ + int rc = SQLITE_OK; /* Return code */ + int i; /* Iterator variable */ + sqlite3 *db = p->db; /* The database connection */ + + if( p->zContentTbl==0 ){ + const char *zLanguageid = p->zLanguageid; + char *zContentCols; /* Columns of %_content table */ + + /* Create a list of user columns for the content table */ + zContentCols = sqlite3_mprintf("docid INTEGER PRIMARY KEY"); + for(i=0; zContentCols && inColumn; i++){ + char *z = p->azColumn[i]; + zContentCols = sqlite3_mprintf("%z, 'c%d%q'", zContentCols, i, z); + } + if( zLanguageid && zContentCols ){ + zContentCols = sqlite3_mprintf("%z, langid", zContentCols, zLanguageid); + } + if( zContentCols==0 ) rc = SQLITE_NOMEM; + + /* Create the content table */ + fts3DbExec(&rc, db, + "CREATE TABLE %Q.'%q_content'(%s)", + p->zDb, p->zName, zContentCols + ); + sqlite3_free(zContentCols); + } + + /* Create other tables */ + fts3DbExec(&rc, db, + "CREATE TABLE %Q.'%q_segments'(blockid INTEGER PRIMARY KEY, block BLOB);", + p->zDb, p->zName + ); + fts3DbExec(&rc, db, + "CREATE TABLE %Q.'%q_segdir'(" + "level INTEGER," + "idx INTEGER," + "start_block INTEGER," + "leaves_end_block INTEGER," + "end_block INTEGER," + "root BLOB," + "PRIMARY KEY(level, idx)" + ");", + p->zDb, p->zName + ); + if( p->bHasDocsize ){ + fts3DbExec(&rc, db, + "CREATE TABLE %Q.'%q_docsize'(docid INTEGER PRIMARY KEY, size BLOB);", + p->zDb, p->zName + ); + } + assert( p->bHasStat==p->bFts4 ); + if( p->bHasStat ){ + sqlite3Fts3CreateStatTable(&rc, p); + } + return rc; +} + +/* +** Store the current database page-size in bytes in p->nPgsz. +** +** If *pRc is non-zero when this function is called, it is a no-op. +** Otherwise, if an error occurs, an SQLite error code is stored in *pRc +** before returning. +*/ +static void fts3DatabasePageSize(int *pRc, Fts3Table *p){ + if( *pRc==SQLITE_OK ){ + int rc; /* Return code */ + char *zSql; /* SQL text "PRAGMA %Q.page_size" */ + sqlite3_stmt *pStmt; /* Compiled "PRAGMA %Q.page_size" statement */ + + zSql = sqlite3_mprintf("PRAGMA %Q.page_size", p->zDb); + if( !zSql ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_step(pStmt); + p->nPgsz = sqlite3_column_int(pStmt, 0); + rc = sqlite3_finalize(pStmt); + }else if( rc==SQLITE_AUTH ){ + p->nPgsz = 1024; + rc = SQLITE_OK; + } + } + assert( p->nPgsz>0 || rc!=SQLITE_OK ); + sqlite3_free(zSql); + *pRc = rc; + } +} + +/* +** "Special" FTS4 arguments are column specifications of the following form: +** +** = +** +** There may not be whitespace surrounding the "=" character. The +** term may be quoted, but the may not. +*/ +static int fts3IsSpecialColumn( + const char *z, + int *pnKey, + char **pzValue +){ + char *zValue; + const char *zCsr = z; + + while( *zCsr!='=' ){ + if( *zCsr=='\0' ) return 0; + zCsr++; + } + + *pnKey = (int)(zCsr-z); + zValue = sqlite3_mprintf("%s", &zCsr[1]); + if( zValue ){ + sqlite3Fts3Dequote(zValue); + } + *pzValue = zValue; + return 1; +} + +/* +** Append the output of a printf() style formatting to an existing string. +*/ +static void fts3Appendf( + int *pRc, /* IN/OUT: Error code */ + char **pz, /* IN/OUT: Pointer to string buffer */ + const char *zFormat, /* Printf format string to append */ + ... /* Arguments for printf format string */ +){ + if( *pRc==SQLITE_OK ){ + va_list ap; + char *z; + va_start(ap, zFormat); + z = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + if( z && *pz ){ + char *z2 = sqlite3_mprintf("%s%s", *pz, z); + sqlite3_free(z); + z = z2; + } + if( z==0 ) *pRc = SQLITE_NOMEM; + sqlite3_free(*pz); + *pz = z; + } +} + +/* +** Return a copy of input string zInput enclosed in double-quotes (") and +** with all double quote characters escaped. For example: +** +** fts3QuoteId("un \"zip\"") -> "un \"\"zip\"\"" +** +** The pointer returned points to memory obtained from sqlite3_malloc(). It +** is the callers responsibility to call sqlite3_free() to release this +** memory. +*/ +static char *fts3QuoteId(char const *zInput){ + int nRet; + char *zRet; + nRet = 2 + (int)strlen(zInput)*2 + 1; + zRet = sqlite3_malloc(nRet); + if( zRet ){ + int i; + char *z = zRet; + *(z++) = '"'; + for(i=0; zInput[i]; i++){ + if( zInput[i]=='"' ) *(z++) = '"'; + *(z++) = zInput[i]; + } + *(z++) = '"'; + *(z++) = '\0'; + } + return zRet; +} + +/* +** Return a list of comma separated SQL expressions and a FROM clause that +** could be used in a SELECT statement such as the following: +** +** SELECT FROM %_content AS x ... +** +** to return the docid, followed by each column of text data in order +** from left to write. If parameter zFunc is not NULL, then instead of +** being returned directly each column of text data is passed to an SQL +** function named zFunc first. For example, if zFunc is "unzip" and the +** table has the three user-defined columns "a", "b", and "c", the following +** string is returned: +** +** "docid, unzip(x.'a'), unzip(x.'b'), unzip(x.'c') FROM %_content AS x" +** +** The pointer returned points to a buffer allocated by sqlite3_malloc(). It +** is the responsibility of the caller to eventually free it. +** +** If *pRc is not SQLITE_OK when this function is called, it is a no-op (and +** a NULL pointer is returned). Otherwise, if an OOM error is encountered +** by this function, NULL is returned and *pRc is set to SQLITE_NOMEM. If +** no error occurs, *pRc is left unmodified. +*/ +static char *fts3ReadExprList(Fts3Table *p, const char *zFunc, int *pRc){ + char *zRet = 0; + char *zFree = 0; + char *zFunction; + int i; + + if( p->zContentTbl==0 ){ + if( !zFunc ){ + zFunction = ""; + }else{ + zFree = zFunction = fts3QuoteId(zFunc); + } + fts3Appendf(pRc, &zRet, "docid"); + for(i=0; inColumn; i++){ + fts3Appendf(pRc, &zRet, ",%s(x.'c%d%q')", zFunction, i, p->azColumn[i]); + } + if( p->zLanguageid ){ + fts3Appendf(pRc, &zRet, ", x.%Q", "langid"); + } + sqlite3_free(zFree); + }else{ + fts3Appendf(pRc, &zRet, "rowid"); + for(i=0; inColumn; i++){ + fts3Appendf(pRc, &zRet, ", x.'%q'", p->azColumn[i]); + } + if( p->zLanguageid ){ + fts3Appendf(pRc, &zRet, ", x.%Q", p->zLanguageid); + } + } + fts3Appendf(pRc, &zRet, " FROM '%q'.'%q%s' AS x", + p->zDb, + (p->zContentTbl ? p->zContentTbl : p->zName), + (p->zContentTbl ? "" : "_content") + ); + return zRet; +} + +/* +** Return a list of N comma separated question marks, where N is the number +** of columns in the %_content table (one for the docid plus one for each +** user-defined text column). +** +** If argument zFunc is not NULL, then all but the first question mark +** is preceded by zFunc and an open bracket, and followed by a closed +** bracket. For example, if zFunc is "zip" and the FTS3 table has three +** user-defined text columns, the following string is returned: +** +** "?, zip(?), zip(?), zip(?)" +** +** The pointer returned points to a buffer allocated by sqlite3_malloc(). It +** is the responsibility of the caller to eventually free it. +** +** If *pRc is not SQLITE_OK when this function is called, it is a no-op (and +** a NULL pointer is returned). Otherwise, if an OOM error is encountered +** by this function, NULL is returned and *pRc is set to SQLITE_NOMEM. If +** no error occurs, *pRc is left unmodified. +*/ +static char *fts3WriteExprList(Fts3Table *p, const char *zFunc, int *pRc){ + char *zRet = 0; + char *zFree = 0; + char *zFunction; + int i; + + if( !zFunc ){ + zFunction = ""; + }else{ + zFree = zFunction = fts3QuoteId(zFunc); + } + fts3Appendf(pRc, &zRet, "?"); + for(i=0; inColumn; i++){ + fts3Appendf(pRc, &zRet, ",%s(?)", zFunction); + } + if( p->zLanguageid ){ + fts3Appendf(pRc, &zRet, ", ?"); + } + sqlite3_free(zFree); + return zRet; +} + +/* +** This function interprets the string at (*pp) as a non-negative integer +** value. It reads the integer and sets *pnOut to the value read, then +** sets *pp to point to the byte immediately following the last byte of +** the integer value. +** +** Only decimal digits ('0'..'9') may be part of an integer value. +** +** If *pp does not being with a decimal digit SQLITE_ERROR is returned and +** the output value undefined. Otherwise SQLITE_OK is returned. +** +** This function is used when parsing the "prefix=" FTS4 parameter. +*/ +static int fts3GobbleInt(const char **pp, int *pnOut){ + const int MAX_NPREFIX = 10000000; + const char *p; /* Iterator pointer */ + int nInt = 0; /* Output value */ + + for(p=*pp; p[0]>='0' && p[0]<='9'; p++){ + nInt = nInt * 10 + (p[0] - '0'); + if( nInt>MAX_NPREFIX ){ + nInt = 0; + break; + } + } + if( p==*pp ) return SQLITE_ERROR; + *pnOut = nInt; + *pp = p; + return SQLITE_OK; +} + +/* +** This function is called to allocate an array of Fts3Index structures +** representing the indexes maintained by the current FTS table. FTS tables +** always maintain the main "terms" index, but may also maintain one or +** more "prefix" indexes, depending on the value of the "prefix=" parameter +** (if any) specified as part of the CREATE VIRTUAL TABLE statement. +** +** Argument zParam is passed the value of the "prefix=" option if one was +** specified, or NULL otherwise. +** +** If no error occurs, SQLITE_OK is returned and *apIndex set to point to +** the allocated array. *pnIndex is set to the number of elements in the +** array. If an error does occur, an SQLite error code is returned. +** +** Regardless of whether or not an error is returned, it is the responsibility +** of the caller to call sqlite3_free() on the output array to free it. +*/ +static int fts3PrefixParameter( + const char *zParam, /* ABC in prefix=ABC parameter to parse */ + int *pnIndex, /* OUT: size of *apIndex[] array */ + struct Fts3Index **apIndex /* OUT: Array of indexes for this table */ +){ + struct Fts3Index *aIndex; /* Allocated array */ + int nIndex = 1; /* Number of entries in array */ + + if( zParam && zParam[0] ){ + const char *p; + nIndex++; + for(p=zParam; *p; p++){ + if( *p==',' ) nIndex++; + } + } + + aIndex = sqlite3_malloc(sizeof(struct Fts3Index) * nIndex); + *apIndex = aIndex; + if( !aIndex ){ + return SQLITE_NOMEM; + } + + memset(aIndex, 0, sizeof(struct Fts3Index) * nIndex); + if( zParam ){ + const char *p = zParam; + int i; + for(i=1; i=0 ); + if( nPrefix==0 ){ + nIndex--; + i--; + }else{ + aIndex[i].nPrefix = nPrefix; + } + p++; + } + } + + *pnIndex = nIndex; + return SQLITE_OK; +} + +/* +** This function is called when initializing an FTS4 table that uses the +** content=xxx option. It determines the number of and names of the columns +** of the new FTS4 table. +** +** The third argument passed to this function is the value passed to the +** config=xxx option (i.e. "xxx"). This function queries the database for +** a table of that name. If found, the output variables are populated +** as follows: +** +** *pnCol: Set to the number of columns table xxx has, +** +** *pnStr: Set to the total amount of space required to store a copy +** of each columns name, including the nul-terminator. +** +** *pazCol: Set to point to an array of *pnCol strings. Each string is +** the name of the corresponding column in table xxx. The array +** and its contents are allocated using a single allocation. It +** is the responsibility of the caller to free this allocation +** by eventually passing the *pazCol value to sqlite3_free(). +** +** If the table cannot be found, an error code is returned and the output +** variables are undefined. Or, if an OOM is encountered, SQLITE_NOMEM is +** returned (and the output variables are undefined). +*/ +static int fts3ContentColumns( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Name of db (i.e. "main", "temp" etc.) */ + const char *zTbl, /* Name of content table */ + const char ***pazCol, /* OUT: Malloc'd array of column names */ + int *pnCol, /* OUT: Size of array *pazCol */ + int *pnStr, /* OUT: Bytes of string content */ + char **pzErr /* OUT: error message */ +){ + int rc = SQLITE_OK; /* Return code */ + char *zSql; /* "SELECT *" statement on zTbl */ + sqlite3_stmt *pStmt = 0; /* Compiled version of zSql */ + + zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q", zDb, zTbl); + if( !zSql ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); + if( rc!=SQLITE_OK ){ + sqlite3Fts3ErrMsg(pzErr, "%s", sqlite3_errmsg(db)); + } + } + sqlite3_free(zSql); + + if( rc==SQLITE_OK ){ + const char **azCol; /* Output array */ + int nStr = 0; /* Size of all column names (incl. 0x00) */ + int nCol; /* Number of table columns */ + int i; /* Used to iterate through columns */ + + /* Loop through the returned columns. Set nStr to the number of bytes of + ** space required to store a copy of each column name, including the + ** nul-terminator byte. */ + nCol = sqlite3_column_count(pStmt); + for(i=0; i module name ("fts3" or "fts4") +** argv[1] -> database name +** argv[2] -> table name +** argv[...] -> "column name" and other module argument fields. +*/ +static int fts3InitVtab( + int isCreate, /* True for xCreate, false for xConnect */ + sqlite3 *db, /* The SQLite database connection */ + void *pAux, /* Hash table containing tokenizers */ + int argc, /* Number of elements in argv array */ + const char * const *argv, /* xCreate/xConnect argument array */ + sqlite3_vtab **ppVTab, /* Write the resulting vtab structure here */ + char **pzErr /* Write any error message here */ +){ + Fts3Hash *pHash = (Fts3Hash *)pAux; + Fts3Table *p = 0; /* Pointer to allocated vtab */ + int rc = SQLITE_OK; /* Return code */ + int i; /* Iterator variable */ + int nByte; /* Size of allocation used for *p */ + int iCol; /* Column index */ + int nString = 0; /* Bytes required to hold all column names */ + int nCol = 0; /* Number of columns in the FTS table */ + char *zCsr; /* Space for holding column names */ + int nDb; /* Bytes required to hold database name */ + int nName; /* Bytes required to hold table name */ + int isFts4 = (argv[0][3]=='4'); /* True for FTS4, false for FTS3 */ + const char **aCol; /* Array of column names */ + sqlite3_tokenizer *pTokenizer = 0; /* Tokenizer for this table */ + + int nIndex = 0; /* Size of aIndex[] array */ + struct Fts3Index *aIndex = 0; /* Array of indexes for this table */ + + /* The results of parsing supported FTS4 key=value options: */ + int bNoDocsize = 0; /* True to omit %_docsize table */ + int bDescIdx = 0; /* True to store descending indexes */ + char *zPrefix = 0; /* Prefix parameter value (or NULL) */ + char *zCompress = 0; /* compress=? parameter (or NULL) */ + char *zUncompress = 0; /* uncompress=? parameter (or NULL) */ + char *zContent = 0; /* content=? parameter (or NULL) */ + char *zLanguageid = 0; /* languageid=? parameter (or NULL) */ + char **azNotindexed = 0; /* The set of notindexed= columns */ + int nNotindexed = 0; /* Size of azNotindexed[] array */ + + assert( strlen(argv[0])==4 ); + assert( (sqlite3_strnicmp(argv[0], "fts4", 4)==0 && isFts4) + || (sqlite3_strnicmp(argv[0], "fts3", 4)==0 && !isFts4) + ); + + nDb = (int)strlen(argv[1]) + 1; + nName = (int)strlen(argv[2]) + 1; + + nByte = sizeof(const char *) * (argc-2); + aCol = (const char **)sqlite3_malloc(nByte); + if( aCol ){ + memset((void*)aCol, 0, nByte); + azNotindexed = (char **)sqlite3_malloc(nByte); + } + if( azNotindexed ){ + memset(azNotindexed, 0, nByte); + } + if( !aCol || !azNotindexed ){ + rc = SQLITE_NOMEM; + goto fts3_init_out; + } + + /* Loop through all of the arguments passed by the user to the FTS3/4 + ** module (i.e. all the column names and special arguments). This loop + ** does the following: + ** + ** + Figures out the number of columns the FTSX table will have, and + ** the number of bytes of space that must be allocated to store copies + ** of the column names. + ** + ** + If there is a tokenizer specification included in the arguments, + ** initializes the tokenizer pTokenizer. + */ + for(i=3; rc==SQLITE_OK && i8 + && 0==sqlite3_strnicmp(z, "tokenize", 8) + && 0==sqlite3Fts3IsIdChar(z[8]) + ){ + rc = sqlite3Fts3InitTokenizer(pHash, &z[9], &pTokenizer, pzErr); + } + + /* Check if it is an FTS4 special argument. */ + else if( isFts4 && fts3IsSpecialColumn(z, &nKey, &zVal) ){ + struct Fts4Option { + const char *zOpt; + int nOpt; + } aFts4Opt[] = { + { "matchinfo", 9 }, /* 0 -> MATCHINFO */ + { "prefix", 6 }, /* 1 -> PREFIX */ + { "compress", 8 }, /* 2 -> COMPRESS */ + { "uncompress", 10 }, /* 3 -> UNCOMPRESS */ + { "order", 5 }, /* 4 -> ORDER */ + { "content", 7 }, /* 5 -> CONTENT */ + { "languageid", 10 }, /* 6 -> LANGUAGEID */ + { "notindexed", 10 } /* 7 -> NOTINDEXED */ + }; + + int iOpt; + if( !zVal ){ + rc = SQLITE_NOMEM; + }else{ + for(iOpt=0; iOptnOpt && !sqlite3_strnicmp(z, pOp->zOpt, pOp->nOpt) ){ + break; + } + } + if( iOpt==SizeofArray(aFts4Opt) ){ + sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z); + rc = SQLITE_ERROR; + }else{ + switch( iOpt ){ + case 0: /* MATCHINFO */ + if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){ + sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal); + rc = SQLITE_ERROR; + } + bNoDocsize = 1; + break; + + case 1: /* PREFIX */ + sqlite3_free(zPrefix); + zPrefix = zVal; + zVal = 0; + break; + + case 2: /* COMPRESS */ + sqlite3_free(zCompress); + zCompress = zVal; + zVal = 0; + break; + + case 3: /* UNCOMPRESS */ + sqlite3_free(zUncompress); + zUncompress = zVal; + zVal = 0; + break; + + case 4: /* ORDER */ + if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3)) + && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4)) + ){ + sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal); + rc = SQLITE_ERROR; + } + bDescIdx = (zVal[0]=='d' || zVal[0]=='D'); + break; + + case 5: /* CONTENT */ + sqlite3_free(zContent); + zContent = zVal; + zVal = 0; + break; + + case 6: /* LANGUAGEID */ + assert( iOpt==6 ); + sqlite3_free(zLanguageid); + zLanguageid = zVal; + zVal = 0; + break; + + case 7: /* NOTINDEXED */ + azNotindexed[nNotindexed++] = zVal; + zVal = 0; + break; + } + } + sqlite3_free(zVal); + } + } + + /* Otherwise, the argument is a column name. */ + else { + nString += (int)(strlen(z) + 1); + aCol[nCol++] = z; + } + } + + /* If a content=xxx option was specified, the following: + ** + ** 1. Ignore any compress= and uncompress= options. + ** + ** 2. If no column names were specified as part of the CREATE VIRTUAL + ** TABLE statement, use all columns from the content table. + */ + if( rc==SQLITE_OK && zContent ){ + sqlite3_free(zCompress); + sqlite3_free(zUncompress); + zCompress = 0; + zUncompress = 0; + if( nCol==0 ){ + sqlite3_free((void*)aCol); + aCol = 0; + rc = fts3ContentColumns(db, argv[1], zContent,&aCol,&nCol,&nString,pzErr); + + /* If a languageid= option was specified, remove the language id + ** column from the aCol[] array. */ + if( rc==SQLITE_OK && zLanguageid ){ + int j; + for(j=0; jdb = db; + p->nColumn = nCol; + p->nPendingData = 0; + p->azColumn = (char **)&p[1]; + p->pTokenizer = pTokenizer; + p->nMaxPendingData = FTS3_MAX_PENDING_DATA; + p->bHasDocsize = (isFts4 && bNoDocsize==0); + p->bHasStat = isFts4; + p->bFts4 = isFts4; + p->bDescIdx = bDescIdx; + p->nAutoincrmerge = 0xff; /* 0xff means setting unknown */ + p->zContentTbl = zContent; + p->zLanguageid = zLanguageid; + zContent = 0; + zLanguageid = 0; + TESTONLY( p->inTransaction = -1 ); + TESTONLY( p->mxSavepoint = -1 ); + + p->aIndex = (struct Fts3Index *)&p->azColumn[nCol]; + memcpy(p->aIndex, aIndex, sizeof(struct Fts3Index) * nIndex); + p->nIndex = nIndex; + for(i=0; iaIndex[i].hPending, FTS3_HASH_STRING, 1); + } + p->abNotindexed = (u8 *)&p->aIndex[nIndex]; + + /* Fill in the zName and zDb fields of the vtab structure. */ + zCsr = (char *)&p->abNotindexed[nCol]; + p->zName = zCsr; + memcpy(zCsr, argv[2], nName); + zCsr += nName; + p->zDb = zCsr; + memcpy(zCsr, argv[1], nDb); + zCsr += nDb; + + /* Fill in the azColumn array */ + for(iCol=0; iColazColumn[iCol] = zCsr; + zCsr += n+1; + assert( zCsr <= &((char *)p)[nByte] ); + } + + /* Fill in the abNotindexed array */ + for(iCol=0; iColazColumn[iCol]); + for(i=0; iazColumn[iCol], zNot, n) + ){ + p->abNotindexed[iCol] = 1; + sqlite3_free(zNot); + azNotindexed[i] = 0; + } + } + } + for(i=0; izReadExprlist = fts3ReadExprList(p, zUncompress, &rc); + p->zWriteExprlist = fts3WriteExprList(p, zCompress, &rc); + if( rc!=SQLITE_OK ) goto fts3_init_out; + + /* If this is an xCreate call, create the underlying tables in the + ** database. TODO: For xConnect(), it could verify that said tables exist. + */ + if( isCreate ){ + rc = fts3CreateTables(p); + } + + /* Check to see if a legacy fts3 table has been "upgraded" by the + ** addition of a %_stat table so that it can use incremental merge. + */ + if( !isFts4 && !isCreate ){ + p->bHasStat = 2; + } + + /* Figure out the page-size for the database. This is required in order to + ** estimate the cost of loading large doclists from the database. */ + fts3DatabasePageSize(&rc, p); + p->nNodeSize = p->nPgsz-35; + + /* Declare the table schema to SQLite. */ + fts3DeclareVtab(&rc, p); + +fts3_init_out: + sqlite3_free(zPrefix); + sqlite3_free(aIndex); + sqlite3_free(zCompress); + sqlite3_free(zUncompress); + sqlite3_free(zContent); + sqlite3_free(zLanguageid); + for(i=0; ipModule->xDestroy(pTokenizer); + } + }else{ + assert( p->pSegments==0 ); + *ppVTab = &p->base; + } + return rc; +} + +/* +** The xConnect() and xCreate() methods for the virtual table. All the +** work is done in function fts3InitVtab(). +*/ +static int fts3ConnectMethod( + sqlite3 *db, /* Database connection */ + void *pAux, /* Pointer to tokenizer hash table */ + int argc, /* Number of elements in argv array */ + const char * const *argv, /* xCreate/xConnect argument array */ + sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ + char **pzErr /* OUT: sqlite3_malloc'd error message */ +){ + return fts3InitVtab(0, db, pAux, argc, argv, ppVtab, pzErr); +} +static int fts3CreateMethod( + sqlite3 *db, /* Database connection */ + void *pAux, /* Pointer to tokenizer hash table */ + int argc, /* Number of elements in argv array */ + const char * const *argv, /* xCreate/xConnect argument array */ + sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ + char **pzErr /* OUT: sqlite3_malloc'd error message */ +){ + return fts3InitVtab(1, db, pAux, argc, argv, ppVtab, pzErr); +} + +/* +** Set the pIdxInfo->estimatedRows variable to nRow. Unless this +** extension is currently being used by a version of SQLite too old to +** support estimatedRows. In that case this function is a no-op. +*/ +static void fts3SetEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){ +#if SQLITE_VERSION_NUMBER>=3008002 + if( sqlite3_libversion_number()>=3008002 ){ + pIdxInfo->estimatedRows = nRow; + } +#endif +} + +/* +** Implementation of the xBestIndex method for FTS3 tables. There +** are three possible strategies, in order of preference: +** +** 1. Direct lookup by rowid or docid. +** 2. Full-text search using a MATCH operator on a non-docid column. +** 3. Linear scan of %_content table. +*/ +static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ + Fts3Table *p = (Fts3Table *)pVTab; + int i; /* Iterator variable */ + int iCons = -1; /* Index of constraint to use */ + + int iLangidCons = -1; /* Index of langid=x constraint, if present */ + int iDocidGe = -1; /* Index of docid>=x constraint, if present */ + int iDocidLe = -1; /* Index of docid<=x constraint, if present */ + int iIdx; + + /* By default use a full table scan. This is an expensive option, + ** so search through the constraints to see if a more efficient + ** strategy is possible. + */ + pInfo->idxNum = FTS3_FULLSCAN_SEARCH; + pInfo->estimatedCost = 5000000; + for(i=0; inConstraint; i++){ + int bDocid; /* True if this constraint is on docid */ + struct sqlite3_index_constraint *pCons = &pInfo->aConstraint[i]; + if( pCons->usable==0 ){ + if( pCons->op==SQLITE_INDEX_CONSTRAINT_MATCH ){ + /* There exists an unusable MATCH constraint. This means that if + ** the planner does elect to use the results of this call as part + ** of the overall query plan the user will see an "unable to use + ** function MATCH in the requested context" error. To discourage + ** this, return a very high cost here. */ + pInfo->idxNum = FTS3_FULLSCAN_SEARCH; + pInfo->estimatedCost = 1e50; + fts3SetEstimatedRows(pInfo, ((sqlite3_int64)1) << 50); + return SQLITE_OK; + } + continue; + } + + bDocid = (pCons->iColumn<0 || pCons->iColumn==p->nColumn+1); + + /* A direct lookup on the rowid or docid column. Assign a cost of 1.0. */ + if( iCons<0 && pCons->op==SQLITE_INDEX_CONSTRAINT_EQ && bDocid ){ + pInfo->idxNum = FTS3_DOCID_SEARCH; + pInfo->estimatedCost = 1.0; + iCons = i; + } + + /* A MATCH constraint. Use a full-text search. + ** + ** If there is more than one MATCH constraint available, use the first + ** one encountered. If there is both a MATCH constraint and a direct + ** rowid/docid lookup, prefer the MATCH strategy. This is done even + ** though the rowid/docid lookup is faster than a MATCH query, selecting + ** it would lead to an "unable to use function MATCH in the requested + ** context" error. + */ + if( pCons->op==SQLITE_INDEX_CONSTRAINT_MATCH + && pCons->iColumn>=0 && pCons->iColumn<=p->nColumn + ){ + pInfo->idxNum = FTS3_FULLTEXT_SEARCH + pCons->iColumn; + pInfo->estimatedCost = 2.0; + iCons = i; + } + + /* Equality constraint on the langid column */ + if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ + && pCons->iColumn==p->nColumn + 2 + ){ + iLangidCons = i; + } + + if( bDocid ){ + switch( pCons->op ){ + case SQLITE_INDEX_CONSTRAINT_GE: + case SQLITE_INDEX_CONSTRAINT_GT: + iDocidGe = i; + break; + + case SQLITE_INDEX_CONSTRAINT_LE: + case SQLITE_INDEX_CONSTRAINT_LT: + iDocidLe = i; + break; + } + } + } + + iIdx = 1; + if( iCons>=0 ){ + pInfo->aConstraintUsage[iCons].argvIndex = iIdx++; + pInfo->aConstraintUsage[iCons].omit = 1; + } + if( iLangidCons>=0 ){ + pInfo->idxNum |= FTS3_HAVE_LANGID; + pInfo->aConstraintUsage[iLangidCons].argvIndex = iIdx++; + } + if( iDocidGe>=0 ){ + pInfo->idxNum |= FTS3_HAVE_DOCID_GE; + pInfo->aConstraintUsage[iDocidGe].argvIndex = iIdx++; + } + if( iDocidLe>=0 ){ + pInfo->idxNum |= FTS3_HAVE_DOCID_LE; + pInfo->aConstraintUsage[iDocidLe].argvIndex = iIdx++; + } + + /* Regardless of the strategy selected, FTS can deliver rows in rowid (or + ** docid) order. Both ascending and descending are possible. + */ + if( pInfo->nOrderBy==1 ){ + struct sqlite3_index_orderby *pOrder = &pInfo->aOrderBy[0]; + if( pOrder->iColumn<0 || pOrder->iColumn==p->nColumn+1 ){ + if( pOrder->desc ){ + pInfo->idxStr = "DESC"; + }else{ + pInfo->idxStr = "ASC"; + } + pInfo->orderByConsumed = 1; + } + } + + assert( p->pSegments==0 ); + return SQLITE_OK; +} + +/* +** Implementation of xOpen method. +*/ +static int fts3OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ + sqlite3_vtab_cursor *pCsr; /* Allocated cursor */ + + UNUSED_PARAMETER(pVTab); + + /* Allocate a buffer large enough for an Fts3Cursor structure. If the + ** allocation succeeds, zero it and return SQLITE_OK. Otherwise, + ** if the allocation fails, return SQLITE_NOMEM. + */ + *ppCsr = pCsr = (sqlite3_vtab_cursor *)sqlite3_malloc(sizeof(Fts3Cursor)); + if( !pCsr ){ + return SQLITE_NOMEM; + } + memset(pCsr, 0, sizeof(Fts3Cursor)); + return SQLITE_OK; +} + +/* +** Close the cursor. For additional information see the documentation +** on the xClose method of the virtual table interface. +*/ +static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){ + Fts3Cursor *pCsr = (Fts3Cursor *)pCursor; + assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); + sqlite3_finalize(pCsr->pStmt); + sqlite3Fts3ExprFree(pCsr->pExpr); + sqlite3Fts3FreeDeferredTokens(pCsr); + sqlite3_free(pCsr->aDoclist); + sqlite3_free(pCsr->aMatchinfo); + assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* +** If pCsr->pStmt has not been prepared (i.e. if pCsr->pStmt==0), then +** compose and prepare an SQL statement of the form: +** +** "SELECT FROM %_content WHERE rowid = ?" +** +** (or the equivalent for a content=xxx table) and set pCsr->pStmt to +** it. If an error occurs, return an SQLite error code. +** +** Otherwise, set *ppStmt to point to pCsr->pStmt and return SQLITE_OK. +*/ +static int fts3CursorSeekStmt(Fts3Cursor *pCsr, sqlite3_stmt **ppStmt){ + int rc = SQLITE_OK; + if( pCsr->pStmt==0 ){ + Fts3Table *p = (Fts3Table *)pCsr->base.pVtab; + char *zSql; + zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist); + if( !zSql ) return SQLITE_NOMEM; + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0); + sqlite3_free(zSql); + } + *ppStmt = pCsr->pStmt; + return rc; +} + +/* +** Position the pCsr->pStmt statement so that it is on the row +** of the %_content table that contains the last match. Return +** SQLITE_OK on success. +*/ +static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){ + int rc = SQLITE_OK; + if( pCsr->isRequireSeek ){ + sqlite3_stmt *pStmt = 0; + + rc = fts3CursorSeekStmt(pCsr, &pStmt); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId); + pCsr->isRequireSeek = 0; + if( SQLITE_ROW==sqlite3_step(pCsr->pStmt) ){ + return SQLITE_OK; + }else{ + rc = sqlite3_reset(pCsr->pStmt); + if( rc==SQLITE_OK && ((Fts3Table *)pCsr->base.pVtab)->zContentTbl==0 ){ + /* If no row was found and no error has occurred, then the %_content + ** table is missing a row that is present in the full-text index. + ** The data structures are corrupt. */ + rc = FTS_CORRUPT_VTAB; + pCsr->isEof = 1; + } + } + } + } + + if( rc!=SQLITE_OK && pContext ){ + sqlite3_result_error_code(pContext, rc); + } + return rc; +} + +/* +** This function is used to process a single interior node when searching +** a b-tree for a term or term prefix. The node data is passed to this +** function via the zNode/nNode parameters. The term to search for is +** passed in zTerm/nTerm. +** +** If piFirst is not NULL, then this function sets *piFirst to the blockid +** of the child node that heads the sub-tree that may contain the term. +** +** If piLast is not NULL, then *piLast is set to the right-most child node +** that heads a sub-tree that may contain a term for which zTerm/nTerm is +** a prefix. +** +** If an OOM error occurs, SQLITE_NOMEM is returned. Otherwise, SQLITE_OK. +*/ +static int fts3ScanInteriorNode( + const char *zTerm, /* Term to select leaves for */ + int nTerm, /* Size of term zTerm in bytes */ + const char *zNode, /* Buffer containing segment interior node */ + int nNode, /* Size of buffer at zNode */ + sqlite3_int64 *piFirst, /* OUT: Selected child node */ + sqlite3_int64 *piLast /* OUT: Selected child node */ +){ + int rc = SQLITE_OK; /* Return code */ + const char *zCsr = zNode; /* Cursor to iterate through node */ + const char *zEnd = &zCsr[nNode];/* End of interior node buffer */ + char *zBuffer = 0; /* Buffer to load terms into */ + int nAlloc = 0; /* Size of allocated buffer */ + int isFirstTerm = 1; /* True when processing first term on page */ + sqlite3_int64 iChild; /* Block id of child node to descend to */ + + /* Skip over the 'height' varint that occurs at the start of every + ** interior node. Then load the blockid of the left-child of the b-tree + ** node into variable iChild. + ** + ** Even if the data structure on disk is corrupted, this (reading two + ** varints from the buffer) does not risk an overread. If zNode is a + ** root node, then the buffer comes from a SELECT statement. SQLite does + ** not make this guarantee explicitly, but in practice there are always + ** either more than 20 bytes of allocated space following the nNode bytes of + ** contents, or two zero bytes. Or, if the node is read from the %_segments + ** table, then there are always 20 bytes of zeroed padding following the + ** nNode bytes of content (see sqlite3Fts3ReadBlock() for details). + */ + zCsr += sqlite3Fts3GetVarint(zCsr, &iChild); + zCsr += sqlite3Fts3GetVarint(zCsr, &iChild); + if( zCsr>zEnd ){ + return FTS_CORRUPT_VTAB; + } + + while( zCsrzEnd ){ + rc = FTS_CORRUPT_VTAB; + goto finish_scan; + } + if( nPrefix+nSuffix>nAlloc ){ + char *zNew; + nAlloc = (nPrefix+nSuffix) * 2; + zNew = (char *)sqlite3_realloc(zBuffer, nAlloc); + if( !zNew ){ + rc = SQLITE_NOMEM; + goto finish_scan; + } + zBuffer = zNew; + } + assert( zBuffer ); + memcpy(&zBuffer[nPrefix], zCsr, nSuffix); + nBuffer = nPrefix + nSuffix; + zCsr += nSuffix; + + /* Compare the term we are searching for with the term just loaded from + ** the interior node. If the specified term is greater than or equal + ** to the term from the interior node, then all terms on the sub-tree + ** headed by node iChild are smaller than zTerm. No need to search + ** iChild. + ** + ** If the interior node term is larger than the specified term, then + ** the tree headed by iChild may contain the specified term. + */ + cmp = memcmp(zTerm, zBuffer, (nBuffer>nTerm ? nTerm : nBuffer)); + if( piFirst && (cmp<0 || (cmp==0 && nBuffer>nTerm)) ){ + *piFirst = iChild; + piFirst = 0; + } + + if( piLast && cmp<0 ){ + *piLast = iChild; + piLast = 0; + } + + iChild++; + }; + + if( piFirst ) *piFirst = iChild; + if( piLast ) *piLast = iChild; + + finish_scan: + sqlite3_free(zBuffer); + return rc; +} + + +/* +** The buffer pointed to by argument zNode (size nNode bytes) contains an +** interior node of a b-tree segment. The zTerm buffer (size nTerm bytes) +** contains a term. This function searches the sub-tree headed by the zNode +** node for the range of leaf nodes that may contain the specified term +** or terms for which the specified term is a prefix. +** +** If piLeaf is not NULL, then *piLeaf is set to the blockid of the +** left-most leaf node in the tree that may contain the specified term. +** If piLeaf2 is not NULL, then *piLeaf2 is set to the blockid of the +** right-most leaf node that may contain a term for which the specified +** term is a prefix. +** +** It is possible that the range of returned leaf nodes does not contain +** the specified term or any terms for which it is a prefix. However, if the +** segment does contain any such terms, they are stored within the identified +** range. Because this function only inspects interior segment nodes (and +** never loads leaf nodes into memory), it is not possible to be sure. +** +** If an error occurs, an error code other than SQLITE_OK is returned. +*/ +static int fts3SelectLeaf( + Fts3Table *p, /* Virtual table handle */ + const char *zTerm, /* Term to select leaves for */ + int nTerm, /* Size of term zTerm in bytes */ + const char *zNode, /* Buffer containing segment interior node */ + int nNode, /* Size of buffer at zNode */ + sqlite3_int64 *piLeaf, /* Selected leaf node */ + sqlite3_int64 *piLeaf2 /* Selected leaf node */ +){ + int rc = SQLITE_OK; /* Return code */ + int iHeight; /* Height of this node in tree */ + + assert( piLeaf || piLeaf2 ); + + fts3GetVarint32(zNode, &iHeight); + rc = fts3ScanInteriorNode(zTerm, nTerm, zNode, nNode, piLeaf, piLeaf2); + assert( !piLeaf2 || !piLeaf || rc!=SQLITE_OK || (*piLeaf<=*piLeaf2) ); + + if( rc==SQLITE_OK && iHeight>1 ){ + char *zBlob = 0; /* Blob read from %_segments table */ + int nBlob = 0; /* Size of zBlob in bytes */ + + if( piLeaf && piLeaf2 && (*piLeaf!=*piLeaf2) ){ + rc = sqlite3Fts3ReadBlock(p, *piLeaf, &zBlob, &nBlob, 0); + if( rc==SQLITE_OK ){ + rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, 0); + } + sqlite3_free(zBlob); + piLeaf = 0; + zBlob = 0; + } + + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3ReadBlock(p, piLeaf?*piLeaf:*piLeaf2, &zBlob, &nBlob, 0); + } + if( rc==SQLITE_OK ){ + rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, piLeaf2); + } + sqlite3_free(zBlob); + } + + return rc; +} + +/* +** This function is used to create delta-encoded serialized lists of FTS3 +** varints. Each call to this function appends a single varint to a list. +*/ +static void fts3PutDeltaVarint( + char **pp, /* IN/OUT: Output pointer */ + sqlite3_int64 *piPrev, /* IN/OUT: Previous value written to list */ + sqlite3_int64 iVal /* Write this value to the list */ +){ + assert( iVal-*piPrev > 0 || (*piPrev==0 && iVal==0) ); + *pp += sqlite3Fts3PutVarint(*pp, iVal-*piPrev); + *piPrev = iVal; +} + +/* +** When this function is called, *ppPoslist is assumed to point to the +** start of a position-list. After it returns, *ppPoslist points to the +** first byte after the position-list. +** +** A position list is list of positions (delta encoded) and columns for +** a single document record of a doclist. So, in other words, this +** routine advances *ppPoslist so that it points to the next docid in +** the doclist, or to the first byte past the end of the doclist. +** +** If pp is not NULL, then the contents of the position list are copied +** to *pp. *pp is set to point to the first byte past the last byte copied +** before this function returns. +*/ +static void fts3PoslistCopy(char **pp, char **ppPoslist){ + char *pEnd = *ppPoslist; + char c = 0; + + /* The end of a position list is marked by a zero encoded as an FTS3 + ** varint. A single POS_END (0) byte. Except, if the 0 byte is preceded by + ** a byte with the 0x80 bit set, then it is not a varint 0, but the tail + ** of some other, multi-byte, value. + ** + ** The following while-loop moves pEnd to point to the first byte that is not + ** immediately preceded by a byte with the 0x80 bit set. Then increments + ** pEnd once more so that it points to the byte immediately following the + ** last byte in the position-list. + */ + while( *pEnd | c ){ + c = *pEnd++ & 0x80; + testcase( c!=0 && (*pEnd)==0 ); + } + pEnd++; /* Advance past the POS_END terminator byte */ + + if( pp ){ + int n = (int)(pEnd - *ppPoslist); + char *p = *pp; + memcpy(p, *ppPoslist, n); + p += n; + *pp = p; + } + *ppPoslist = pEnd; +} + +/* +** When this function is called, *ppPoslist is assumed to point to the +** start of a column-list. After it returns, *ppPoslist points to the +** to the terminator (POS_COLUMN or POS_END) byte of the column-list. +** +** A column-list is list of delta-encoded positions for a single column +** within a single document within a doclist. +** +** The column-list is terminated either by a POS_COLUMN varint (1) or +** a POS_END varint (0). This routine leaves *ppPoslist pointing to +** the POS_COLUMN or POS_END that terminates the column-list. +** +** If pp is not NULL, then the contents of the column-list are copied +** to *pp. *pp is set to point to the first byte past the last byte copied +** before this function returns. The POS_COLUMN or POS_END terminator +** is not copied into *pp. +*/ +static void fts3ColumnlistCopy(char **pp, char **ppPoslist){ + char *pEnd = *ppPoslist; + char c = 0; + + /* A column-list is terminated by either a 0x01 or 0x00 byte that is + ** not part of a multi-byte varint. + */ + while( 0xFE & (*pEnd | c) ){ + c = *pEnd++ & 0x80; + testcase( c!=0 && ((*pEnd)&0xfe)==0 ); + } + if( pp ){ + int n = (int)(pEnd - *ppPoslist); + char *p = *pp; + memcpy(p, *ppPoslist, n); + p += n; + *pp = p; + } + *ppPoslist = pEnd; +} + +/* +** Value used to signify the end of an position-list. This is safe because +** it is not possible to have a document with 2^31 terms. +*/ +#define POSITION_LIST_END 0x7fffffff + +/* +** This function is used to help parse position-lists. When this function is +** called, *pp may point to the start of the next varint in the position-list +** being parsed, or it may point to 1 byte past the end of the position-list +** (in which case **pp will be a terminator bytes POS_END (0) or +** (1)). +** +** If *pp points past the end of the current position-list, set *pi to +** POSITION_LIST_END and return. Otherwise, read the next varint from *pp, +** increment the current value of *pi by the value read, and set *pp to +** point to the next value before returning. +** +** Before calling this routine *pi must be initialized to the value of +** the previous position, or zero if we are reading the first position +** in the position-list. Because positions are delta-encoded, the value +** of the previous position is needed in order to compute the value of +** the next position. +*/ +static void fts3ReadNextPos( + char **pp, /* IN/OUT: Pointer into position-list buffer */ + sqlite3_int64 *pi /* IN/OUT: Value read from position-list */ +){ + if( (**pp)&0xFE ){ + fts3GetDeltaVarint(pp, pi); + *pi -= 2; + }else{ + *pi = POSITION_LIST_END; + } +} + +/* +** If parameter iCol is not 0, write an POS_COLUMN (1) byte followed by +** the value of iCol encoded as a varint to *pp. This will start a new +** column list. +** +** Set *pp to point to the byte just after the last byte written before +** returning (do not modify it if iCol==0). Return the total number of bytes +** written (0 if iCol==0). +*/ +static int fts3PutColNumber(char **pp, int iCol){ + int n = 0; /* Number of bytes written */ + if( iCol ){ + char *p = *pp; /* Output pointer */ + n = 1 + sqlite3Fts3PutVarint(&p[1], iCol); + *p = 0x01; + *pp = &p[n]; + } + return n; +} + +/* +** Compute the union of two position lists. The output written +** into *pp contains all positions of both *pp1 and *pp2 in sorted +** order and with any duplicates removed. All pointers are +** updated appropriately. The caller is responsible for insuring +** that there is enough space in *pp to hold the complete output. +*/ +static void fts3PoslistMerge( + char **pp, /* Output buffer */ + char **pp1, /* Left input list */ + char **pp2 /* Right input list */ +){ + char *p = *pp; + char *p1 = *pp1; + char *p2 = *pp2; + + while( *p1 || *p2 ){ + int iCol1; /* The current column index in pp1 */ + int iCol2; /* The current column index in pp2 */ + + if( *p1==POS_COLUMN ) fts3GetVarint32(&p1[1], &iCol1); + else if( *p1==POS_END ) iCol1 = POSITION_LIST_END; + else iCol1 = 0; + + if( *p2==POS_COLUMN ) fts3GetVarint32(&p2[1], &iCol2); + else if( *p2==POS_END ) iCol2 = POSITION_LIST_END; + else iCol2 = 0; + + if( iCol1==iCol2 ){ + sqlite3_int64 i1 = 0; /* Last position from pp1 */ + sqlite3_int64 i2 = 0; /* Last position from pp2 */ + sqlite3_int64 iPrev = 0; + int n = fts3PutColNumber(&p, iCol1); + p1 += n; + p2 += n; + + /* At this point, both p1 and p2 point to the start of column-lists + ** for the same column (the column with index iCol1 and iCol2). + ** A column-list is a list of non-negative delta-encoded varints, each + ** incremented by 2 before being stored. Each list is terminated by a + ** POS_END (0) or POS_COLUMN (1). The following block merges the two lists + ** and writes the results to buffer p. p is left pointing to the byte + ** after the list written. No terminator (POS_END or POS_COLUMN) is + ** written to the output. + */ + fts3GetDeltaVarint(&p1, &i1); + fts3GetDeltaVarint(&p2, &i2); + do { + fts3PutDeltaVarint(&p, &iPrev, (i1pos(*pp1) && pos(*pp2)-pos(*pp1)<=nToken). i.e. +** when the *pp1 token appears before the *pp2 token, but not more than nToken +** slots before it. +** +** e.g. nToken==1 searches for adjacent positions. +*/ +static int fts3PoslistPhraseMerge( + char **pp, /* IN/OUT: Preallocated output buffer */ + int nToken, /* Maximum difference in token positions */ + int isSaveLeft, /* Save the left position */ + int isExact, /* If *pp1 is exactly nTokens before *pp2 */ + char **pp1, /* IN/OUT: Left input list */ + char **pp2 /* IN/OUT: Right input list */ +){ + char *p = *pp; + char *p1 = *pp1; + char *p2 = *pp2; + int iCol1 = 0; + int iCol2 = 0; + + /* Never set both isSaveLeft and isExact for the same invocation. */ + assert( isSaveLeft==0 || isExact==0 ); + + assert( p!=0 && *p1!=0 && *p2!=0 ); + if( *p1==POS_COLUMN ){ + p1++; + p1 += fts3GetVarint32(p1, &iCol1); + } + if( *p2==POS_COLUMN ){ + p2++; + p2 += fts3GetVarint32(p2, &iCol2); + } + + while( 1 ){ + if( iCol1==iCol2 ){ + char *pSave = p; + sqlite3_int64 iPrev = 0; + sqlite3_int64 iPos1 = 0; + sqlite3_int64 iPos2 = 0; + + if( iCol1 ){ + *p++ = POS_COLUMN; + p += sqlite3Fts3PutVarint(p, iCol1); + } + + assert( *p1!=POS_END && *p1!=POS_COLUMN ); + assert( *p2!=POS_END && *p2!=POS_COLUMN ); + fts3GetDeltaVarint(&p1, &iPos1); iPos1 -= 2; + fts3GetDeltaVarint(&p2, &iPos2); iPos2 -= 2; + + while( 1 ){ + if( iPos2==iPos1+nToken + || (isExact==0 && iPos2>iPos1 && iPos2<=iPos1+nToken) + ){ + sqlite3_int64 iSave; + iSave = isSaveLeft ? iPos1 : iPos2; + fts3PutDeltaVarint(&p, &iPrev, iSave+2); iPrev -= 2; + pSave = 0; + assert( p ); + } + if( (!isSaveLeft && iPos2<=(iPos1+nToken)) || iPos2<=iPos1 ){ + if( (*p2&0xFE)==0 ) break; + fts3GetDeltaVarint(&p2, &iPos2); iPos2 -= 2; + }else{ + if( (*p1&0xFE)==0 ) break; + fts3GetDeltaVarint(&p1, &iPos1); iPos1 -= 2; + } + } + + if( pSave ){ + assert( pp && p ); + p = pSave; + } + + fts3ColumnlistCopy(0, &p1); + fts3ColumnlistCopy(0, &p2); + assert( (*p1&0xFE)==0 && (*p2&0xFE)==0 ); + if( 0==*p1 || 0==*p2 ) break; + + p1++; + p1 += fts3GetVarint32(p1, &iCol1); + p2++; + p2 += fts3GetVarint32(p2, &iCol2); + } + + /* Advance pointer p1 or p2 (whichever corresponds to the smaller of + ** iCol1 and iCol2) so that it points to either the 0x00 that marks the + ** end of the position list, or the 0x01 that precedes the next + ** column-number in the position list. + */ + else if( iCol1=pEnd ){ + *pp = 0; + }else{ + sqlite3_int64 iVal; + *pp += sqlite3Fts3GetVarint(*pp, &iVal); + if( bDescIdx ){ + *pVal -= iVal; + }else{ + *pVal += iVal; + } + } +} + +/* +** This function is used to write a single varint to a buffer. The varint +** is written to *pp. Before returning, *pp is set to point 1 byte past the +** end of the value written. +** +** If *pbFirst is zero when this function is called, the value written to +** the buffer is that of parameter iVal. +** +** If *pbFirst is non-zero when this function is called, then the value +** written is either (iVal-*piPrev) (if bDescIdx is zero) or (*piPrev-iVal) +** (if bDescIdx is non-zero). +** +** Before returning, this function always sets *pbFirst to 1 and *piPrev +** to the value of parameter iVal. +*/ +static void fts3PutDeltaVarint3( + char **pp, /* IN/OUT: Output pointer */ + int bDescIdx, /* True for descending docids */ + sqlite3_int64 *piPrev, /* IN/OUT: Previous value written to list */ + int *pbFirst, /* IN/OUT: True after first int written */ + sqlite3_int64 iVal /* Write this value to the list */ +){ + sqlite3_int64 iWrite; + if( bDescIdx==0 || *pbFirst==0 ){ + iWrite = iVal - *piPrev; + }else{ + iWrite = *piPrev - iVal; + } + assert( *pbFirst || *piPrev==0 ); + assert( *pbFirst==0 || iWrite>0 ); + *pp += sqlite3Fts3PutVarint(*pp, iWrite); + *piPrev = iVal; + *pbFirst = 1; +} + + +/* +** This macro is used by various functions that merge doclists. The two +** arguments are 64-bit docid values. If the value of the stack variable +** bDescDoclist is 0 when this macro is invoked, then it returns (i1-i2). +** Otherwise, (i2-i1). +** +** Using this makes it easier to write code that can merge doclists that are +** sorted in either ascending or descending order. +*/ +#define DOCID_CMP(i1, i2) ((bDescDoclist?-1:1) * (i1-i2)) + +/* +** This function does an "OR" merge of two doclists (output contains all +** positions contained in either argument doclist). If the docids in the +** input doclists are sorted in ascending order, parameter bDescDoclist +** should be false. If they are sorted in ascending order, it should be +** passed a non-zero value. +** +** If no error occurs, *paOut is set to point at an sqlite3_malloc'd buffer +** containing the output doclist and SQLITE_OK is returned. In this case +** *pnOut is set to the number of bytes in the output doclist. +** +** If an error occurs, an SQLite error code is returned. The output values +** are undefined in this case. +*/ +static int fts3DoclistOrMerge( + int bDescDoclist, /* True if arguments are desc */ + char *a1, int n1, /* First doclist */ + char *a2, int n2, /* Second doclist */ + char **paOut, int *pnOut /* OUT: Malloc'd doclist */ +){ + sqlite3_int64 i1 = 0; + sqlite3_int64 i2 = 0; + sqlite3_int64 iPrev = 0; + char *pEnd1 = &a1[n1]; + char *pEnd2 = &a2[n2]; + char *p1 = a1; + char *p2 = a2; + char *p; + char *aOut; + int bFirstOut = 0; + + *paOut = 0; + *pnOut = 0; + + /* Allocate space for the output. Both the input and output doclists + ** are delta encoded. If they are in ascending order (bDescDoclist==0), + ** then the first docid in each list is simply encoded as a varint. For + ** each subsequent docid, the varint stored is the difference between the + ** current and previous docid (a positive number - since the list is in + ** ascending order). + ** + ** The first docid written to the output is therefore encoded using the + ** same number of bytes as it is in whichever of the input lists it is + ** read from. And each subsequent docid read from the same input list + ** consumes either the same or less bytes as it did in the input (since + ** the difference between it and the previous value in the output must + ** be a positive value less than or equal to the delta value read from + ** the input list). The same argument applies to all but the first docid + ** read from the 'other' list. And to the contents of all position lists + ** that will be copied and merged from the input to the output. + ** + ** However, if the first docid copied to the output is a negative number, + ** then the encoding of the first docid from the 'other' input list may + ** be larger in the output than it was in the input (since the delta value + ** may be a larger positive integer than the actual docid). + ** + ** The space required to store the output is therefore the sum of the + ** sizes of the two inputs, plus enough space for exactly one of the input + ** docids to grow. + ** + ** A symetric argument may be made if the doclists are in descending + ** order. + */ + aOut = sqlite3_malloc(n1+n2+FTS3_VARINT_MAX-1); + if( !aOut ) return SQLITE_NOMEM; + + p = aOut; + fts3GetDeltaVarint3(&p1, pEnd1, 0, &i1); + fts3GetDeltaVarint3(&p2, pEnd2, 0, &i2); + while( p1 || p2 ){ + sqlite3_int64 iDiff = DOCID_CMP(i1, i2); + + if( p2 && p1 && iDiff==0 ){ + fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1); + fts3PoslistMerge(&p, &p1, &p2); + fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1); + fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); + }else if( !p2 || (p1 && iDiff<0) ){ + fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1); + fts3PoslistCopy(&p, &p1); + fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1); + }else{ + fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i2); + fts3PoslistCopy(&p, &p2); + fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); + } + } + + *paOut = aOut; + *pnOut = (int)(p-aOut); + assert( *pnOut<=n1+n2+FTS3_VARINT_MAX-1 ); + return SQLITE_OK; +} + +/* +** This function does a "phrase" merge of two doclists. In a phrase merge, +** the output contains a copy of each position from the right-hand input +** doclist for which there is a position in the left-hand input doclist +** exactly nDist tokens before it. +** +** If the docids in the input doclists are sorted in ascending order, +** parameter bDescDoclist should be false. If they are sorted in ascending +** order, it should be passed a non-zero value. +** +** The right-hand input doclist is overwritten by this function. +*/ +static int fts3DoclistPhraseMerge( + int bDescDoclist, /* True if arguments are desc */ + int nDist, /* Distance from left to right (1=adjacent) */ + char *aLeft, int nLeft, /* Left doclist */ + char **paRight, int *pnRight /* IN/OUT: Right/output doclist */ +){ + sqlite3_int64 i1 = 0; + sqlite3_int64 i2 = 0; + sqlite3_int64 iPrev = 0; + char *aRight = *paRight; + char *pEnd1 = &aLeft[nLeft]; + char *pEnd2 = &aRight[*pnRight]; + char *p1 = aLeft; + char *p2 = aRight; + char *p; + int bFirstOut = 0; + char *aOut; + + assert( nDist>0 ); + if( bDescDoclist ){ + aOut = sqlite3_malloc(*pnRight + FTS3_VARINT_MAX); + if( aOut==0 ) return SQLITE_NOMEM; + }else{ + aOut = aRight; + } + p = aOut; + + fts3GetDeltaVarint3(&p1, pEnd1, 0, &i1); + fts3GetDeltaVarint3(&p2, pEnd2, 0, &i2); + + while( p1 && p2 ){ + sqlite3_int64 iDiff = DOCID_CMP(i1, i2); + if( iDiff==0 ){ + char *pSave = p; + sqlite3_int64 iPrevSave = iPrev; + int bFirstOutSave = bFirstOut; + + fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1); + if( 0==fts3PoslistPhraseMerge(&p, nDist, 0, 1, &p1, &p2) ){ + p = pSave; + iPrev = iPrevSave; + bFirstOut = bFirstOutSave; + } + fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1); + fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); + }else if( iDiff<0 ){ + fts3PoslistCopy(0, &p1); + fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1); + }else{ + fts3PoslistCopy(0, &p2); + fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); + } + } + + *pnRight = (int)(p - aOut); + if( bDescDoclist ){ + sqlite3_free(aRight); + *paRight = aOut; + } + + return SQLITE_OK; +} + +/* +** Argument pList points to a position list nList bytes in size. This +** function checks to see if the position list contains any entries for +** a token in position 0 (of any column). If so, it writes argument iDelta +** to the output buffer pOut, followed by a position list consisting only +** of the entries from pList at position 0, and terminated by an 0x00 byte. +** The value returned is the number of bytes written to pOut (if any). +*/ +SQLITE_PRIVATE int sqlite3Fts3FirstFilter( + sqlite3_int64 iDelta, /* Varint that may be written to pOut */ + char *pList, /* Position list (no 0x00 term) */ + int nList, /* Size of pList in bytes */ + char *pOut /* Write output here */ +){ + int nOut = 0; + int bWritten = 0; /* True once iDelta has been written */ + char *p = pList; + char *pEnd = &pList[nList]; + + if( *p!=0x01 ){ + if( *p==0x02 ){ + nOut += sqlite3Fts3PutVarint(&pOut[nOut], iDelta); + pOut[nOut++] = 0x02; + bWritten = 1; + } + fts3ColumnlistCopy(0, &p); + } + + while( paaOutput); i++){ + if( pTS->aaOutput[i] ){ + if( !aOut ){ + aOut = pTS->aaOutput[i]; + nOut = pTS->anOutput[i]; + pTS->aaOutput[i] = 0; + }else{ + int nNew; + char *aNew; + + int rc = fts3DoclistOrMerge(p->bDescIdx, + pTS->aaOutput[i], pTS->anOutput[i], aOut, nOut, &aNew, &nNew + ); + if( rc!=SQLITE_OK ){ + sqlite3_free(aOut); + return rc; + } + + sqlite3_free(pTS->aaOutput[i]); + sqlite3_free(aOut); + pTS->aaOutput[i] = 0; + aOut = aNew; + nOut = nNew; + } + } + } + + pTS->aaOutput[0] = aOut; + pTS->anOutput[0] = nOut; + return SQLITE_OK; +} + +/* +** Merge the doclist aDoclist/nDoclist into the TermSelect object passed +** as the first argument. The merge is an "OR" merge (see function +** fts3DoclistOrMerge() for details). +** +** This function is called with the doclist for each term that matches +** a queried prefix. It merges all these doclists into one, the doclist +** for the specified prefix. Since there can be a very large number of +** doclists to merge, the merging is done pair-wise using the TermSelect +** object. +** +** This function returns SQLITE_OK if the merge is successful, or an +** SQLite error code (SQLITE_NOMEM) if an error occurs. +*/ +static int fts3TermSelectMerge( + Fts3Table *p, /* FTS table handle */ + TermSelect *pTS, /* TermSelect object to merge into */ + char *aDoclist, /* Pointer to doclist */ + int nDoclist /* Size of aDoclist in bytes */ +){ + if( pTS->aaOutput[0]==0 ){ + /* If this is the first term selected, copy the doclist to the output + ** buffer using memcpy(). + ** + ** Add FTS3_VARINT_MAX bytes of unused space to the end of the + ** allocation. This is so as to ensure that the buffer is big enough + ** to hold the current doclist AND'd with any other doclist. If the + ** doclists are stored in order=ASC order, this padding would not be + ** required (since the size of [doclistA AND doclistB] is always less + ** than or equal to the size of [doclistA] in that case). But this is + ** not true for order=DESC. For example, a doclist containing (1, -1) + ** may be smaller than (-1), as in the first example the -1 may be stored + ** as a single-byte delta, whereas in the second it must be stored as a + ** FTS3_VARINT_MAX byte varint. + ** + ** Similar padding is added in the fts3DoclistOrMerge() function. + */ + pTS->aaOutput[0] = sqlite3_malloc(nDoclist + FTS3_VARINT_MAX + 1); + pTS->anOutput[0] = nDoclist; + if( pTS->aaOutput[0] ){ + memcpy(pTS->aaOutput[0], aDoclist, nDoclist); + }else{ + return SQLITE_NOMEM; + } + }else{ + char *aMerge = aDoclist; + int nMerge = nDoclist; + int iOut; + + for(iOut=0; iOutaaOutput); iOut++){ + if( pTS->aaOutput[iOut]==0 ){ + assert( iOut>0 ); + pTS->aaOutput[iOut] = aMerge; + pTS->anOutput[iOut] = nMerge; + break; + }else{ + char *aNew; + int nNew; + + int rc = fts3DoclistOrMerge(p->bDescIdx, aMerge, nMerge, + pTS->aaOutput[iOut], pTS->anOutput[iOut], &aNew, &nNew + ); + if( rc!=SQLITE_OK ){ + if( aMerge!=aDoclist ) sqlite3_free(aMerge); + return rc; + } + + if( aMerge!=aDoclist ) sqlite3_free(aMerge); + sqlite3_free(pTS->aaOutput[iOut]); + pTS->aaOutput[iOut] = 0; + + aMerge = aNew; + nMerge = nNew; + if( (iOut+1)==SizeofArray(pTS->aaOutput) ){ + pTS->aaOutput[iOut] = aMerge; + pTS->anOutput[iOut] = nMerge; + } + } + } + } + return SQLITE_OK; +} + +/* +** Append SegReader object pNew to the end of the pCsr->apSegment[] array. +*/ +static int fts3SegReaderCursorAppend( + Fts3MultiSegReader *pCsr, + Fts3SegReader *pNew +){ + if( (pCsr->nSegment%16)==0 ){ + Fts3SegReader **apNew; + int nByte = (pCsr->nSegment + 16)*sizeof(Fts3SegReader*); + apNew = (Fts3SegReader **)sqlite3_realloc(pCsr->apSegment, nByte); + if( !apNew ){ + sqlite3Fts3SegReaderFree(pNew); + return SQLITE_NOMEM; + } + pCsr->apSegment = apNew; + } + pCsr->apSegment[pCsr->nSegment++] = pNew; + return SQLITE_OK; +} + +/* +** Add seg-reader objects to the Fts3MultiSegReader object passed as the +** 8th argument. +** +** This function returns SQLITE_OK if successful, or an SQLite error code +** otherwise. +*/ +static int fts3SegReaderCursor( + Fts3Table *p, /* FTS3 table handle */ + int iLangid, /* Language id */ + int iIndex, /* Index to search (from 0 to p->nIndex-1) */ + int iLevel, /* Level of segments to scan */ + const char *zTerm, /* Term to query for */ + int nTerm, /* Size of zTerm in bytes */ + int isPrefix, /* True for a prefix search */ + int isScan, /* True to scan from zTerm to EOF */ + Fts3MultiSegReader *pCsr /* Cursor object to populate */ +){ + int rc = SQLITE_OK; /* Error code */ + sqlite3_stmt *pStmt = 0; /* Statement to iterate through segments */ + int rc2; /* Result of sqlite3_reset() */ + + /* If iLevel is less than 0 and this is not a scan, include a seg-reader + ** for the pending-terms. If this is a scan, then this call must be being + ** made by an fts4aux module, not an FTS table. In this case calling + ** Fts3SegReaderPending might segfault, as the data structures used by + ** fts4aux are not completely populated. So it's easiest to filter these + ** calls out here. */ + if( iLevel<0 && p->aIndex ){ + Fts3SegReader *pSeg = 0; + rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix||isScan, &pSeg); + if( rc==SQLITE_OK && pSeg ){ + rc = fts3SegReaderCursorAppend(pCsr, pSeg); + } + } + + if( iLevel!=FTS3_SEGCURSOR_PENDING ){ + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3AllSegdirs(p, iLangid, iIndex, iLevel, &pStmt); + } + + while( rc==SQLITE_OK && SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){ + Fts3SegReader *pSeg = 0; + + /* Read the values returned by the SELECT into local variables. */ + sqlite3_int64 iStartBlock = sqlite3_column_int64(pStmt, 1); + sqlite3_int64 iLeavesEndBlock = sqlite3_column_int64(pStmt, 2); + sqlite3_int64 iEndBlock = sqlite3_column_int64(pStmt, 3); + int nRoot = sqlite3_column_bytes(pStmt, 4); + char const *zRoot = sqlite3_column_blob(pStmt, 4); + + /* If zTerm is not NULL, and this segment is not stored entirely on its + ** root node, the range of leaves scanned can be reduced. Do this. */ + if( iStartBlock && zTerm ){ + sqlite3_int64 *pi = (isPrefix ? &iLeavesEndBlock : 0); + rc = fts3SelectLeaf(p, zTerm, nTerm, zRoot, nRoot, &iStartBlock, pi); + if( rc!=SQLITE_OK ) goto finished; + if( isPrefix==0 && isScan==0 ) iLeavesEndBlock = iStartBlock; + } + + rc = sqlite3Fts3SegReaderNew(pCsr->nSegment+1, + (isPrefix==0 && isScan==0), + iStartBlock, iLeavesEndBlock, + iEndBlock, zRoot, nRoot, &pSeg + ); + if( rc!=SQLITE_OK ) goto finished; + rc = fts3SegReaderCursorAppend(pCsr, pSeg); + } + } + + finished: + rc2 = sqlite3_reset(pStmt); + if( rc==SQLITE_DONE ) rc = rc2; + + return rc; +} + +/* +** Set up a cursor object for iterating through a full-text index or a +** single level therein. +*/ +SQLITE_PRIVATE int sqlite3Fts3SegReaderCursor( + Fts3Table *p, /* FTS3 table handle */ + int iLangid, /* Language-id to search */ + int iIndex, /* Index to search (from 0 to p->nIndex-1) */ + int iLevel, /* Level of segments to scan */ + const char *zTerm, /* Term to query for */ + int nTerm, /* Size of zTerm in bytes */ + int isPrefix, /* True for a prefix search */ + int isScan, /* True to scan from zTerm to EOF */ + Fts3MultiSegReader *pCsr /* Cursor object to populate */ +){ + assert( iIndex>=0 && iIndexnIndex ); + assert( iLevel==FTS3_SEGCURSOR_ALL + || iLevel==FTS3_SEGCURSOR_PENDING + || iLevel>=0 + ); + assert( iLevelbase.pVtab; + + if( isPrefix ){ + for(i=1; bFound==0 && inIndex; i++){ + if( p->aIndex[i].nPrefix==nTerm ){ + bFound = 1; + rc = sqlite3Fts3SegReaderCursor(p, pCsr->iLangid, + i, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 0, 0, pSegcsr + ); + pSegcsr->bLookup = 1; + } + } + + for(i=1; bFound==0 && inIndex; i++){ + if( p->aIndex[i].nPrefix==nTerm+1 ){ + bFound = 1; + rc = sqlite3Fts3SegReaderCursor(p, pCsr->iLangid, + i, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 1, 0, pSegcsr + ); + if( rc==SQLITE_OK ){ + rc = fts3SegReaderCursorAddZero( + p, pCsr->iLangid, zTerm, nTerm, pSegcsr + ); + } + } + } + } + + if( bFound==0 ){ + rc = sqlite3Fts3SegReaderCursor(p, pCsr->iLangid, + 0, FTS3_SEGCURSOR_ALL, zTerm, nTerm, isPrefix, 0, pSegcsr + ); + pSegcsr->bLookup = !isPrefix; + } + } + + *ppSegcsr = pSegcsr; + return rc; +} + +/* +** Free an Fts3MultiSegReader allocated by fts3TermSegReaderCursor(). +*/ +static void fts3SegReaderCursorFree(Fts3MultiSegReader *pSegcsr){ + sqlite3Fts3SegReaderFinish(pSegcsr); + sqlite3_free(pSegcsr); +} + +/* +** This function retrieves the doclist for the specified term (or term +** prefix) from the database. +*/ +static int fts3TermSelect( + Fts3Table *p, /* Virtual table handle */ + Fts3PhraseToken *pTok, /* Token to query for */ + int iColumn, /* Column to query (or -ve for all columns) */ + int *pnOut, /* OUT: Size of buffer at *ppOut */ + char **ppOut /* OUT: Malloced result buffer */ +){ + int rc; /* Return code */ + Fts3MultiSegReader *pSegcsr; /* Seg-reader cursor for this term */ + TermSelect tsc; /* Object for pair-wise doclist merging */ + Fts3SegFilter filter; /* Segment term filter configuration */ + + pSegcsr = pTok->pSegcsr; + memset(&tsc, 0, sizeof(TermSelect)); + + filter.flags = FTS3_SEGMENT_IGNORE_EMPTY | FTS3_SEGMENT_REQUIRE_POS + | (pTok->isPrefix ? FTS3_SEGMENT_PREFIX : 0) + | (pTok->bFirst ? FTS3_SEGMENT_FIRST : 0) + | (iColumnnColumn ? FTS3_SEGMENT_COLUMN_FILTER : 0); + filter.iCol = iColumn; + filter.zTerm = pTok->z; + filter.nTerm = pTok->n; + + rc = sqlite3Fts3SegReaderStart(p, pSegcsr, &filter); + while( SQLITE_OK==rc + && SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, pSegcsr)) + ){ + rc = fts3TermSelectMerge(p, &tsc, pSegcsr->aDoclist, pSegcsr->nDoclist); + } + + if( rc==SQLITE_OK ){ + rc = fts3TermSelectFinishMerge(p, &tsc); + } + if( rc==SQLITE_OK ){ + *ppOut = tsc.aaOutput[0]; + *pnOut = tsc.anOutput[0]; + }else{ + int i; + for(i=0; ipSegcsr = 0; + return rc; +} + +/* +** This function counts the total number of docids in the doclist stored +** in buffer aList[], size nList bytes. +** +** If the isPoslist argument is true, then it is assumed that the doclist +** contains a position-list following each docid. Otherwise, it is assumed +** that the doclist is simply a list of docids stored as delta encoded +** varints. +*/ +static int fts3DoclistCountDocids(char *aList, int nList){ + int nDoc = 0; /* Return value */ + if( aList ){ + char *aEnd = &aList[nList]; /* Pointer to one byte after EOF */ + char *p = aList; /* Cursor */ + while( peSearch==FTS3_DOCID_SEARCH || pCsr->eSearch==FTS3_FULLSCAN_SEARCH ){ + if( SQLITE_ROW!=sqlite3_step(pCsr->pStmt) ){ + pCsr->isEof = 1; + rc = sqlite3_reset(pCsr->pStmt); + }else{ + pCsr->iPrevId = sqlite3_column_int64(pCsr->pStmt, 0); + rc = SQLITE_OK; + } + }else{ + rc = fts3EvalNext((Fts3Cursor *)pCursor); + } + assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); + return rc; +} + +/* +** The following are copied from sqliteInt.h. +** +** Constants for the largest and smallest possible 64-bit signed integers. +** These macros are designed to work correctly on both 32-bit and 64-bit +** compilers. +*/ +#ifndef SQLITE_AMALGAMATION +# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) +# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) +#endif + +/* +** If the numeric type of argument pVal is "integer", then return it +** converted to a 64-bit signed integer. Otherwise, return a copy of +** the second parameter, iDefault. +*/ +static sqlite3_int64 fts3DocidRange(sqlite3_value *pVal, i64 iDefault){ + if( pVal ){ + int eType = sqlite3_value_numeric_type(pVal); + if( eType==SQLITE_INTEGER ){ + return sqlite3_value_int64(pVal); + } + } + return iDefault; +} + +/* +** This is the xFilter interface for the virtual table. See +** the virtual table xFilter method documentation for additional +** information. +** +** If idxNum==FTS3_FULLSCAN_SEARCH then do a full table scan against +** the %_content table. +** +** If idxNum==FTS3_DOCID_SEARCH then do a docid lookup for a single entry +** in the %_content table. +** +** If idxNum>=FTS3_FULLTEXT_SEARCH then use the full text index. The +** column on the left-hand side of the MATCH operator is column +** number idxNum-FTS3_FULLTEXT_SEARCH, 0 indexed. argv[0] is the right-hand +** side of the MATCH operator. +*/ +static int fts3FilterMethod( + sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ + int idxNum, /* Strategy index */ + const char *idxStr, /* Unused */ + int nVal, /* Number of elements in apVal */ + sqlite3_value **apVal /* Arguments for the indexing scheme */ +){ + int rc = SQLITE_OK; + char *zSql; /* SQL statement used to access %_content */ + int eSearch; + Fts3Table *p = (Fts3Table *)pCursor->pVtab; + Fts3Cursor *pCsr = (Fts3Cursor *)pCursor; + + sqlite3_value *pCons = 0; /* The MATCH or rowid constraint, if any */ + sqlite3_value *pLangid = 0; /* The "langid = ?" constraint, if any */ + sqlite3_value *pDocidGe = 0; /* The "docid >= ?" constraint, if any */ + sqlite3_value *pDocidLe = 0; /* The "docid <= ?" constraint, if any */ + int iIdx; + + UNUSED_PARAMETER(idxStr); + UNUSED_PARAMETER(nVal); + + eSearch = (idxNum & 0x0000FFFF); + assert( eSearch>=0 && eSearch<=(FTS3_FULLTEXT_SEARCH+p->nColumn) ); + assert( p->pSegments==0 ); + + /* Collect arguments into local variables */ + iIdx = 0; + if( eSearch!=FTS3_FULLSCAN_SEARCH ) pCons = apVal[iIdx++]; + if( idxNum & FTS3_HAVE_LANGID ) pLangid = apVal[iIdx++]; + if( idxNum & FTS3_HAVE_DOCID_GE ) pDocidGe = apVal[iIdx++]; + if( idxNum & FTS3_HAVE_DOCID_LE ) pDocidLe = apVal[iIdx++]; + assert( iIdx==nVal ); + + /* In case the cursor has been used before, clear it now. */ + sqlite3_finalize(pCsr->pStmt); + sqlite3_free(pCsr->aDoclist); + sqlite3_free(pCsr->aMatchinfo); + sqlite3Fts3ExprFree(pCsr->pExpr); + memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor)); + + /* Set the lower and upper bounds on docids to return */ + pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64); + pCsr->iMaxDocid = fts3DocidRange(pDocidLe, LARGEST_INT64); + + if( idxStr ){ + pCsr->bDesc = (idxStr[0]=='D'); + }else{ + pCsr->bDesc = p->bDescIdx; + } + pCsr->eSearch = (i16)eSearch; + + if( eSearch!=FTS3_DOCID_SEARCH && eSearch!=FTS3_FULLSCAN_SEARCH ){ + int iCol = eSearch-FTS3_FULLTEXT_SEARCH; + const char *zQuery = (const char *)sqlite3_value_text(pCons); + + if( zQuery==0 && sqlite3_value_type(pCons)!=SQLITE_NULL ){ + return SQLITE_NOMEM; + } + + pCsr->iLangid = 0; + if( pLangid ) pCsr->iLangid = sqlite3_value_int(pLangid); + + assert( p->base.zErrMsg==0 ); + rc = sqlite3Fts3ExprParse(p->pTokenizer, pCsr->iLangid, + p->azColumn, p->bFts4, p->nColumn, iCol, zQuery, -1, &pCsr->pExpr, + &p->base.zErrMsg + ); + if( rc!=SQLITE_OK ){ + return rc; + } + + rc = fts3EvalStart(pCsr); + sqlite3Fts3SegmentsClose(p); + if( rc!=SQLITE_OK ) return rc; + pCsr->pNextId = pCsr->aDoclist; + pCsr->iPrevId = 0; + } + + /* Compile a SELECT statement for this cursor. For a full-table-scan, the + ** statement loops through all rows of the %_content table. For a + ** full-text query or docid lookup, the statement retrieves a single + ** row by docid. + */ + if( eSearch==FTS3_FULLSCAN_SEARCH ){ + if( pDocidGe || pDocidLe ){ + zSql = sqlite3_mprintf( + "SELECT %s WHERE rowid BETWEEN %lld AND %lld ORDER BY rowid %s", + p->zReadExprlist, pCsr->iMinDocid, pCsr->iMaxDocid, + (pCsr->bDesc ? "DESC" : "ASC") + ); + }else{ + zSql = sqlite3_mprintf("SELECT %s ORDER BY rowid %s", + p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC") + ); + } + if( zSql ){ + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0); + sqlite3_free(zSql); + }else{ + rc = SQLITE_NOMEM; + } + }else if( eSearch==FTS3_DOCID_SEARCH ){ + rc = fts3CursorSeekStmt(pCsr, &pCsr->pStmt); + if( rc==SQLITE_OK ){ + rc = sqlite3_bind_value(pCsr->pStmt, 1, pCons); + } + } + if( rc!=SQLITE_OK ) return rc; + + return fts3NextMethod(pCursor); +} + +/* +** This is the xEof method of the virtual table. SQLite calls this +** routine to find out if it has reached the end of a result set. +*/ +static int fts3EofMethod(sqlite3_vtab_cursor *pCursor){ + return ((Fts3Cursor *)pCursor)->isEof; +} + +/* +** This is the xRowid method. The SQLite core calls this routine to +** retrieve the rowid for the current row of the result set. fts3 +** exposes %_content.docid as the rowid for the virtual table. The +** rowid should be written to *pRowid. +*/ +static int fts3RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ + Fts3Cursor *pCsr = (Fts3Cursor *) pCursor; + *pRowid = pCsr->iPrevId; + return SQLITE_OK; +} + +/* +** This is the xColumn method, called by SQLite to request a value from +** the row that the supplied cursor currently points to. +** +** If: +** +** (iCol < p->nColumn) -> The value of the iCol'th user column. +** (iCol == p->nColumn) -> Magic column with the same name as the table. +** (iCol == p->nColumn+1) -> Docid column +** (iCol == p->nColumn+2) -> Langid column +*/ +static int fts3ColumnMethod( + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ + int iCol /* Index of column to read value from */ +){ + int rc = SQLITE_OK; /* Return Code */ + Fts3Cursor *pCsr = (Fts3Cursor *) pCursor; + Fts3Table *p = (Fts3Table *)pCursor->pVtab; + + /* The column value supplied by SQLite must be in range. */ + assert( iCol>=0 && iCol<=p->nColumn+2 ); + + if( iCol==p->nColumn+1 ){ + /* This call is a request for the "docid" column. Since "docid" is an + ** alias for "rowid", use the xRowid() method to obtain the value. + */ + sqlite3_result_int64(pCtx, pCsr->iPrevId); + }else if( iCol==p->nColumn ){ + /* The extra column whose name is the same as the table. + ** Return a blob which is a pointer to the cursor. */ + sqlite3_result_blob(pCtx, &pCsr, sizeof(pCsr), SQLITE_TRANSIENT); + }else if( iCol==p->nColumn+2 && pCsr->pExpr ){ + sqlite3_result_int64(pCtx, pCsr->iLangid); + }else{ + /* The requested column is either a user column (one that contains + ** indexed data), or the language-id column. */ + rc = fts3CursorSeek(0, pCsr); + + if( rc==SQLITE_OK ){ + if( iCol==p->nColumn+2 ){ + int iLangid = 0; + if( p->zLanguageid ){ + iLangid = sqlite3_column_int(pCsr->pStmt, p->nColumn+1); + } + sqlite3_result_int(pCtx, iLangid); + }else if( sqlite3_data_count(pCsr->pStmt)>(iCol+1) ){ + sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1)); + } + } + } + + assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); + return rc; +} + +/* +** This function is the implementation of the xUpdate callback used by +** FTS3 virtual tables. It is invoked by SQLite each time a row is to be +** inserted, updated or deleted. +*/ +static int fts3UpdateMethod( + sqlite3_vtab *pVtab, /* Virtual table handle */ + int nArg, /* Size of argument array */ + sqlite3_value **apVal, /* Array of arguments */ + sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */ +){ + return sqlite3Fts3UpdateMethod(pVtab, nArg, apVal, pRowid); +} + +/* +** Implementation of xSync() method. Flush the contents of the pending-terms +** hash-table to the database. +*/ +static int fts3SyncMethod(sqlite3_vtab *pVtab){ + + /* Following an incremental-merge operation, assuming that the input + ** segments are not completely consumed (the usual case), they are updated + ** in place to remove the entries that have already been merged. This + ** involves updating the leaf block that contains the smallest unmerged + ** entry and each block (if any) between the leaf and the root node. So + ** if the height of the input segment b-trees is N, and input segments + ** are merged eight at a time, updating the input segments at the end + ** of an incremental-merge requires writing (8*(1+N)) blocks. N is usually + ** small - often between 0 and 2. So the overhead of the incremental + ** merge is somewhere between 8 and 24 blocks. To avoid this overhead + ** dwarfing the actual productive work accomplished, the incremental merge + ** is only attempted if it will write at least 64 leaf blocks. Hence + ** nMinMerge. + ** + ** Of course, updating the input segments also involves deleting a bunch + ** of blocks from the segments table. But this is not considered overhead + ** as it would also be required by a crisis-merge that used the same input + ** segments. + */ + const u32 nMinMerge = 64; /* Minimum amount of incr-merge work to do */ + + Fts3Table *p = (Fts3Table*)pVtab; + int rc = sqlite3Fts3PendingTermsFlush(p); + + if( rc==SQLITE_OK + && p->nLeafAdd>(nMinMerge/16) + && p->nAutoincrmerge && p->nAutoincrmerge!=0xff + ){ + int mxLevel = 0; /* Maximum relative level value in db */ + int A; /* Incr-merge parameter A */ + + rc = sqlite3Fts3MaxLevel(p, &mxLevel); + assert( rc==SQLITE_OK || mxLevel==0 ); + A = p->nLeafAdd * mxLevel; + A += (A/2); + if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, p->nAutoincrmerge); + } + sqlite3Fts3SegmentsClose(p); + return rc; +} + +/* +** If it is currently unknown whether or not the FTS table has an %_stat +** table (if p->bHasStat==2), attempt to determine this (set p->bHasStat +** to 0 or 1). Return SQLITE_OK if successful, or an SQLite error code +** if an error occurs. +*/ +static int fts3SetHasStat(Fts3Table *p){ + int rc = SQLITE_OK; + if( p->bHasStat==2 ){ + const char *zFmt ="SELECT 1 FROM %Q.sqlite_master WHERE tbl_name='%q_stat'"; + char *zSql = sqlite3_mprintf(zFmt, p->zDb, p->zName); + if( zSql ){ + sqlite3_stmt *pStmt = 0; + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + if( rc==SQLITE_OK ){ + int bHasStat = (sqlite3_step(pStmt)==SQLITE_ROW); + rc = sqlite3_finalize(pStmt); + if( rc==SQLITE_OK ) p->bHasStat = bHasStat; + } + sqlite3_free(zSql); + }else{ + rc = SQLITE_NOMEM; + } + } + return rc; +} + +/* +** Implementation of xBegin() method. +*/ +static int fts3BeginMethod(sqlite3_vtab *pVtab){ + Fts3Table *p = (Fts3Table*)pVtab; + UNUSED_PARAMETER(pVtab); + assert( p->pSegments==0 ); + assert( p->nPendingData==0 ); + assert( p->inTransaction!=1 ); + TESTONLY( p->inTransaction = 1 ); + TESTONLY( p->mxSavepoint = -1; ); + p->nLeafAdd = 0; + return fts3SetHasStat(p); +} + +/* +** Implementation of xCommit() method. This is a no-op. The contents of +** the pending-terms hash-table have already been flushed into the database +** by fts3SyncMethod(). +*/ +static int fts3CommitMethod(sqlite3_vtab *pVtab){ + TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); + UNUSED_PARAMETER(pVtab); + assert( p->nPendingData==0 ); + assert( p->inTransaction!=0 ); + assert( p->pSegments==0 ); + TESTONLY( p->inTransaction = 0 ); + TESTONLY( p->mxSavepoint = -1; ); + return SQLITE_OK; +} + +/* +** Implementation of xRollback(). Discard the contents of the pending-terms +** hash-table. Any changes made to the database are reverted by SQLite. +*/ +static int fts3RollbackMethod(sqlite3_vtab *pVtab){ + Fts3Table *p = (Fts3Table*)pVtab; + sqlite3Fts3PendingTermsClear(p); + assert( p->inTransaction!=0 ); + TESTONLY( p->inTransaction = 0 ); + TESTONLY( p->mxSavepoint = -1; ); + return SQLITE_OK; +} + +/* +** When called, *ppPoslist must point to the byte immediately following the +** end of a position-list. i.e. ( (*ppPoslist)[-1]==POS_END ). This function +** moves *ppPoslist so that it instead points to the first byte of the +** same position list. +*/ +static void fts3ReversePoslist(char *pStart, char **ppPoslist){ + char *p = &(*ppPoslist)[-2]; + char c = 0; + + /* Skip backwards passed any trailing 0x00 bytes added by NearTrim() */ + while( p>pStart && (c=*p--)==0 ); + + /* Search backwards for a varint with value zero (the end of the previous + ** poslist). This is an 0x00 byte preceded by some byte that does not + ** have the 0x80 bit set. */ + while( p>pStart && (*p & 0x80) | c ){ + c = *p--; + } + assert( p==pStart || c==0 ); + + /* At this point p points to that preceding byte without the 0x80 bit + ** set. So to find the start of the poslist, skip forward 2 bytes then + ** over a varint. + ** + ** Normally. The other case is that p==pStart and the poslist to return + ** is the first in the doclist. In this case do not skip forward 2 bytes. + ** The second part of the if condition (c==0 && *ppPoslist>&p[2]) + ** is required for cases where the first byte of a doclist and the + ** doclist is empty. For example, if the first docid is 10, a doclist + ** that begins with: + ** + ** 0x0A 0x00 + */ + if( p>pStart || (c==0 && *ppPoslist>&p[2]) ){ p = &p[2]; } + while( *p++&0x80 ); + *ppPoslist = p; +} + +/* +** Helper function used by the implementation of the overloaded snippet(), +** offsets() and optimize() SQL functions. +** +** If the value passed as the third argument is a blob of size +** sizeof(Fts3Cursor*), then the blob contents are copied to the +** output variable *ppCsr and SQLITE_OK is returned. Otherwise, an error +** message is written to context pContext and SQLITE_ERROR returned. The +** string passed via zFunc is used as part of the error message. +*/ +static int fts3FunctionArg( + sqlite3_context *pContext, /* SQL function call context */ + const char *zFunc, /* Function name */ + sqlite3_value *pVal, /* argv[0] passed to function */ + Fts3Cursor **ppCsr /* OUT: Store cursor handle here */ +){ + Fts3Cursor *pRet; + if( sqlite3_value_type(pVal)!=SQLITE_BLOB + || sqlite3_value_bytes(pVal)!=sizeof(Fts3Cursor *) + ){ + char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc); + sqlite3_result_error(pContext, zErr, -1); + sqlite3_free(zErr); + return SQLITE_ERROR; + } + memcpy(&pRet, sqlite3_value_blob(pVal), sizeof(Fts3Cursor *)); + *ppCsr = pRet; + return SQLITE_OK; +} + +/* +** Implementation of the snippet() function for FTS3 +*/ +static void fts3SnippetFunc( + sqlite3_context *pContext, /* SQLite function call context */ + int nVal, /* Size of apVal[] array */ + sqlite3_value **apVal /* Array of arguments */ +){ + Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */ + const char *zStart = ""; + const char *zEnd = ""; + const char *zEllipsis = "..."; + int iCol = -1; + int nToken = 15; /* Default number of tokens in snippet */ + + /* There must be at least one argument passed to this function (otherwise + ** the non-overloaded version would have been called instead of this one). + */ + assert( nVal>=1 ); + + if( nVal>6 ){ + sqlite3_result_error(pContext, + "wrong number of arguments to function snippet()", -1); + return; + } + if( fts3FunctionArg(pContext, "snippet", apVal[0], &pCsr) ) return; + + switch( nVal ){ + case 6: nToken = sqlite3_value_int(apVal[5]); + case 5: iCol = sqlite3_value_int(apVal[4]); + case 4: zEllipsis = (const char*)sqlite3_value_text(apVal[3]); + case 3: zEnd = (const char*)sqlite3_value_text(apVal[2]); + case 2: zStart = (const char*)sqlite3_value_text(apVal[1]); + } + if( !zEllipsis || !zEnd || !zStart ){ + sqlite3_result_error_nomem(pContext); + }else if( nToken==0 ){ + sqlite3_result_text(pContext, "", -1, SQLITE_STATIC); + }else if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){ + sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis, iCol, nToken); + } +} + +/* +** Implementation of the offsets() function for FTS3 +*/ +static void fts3OffsetsFunc( + sqlite3_context *pContext, /* SQLite function call context */ + int nVal, /* Size of argument array */ + sqlite3_value **apVal /* Array of arguments */ +){ + Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */ + + UNUSED_PARAMETER(nVal); + + assert( nVal==1 ); + if( fts3FunctionArg(pContext, "offsets", apVal[0], &pCsr) ) return; + assert( pCsr ); + if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){ + sqlite3Fts3Offsets(pContext, pCsr); + } +} + +/* +** Implementation of the special optimize() function for FTS3. This +** function merges all segments in the database to a single segment. +** Example usage is: +** +** SELECT optimize(t) FROM t LIMIT 1; +** +** where 't' is the name of an FTS3 table. +*/ +static void fts3OptimizeFunc( + sqlite3_context *pContext, /* SQLite function call context */ + int nVal, /* Size of argument array */ + sqlite3_value **apVal /* Array of arguments */ +){ + int rc; /* Return code */ + Fts3Table *p; /* Virtual table handle */ + Fts3Cursor *pCursor; /* Cursor handle passed through apVal[0] */ + + UNUSED_PARAMETER(nVal); + + assert( nVal==1 ); + if( fts3FunctionArg(pContext, "optimize", apVal[0], &pCursor) ) return; + p = (Fts3Table *)pCursor->base.pVtab; + assert( p ); + + rc = sqlite3Fts3Optimize(p); + + switch( rc ){ + case SQLITE_OK: + sqlite3_result_text(pContext, "Index optimized", -1, SQLITE_STATIC); + break; + case SQLITE_DONE: + sqlite3_result_text(pContext, "Index already optimal", -1, SQLITE_STATIC); + break; + default: + sqlite3_result_error_code(pContext, rc); + break; + } +} + +/* +** Implementation of the matchinfo() function for FTS3 +*/ +static void fts3MatchinfoFunc( + sqlite3_context *pContext, /* SQLite function call context */ + int nVal, /* Size of argument array */ + sqlite3_value **apVal /* Array of arguments */ +){ + Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */ + assert( nVal==1 || nVal==2 ); + if( SQLITE_OK==fts3FunctionArg(pContext, "matchinfo", apVal[0], &pCsr) ){ + const char *zArg = 0; + if( nVal>1 ){ + zArg = (const char *)sqlite3_value_text(apVal[1]); + } + sqlite3Fts3Matchinfo(pContext, pCsr, zArg); + } +} + +/* +** This routine implements the xFindFunction method for the FTS3 +** virtual table. +*/ +static int fts3FindFunctionMethod( + sqlite3_vtab *pVtab, /* Virtual table handle */ + int nArg, /* Number of SQL function arguments */ + const char *zName, /* Name of SQL function */ + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */ + void **ppArg /* Unused */ +){ + struct Overloaded { + const char *zName; + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); + } aOverload[] = { + { "snippet", fts3SnippetFunc }, + { "offsets", fts3OffsetsFunc }, + { "optimize", fts3OptimizeFunc }, + { "matchinfo", fts3MatchinfoFunc }, + }; + int i; /* Iterator variable */ + + UNUSED_PARAMETER(pVtab); + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(ppArg); + + for(i=0; idb; /* Database connection */ + int rc; /* Return Code */ + + /* At this point it must be known if the %_stat table exists or not. + ** So bHasStat may not be 2. */ + rc = fts3SetHasStat(p); + + /* As it happens, the pending terms table is always empty here. This is + ** because an "ALTER TABLE RENAME TABLE" statement inside a transaction + ** always opens a savepoint transaction. And the xSavepoint() method + ** flushes the pending terms table. But leave the (no-op) call to + ** PendingTermsFlush() in in case that changes. + */ + assert( p->nPendingData==0 ); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3PendingTermsFlush(p); + } + + if( p->zContentTbl==0 ){ + fts3DbExec(&rc, db, + "ALTER TABLE %Q.'%q_content' RENAME TO '%q_content';", + p->zDb, p->zName, zName + ); + } + + if( p->bHasDocsize ){ + fts3DbExec(&rc, db, + "ALTER TABLE %Q.'%q_docsize' RENAME TO '%q_docsize';", + p->zDb, p->zName, zName + ); + } + if( p->bHasStat ){ + fts3DbExec(&rc, db, + "ALTER TABLE %Q.'%q_stat' RENAME TO '%q_stat';", + p->zDb, p->zName, zName + ); + } + fts3DbExec(&rc, db, + "ALTER TABLE %Q.'%q_segments' RENAME TO '%q_segments';", + p->zDb, p->zName, zName + ); + fts3DbExec(&rc, db, + "ALTER TABLE %Q.'%q_segdir' RENAME TO '%q_segdir';", + p->zDb, p->zName, zName + ); + return rc; +} + +/* +** The xSavepoint() method. +** +** Flush the contents of the pending-terms table to disk. +*/ +static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ + int rc = SQLITE_OK; + UNUSED_PARAMETER(iSavepoint); + assert( ((Fts3Table *)pVtab)->inTransaction ); + assert( ((Fts3Table *)pVtab)->mxSavepoint < iSavepoint ); + TESTONLY( ((Fts3Table *)pVtab)->mxSavepoint = iSavepoint ); + if( ((Fts3Table *)pVtab)->bIgnoreSavepoint==0 ){ + rc = fts3SyncMethod(pVtab); + } + return rc; +} + +/* +** The xRelease() method. +** +** This is a no-op. +*/ +static int fts3ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ + TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); + UNUSED_PARAMETER(iSavepoint); + UNUSED_PARAMETER(pVtab); + assert( p->inTransaction ); + assert( p->mxSavepoint >= iSavepoint ); + TESTONLY( p->mxSavepoint = iSavepoint-1 ); + return SQLITE_OK; +} + +/* +** The xRollbackTo() method. +** +** Discard the contents of the pending terms table. +*/ +static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ + Fts3Table *p = (Fts3Table*)pVtab; + UNUSED_PARAMETER(iSavepoint); + assert( p->inTransaction ); + assert( p->mxSavepoint >= iSavepoint ); + TESTONLY( p->mxSavepoint = iSavepoint ); + sqlite3Fts3PendingTermsClear(p); + return SQLITE_OK; +} + +static const sqlite3_module fts3Module = { + /* iVersion */ 2, + /* xCreate */ fts3CreateMethod, + /* xConnect */ fts3ConnectMethod, + /* xBestIndex */ fts3BestIndexMethod, + /* xDisconnect */ fts3DisconnectMethod, + /* xDestroy */ fts3DestroyMethod, + /* xOpen */ fts3OpenMethod, + /* xClose */ fts3CloseMethod, + /* xFilter */ fts3FilterMethod, + /* xNext */ fts3NextMethod, + /* xEof */ fts3EofMethod, + /* xColumn */ fts3ColumnMethod, + /* xRowid */ fts3RowidMethod, + /* xUpdate */ fts3UpdateMethod, + /* xBegin */ fts3BeginMethod, + /* xSync */ fts3SyncMethod, + /* xCommit */ fts3CommitMethod, + /* xRollback */ fts3RollbackMethod, + /* xFindFunction */ fts3FindFunctionMethod, + /* xRename */ fts3RenameMethod, + /* xSavepoint */ fts3SavepointMethod, + /* xRelease */ fts3ReleaseMethod, + /* xRollbackTo */ fts3RollbackToMethod, +}; + +/* +** This function is registered as the module destructor (called when an +** FTS3 enabled database connection is closed). It frees the memory +** allocated for the tokenizer hash table. +*/ +static void hashDestroy(void *p){ + Fts3Hash *pHash = (Fts3Hash *)p; + sqlite3Fts3HashClear(pHash); + sqlite3_free(pHash); +} + +/* +** The fts3 built-in tokenizers - "simple", "porter" and "icu"- are +** implemented in files fts3_tokenizer1.c, fts3_porter.c and fts3_icu.c +** respectively. The following three forward declarations are for functions +** declared in these files used to retrieve the respective implementations. +** +** Calling sqlite3Fts3SimpleTokenizerModule() sets the value pointed +** to by the argument to point to the "simple" tokenizer implementation. +** And so on. +*/ +SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule); +SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule); +#ifndef SQLITE_DISABLE_FTS3_UNICODE +SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const**ppModule); +#endif +#ifdef SQLITE_ENABLE_ICU +SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule); +#endif + +/* +** Initialize the fts3 extension. If this extension is built as part +** of the sqlite library, then this function is called directly by +** SQLite. If fts3 is built as a dynamically loadable extension, this +** function is called by the sqlite3_extension_init() entry point. +*/ +SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ + int rc = SQLITE_OK; + Fts3Hash *pHash = 0; + const sqlite3_tokenizer_module *pSimple = 0; + const sqlite3_tokenizer_module *pPorter = 0; +#ifndef SQLITE_DISABLE_FTS3_UNICODE + const sqlite3_tokenizer_module *pUnicode = 0; +#endif + +#ifdef SQLITE_ENABLE_ICU + const sqlite3_tokenizer_module *pIcu = 0; + sqlite3Fts3IcuTokenizerModule(&pIcu); +#endif + +#ifndef SQLITE_DISABLE_FTS3_UNICODE + sqlite3Fts3UnicodeTokenizer(&pUnicode); +#endif + +#ifdef SQLITE_TEST + rc = sqlite3Fts3InitTerm(db); + if( rc!=SQLITE_OK ) return rc; +#endif + + rc = sqlite3Fts3InitAux(db); + if( rc!=SQLITE_OK ) return rc; + + sqlite3Fts3SimpleTokenizerModule(&pSimple); + sqlite3Fts3PorterTokenizerModule(&pPorter); + + /* Allocate and initialize the hash-table used to store tokenizers. */ + pHash = sqlite3_malloc(sizeof(Fts3Hash)); + if( !pHash ){ + rc = SQLITE_NOMEM; + }else{ + sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1); + } + + /* Load the built-in tokenizers into the hash table */ + if( rc==SQLITE_OK ){ + if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple) + || sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter) + +#ifndef SQLITE_DISABLE_FTS3_UNICODE + || sqlite3Fts3HashInsert(pHash, "unicode61", 10, (void *)pUnicode) +#endif +#ifdef SQLITE_ENABLE_ICU + || (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu)) +#endif + ){ + rc = SQLITE_NOMEM; + } + } + +#ifdef SQLITE_TEST + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3ExprInitTestInterface(db); + } +#endif + + /* Create the virtual table wrapper around the hash-table and overload + ** the two scalar functions. If this is successful, register the + ** module with sqlite. + */ + if( SQLITE_OK==rc + && SQLITE_OK==(rc = sqlite3Fts3InitHashTable(db, pHash, "fts3_tokenizer")) + && SQLITE_OK==(rc = sqlite3_overload_function(db, "snippet", -1)) + && SQLITE_OK==(rc = sqlite3_overload_function(db, "offsets", 1)) + && SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 1)) + && SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 2)) + && SQLITE_OK==(rc = sqlite3_overload_function(db, "optimize", 1)) + ){ + rc = sqlite3_create_module_v2( + db, "fts3", &fts3Module, (void *)pHash, hashDestroy + ); + if( rc==SQLITE_OK ){ + rc = sqlite3_create_module_v2( + db, "fts4", &fts3Module, (void *)pHash, 0 + ); + } + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3InitTok(db, (void *)pHash); + } + return rc; + } + + + /* An error has occurred. Delete the hash table and return the error code. */ + assert( rc!=SQLITE_OK ); + if( pHash ){ + sqlite3Fts3HashClear(pHash); + sqlite3_free(pHash); + } + return rc; +} + +/* +** Allocate an Fts3MultiSegReader for each token in the expression headed +** by pExpr. +** +** An Fts3SegReader object is a cursor that can seek or scan a range of +** entries within a single segment b-tree. An Fts3MultiSegReader uses multiple +** Fts3SegReader objects internally to provide an interface to seek or scan +** within the union of all segments of a b-tree. Hence the name. +** +** If the allocated Fts3MultiSegReader just seeks to a single entry in a +** segment b-tree (if the term is not a prefix or it is a prefix for which +** there exists prefix b-tree of the right length) then it may be traversed +** and merged incrementally. Otherwise, it has to be merged into an in-memory +** doclist and then traversed. +*/ +static void fts3EvalAllocateReaders( + Fts3Cursor *pCsr, /* FTS cursor handle */ + Fts3Expr *pExpr, /* Allocate readers for this expression */ + int *pnToken, /* OUT: Total number of tokens in phrase. */ + int *pnOr, /* OUT: Total number of OR nodes in expr. */ + int *pRc /* IN/OUT: Error code */ +){ + if( pExpr && SQLITE_OK==*pRc ){ + if( pExpr->eType==FTSQUERY_PHRASE ){ + int i; + int nToken = pExpr->pPhrase->nToken; + *pnToken += nToken; + for(i=0; ipPhrase->aToken[i]; + int rc = fts3TermSegReaderCursor(pCsr, + pToken->z, pToken->n, pToken->isPrefix, &pToken->pSegcsr + ); + if( rc!=SQLITE_OK ){ + *pRc = rc; + return; + } + } + assert( pExpr->pPhrase->iDoclistToken==0 ); + pExpr->pPhrase->iDoclistToken = -1; + }else{ + *pnOr += (pExpr->eType==FTSQUERY_OR); + fts3EvalAllocateReaders(pCsr, pExpr->pLeft, pnToken, pnOr, pRc); + fts3EvalAllocateReaders(pCsr, pExpr->pRight, pnToken, pnOr, pRc); + } + } +} + +/* +** Arguments pList/nList contain the doclist for token iToken of phrase p. +** It is merged into the main doclist stored in p->doclist.aAll/nAll. +** +** This function assumes that pList points to a buffer allocated using +** sqlite3_malloc(). This function takes responsibility for eventually +** freeing the buffer. +** +** SQLITE_OK is returned if successful, or SQLITE_NOMEM if an error occurs. +*/ +static int fts3EvalPhraseMergeToken( + Fts3Table *pTab, /* FTS Table pointer */ + Fts3Phrase *p, /* Phrase to merge pList/nList into */ + int iToken, /* Token pList/nList corresponds to */ + char *pList, /* Pointer to doclist */ + int nList /* Number of bytes in pList */ +){ + int rc = SQLITE_OK; + assert( iToken!=p->iDoclistToken ); + + if( pList==0 ){ + sqlite3_free(p->doclist.aAll); + p->doclist.aAll = 0; + p->doclist.nAll = 0; + } + + else if( p->iDoclistToken<0 ){ + p->doclist.aAll = pList; + p->doclist.nAll = nList; + } + + else if( p->doclist.aAll==0 ){ + sqlite3_free(pList); + } + + else { + char *pLeft; + char *pRight; + int nLeft; + int nRight; + int nDiff; + + if( p->iDoclistTokendoclist.aAll; + nLeft = p->doclist.nAll; + pRight = pList; + nRight = nList; + nDiff = iToken - p->iDoclistToken; + }else{ + pRight = p->doclist.aAll; + nRight = p->doclist.nAll; + pLeft = pList; + nLeft = nList; + nDiff = p->iDoclistToken - iToken; + } + + rc = fts3DoclistPhraseMerge( + pTab->bDescIdx, nDiff, pLeft, nLeft, &pRight, &nRight + ); + sqlite3_free(pLeft); + p->doclist.aAll = pRight; + p->doclist.nAll = nRight; + } + + if( iToken>p->iDoclistToken ) p->iDoclistToken = iToken; + return rc; +} + +/* +** Load the doclist for phrase p into p->doclist.aAll/nAll. The loaded doclist +** does not take deferred tokens into account. +** +** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code. +*/ +static int fts3EvalPhraseLoad( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Phrase *p /* Phrase object */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int iToken; + int rc = SQLITE_OK; + + for(iToken=0; rc==SQLITE_OK && iTokennToken; iToken++){ + Fts3PhraseToken *pToken = &p->aToken[iToken]; + assert( pToken->pDeferred==0 || pToken->pSegcsr==0 ); + + if( pToken->pSegcsr ){ + int nThis = 0; + char *pThis = 0; + rc = fts3TermSelect(pTab, pToken, p->iColumn, &nThis, &pThis); + if( rc==SQLITE_OK ){ + rc = fts3EvalPhraseMergeToken(pTab, p, iToken, pThis, nThis); + } + } + assert( pToken->pSegcsr==0 ); + } + + return rc; +} + +/* +** This function is called on each phrase after the position lists for +** any deferred tokens have been loaded into memory. It updates the phrases +** current position list to include only those positions that are really +** instances of the phrase (after considering deferred tokens). If this +** means that the phrase does not appear in the current row, doclist.pList +** and doclist.nList are both zeroed. +** +** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code. +*/ +static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ + int iToken; /* Used to iterate through phrase tokens */ + char *aPoslist = 0; /* Position list for deferred tokens */ + int nPoslist = 0; /* Number of bytes in aPoslist */ + int iPrev = -1; /* Token number of previous deferred token */ + + assert( pPhrase->doclist.bFreeList==0 ); + + for(iToken=0; iTokennToken; iToken++){ + Fts3PhraseToken *pToken = &pPhrase->aToken[iToken]; + Fts3DeferredToken *pDeferred = pToken->pDeferred; + + if( pDeferred ){ + char *pList; + int nList; + int rc = sqlite3Fts3DeferredTokenList(pDeferred, &pList, &nList); + if( rc!=SQLITE_OK ) return rc; + + if( pList==0 ){ + sqlite3_free(aPoslist); + pPhrase->doclist.pList = 0; + pPhrase->doclist.nList = 0; + return SQLITE_OK; + + }else if( aPoslist==0 ){ + aPoslist = pList; + nPoslist = nList; + + }else{ + char *aOut = pList; + char *p1 = aPoslist; + char *p2 = aOut; + + assert( iPrev>=0 ); + fts3PoslistPhraseMerge(&aOut, iToken-iPrev, 0, 1, &p1, &p2); + sqlite3_free(aPoslist); + aPoslist = pList; + nPoslist = (int)(aOut - aPoslist); + if( nPoslist==0 ){ + sqlite3_free(aPoslist); + pPhrase->doclist.pList = 0; + pPhrase->doclist.nList = 0; + return SQLITE_OK; + } + } + iPrev = iToken; + } + } + + if( iPrev>=0 ){ + int nMaxUndeferred = pPhrase->iDoclistToken; + if( nMaxUndeferred<0 ){ + pPhrase->doclist.pList = aPoslist; + pPhrase->doclist.nList = nPoslist; + pPhrase->doclist.iDocid = pCsr->iPrevId; + pPhrase->doclist.bFreeList = 1; + }else{ + int nDistance; + char *p1; + char *p2; + char *aOut; + + if( nMaxUndeferred>iPrev ){ + p1 = aPoslist; + p2 = pPhrase->doclist.pList; + nDistance = nMaxUndeferred - iPrev; + }else{ + p1 = pPhrase->doclist.pList; + p2 = aPoslist; + nDistance = iPrev - nMaxUndeferred; + } + + aOut = (char *)sqlite3_malloc(nPoslist+8); + if( !aOut ){ + sqlite3_free(aPoslist); + return SQLITE_NOMEM; + } + + pPhrase->doclist.pList = aOut; + if( fts3PoslistPhraseMerge(&aOut, nDistance, 0, 1, &p1, &p2) ){ + pPhrase->doclist.bFreeList = 1; + pPhrase->doclist.nList = (int)(aOut - pPhrase->doclist.pList); + }else{ + sqlite3_free(aOut); + pPhrase->doclist.pList = 0; + pPhrase->doclist.nList = 0; + } + sqlite3_free(aPoslist); + } + } + + return SQLITE_OK; +} + +/* +** Maximum number of tokens a phrase may have to be considered for the +** incremental doclists strategy. +*/ +#define MAX_INCR_PHRASE_TOKENS 4 + +/* +** This function is called for each Fts3Phrase in a full-text query +** expression to initialize the mechanism for returning rows. Once this +** function has been called successfully on an Fts3Phrase, it may be +** used with fts3EvalPhraseNext() to iterate through the matching docids. +** +** If parameter bOptOk is true, then the phrase may (or may not) use the +** incremental loading strategy. Otherwise, the entire doclist is loaded into +** memory within this call. +** +** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code. +*/ +static int fts3EvalPhraseStart(Fts3Cursor *pCsr, int bOptOk, Fts3Phrase *p){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int rc = SQLITE_OK; /* Error code */ + int i; + + /* Determine if doclists may be loaded from disk incrementally. This is + ** possible if the bOptOk argument is true, the FTS doclists will be + ** scanned in forward order, and the phrase consists of + ** MAX_INCR_PHRASE_TOKENS or fewer tokens, none of which are are "^first" + ** tokens or prefix tokens that cannot use a prefix-index. */ + int bHaveIncr = 0; + int bIncrOk = (bOptOk + && pCsr->bDesc==pTab->bDescIdx + && p->nToken<=MAX_INCR_PHRASE_TOKENS && p->nToken>0 + && p->nToken<=MAX_INCR_PHRASE_TOKENS && p->nToken>0 +#ifdef SQLITE_TEST + && pTab->bNoIncrDoclist==0 +#endif + ); + for(i=0; bIncrOk==1 && inToken; i++){ + Fts3PhraseToken *pToken = &p->aToken[i]; + if( pToken->bFirst || (pToken->pSegcsr!=0 && !pToken->pSegcsr->bLookup) ){ + bIncrOk = 0; + } + if( pToken->pSegcsr ) bHaveIncr = 1; + } + + if( bIncrOk && bHaveIncr ){ + /* Use the incremental approach. */ + int iCol = (p->iColumn >= pTab->nColumn ? -1 : p->iColumn); + for(i=0; rc==SQLITE_OK && inToken; i++){ + Fts3PhraseToken *pToken = &p->aToken[i]; + Fts3MultiSegReader *pSegcsr = pToken->pSegcsr; + if( pSegcsr ){ + rc = sqlite3Fts3MsrIncrStart(pTab, pSegcsr, iCol, pToken->z, pToken->n); + } + } + p->bIncr = 1; + }else{ + /* Load the full doclist for the phrase into memory. */ + rc = fts3EvalPhraseLoad(pCsr, p); + p->bIncr = 0; + } + + assert( rc!=SQLITE_OK || p->nToken<1 || p->aToken[0].pSegcsr==0 || p->bIncr ); + return rc; +} + +/* +** This function is used to iterate backwards (from the end to start) +** through doclists. It is used by this module to iterate through phrase +** doclists in reverse and by the fts3_write.c module to iterate through +** pending-terms lists when writing to databases with "order=desc". +** +** The doclist may be sorted in ascending (parameter bDescIdx==0) or +** descending (parameter bDescIdx==1) order of docid. Regardless, this +** function iterates from the end of the doclist to the beginning. +*/ +SQLITE_PRIVATE void sqlite3Fts3DoclistPrev( + int bDescIdx, /* True if the doclist is desc */ + char *aDoclist, /* Pointer to entire doclist */ + int nDoclist, /* Length of aDoclist in bytes */ + char **ppIter, /* IN/OUT: Iterator pointer */ + sqlite3_int64 *piDocid, /* IN/OUT: Docid pointer */ + int *pnList, /* OUT: List length pointer */ + u8 *pbEof /* OUT: End-of-file flag */ +){ + char *p = *ppIter; + + assert( nDoclist>0 ); + assert( *pbEof==0 ); + assert( p || *piDocid==0 ); + assert( !p || (p>aDoclist && p<&aDoclist[nDoclist]) ); + + if( p==0 ){ + sqlite3_int64 iDocid = 0; + char *pNext = 0; + char *pDocid = aDoclist; + char *pEnd = &aDoclist[nDoclist]; + int iMul = 1; + + while( pDocid0 ); + assert( *pbEof==0 ); + assert( p || *piDocid==0 ); + assert( !p || (p>=aDoclist && p<=&aDoclist[nDoclist]) ); + + if( p==0 ){ + p = aDoclist; + p += sqlite3Fts3GetVarint(p, piDocid); + }else{ + fts3PoslistCopy(0, &p); + if( p>=&aDoclist[nDoclist] ){ + *pbEof = 1; + }else{ + sqlite3_int64 iVar; + p += sqlite3Fts3GetVarint(p, &iVar); + *piDocid += ((bDescIdx ? -1 : 1) * iVar); + } + } + + *ppIter = p; +} + +/* +** Advance the iterator pDL to the next entry in pDL->aAll/nAll. Set *pbEof +** to true if EOF is reached. +*/ +static void fts3EvalDlPhraseNext( + Fts3Table *pTab, + Fts3Doclist *pDL, + u8 *pbEof +){ + char *pIter; /* Used to iterate through aAll */ + char *pEnd = &pDL->aAll[pDL->nAll]; /* 1 byte past end of aAll */ + + if( pDL->pNextDocid ){ + pIter = pDL->pNextDocid; + }else{ + pIter = pDL->aAll; + } + + if( pIter>=pEnd ){ + /* We have already reached the end of this doclist. EOF. */ + *pbEof = 1; + }else{ + sqlite3_int64 iDelta; + pIter += sqlite3Fts3GetVarint(pIter, &iDelta); + if( pTab->bDescIdx==0 || pDL->pNextDocid==0 ){ + pDL->iDocid += iDelta; + }else{ + pDL->iDocid -= iDelta; + } + pDL->pList = pIter; + fts3PoslistCopy(0, &pIter); + pDL->nList = (int)(pIter - pDL->pList); + + /* pIter now points just past the 0x00 that terminates the position- + ** list for document pDL->iDocid. However, if this position-list was + ** edited in place by fts3EvalNearTrim(), then pIter may not actually + ** point to the start of the next docid value. The following line deals + ** with this case by advancing pIter past the zero-padding added by + ** fts3EvalNearTrim(). */ + while( pIterpNextDocid = pIter; + assert( pIter>=&pDL->aAll[pDL->nAll] || *pIter ); + *pbEof = 0; + } +} + +/* +** Helper type used by fts3EvalIncrPhraseNext() and incrPhraseTokenNext(). +*/ +typedef struct TokenDoclist TokenDoclist; +struct TokenDoclist { + int bIgnore; + sqlite3_int64 iDocid; + char *pList; + int nList; +}; + +/* +** Token pToken is an incrementally loaded token that is part of a +** multi-token phrase. Advance it to the next matching document in the +** database and populate output variable *p with the details of the new +** entry. Or, if the iterator has reached EOF, set *pbEof to true. +** +** If an error occurs, return an SQLite error code. Otherwise, return +** SQLITE_OK. +*/ +static int incrPhraseTokenNext( + Fts3Table *pTab, /* Virtual table handle */ + Fts3Phrase *pPhrase, /* Phrase to advance token of */ + int iToken, /* Specific token to advance */ + TokenDoclist *p, /* OUT: Docid and doclist for new entry */ + u8 *pbEof /* OUT: True if iterator is at EOF */ +){ + int rc = SQLITE_OK; + + if( pPhrase->iDoclistToken==iToken ){ + assert( p->bIgnore==0 ); + assert( pPhrase->aToken[iToken].pSegcsr==0 ); + fts3EvalDlPhraseNext(pTab, &pPhrase->doclist, pbEof); + p->pList = pPhrase->doclist.pList; + p->nList = pPhrase->doclist.nList; + p->iDocid = pPhrase->doclist.iDocid; + }else{ + Fts3PhraseToken *pToken = &pPhrase->aToken[iToken]; + assert( pToken->pDeferred==0 ); + assert( pToken->pSegcsr || pPhrase->iDoclistToken>=0 ); + if( pToken->pSegcsr ){ + assert( p->bIgnore==0 ); + rc = sqlite3Fts3MsrIncrNext( + pTab, pToken->pSegcsr, &p->iDocid, &p->pList, &p->nList + ); + if( p->pList==0 ) *pbEof = 1; + }else{ + p->bIgnore = 1; + } + } + + return rc; +} + + +/* +** The phrase iterator passed as the second argument: +** +** * features at least one token that uses an incremental doclist, and +** +** * does not contain any deferred tokens. +** +** Advance it to the next matching documnent in the database and populate +** the Fts3Doclist.pList and nList fields. +** +** If there is no "next" entry and no error occurs, then *pbEof is set to +** 1 before returning. Otherwise, if no error occurs and the iterator is +** successfully advanced, *pbEof is set to 0. +** +** If an error occurs, return an SQLite error code. Otherwise, return +** SQLITE_OK. +*/ +static int fts3EvalIncrPhraseNext( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Phrase *p, /* Phrase object to advance to next docid */ + u8 *pbEof /* OUT: Set to 1 if EOF */ +){ + int rc = SQLITE_OK; + Fts3Doclist *pDL = &p->doclist; + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + u8 bEof = 0; + + /* This is only called if it is guaranteed that the phrase has at least + ** one incremental token. In which case the bIncr flag is set. */ + assert( p->bIncr==1 ); + + if( p->nToken==1 && p->bIncr ){ + rc = sqlite3Fts3MsrIncrNext(pTab, p->aToken[0].pSegcsr, + &pDL->iDocid, &pDL->pList, &pDL->nList + ); + if( pDL->pList==0 ) bEof = 1; + }else{ + int bDescDoclist = pCsr->bDesc; + struct TokenDoclist a[MAX_INCR_PHRASE_TOKENS]; + + memset(a, 0, sizeof(a)); + assert( p->nToken<=MAX_INCR_PHRASE_TOKENS ); + assert( p->iDoclistTokennToken && bEof==0; i++){ + rc = incrPhraseTokenNext(pTab, p, i, &a[i], &bEof); + if( a[i].bIgnore==0 && (bMaxSet==0 || DOCID_CMP(iMax, a[i].iDocid)<0) ){ + iMax = a[i].iDocid; + bMaxSet = 1; + } + } + assert( rc!=SQLITE_OK || (p->nToken>=1 && a[p->nToken-1].bIgnore==0) ); + assert( rc!=SQLITE_OK || bMaxSet ); + + /* Keep advancing iterators until they all point to the same document */ + for(i=0; inToken; i++){ + while( rc==SQLITE_OK && bEof==0 + && a[i].bIgnore==0 && DOCID_CMP(a[i].iDocid, iMax)<0 + ){ + rc = incrPhraseTokenNext(pTab, p, i, &a[i], &bEof); + if( DOCID_CMP(a[i].iDocid, iMax)>0 ){ + iMax = a[i].iDocid; + i = 0; + } + } + } + + /* Check if the current entries really are a phrase match */ + if( bEof==0 ){ + int nList = 0; + int nByte = a[p->nToken-1].nList; + char *aDoclist = sqlite3_malloc(nByte+1); + if( !aDoclist ) return SQLITE_NOMEM; + memcpy(aDoclist, a[p->nToken-1].pList, nByte+1); + + for(i=0; i<(p->nToken-1); i++){ + if( a[i].bIgnore==0 ){ + char *pL = a[i].pList; + char *pR = aDoclist; + char *pOut = aDoclist; + int nDist = p->nToken-1-i; + int res = fts3PoslistPhraseMerge(&pOut, nDist, 0, 1, &pL, &pR); + if( res==0 ) break; + nList = (int)(pOut - aDoclist); + } + } + if( i==(p->nToken-1) ){ + pDL->iDocid = iMax; + pDL->pList = aDoclist; + pDL->nList = nList; + pDL->bFreeList = 1; + break; + } + sqlite3_free(aDoclist); + } + } + } + + *pbEof = bEof; + return rc; +} + +/* +** Attempt to move the phrase iterator to point to the next matching docid. +** If an error occurs, return an SQLite error code. Otherwise, return +** SQLITE_OK. +** +** If there is no "next" entry and no error occurs, then *pbEof is set to +** 1 before returning. Otherwise, if no error occurs and the iterator is +** successfully advanced, *pbEof is set to 0. +*/ +static int fts3EvalPhraseNext( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Phrase *p, /* Phrase object to advance to next docid */ + u8 *pbEof /* OUT: Set to 1 if EOF */ +){ + int rc = SQLITE_OK; + Fts3Doclist *pDL = &p->doclist; + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + + if( p->bIncr ){ + rc = fts3EvalIncrPhraseNext(pCsr, p, pbEof); + }else if( pCsr->bDesc!=pTab->bDescIdx && pDL->nAll ){ + sqlite3Fts3DoclistPrev(pTab->bDescIdx, pDL->aAll, pDL->nAll, + &pDL->pNextDocid, &pDL->iDocid, &pDL->nList, pbEof + ); + pDL->pList = pDL->pNextDocid; + }else{ + fts3EvalDlPhraseNext(pTab, pDL, pbEof); + } + + return rc; +} + +/* +** +** If *pRc is not SQLITE_OK when this function is called, it is a no-op. +** Otherwise, fts3EvalPhraseStart() is called on all phrases within the +** expression. Also the Fts3Expr.bDeferred variable is set to true for any +** expressions for which all descendent tokens are deferred. +** +** If parameter bOptOk is zero, then it is guaranteed that the +** Fts3Phrase.doclist.aAll/nAll variables contain the entire doclist for +** each phrase in the expression (subject to deferred token processing). +** Or, if bOptOk is non-zero, then one or more tokens within the expression +** may be loaded incrementally, meaning doclist.aAll/nAll is not available. +** +** If an error occurs within this function, *pRc is set to an SQLite error +** code before returning. +*/ +static void fts3EvalStartReaders( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Expr *pExpr, /* Expression to initialize phrases in */ + int *pRc /* IN/OUT: Error code */ +){ + if( pExpr && SQLITE_OK==*pRc ){ + if( pExpr->eType==FTSQUERY_PHRASE ){ + int nToken = pExpr->pPhrase->nToken; + if( nToken ){ + int i; + for(i=0; ipPhrase->aToken[i].pDeferred==0 ) break; + } + pExpr->bDeferred = (i==nToken); + } + *pRc = fts3EvalPhraseStart(pCsr, 1, pExpr->pPhrase); + }else{ + fts3EvalStartReaders(pCsr, pExpr->pLeft, pRc); + fts3EvalStartReaders(pCsr, pExpr->pRight, pRc); + pExpr->bDeferred = (pExpr->pLeft->bDeferred && pExpr->pRight->bDeferred); + } + } +} + +/* +** An array of the following structures is assembled as part of the process +** of selecting tokens to defer before the query starts executing (as part +** of the xFilter() method). There is one element in the array for each +** token in the FTS expression. +** +** Tokens are divided into AND/NEAR clusters. All tokens in a cluster belong +** to phrases that are connected only by AND and NEAR operators (not OR or +** NOT). When determining tokens to defer, each AND/NEAR cluster is considered +** separately. The root of a tokens AND/NEAR cluster is stored in +** Fts3TokenAndCost.pRoot. +*/ +typedef struct Fts3TokenAndCost Fts3TokenAndCost; +struct Fts3TokenAndCost { + Fts3Phrase *pPhrase; /* The phrase the token belongs to */ + int iToken; /* Position of token in phrase */ + Fts3PhraseToken *pToken; /* The token itself */ + Fts3Expr *pRoot; /* Root of NEAR/AND cluster */ + int nOvfl; /* Number of overflow pages to load doclist */ + int iCol; /* The column the token must match */ +}; + +/* +** This function is used to populate an allocated Fts3TokenAndCost array. +** +** If *pRc is not SQLITE_OK when this function is called, it is a no-op. +** Otherwise, if an error occurs during execution, *pRc is set to an +** SQLite error code. +*/ +static void fts3EvalTokenCosts( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Expr *pRoot, /* Root of current AND/NEAR cluster */ + Fts3Expr *pExpr, /* Expression to consider */ + Fts3TokenAndCost **ppTC, /* Write new entries to *(*ppTC)++ */ + Fts3Expr ***ppOr, /* Write new OR root to *(*ppOr)++ */ + int *pRc /* IN/OUT: Error code */ +){ + if( *pRc==SQLITE_OK ){ + if( pExpr->eType==FTSQUERY_PHRASE ){ + Fts3Phrase *pPhrase = pExpr->pPhrase; + int i; + for(i=0; *pRc==SQLITE_OK && inToken; i++){ + Fts3TokenAndCost *pTC = (*ppTC)++; + pTC->pPhrase = pPhrase; + pTC->iToken = i; + pTC->pRoot = pRoot; + pTC->pToken = &pPhrase->aToken[i]; + pTC->iCol = pPhrase->iColumn; + *pRc = sqlite3Fts3MsrOvfl(pCsr, pTC->pToken->pSegcsr, &pTC->nOvfl); + } + }else if( pExpr->eType!=FTSQUERY_NOT ){ + assert( pExpr->eType==FTSQUERY_OR + || pExpr->eType==FTSQUERY_AND + || pExpr->eType==FTSQUERY_NEAR + ); + assert( pExpr->pLeft && pExpr->pRight ); + if( pExpr->eType==FTSQUERY_OR ){ + pRoot = pExpr->pLeft; + **ppOr = pRoot; + (*ppOr)++; + } + fts3EvalTokenCosts(pCsr, pRoot, pExpr->pLeft, ppTC, ppOr, pRc); + if( pExpr->eType==FTSQUERY_OR ){ + pRoot = pExpr->pRight; + **ppOr = pRoot; + (*ppOr)++; + } + fts3EvalTokenCosts(pCsr, pRoot, pExpr->pRight, ppTC, ppOr, pRc); + } + } +} + +/* +** Determine the average document (row) size in pages. If successful, +** write this value to *pnPage and return SQLITE_OK. Otherwise, return +** an SQLite error code. +** +** The average document size in pages is calculated by first calculating +** determining the average size in bytes, B. If B is less than the amount +** of data that will fit on a single leaf page of an intkey table in +** this database, then the average docsize is 1. Otherwise, it is 1 plus +** the number of overflow pages consumed by a record B bytes in size. +*/ +static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){ + if( pCsr->nRowAvg==0 ){ + /* The average document size, which is required to calculate the cost + ** of each doclist, has not yet been determined. Read the required + ** data from the %_stat table to calculate it. + ** + ** Entry 0 of the %_stat table is a blob containing (nCol+1) FTS3 + ** varints, where nCol is the number of columns in the FTS3 table. + ** The first varint is the number of documents currently stored in + ** the table. The following nCol varints contain the total amount of + ** data stored in all rows of each column of the table, from left + ** to right. + */ + int rc; + Fts3Table *p = (Fts3Table*)pCsr->base.pVtab; + sqlite3_stmt *pStmt; + sqlite3_int64 nDoc = 0; + sqlite3_int64 nByte = 0; + const char *pEnd; + const char *a; + + rc = sqlite3Fts3SelectDoctotal(p, &pStmt); + if( rc!=SQLITE_OK ) return rc; + a = sqlite3_column_blob(pStmt, 0); + assert( a ); + + pEnd = &a[sqlite3_column_bytes(pStmt, 0)]; + a += sqlite3Fts3GetVarint(a, &nDoc); + while( anDoc = nDoc; + pCsr->nRowAvg = (int)(((nByte / nDoc) + p->nPgsz) / p->nPgsz); + assert( pCsr->nRowAvg>0 ); + rc = sqlite3_reset(pStmt); + if( rc!=SQLITE_OK ) return rc; + } + + *pnPage = pCsr->nRowAvg; + return SQLITE_OK; +} + +/* +** This function is called to select the tokens (if any) that will be +** deferred. The array aTC[] has already been populated when this is +** called. +** +** This function is called once for each AND/NEAR cluster in the +** expression. Each invocation determines which tokens to defer within +** the cluster with root node pRoot. See comments above the definition +** of struct Fts3TokenAndCost for more details. +** +** If no error occurs, SQLITE_OK is returned and sqlite3Fts3DeferToken() +** called on each token to defer. Otherwise, an SQLite error code is +** returned. +*/ +static int fts3EvalSelectDeferred( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Expr *pRoot, /* Consider tokens with this root node */ + Fts3TokenAndCost *aTC, /* Array of expression tokens and costs */ + int nTC /* Number of entries in aTC[] */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int nDocSize = 0; /* Number of pages per doc loaded */ + int rc = SQLITE_OK; /* Return code */ + int ii; /* Iterator variable for various purposes */ + int nOvfl = 0; /* Total overflow pages used by doclists */ + int nToken = 0; /* Total number of tokens in cluster */ + + int nMinEst = 0; /* The minimum count for any phrase so far. */ + int nLoad4 = 1; /* (Phrases that will be loaded)^4. */ + + /* Tokens are never deferred for FTS tables created using the content=xxx + ** option. The reason being that it is not guaranteed that the content + ** table actually contains the same data as the index. To prevent this from + ** causing any problems, the deferred token optimization is completely + ** disabled for content=xxx tables. */ + if( pTab->zContentTbl ){ + return SQLITE_OK; + } + + /* Count the tokens in this AND/NEAR cluster. If none of the doclists + ** associated with the tokens spill onto overflow pages, or if there is + ** only 1 token, exit early. No tokens to defer in this case. */ + for(ii=0; ii0 ); + + + /* Iterate through all tokens in this AND/NEAR cluster, in ascending order + ** of the number of overflow pages that will be loaded by the pager layer + ** to retrieve the entire doclist for the token from the full-text index. + ** Load the doclists for tokens that are either: + ** + ** a. The cheapest token in the entire query (i.e. the one visited by the + ** first iteration of this loop), or + ** + ** b. Part of a multi-token phrase. + ** + ** After each token doclist is loaded, merge it with the others from the + ** same phrase and count the number of documents that the merged doclist + ** contains. Set variable "nMinEst" to the smallest number of documents in + ** any phrase doclist for which 1 or more token doclists have been loaded. + ** Let nOther be the number of other phrases for which it is certain that + ** one or more tokens will not be deferred. + ** + ** Then, for each token, defer it if loading the doclist would result in + ** loading N or more overflow pages into memory, where N is computed as: + ** + ** (nMinEst + 4^nOther - 1) / (4^nOther) + */ + for(ii=0; iinOvfl) + ){ + pTC = &aTC[iTC]; + } + } + assert( pTC ); + + if( ii && pTC->nOvfl>=((nMinEst+(nLoad4/4)-1)/(nLoad4/4))*nDocSize ){ + /* The number of overflow pages to load for this (and therefore all + ** subsequent) tokens is greater than the estimated number of pages + ** that will be loaded if all subsequent tokens are deferred. + */ + Fts3PhraseToken *pToken = pTC->pToken; + rc = sqlite3Fts3DeferToken(pCsr, pToken, pTC->iCol); + fts3SegReaderCursorFree(pToken->pSegcsr); + pToken->pSegcsr = 0; + }else{ + /* Set nLoad4 to the value of (4^nOther) for the next iteration of the + ** for-loop. Except, limit the value to 2^24 to prevent it from + ** overflowing the 32-bit integer it is stored in. */ + if( ii<12 ) nLoad4 = nLoad4*4; + + if( ii==0 || (pTC->pPhrase->nToken>1 && ii!=nToken-1) ){ + /* Either this is the cheapest token in the entire query, or it is + ** part of a multi-token phrase. Either way, the entire doclist will + ** (eventually) be loaded into memory. It may as well be now. */ + Fts3PhraseToken *pToken = pTC->pToken; + int nList = 0; + char *pList = 0; + rc = fts3TermSelect(pTab, pToken, pTC->iCol, &nList, &pList); + assert( rc==SQLITE_OK || pList==0 ); + if( rc==SQLITE_OK ){ + rc = fts3EvalPhraseMergeToken( + pTab, pTC->pPhrase, pTC->iToken,pList,nList + ); + } + if( rc==SQLITE_OK ){ + int nCount; + nCount = fts3DoclistCountDocids( + pTC->pPhrase->doclist.aAll, pTC->pPhrase->doclist.nAll + ); + if( ii==0 || nCountpToken = 0; + } + + return rc; +} + +/* +** This function is called from within the xFilter method. It initializes +** the full-text query currently stored in pCsr->pExpr. To iterate through +** the results of a query, the caller does: +** +** fts3EvalStart(pCsr); +** while( 1 ){ +** fts3EvalNext(pCsr); +** if( pCsr->bEof ) break; +** ... return row pCsr->iPrevId to the caller ... +** } +*/ +static int fts3EvalStart(Fts3Cursor *pCsr){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int rc = SQLITE_OK; + int nToken = 0; + int nOr = 0; + + /* Allocate a MultiSegReader for each token in the expression. */ + fts3EvalAllocateReaders(pCsr, pCsr->pExpr, &nToken, &nOr, &rc); + + /* Determine which, if any, tokens in the expression should be deferred. */ +#ifndef SQLITE_DISABLE_FTS4_DEFERRED + if( rc==SQLITE_OK && nToken>1 && pTab->bFts4 ){ + Fts3TokenAndCost *aTC; + Fts3Expr **apOr; + aTC = (Fts3TokenAndCost *)sqlite3_malloc( + sizeof(Fts3TokenAndCost) * nToken + + sizeof(Fts3Expr *) * nOr * 2 + ); + apOr = (Fts3Expr **)&aTC[nToken]; + + if( !aTC ){ + rc = SQLITE_NOMEM; + }else{ + int ii; + Fts3TokenAndCost *pTC = aTC; + Fts3Expr **ppOr = apOr; + + fts3EvalTokenCosts(pCsr, 0, pCsr->pExpr, &pTC, &ppOr, &rc); + nToken = (int)(pTC-aTC); + nOr = (int)(ppOr-apOr); + + if( rc==SQLITE_OK ){ + rc = fts3EvalSelectDeferred(pCsr, 0, aTC, nToken); + for(ii=0; rc==SQLITE_OK && iipExpr, &rc); + return rc; +} + +/* +** Invalidate the current position list for phrase pPhrase. +*/ +static void fts3EvalInvalidatePoslist(Fts3Phrase *pPhrase){ + if( pPhrase->doclist.bFreeList ){ + sqlite3_free(pPhrase->doclist.pList); + } + pPhrase->doclist.pList = 0; + pPhrase->doclist.nList = 0; + pPhrase->doclist.bFreeList = 0; +} + +/* +** This function is called to edit the position list associated with +** the phrase object passed as the fifth argument according to a NEAR +** condition. For example: +** +** abc NEAR/5 "def ghi" +** +** Parameter nNear is passed the NEAR distance of the expression (5 in +** the example above). When this function is called, *paPoslist points to +** the position list, and *pnToken is the number of phrase tokens in, the +** phrase on the other side of the NEAR operator to pPhrase. For example, +** if pPhrase refers to the "def ghi" phrase, then *paPoslist points to +** the position list associated with phrase "abc". +** +** All positions in the pPhrase position list that are not sufficiently +** close to a position in the *paPoslist position list are removed. If this +** leaves 0 positions, zero is returned. Otherwise, non-zero. +** +** Before returning, *paPoslist is set to point to the position lsit +** associated with pPhrase. And *pnToken is set to the number of tokens in +** pPhrase. +*/ +static int fts3EvalNearTrim( + int nNear, /* NEAR distance. As in "NEAR/nNear". */ + char *aTmp, /* Temporary space to use */ + char **paPoslist, /* IN/OUT: Position list */ + int *pnToken, /* IN/OUT: Tokens in phrase of *paPoslist */ + Fts3Phrase *pPhrase /* The phrase object to trim the doclist of */ +){ + int nParam1 = nNear + pPhrase->nToken; + int nParam2 = nNear + *pnToken; + int nNew; + char *p2; + char *pOut; + int res; + + assert( pPhrase->doclist.pList ); + + p2 = pOut = pPhrase->doclist.pList; + res = fts3PoslistNearMerge( + &pOut, aTmp, nParam1, nParam2, paPoslist, &p2 + ); + if( res ){ + nNew = (int)(pOut - pPhrase->doclist.pList) - 1; + assert( pPhrase->doclist.pList[nNew]=='\0' ); + assert( nNew<=pPhrase->doclist.nList && nNew>0 ); + memset(&pPhrase->doclist.pList[nNew], 0, pPhrase->doclist.nList - nNew); + pPhrase->doclist.nList = nNew; + *paPoslist = pPhrase->doclist.pList; + *pnToken = pPhrase->nToken; + } + + return res; +} + +/* +** This function is a no-op if *pRc is other than SQLITE_OK when it is called. +** Otherwise, it advances the expression passed as the second argument to +** point to the next matching row in the database. Expressions iterate through +** matching rows in docid order. Ascending order if Fts3Cursor.bDesc is zero, +** or descending if it is non-zero. +** +** If an error occurs, *pRc is set to an SQLite error code. Otherwise, if +** successful, the following variables in pExpr are set: +** +** Fts3Expr.bEof (non-zero if EOF - there is no next row) +** Fts3Expr.iDocid (valid if bEof==0. The docid of the next row) +** +** If the expression is of type FTSQUERY_PHRASE, and the expression is not +** at EOF, then the following variables are populated with the position list +** for the phrase for the visited row: +** +** FTs3Expr.pPhrase->doclist.nList (length of pList in bytes) +** FTs3Expr.pPhrase->doclist.pList (pointer to position list) +** +** It says above that this function advances the expression to the next +** matching row. This is usually true, but there are the following exceptions: +** +** 1. Deferred tokens are not taken into account. If a phrase consists +** entirely of deferred tokens, it is assumed to match every row in +** the db. In this case the position-list is not populated at all. +** +** Or, if a phrase contains one or more deferred tokens and one or +** more non-deferred tokens, then the expression is advanced to the +** next possible match, considering only non-deferred tokens. In other +** words, if the phrase is "A B C", and "B" is deferred, the expression +** is advanced to the next row that contains an instance of "A * C", +** where "*" may match any single token. The position list in this case +** is populated as for "A * C" before returning. +** +** 2. NEAR is treated as AND. If the expression is "x NEAR y", it is +** advanced to point to the next row that matches "x AND y". +** +** See fts3EvalTestDeferredAndNear() for details on testing if a row is +** really a match, taking into account deferred tokens and NEAR operators. +*/ +static void fts3EvalNextRow( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Expr *pExpr, /* Expr. to advance to next matching row */ + int *pRc /* IN/OUT: Error code */ +){ + if( *pRc==SQLITE_OK ){ + int bDescDoclist = pCsr->bDesc; /* Used by DOCID_CMP() macro */ + assert( pExpr->bEof==0 ); + pExpr->bStart = 1; + + switch( pExpr->eType ){ + case FTSQUERY_NEAR: + case FTSQUERY_AND: { + Fts3Expr *pLeft = pExpr->pLeft; + Fts3Expr *pRight = pExpr->pRight; + assert( !pLeft->bDeferred || !pRight->bDeferred ); + + if( pLeft->bDeferred ){ + /* LHS is entirely deferred. So we assume it matches every row. + ** Advance the RHS iterator to find the next row visited. */ + fts3EvalNextRow(pCsr, pRight, pRc); + pExpr->iDocid = pRight->iDocid; + pExpr->bEof = pRight->bEof; + }else if( pRight->bDeferred ){ + /* RHS is entirely deferred. So we assume it matches every row. + ** Advance the LHS iterator to find the next row visited. */ + fts3EvalNextRow(pCsr, pLeft, pRc); + pExpr->iDocid = pLeft->iDocid; + pExpr->bEof = pLeft->bEof; + }else{ + /* Neither the RHS or LHS are deferred. */ + fts3EvalNextRow(pCsr, pLeft, pRc); + fts3EvalNextRow(pCsr, pRight, pRc); + while( !pLeft->bEof && !pRight->bEof && *pRc==SQLITE_OK ){ + sqlite3_int64 iDiff = DOCID_CMP(pLeft->iDocid, pRight->iDocid); + if( iDiff==0 ) break; + if( iDiff<0 ){ + fts3EvalNextRow(pCsr, pLeft, pRc); + }else{ + fts3EvalNextRow(pCsr, pRight, pRc); + } + } + pExpr->iDocid = pLeft->iDocid; + pExpr->bEof = (pLeft->bEof || pRight->bEof); + if( pExpr->eType==FTSQUERY_NEAR && pExpr->bEof ){ + if( pRight->pPhrase && pRight->pPhrase->doclist.aAll ){ + Fts3Doclist *pDl = &pRight->pPhrase->doclist; + while( *pRc==SQLITE_OK && pRight->bEof==0 ){ + memset(pDl->pList, 0, pDl->nList); + fts3EvalNextRow(pCsr, pRight, pRc); + } + } + if( pLeft->pPhrase && pLeft->pPhrase->doclist.aAll ){ + Fts3Doclist *pDl = &pLeft->pPhrase->doclist; + while( *pRc==SQLITE_OK && pLeft->bEof==0 ){ + memset(pDl->pList, 0, pDl->nList); + fts3EvalNextRow(pCsr, pLeft, pRc); + } + } + } + } + break; + } + + case FTSQUERY_OR: { + Fts3Expr *pLeft = pExpr->pLeft; + Fts3Expr *pRight = pExpr->pRight; + sqlite3_int64 iCmp = DOCID_CMP(pLeft->iDocid, pRight->iDocid); + + assert( pLeft->bStart || pLeft->iDocid==pRight->iDocid ); + assert( pRight->bStart || pLeft->iDocid==pRight->iDocid ); + + if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){ + fts3EvalNextRow(pCsr, pLeft, pRc); + }else if( pLeft->bEof || (pRight->bEof==0 && iCmp>0) ){ + fts3EvalNextRow(pCsr, pRight, pRc); + }else{ + fts3EvalNextRow(pCsr, pLeft, pRc); + fts3EvalNextRow(pCsr, pRight, pRc); + } + + pExpr->bEof = (pLeft->bEof && pRight->bEof); + iCmp = DOCID_CMP(pLeft->iDocid, pRight->iDocid); + if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){ + pExpr->iDocid = pLeft->iDocid; + }else{ + pExpr->iDocid = pRight->iDocid; + } + + break; + } + + case FTSQUERY_NOT: { + Fts3Expr *pLeft = pExpr->pLeft; + Fts3Expr *pRight = pExpr->pRight; + + if( pRight->bStart==0 ){ + fts3EvalNextRow(pCsr, pRight, pRc); + assert( *pRc!=SQLITE_OK || pRight->bStart ); + } + + fts3EvalNextRow(pCsr, pLeft, pRc); + if( pLeft->bEof==0 ){ + while( !*pRc + && !pRight->bEof + && DOCID_CMP(pLeft->iDocid, pRight->iDocid)>0 + ){ + fts3EvalNextRow(pCsr, pRight, pRc); + } + } + pExpr->iDocid = pLeft->iDocid; + pExpr->bEof = pLeft->bEof; + break; + } + + default: { + Fts3Phrase *pPhrase = pExpr->pPhrase; + fts3EvalInvalidatePoslist(pPhrase); + *pRc = fts3EvalPhraseNext(pCsr, pPhrase, &pExpr->bEof); + pExpr->iDocid = pPhrase->doclist.iDocid; + break; + } + } + } +} + +/* +** If *pRc is not SQLITE_OK, or if pExpr is not the root node of a NEAR +** cluster, then this function returns 1 immediately. +** +** Otherwise, it checks if the current row really does match the NEAR +** expression, using the data currently stored in the position lists +** (Fts3Expr->pPhrase.doclist.pList/nList) for each phrase in the expression. +** +** If the current row is a match, the position list associated with each +** phrase in the NEAR expression is edited in place to contain only those +** phrase instances sufficiently close to their peers to satisfy all NEAR +** constraints. In this case it returns 1. If the NEAR expression does not +** match the current row, 0 is returned. The position lists may or may not +** be edited if 0 is returned. +*/ +static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){ + int res = 1; + + /* The following block runs if pExpr is the root of a NEAR query. + ** For example, the query: + ** + ** "w" NEAR "x" NEAR "y" NEAR "z" + ** + ** which is represented in tree form as: + ** + ** | + ** +--NEAR--+ <-- root of NEAR query + ** | | + ** +--NEAR--+ "z" + ** | | + ** +--NEAR--+ "y" + ** | | + ** "w" "x" + ** + ** The right-hand child of a NEAR node is always a phrase. The + ** left-hand child may be either a phrase or a NEAR node. There are + ** no exceptions to this - it's the way the parser in fts3_expr.c works. + */ + if( *pRc==SQLITE_OK + && pExpr->eType==FTSQUERY_NEAR + && pExpr->bEof==0 + && (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR) + ){ + Fts3Expr *p; + int nTmp = 0; /* Bytes of temp space */ + char *aTmp; /* Temp space for PoslistNearMerge() */ + + /* Allocate temporary working space. */ + for(p=pExpr; p->pLeft; p=p->pLeft){ + nTmp += p->pRight->pPhrase->doclist.nList; + } + nTmp += p->pPhrase->doclist.nList; + if( nTmp==0 ){ + res = 0; + }else{ + aTmp = sqlite3_malloc(nTmp*2); + if( !aTmp ){ + *pRc = SQLITE_NOMEM; + res = 0; + }else{ + char *aPoslist = p->pPhrase->doclist.pList; + int nToken = p->pPhrase->nToken; + + for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){ + Fts3Phrase *pPhrase = p->pRight->pPhrase; + int nNear = p->nNear; + res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase); + } + + aPoslist = pExpr->pRight->pPhrase->doclist.pList; + nToken = pExpr->pRight->pPhrase->nToken; + for(p=pExpr->pLeft; p && res; p=p->pLeft){ + int nNear; + Fts3Phrase *pPhrase; + assert( p->pParent && p->pParent->pLeft==p ); + nNear = p->pParent->nNear; + pPhrase = ( + p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase + ); + res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase); + } + } + + sqlite3_free(aTmp); + } + } + + return res; +} + +/* +** This function is a helper function for fts3EvalTestDeferredAndNear(). +** Assuming no error occurs or has occurred, It returns non-zero if the +** expression passed as the second argument matches the row that pCsr +** currently points to, or zero if it does not. +** +** If *pRc is not SQLITE_OK when this function is called, it is a no-op. +** If an error occurs during execution of this function, *pRc is set to +** the appropriate SQLite error code. In this case the returned value is +** undefined. +*/ +static int fts3EvalTestExpr( + Fts3Cursor *pCsr, /* FTS cursor handle */ + Fts3Expr *pExpr, /* Expr to test. May or may not be root. */ + int *pRc /* IN/OUT: Error code */ +){ + int bHit = 1; /* Return value */ + if( *pRc==SQLITE_OK ){ + switch( pExpr->eType ){ + case FTSQUERY_NEAR: + case FTSQUERY_AND: + bHit = ( + fts3EvalTestExpr(pCsr, pExpr->pLeft, pRc) + && fts3EvalTestExpr(pCsr, pExpr->pRight, pRc) + && fts3EvalNearTest(pExpr, pRc) + ); + + /* If the NEAR expression does not match any rows, zero the doclist for + ** all phrases involved in the NEAR. This is because the snippet(), + ** offsets() and matchinfo() functions are not supposed to recognize + ** any instances of phrases that are part of unmatched NEAR queries. + ** For example if this expression: + ** + ** ... MATCH 'a OR (b NEAR c)' + ** + ** is matched against a row containing: + ** + ** 'a b d e' + ** + ** then any snippet() should ony highlight the "a" term, not the "b" + ** (as "b" is part of a non-matching NEAR clause). + */ + if( bHit==0 + && pExpr->eType==FTSQUERY_NEAR + && (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR) + ){ + Fts3Expr *p; + for(p=pExpr; p->pPhrase==0; p=p->pLeft){ + if( p->pRight->iDocid==pCsr->iPrevId ){ + fts3EvalInvalidatePoslist(p->pRight->pPhrase); + } + } + if( p->iDocid==pCsr->iPrevId ){ + fts3EvalInvalidatePoslist(p->pPhrase); + } + } + + break; + + case FTSQUERY_OR: { + int bHit1 = fts3EvalTestExpr(pCsr, pExpr->pLeft, pRc); + int bHit2 = fts3EvalTestExpr(pCsr, pExpr->pRight, pRc); + bHit = bHit1 || bHit2; + break; + } + + case FTSQUERY_NOT: + bHit = ( + fts3EvalTestExpr(pCsr, pExpr->pLeft, pRc) + && !fts3EvalTestExpr(pCsr, pExpr->pRight, pRc) + ); + break; + + default: { +#ifndef SQLITE_DISABLE_FTS4_DEFERRED + if( pCsr->pDeferred + && (pExpr->iDocid==pCsr->iPrevId || pExpr->bDeferred) + ){ + Fts3Phrase *pPhrase = pExpr->pPhrase; + assert( pExpr->bDeferred || pPhrase->doclist.bFreeList==0 ); + if( pExpr->bDeferred ){ + fts3EvalInvalidatePoslist(pPhrase); + } + *pRc = fts3EvalDeferredPhrase(pCsr, pPhrase); + bHit = (pPhrase->doclist.pList!=0); + pExpr->iDocid = pCsr->iPrevId; + }else +#endif + { + bHit = (pExpr->bEof==0 && pExpr->iDocid==pCsr->iPrevId); + } + break; + } + } + } + return bHit; +} + +/* +** This function is called as the second part of each xNext operation when +** iterating through the results of a full-text query. At this point the +** cursor points to a row that matches the query expression, with the +** following caveats: +** +** * Up until this point, "NEAR" operators in the expression have been +** treated as "AND". +** +** * Deferred tokens have not yet been considered. +** +** If *pRc is not SQLITE_OK when this function is called, it immediately +** returns 0. Otherwise, it tests whether or not after considering NEAR +** operators and deferred tokens the current row is still a match for the +** expression. It returns 1 if both of the following are true: +** +** 1. *pRc is SQLITE_OK when this function returns, and +** +** 2. After scanning the current FTS table row for the deferred tokens, +** it is determined that the row does *not* match the query. +** +** Or, if no error occurs and it seems the current row does match the FTS +** query, return 0. +*/ +static int fts3EvalTestDeferredAndNear(Fts3Cursor *pCsr, int *pRc){ + int rc = *pRc; + int bMiss = 0; + if( rc==SQLITE_OK ){ + + /* If there are one or more deferred tokens, load the current row into + ** memory and scan it to determine the position list for each deferred + ** token. Then, see if this row is really a match, considering deferred + ** tokens and NEAR operators (neither of which were taken into account + ** earlier, by fts3EvalNextRow()). + */ + if( pCsr->pDeferred ){ + rc = fts3CursorSeek(0, pCsr); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3CacheDeferredDoclists(pCsr); + } + } + bMiss = (0==fts3EvalTestExpr(pCsr, pCsr->pExpr, &rc)); + + /* Free the position-lists accumulated for each deferred token above. */ + sqlite3Fts3FreeDeferredDoclists(pCsr); + *pRc = rc; + } + return (rc==SQLITE_OK && bMiss); +} + +/* +** Advance to the next document that matches the FTS expression in +** Fts3Cursor.pExpr. +*/ +static int fts3EvalNext(Fts3Cursor *pCsr){ + int rc = SQLITE_OK; /* Return Code */ + Fts3Expr *pExpr = pCsr->pExpr; + assert( pCsr->isEof==0 ); + if( pExpr==0 ){ + pCsr->isEof = 1; + }else{ + do { + if( pCsr->isRequireSeek==0 ){ + sqlite3_reset(pCsr->pStmt); + } + assert( sqlite3_data_count(pCsr->pStmt)==0 ); + fts3EvalNextRow(pCsr, pExpr, &rc); + pCsr->isEof = pExpr->bEof; + pCsr->isRequireSeek = 1; + pCsr->isMatchinfoNeeded = 1; + pCsr->iPrevId = pExpr->iDocid; + }while( pCsr->isEof==0 && fts3EvalTestDeferredAndNear(pCsr, &rc) ); + } + + /* Check if the cursor is past the end of the docid range specified + ** by Fts3Cursor.iMinDocid/iMaxDocid. If so, set the EOF flag. */ + if( rc==SQLITE_OK && ( + (pCsr->bDesc==0 && pCsr->iPrevId>pCsr->iMaxDocid) + || (pCsr->bDesc!=0 && pCsr->iPrevIdiMinDocid) + )){ + pCsr->isEof = 1; + } + + return rc; +} + +/* +** Restart interation for expression pExpr so that the next call to +** fts3EvalNext() visits the first row. Do not allow incremental +** loading or merging of phrase doclists for this iteration. +** +** If *pRc is other than SQLITE_OK when this function is called, it is +** a no-op. If an error occurs within this function, *pRc is set to an +** SQLite error code before returning. +*/ +static void fts3EvalRestart( + Fts3Cursor *pCsr, + Fts3Expr *pExpr, + int *pRc +){ + if( pExpr && *pRc==SQLITE_OK ){ + Fts3Phrase *pPhrase = pExpr->pPhrase; + + if( pPhrase ){ + fts3EvalInvalidatePoslist(pPhrase); + if( pPhrase->bIncr ){ + int i; + for(i=0; inToken; i++){ + Fts3PhraseToken *pToken = &pPhrase->aToken[i]; + assert( pToken->pDeferred==0 ); + if( pToken->pSegcsr ){ + sqlite3Fts3MsrIncrRestart(pToken->pSegcsr); + } + } + *pRc = fts3EvalPhraseStart(pCsr, 0, pPhrase); + } + pPhrase->doclist.pNextDocid = 0; + pPhrase->doclist.iDocid = 0; + pPhrase->pOrPoslist = 0; + } + + pExpr->iDocid = 0; + pExpr->bEof = 0; + pExpr->bStart = 0; + + fts3EvalRestart(pCsr, pExpr->pLeft, pRc); + fts3EvalRestart(pCsr, pExpr->pRight, pRc); + } +} + +/* +** After allocating the Fts3Expr.aMI[] array for each phrase in the +** expression rooted at pExpr, the cursor iterates through all rows matched +** by pExpr, calling this function for each row. This function increments +** the values in Fts3Expr.aMI[] according to the position-list currently +** found in Fts3Expr.pPhrase->doclist.pList for each of the phrase +** expression nodes. +*/ +static void fts3EvalUpdateCounts(Fts3Expr *pExpr){ + if( pExpr ){ + Fts3Phrase *pPhrase = pExpr->pPhrase; + if( pPhrase && pPhrase->doclist.pList ){ + int iCol = 0; + char *p = pPhrase->doclist.pList; + + assert( *p ); + while( 1 ){ + u8 c = 0; + int iCnt = 0; + while( 0xFE & (*p | c) ){ + if( (c&0x80)==0 ) iCnt++; + c = *p++ & 0x80; + } + + /* aMI[iCol*3 + 1] = Number of occurrences + ** aMI[iCol*3 + 2] = Number of rows containing at least one instance + */ + pExpr->aMI[iCol*3 + 1] += iCnt; + pExpr->aMI[iCol*3 + 2] += (iCnt>0); + if( *p==0x00 ) break; + p++; + p += fts3GetVarint32(p, &iCol); + } + } + + fts3EvalUpdateCounts(pExpr->pLeft); + fts3EvalUpdateCounts(pExpr->pRight); + } +} + +/* +** Expression pExpr must be of type FTSQUERY_PHRASE. +** +** If it is not already allocated and populated, this function allocates and +** populates the Fts3Expr.aMI[] array for expression pExpr. If pExpr is part +** of a NEAR expression, then it also allocates and populates the same array +** for all other phrases that are part of the NEAR expression. +** +** SQLITE_OK is returned if the aMI[] array is successfully allocated and +** populated. Otherwise, if an error occurs, an SQLite error code is returned. +*/ +static int fts3EvalGatherStats( + Fts3Cursor *pCsr, /* Cursor object */ + Fts3Expr *pExpr /* FTSQUERY_PHRASE expression */ +){ + int rc = SQLITE_OK; /* Return code */ + + assert( pExpr->eType==FTSQUERY_PHRASE ); + if( pExpr->aMI==0 ){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + Fts3Expr *pRoot; /* Root of NEAR expression */ + Fts3Expr *p; /* Iterator used for several purposes */ + + sqlite3_int64 iPrevId = pCsr->iPrevId; + sqlite3_int64 iDocid; + u8 bEof; + + /* Find the root of the NEAR expression */ + pRoot = pExpr; + while( pRoot->pParent && pRoot->pParent->eType==FTSQUERY_NEAR ){ + pRoot = pRoot->pParent; + } + iDocid = pRoot->iDocid; + bEof = pRoot->bEof; + assert( pRoot->bStart ); + + /* Allocate space for the aMSI[] array of each FTSQUERY_PHRASE node */ + for(p=pRoot; p; p=p->pLeft){ + Fts3Expr *pE = (p->eType==FTSQUERY_PHRASE?p:p->pRight); + assert( pE->aMI==0 ); + pE->aMI = (u32 *)sqlite3_malloc(pTab->nColumn * 3 * sizeof(u32)); + if( !pE->aMI ) return SQLITE_NOMEM; + memset(pE->aMI, 0, pTab->nColumn * 3 * sizeof(u32)); + } + + fts3EvalRestart(pCsr, pRoot, &rc); + + while( pCsr->isEof==0 && rc==SQLITE_OK ){ + + do { + /* Ensure the %_content statement is reset. */ + if( pCsr->isRequireSeek==0 ) sqlite3_reset(pCsr->pStmt); + assert( sqlite3_data_count(pCsr->pStmt)==0 ); + + /* Advance to the next document */ + fts3EvalNextRow(pCsr, pRoot, &rc); + pCsr->isEof = pRoot->bEof; + pCsr->isRequireSeek = 1; + pCsr->isMatchinfoNeeded = 1; + pCsr->iPrevId = pRoot->iDocid; + }while( pCsr->isEof==0 + && pRoot->eType==FTSQUERY_NEAR + && fts3EvalTestDeferredAndNear(pCsr, &rc) + ); + + if( rc==SQLITE_OK && pCsr->isEof==0 ){ + fts3EvalUpdateCounts(pRoot); + } + } + + pCsr->isEof = 0; + pCsr->iPrevId = iPrevId; + + if( bEof ){ + pRoot->bEof = bEof; + }else{ + /* Caution: pRoot may iterate through docids in ascending or descending + ** order. For this reason, even though it seems more defensive, the + ** do loop can not be written: + ** + ** do {...} while( pRoot->iDocidbEof==0 ); + }while( pRoot->iDocid!=iDocid && rc==SQLITE_OK ); + fts3EvalTestDeferredAndNear(pCsr, &rc); + } + } + return rc; +} + +/* +** This function is used by the matchinfo() module to query a phrase +** expression node for the following information: +** +** 1. The total number of occurrences of the phrase in each column of +** the FTS table (considering all rows), and +** +** 2. For each column, the number of rows in the table for which the +** column contains at least one instance of the phrase. +** +** If no error occurs, SQLITE_OK is returned and the values for each column +** written into the array aiOut as follows: +** +** aiOut[iCol*3 + 1] = Number of occurrences +** aiOut[iCol*3 + 2] = Number of rows containing at least one instance +** +** Caveats: +** +** * If a phrase consists entirely of deferred tokens, then all output +** values are set to the number of documents in the table. In other +** words we assume that very common tokens occur exactly once in each +** column of each row of the table. +** +** * If a phrase contains some deferred tokens (and some non-deferred +** tokens), count the potential occurrence identified by considering +** the non-deferred tokens instead of actual phrase occurrences. +** +** * If the phrase is part of a NEAR expression, then only phrase instances +** that meet the NEAR constraint are included in the counts. +*/ +SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats( + Fts3Cursor *pCsr, /* FTS cursor handle */ + Fts3Expr *pExpr, /* Phrase expression */ + u32 *aiOut /* Array to write results into (see above) */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int rc = SQLITE_OK; + int iCol; + + if( pExpr->bDeferred && pExpr->pParent->eType!=FTSQUERY_NEAR ){ + assert( pCsr->nDoc>0 ); + for(iCol=0; iColnColumn; iCol++){ + aiOut[iCol*3 + 1] = (u32)pCsr->nDoc; + aiOut[iCol*3 + 2] = (u32)pCsr->nDoc; + } + }else{ + rc = fts3EvalGatherStats(pCsr, pExpr); + if( rc==SQLITE_OK ){ + assert( pExpr->aMI ); + for(iCol=0; iColnColumn; iCol++){ + aiOut[iCol*3 + 1] = pExpr->aMI[iCol*3 + 1]; + aiOut[iCol*3 + 2] = pExpr->aMI[iCol*3 + 2]; + } + } + } + + return rc; +} + +/* +** The expression pExpr passed as the second argument to this function +** must be of type FTSQUERY_PHRASE. +** +** The returned value is either NULL or a pointer to a buffer containing +** a position-list indicating the occurrences of the phrase in column iCol +** of the current row. +** +** More specifically, the returned buffer contains 1 varint for each +** occurrence of the phrase in the column, stored using the normal (delta+2) +** compression and is terminated by either an 0x01 or 0x00 byte. For example, +** if the requested column contains "a b X c d X X" and the position-list +** for 'X' is requested, the buffer returned may contain: +** +** 0x04 0x05 0x03 0x01 or 0x04 0x05 0x03 0x00 +** +** This function works regardless of whether or not the phrase is deferred, +** incremental, or neither. +*/ +SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist( + Fts3Cursor *pCsr, /* FTS3 cursor object */ + Fts3Expr *pExpr, /* Phrase to return doclist for */ + int iCol, /* Column to return position list for */ + char **ppOut /* OUT: Pointer to position list */ +){ + Fts3Phrase *pPhrase = pExpr->pPhrase; + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + char *pIter; + int iThis; + sqlite3_int64 iDocid; + + /* If this phrase is applies specifically to some column other than + ** column iCol, return a NULL pointer. */ + *ppOut = 0; + assert( iCol>=0 && iColnColumn ); + if( (pPhrase->iColumnnColumn && pPhrase->iColumn!=iCol) ){ + return SQLITE_OK; + } + + iDocid = pExpr->iDocid; + pIter = pPhrase->doclist.pList; + if( iDocid!=pCsr->iPrevId || pExpr->bEof ){ + int rc = SQLITE_OK; + int bDescDoclist = pTab->bDescIdx; /* For DOCID_CMP macro */ + int bOr = 0; + u8 bEof = 0; + u8 bTreeEof = 0; + Fts3Expr *p; /* Used to iterate from pExpr to root */ + Fts3Expr *pNear; /* Most senior NEAR ancestor (or pExpr) */ + + /* Check if this phrase descends from an OR expression node. If not, + ** return NULL. Otherwise, the entry that corresponds to docid + ** pCsr->iPrevId may lie earlier in the doclist buffer. Or, if the + ** tree that the node is part of has been marked as EOF, but the node + ** itself is not EOF, then it may point to an earlier entry. */ + pNear = pExpr; + for(p=pExpr->pParent; p; p=p->pParent){ + if( p->eType==FTSQUERY_OR ) bOr = 1; + if( p->eType==FTSQUERY_NEAR ) pNear = p; + if( p->bEof ) bTreeEof = 1; + } + if( bOr==0 ) return SQLITE_OK; + + /* This is the descendent of an OR node. In this case we cannot use + ** an incremental phrase. Load the entire doclist for the phrase + ** into memory in this case. */ + if( pPhrase->bIncr ){ + int bEofSave = pNear->bEof; + fts3EvalRestart(pCsr, pNear, &rc); + while( rc==SQLITE_OK && !pNear->bEof ){ + fts3EvalNextRow(pCsr, pNear, &rc); + if( bEofSave==0 && pNear->iDocid==iDocid ) break; + } + assert( rc!=SQLITE_OK || pPhrase->bIncr==0 ); + } + if( bTreeEof ){ + while( rc==SQLITE_OK && !pNear->bEof ){ + fts3EvalNextRow(pCsr, pNear, &rc); + } + } + if( rc!=SQLITE_OK ) return rc; + + pIter = pPhrase->pOrPoslist; + iDocid = pPhrase->iOrDocid; + if( pCsr->bDesc==bDescDoclist ){ + bEof = !pPhrase->doclist.nAll || + (pIter >= (pPhrase->doclist.aAll + pPhrase->doclist.nAll)); + while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){ + sqlite3Fts3DoclistNext( + bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, + &pIter, &iDocid, &bEof + ); + } + }else{ + bEof = !pPhrase->doclist.nAll || (pIter && pIter<=pPhrase->doclist.aAll); + while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){ + int dummy; + sqlite3Fts3DoclistPrev( + bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, + &pIter, &iDocid, &dummy, &bEof + ); + } + } + pPhrase->pOrPoslist = pIter; + pPhrase->iOrDocid = iDocid; + + if( bEof || iDocid!=pCsr->iPrevId ) pIter = 0; + } + if( pIter==0 ) return SQLITE_OK; + + if( *pIter==0x01 ){ + pIter++; + pIter += fts3GetVarint32(pIter, &iThis); + }else{ + iThis = 0; + } + while( iThisdoclist, and +** * any Fts3MultiSegReader objects held by phrase tokens. +*/ +SQLITE_PRIVATE void sqlite3Fts3EvalPhraseCleanup(Fts3Phrase *pPhrase){ + if( pPhrase ){ + int i; + sqlite3_free(pPhrase->doclist.aAll); + fts3EvalInvalidatePoslist(pPhrase); + memset(&pPhrase->doclist, 0, sizeof(Fts3Doclist)); + for(i=0; inToken; i++){ + fts3SegReaderCursorFree(pPhrase->aToken[i].pSegcsr); + pPhrase->aToken[i].pSegcsr = 0; + } + } +} + + +/* +** Return SQLITE_CORRUPT_VTAB. +*/ +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3Fts3Corrupt(){ + return SQLITE_CORRUPT_VTAB; +} +#endif + +#if !SQLITE_CORE +/* +** Initialize API pointer table, if required. +*/ +#ifdef _WIN32 +__declspec(dllexport) +#endif +SQLITE_API int SQLITE_STDCALL sqlite3_fts3_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + SQLITE_EXTENSION_INIT2(pApi) + return sqlite3Fts3Init(db); +} +#endif + +#endif + +/************** End of fts3.c ************************************************/ +/************** Begin file fts3_aux.c ****************************************/ +/* +** 2011 Jan 27 +** +** 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. +** +****************************************************************************** +** +*/ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ + +typedef struct Fts3auxTable Fts3auxTable; +typedef struct Fts3auxCursor Fts3auxCursor; + +struct Fts3auxTable { + sqlite3_vtab base; /* Base class used by SQLite core */ + Fts3Table *pFts3Tab; +}; + +struct Fts3auxCursor { + sqlite3_vtab_cursor base; /* Base class used by SQLite core */ + Fts3MultiSegReader csr; /* Must be right after "base" */ + Fts3SegFilter filter; + char *zStop; + int nStop; /* Byte-length of string zStop */ + int iLangid; /* Language id to query */ + int isEof; /* True if cursor is at EOF */ + sqlite3_int64 iRowid; /* Current rowid */ + + int iCol; /* Current value of 'col' column */ + int nStat; /* Size of aStat[] array */ + struct Fts3auxColstats { + sqlite3_int64 nDoc; /* 'documents' values for current csr row */ + sqlite3_int64 nOcc; /* 'occurrences' values for current csr row */ + } *aStat; +}; + +/* +** Schema of the terms table. +*/ +#define FTS3_AUX_SCHEMA \ + "CREATE TABLE x(term, col, documents, occurrences, languageid HIDDEN)" + +/* +** This function does all the work for both the xConnect and xCreate methods. +** These tables have no persistent representation of their own, so xConnect +** and xCreate are identical operations. +*/ +static int fts3auxConnectMethod( + sqlite3 *db, /* Database connection */ + void *pUnused, /* Unused */ + int argc, /* Number of elements in argv array */ + const char * const *argv, /* xCreate/xConnect argument array */ + sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ + char **pzErr /* OUT: sqlite3_malloc'd error message */ +){ + char const *zDb; /* Name of database (e.g. "main") */ + char const *zFts3; /* Name of fts3 table */ + int nDb; /* Result of strlen(zDb) */ + int nFts3; /* Result of strlen(zFts3) */ + int nByte; /* Bytes of space to allocate here */ + int rc; /* value returned by declare_vtab() */ + Fts3auxTable *p; /* Virtual table object to return */ + + UNUSED_PARAMETER(pUnused); + + /* The user should invoke this in one of two forms: + ** + ** CREATE VIRTUAL TABLE xxx USING fts4aux(fts4-table); + ** CREATE VIRTUAL TABLE xxx USING fts4aux(fts4-table-db, fts4-table); + */ + if( argc!=4 && argc!=5 ) goto bad_args; + + zDb = argv[1]; + nDb = (int)strlen(zDb); + if( argc==5 ){ + if( nDb==4 && 0==sqlite3_strnicmp("temp", zDb, 4) ){ + zDb = argv[3]; + nDb = (int)strlen(zDb); + zFts3 = argv[4]; + }else{ + goto bad_args; + } + }else{ + zFts3 = argv[3]; + } + nFts3 = (int)strlen(zFts3); + + rc = sqlite3_declare_vtab(db, FTS3_AUX_SCHEMA); + if( rc!=SQLITE_OK ) return rc; + + nByte = sizeof(Fts3auxTable) + sizeof(Fts3Table) + nDb + nFts3 + 2; + p = (Fts3auxTable *)sqlite3_malloc(nByte); + if( !p ) return SQLITE_NOMEM; + memset(p, 0, nByte); + + p->pFts3Tab = (Fts3Table *)&p[1]; + p->pFts3Tab->zDb = (char *)&p->pFts3Tab[1]; + p->pFts3Tab->zName = &p->pFts3Tab->zDb[nDb+1]; + p->pFts3Tab->db = db; + p->pFts3Tab->nIndex = 1; + + memcpy((char *)p->pFts3Tab->zDb, zDb, nDb); + memcpy((char *)p->pFts3Tab->zName, zFts3, nFts3); + sqlite3Fts3Dequote((char *)p->pFts3Tab->zName); + + *ppVtab = (sqlite3_vtab *)p; + return SQLITE_OK; + + bad_args: + sqlite3Fts3ErrMsg(pzErr, "invalid arguments to fts4aux constructor"); + return SQLITE_ERROR; +} + +/* +** This function does the work for both the xDisconnect and xDestroy methods. +** These tables have no persistent representation of their own, so xDisconnect +** and xDestroy are identical operations. +*/ +static int fts3auxDisconnectMethod(sqlite3_vtab *pVtab){ + Fts3auxTable *p = (Fts3auxTable *)pVtab; + Fts3Table *pFts3 = p->pFts3Tab; + int i; + + /* Free any prepared statements held */ + for(i=0; iaStmt); i++){ + sqlite3_finalize(pFts3->aStmt[i]); + } + sqlite3_free(pFts3->zSegmentsTbl); + sqlite3_free(p); + return SQLITE_OK; +} + +#define FTS4AUX_EQ_CONSTRAINT 1 +#define FTS4AUX_GE_CONSTRAINT 2 +#define FTS4AUX_LE_CONSTRAINT 4 + +/* +** xBestIndex - Analyze a WHERE and ORDER BY clause. +*/ +static int fts3auxBestIndexMethod( + sqlite3_vtab *pVTab, + sqlite3_index_info *pInfo +){ + int i; + int iEq = -1; + int iGe = -1; + int iLe = -1; + int iLangid = -1; + int iNext = 1; /* Next free argvIndex value */ + + UNUSED_PARAMETER(pVTab); + + /* This vtab delivers always results in "ORDER BY term ASC" order. */ + if( pInfo->nOrderBy==1 + && pInfo->aOrderBy[0].iColumn==0 + && pInfo->aOrderBy[0].desc==0 + ){ + pInfo->orderByConsumed = 1; + } + + /* Search for equality and range constraints on the "term" column. + ** And equality constraints on the hidden "languageid" column. */ + for(i=0; inConstraint; i++){ + if( pInfo->aConstraint[i].usable ){ + int op = pInfo->aConstraint[i].op; + int iCol = pInfo->aConstraint[i].iColumn; + + if( iCol==0 ){ + if( op==SQLITE_INDEX_CONSTRAINT_EQ ) iEq = i; + if( op==SQLITE_INDEX_CONSTRAINT_LT ) iLe = i; + if( op==SQLITE_INDEX_CONSTRAINT_LE ) iLe = i; + if( op==SQLITE_INDEX_CONSTRAINT_GT ) iGe = i; + if( op==SQLITE_INDEX_CONSTRAINT_GE ) iGe = i; + } + if( iCol==4 ){ + if( op==SQLITE_INDEX_CONSTRAINT_EQ ) iLangid = i; + } + } + } + + if( iEq>=0 ){ + pInfo->idxNum = FTS4AUX_EQ_CONSTRAINT; + pInfo->aConstraintUsage[iEq].argvIndex = iNext++; + pInfo->estimatedCost = 5; + }else{ + pInfo->idxNum = 0; + pInfo->estimatedCost = 20000; + if( iGe>=0 ){ + pInfo->idxNum += FTS4AUX_GE_CONSTRAINT; + pInfo->aConstraintUsage[iGe].argvIndex = iNext++; + pInfo->estimatedCost /= 2; + } + if( iLe>=0 ){ + pInfo->idxNum += FTS4AUX_LE_CONSTRAINT; + pInfo->aConstraintUsage[iLe].argvIndex = iNext++; + pInfo->estimatedCost /= 2; + } + } + if( iLangid>=0 ){ + pInfo->aConstraintUsage[iLangid].argvIndex = iNext++; + pInfo->estimatedCost--; + } + + return SQLITE_OK; +} + +/* +** xOpen - Open a cursor. +*/ +static int fts3auxOpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ + Fts3auxCursor *pCsr; /* Pointer to cursor object to return */ + + UNUSED_PARAMETER(pVTab); + + pCsr = (Fts3auxCursor *)sqlite3_malloc(sizeof(Fts3auxCursor)); + if( !pCsr ) return SQLITE_NOMEM; + memset(pCsr, 0, sizeof(Fts3auxCursor)); + + *ppCsr = (sqlite3_vtab_cursor *)pCsr; + return SQLITE_OK; +} + +/* +** xClose - Close a cursor. +*/ +static int fts3auxCloseMethod(sqlite3_vtab_cursor *pCursor){ + Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; + Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; + + sqlite3Fts3SegmentsClose(pFts3); + sqlite3Fts3SegReaderFinish(&pCsr->csr); + sqlite3_free((void *)pCsr->filter.zTerm); + sqlite3_free(pCsr->zStop); + sqlite3_free(pCsr->aStat); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +static int fts3auxGrowStatArray(Fts3auxCursor *pCsr, int nSize){ + if( nSize>pCsr->nStat ){ + struct Fts3auxColstats *aNew; + aNew = (struct Fts3auxColstats *)sqlite3_realloc(pCsr->aStat, + sizeof(struct Fts3auxColstats) * nSize + ); + if( aNew==0 ) return SQLITE_NOMEM; + memset(&aNew[pCsr->nStat], 0, + sizeof(struct Fts3auxColstats) * (nSize - pCsr->nStat) + ); + pCsr->aStat = aNew; + pCsr->nStat = nSize; + } + return SQLITE_OK; +} + +/* +** xNext - Advance the cursor to the next row, if any. +*/ +static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){ + Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; + Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; + int rc; + + /* Increment our pretend rowid value. */ + pCsr->iRowid++; + + for(pCsr->iCol++; pCsr->iColnStat; pCsr->iCol++){ + if( pCsr->aStat[pCsr->iCol].nDoc>0 ) return SQLITE_OK; + } + + rc = sqlite3Fts3SegReaderStep(pFts3, &pCsr->csr); + if( rc==SQLITE_ROW ){ + int i = 0; + int nDoclist = pCsr->csr.nDoclist; + char *aDoclist = pCsr->csr.aDoclist; + int iCol; + + int eState = 0; + + if( pCsr->zStop ){ + int n = (pCsr->nStopcsr.nTerm) ? pCsr->nStop : pCsr->csr.nTerm; + int mc = memcmp(pCsr->zStop, pCsr->csr.zTerm, n); + if( mc<0 || (mc==0 && pCsr->csr.nTerm>pCsr->nStop) ){ + pCsr->isEof = 1; + return SQLITE_OK; + } + } + + if( fts3auxGrowStatArray(pCsr, 2) ) return SQLITE_NOMEM; + memset(pCsr->aStat, 0, sizeof(struct Fts3auxColstats) * pCsr->nStat); + iCol = 0; + + while( iaStat[0].nDoc++; + eState = 1; + iCol = 0; + break; + + /* State 1. In this state we are expecting either a 1, indicating + ** that the following integer will be a column number, or the + ** start of a position list for column 0. + ** + ** The only difference between state 1 and state 2 is that if the + ** integer encountered in state 1 is not 0 or 1, then we need to + ** increment the column 0 "nDoc" count for this term. + */ + case 1: + assert( iCol==0 ); + if( v>1 ){ + pCsr->aStat[1].nDoc++; + } + eState = 2; + /* fall through */ + + case 2: + if( v==0 ){ /* 0x00. Next integer will be a docid. */ + eState = 0; + }else if( v==1 ){ /* 0x01. Next integer will be a column number. */ + eState = 3; + }else{ /* 2 or greater. A position. */ + pCsr->aStat[iCol+1].nOcc++; + pCsr->aStat[0].nOcc++; + } + break; + + /* State 3. The integer just read is a column number. */ + default: assert( eState==3 ); + iCol = (int)v; + if( fts3auxGrowStatArray(pCsr, iCol+2) ) return SQLITE_NOMEM; + pCsr->aStat[iCol+1].nDoc++; + eState = 2; + break; + } + } + + pCsr->iCol = 0; + rc = SQLITE_OK; + }else{ + pCsr->isEof = 1; + } + return rc; +} + +/* +** xFilter - Initialize a cursor to point at the start of its data. +*/ +static int fts3auxFilterMethod( + sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ + int idxNum, /* Strategy index */ + const char *idxStr, /* Unused */ + int nVal, /* Number of elements in apVal */ + sqlite3_value **apVal /* Arguments for the indexing scheme */ +){ + Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; + Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; + int rc; + int isScan = 0; + int iLangVal = 0; /* Language id to query */ + + int iEq = -1; /* Index of term=? value in apVal */ + int iGe = -1; /* Index of term>=? value in apVal */ + int iLe = -1; /* Index of term<=? value in apVal */ + int iLangid = -1; /* Index of languageid=? value in apVal */ + int iNext = 0; + + UNUSED_PARAMETER(nVal); + UNUSED_PARAMETER(idxStr); + + assert( idxStr==0 ); + assert( idxNum==FTS4AUX_EQ_CONSTRAINT || idxNum==0 + || idxNum==FTS4AUX_LE_CONSTRAINT || idxNum==FTS4AUX_GE_CONSTRAINT + || idxNum==(FTS4AUX_LE_CONSTRAINT|FTS4AUX_GE_CONSTRAINT) + ); + + if( idxNum==FTS4AUX_EQ_CONSTRAINT ){ + iEq = iNext++; + }else{ + isScan = 1; + if( idxNum & FTS4AUX_GE_CONSTRAINT ){ + iGe = iNext++; + } + if( idxNum & FTS4AUX_LE_CONSTRAINT ){ + iLe = iNext++; + } + } + if( iNextfilter.zTerm); + sqlite3Fts3SegReaderFinish(&pCsr->csr); + sqlite3_free((void *)pCsr->filter.zTerm); + sqlite3_free(pCsr->aStat); + memset(&pCsr->csr, 0, ((u8*)&pCsr[1]) - (u8*)&pCsr->csr); + + pCsr->filter.flags = FTS3_SEGMENT_REQUIRE_POS|FTS3_SEGMENT_IGNORE_EMPTY; + if( isScan ) pCsr->filter.flags |= FTS3_SEGMENT_SCAN; + + if( iEq>=0 || iGe>=0 ){ + const unsigned char *zStr = sqlite3_value_text(apVal[0]); + assert( (iEq==0 && iGe==-1) || (iEq==-1 && iGe==0) ); + if( zStr ){ + pCsr->filter.zTerm = sqlite3_mprintf("%s", zStr); + pCsr->filter.nTerm = sqlite3_value_bytes(apVal[0]); + if( pCsr->filter.zTerm==0 ) return SQLITE_NOMEM; + } + } + + if( iLe>=0 ){ + pCsr->zStop = sqlite3_mprintf("%s", sqlite3_value_text(apVal[iLe])); + pCsr->nStop = sqlite3_value_bytes(apVal[iLe]); + if( pCsr->zStop==0 ) return SQLITE_NOMEM; + } + + if( iLangid>=0 ){ + iLangVal = sqlite3_value_int(apVal[iLangid]); + + /* If the user specified a negative value for the languageid, use zero + ** instead. This works, as the "languageid=?" constraint will also + ** be tested by the VDBE layer. The test will always be false (since + ** this module will not return a row with a negative languageid), and + ** so the overall query will return zero rows. */ + if( iLangVal<0 ) iLangVal = 0; + } + pCsr->iLangid = iLangVal; + + rc = sqlite3Fts3SegReaderCursor(pFts3, iLangVal, 0, FTS3_SEGCURSOR_ALL, + pCsr->filter.zTerm, pCsr->filter.nTerm, 0, isScan, &pCsr->csr + ); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3SegReaderStart(pFts3, &pCsr->csr, &pCsr->filter); + } + + if( rc==SQLITE_OK ) rc = fts3auxNextMethod(pCursor); + return rc; +} + +/* +** xEof - Return true if the cursor is at EOF, or false otherwise. +*/ +static int fts3auxEofMethod(sqlite3_vtab_cursor *pCursor){ + Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; + return pCsr->isEof; +} + +/* +** xColumn - Return a column value. +*/ +static int fts3auxColumnMethod( + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ + int iCol /* Index of column to read value from */ +){ + Fts3auxCursor *p = (Fts3auxCursor *)pCursor; + + assert( p->isEof==0 ); + switch( iCol ){ + case 0: /* term */ + sqlite3_result_text(pCtx, p->csr.zTerm, p->csr.nTerm, SQLITE_TRANSIENT); + break; + + case 1: /* col */ + if( p->iCol ){ + sqlite3_result_int(pCtx, p->iCol-1); + }else{ + sqlite3_result_text(pCtx, "*", -1, SQLITE_STATIC); + } + break; + + case 2: /* documents */ + sqlite3_result_int64(pCtx, p->aStat[p->iCol].nDoc); + break; + + case 3: /* occurrences */ + sqlite3_result_int64(pCtx, p->aStat[p->iCol].nOcc); + break; + + default: /* languageid */ + assert( iCol==4 ); + sqlite3_result_int(pCtx, p->iLangid); + break; + } + + return SQLITE_OK; +} + +/* +** xRowid - Return the current rowid for the cursor. +*/ +static int fts3auxRowidMethod( + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite_int64 *pRowid /* OUT: Rowid value */ +){ + Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; + *pRowid = pCsr->iRowid; + return SQLITE_OK; +} + +/* +** Register the fts3aux module with database connection db. Return SQLITE_OK +** if successful or an error code if sqlite3_create_module() fails. +*/ +SQLITE_PRIVATE int sqlite3Fts3InitAux(sqlite3 *db){ + static const sqlite3_module fts3aux_module = { + 0, /* iVersion */ + fts3auxConnectMethod, /* xCreate */ + fts3auxConnectMethod, /* xConnect */ + fts3auxBestIndexMethod, /* xBestIndex */ + fts3auxDisconnectMethod, /* xDisconnect */ + fts3auxDisconnectMethod, /* xDestroy */ + fts3auxOpenMethod, /* xOpen */ + fts3auxCloseMethod, /* xClose */ + fts3auxFilterMethod, /* xFilter */ + fts3auxNextMethod, /* xNext */ + fts3auxEofMethod, /* xEof */ + fts3auxColumnMethod, /* xColumn */ + fts3auxRowidMethod, /* xRowid */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindFunction */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0 /* xRollbackTo */ + }; + int rc; /* Return code */ + + rc = sqlite3_create_module(db, "fts4aux", &fts3aux_module, 0); + return rc; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_aux.c ********************************************/ +/************** Begin file fts3_expr.c ***************************************/ +/* +** 2008 Nov 28 +** +** 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 module contains code that implements a parser for fts3 query strings +** (the right-hand argument to the MATCH operator). Because the supported +** syntax is relatively simple, the whole tokenizer/parser system is +** hand-coded. +*/ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* +** By default, this module parses the legacy syntax that has been +** traditionally used by fts3. Or, if SQLITE_ENABLE_FTS3_PARENTHESIS +** is defined, then it uses the new syntax. The differences between +** the new and the old syntaxes are: +** +** a) The new syntax supports parenthesis. The old does not. +** +** b) The new syntax supports the AND and NOT operators. The old does not. +** +** c) The old syntax supports the "-" token qualifier. This is not +** supported by the new syntax (it is replaced by the NOT operator). +** +** d) When using the old syntax, the OR operator has a greater precedence +** than an implicit AND. When using the new, both implicity and explicit +** AND operators have a higher precedence than OR. +** +** If compiled with SQLITE_TEST defined, then this module exports the +** symbol "int sqlite3_fts3_enable_parentheses". Setting this variable +** to zero causes the module to use the old syntax. If it is set to +** non-zero the new syntax is activated. This is so both syntaxes can +** be tested using a single build of testfixture. +** +** The following describes the syntax supported by the fts3 MATCH +** operator in a similar format to that used by the lemon parser +** generator. This module does not use actually lemon, it uses a +** custom parser. +** +** query ::= andexpr (OR andexpr)*. +** +** andexpr ::= notexpr (AND? notexpr)*. +** +** notexpr ::= nearexpr (NOT nearexpr|-TOKEN)*. +** notexpr ::= LP query RP. +** +** nearexpr ::= phrase (NEAR distance_opt nearexpr)*. +** +** distance_opt ::= . +** distance_opt ::= / INTEGER. +** +** phrase ::= TOKEN. +** phrase ::= COLUMN:TOKEN. +** phrase ::= "TOKEN TOKEN TOKEN...". +*/ + +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_fts3_enable_parentheses = 0; +#else +# ifdef SQLITE_ENABLE_FTS3_PARENTHESIS +# define sqlite3_fts3_enable_parentheses 1 +# else +# define sqlite3_fts3_enable_parentheses 0 +# endif +#endif + +/* +** Default span for NEAR operators. +*/ +#define SQLITE_FTS3_DEFAULT_NEAR_PARAM 10 + +/* #include */ +/* #include */ + +/* +** isNot: +** This variable is used by function getNextNode(). When getNextNode() is +** called, it sets ParseContext.isNot to true if the 'next node' is a +** FTSQUERY_PHRASE with a unary "-" attached to it. i.e. "mysql" in the +** FTS3 query "sqlite -mysql". Otherwise, ParseContext.isNot is set to +** zero. +*/ +typedef struct ParseContext ParseContext; +struct ParseContext { + sqlite3_tokenizer *pTokenizer; /* Tokenizer module */ + int iLangid; /* Language id used with tokenizer */ + const char **azCol; /* Array of column names for fts3 table */ + int bFts4; /* True to allow FTS4-only syntax */ + int nCol; /* Number of entries in azCol[] */ + int iDefaultCol; /* Default column to query */ + int isNot; /* True if getNextNode() sees a unary - */ + sqlite3_context *pCtx; /* Write error message here */ + int nNest; /* Number of nested brackets */ +}; + +/* +** This function is equivalent to the standard isspace() function. +** +** The standard isspace() can be awkward to use safely, because although it +** is defined to accept an argument of type int, its behavior when passed +** an integer that falls outside of the range of the unsigned char type +** is undefined (and sometimes, "undefined" means segfault). This wrapper +** is defined to accept an argument of type char, and always returns 0 for +** any values that fall outside of the range of the unsigned char type (i.e. +** negative values). +*/ +static int fts3isspace(char c){ + return c==' ' || c=='\t' || c=='\n' || c=='\r' || c=='\v' || c=='\f'; +} + +/* +** Allocate nByte bytes of memory using sqlite3_malloc(). If successful, +** zero the memory before returning a pointer to it. If unsuccessful, +** return NULL. +*/ +static void *fts3MallocZero(int nByte){ + void *pRet = sqlite3_malloc(nByte); + if( pRet ) memset(pRet, 0, nByte); + return pRet; +} + +SQLITE_PRIVATE int sqlite3Fts3OpenTokenizer( + sqlite3_tokenizer *pTokenizer, + int iLangid, + const char *z, + int n, + sqlite3_tokenizer_cursor **ppCsr +){ + sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; + sqlite3_tokenizer_cursor *pCsr = 0; + int rc; + + rc = pModule->xOpen(pTokenizer, z, n, &pCsr); + assert( rc==SQLITE_OK || pCsr==0 ); + if( rc==SQLITE_OK ){ + pCsr->pTokenizer = pTokenizer; + if( pModule->iVersion>=1 ){ + rc = pModule->xLanguageid(pCsr, iLangid); + if( rc!=SQLITE_OK ){ + pModule->xClose(pCsr); + pCsr = 0; + } + } + } + *ppCsr = pCsr; + return rc; +} + +/* +** Function getNextNode(), which is called by fts3ExprParse(), may itself +** call fts3ExprParse(). So this forward declaration is required. +*/ +static int fts3ExprParse(ParseContext *, const char *, int, Fts3Expr **, int *); + +/* +** Extract the next token from buffer z (length n) using the tokenizer +** and other information (column names etc.) in pParse. Create an Fts3Expr +** structure of type FTSQUERY_PHRASE containing a phrase consisting of this +** single token and set *ppExpr to point to it. If the end of the buffer is +** reached before a token is found, set *ppExpr to zero. It is the +** responsibility of the caller to eventually deallocate the allocated +** Fts3Expr structure (if any) by passing it to sqlite3_free(). +** +** Return SQLITE_OK if successful, or SQLITE_NOMEM if a memory allocation +** fails. +*/ +static int getNextToken( + ParseContext *pParse, /* fts3 query parse context */ + int iCol, /* Value for Fts3Phrase.iColumn */ + const char *z, int n, /* Input string */ + Fts3Expr **ppExpr, /* OUT: expression */ + int *pnConsumed /* OUT: Number of bytes consumed */ +){ + sqlite3_tokenizer *pTokenizer = pParse->pTokenizer; + sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; + int rc; + sqlite3_tokenizer_cursor *pCursor; + Fts3Expr *pRet = 0; + int i = 0; + + /* Set variable i to the maximum number of bytes of input to tokenize. */ + for(i=0; iiLangid, z, i, &pCursor); + if( rc==SQLITE_OK ){ + const char *zToken; + int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0; + int nByte; /* total space to allocate */ + + rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition); + if( rc==SQLITE_OK ){ + nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken; + pRet = (Fts3Expr *)fts3MallocZero(nByte); + if( !pRet ){ + rc = SQLITE_NOMEM; + }else{ + pRet->eType = FTSQUERY_PHRASE; + pRet->pPhrase = (Fts3Phrase *)&pRet[1]; + pRet->pPhrase->nToken = 1; + pRet->pPhrase->iColumn = iCol; + pRet->pPhrase->aToken[0].n = nToken; + pRet->pPhrase->aToken[0].z = (char *)&pRet->pPhrase[1]; + memcpy(pRet->pPhrase->aToken[0].z, zToken, nToken); + + if( iEndpPhrase->aToken[0].isPrefix = 1; + iEnd++; + } + + while( 1 ){ + if( !sqlite3_fts3_enable_parentheses + && iStart>0 && z[iStart-1]=='-' + ){ + pParse->isNot = 1; + iStart--; + }else if( pParse->bFts4 && iStart>0 && z[iStart-1]=='^' ){ + pRet->pPhrase->aToken[0].bFirst = 1; + iStart--; + }else{ + break; + } + } + + } + *pnConsumed = iEnd; + }else if( i && rc==SQLITE_DONE ){ + rc = SQLITE_OK; + } + + pModule->xClose(pCursor); + } + + *ppExpr = pRet; + return rc; +} + + +/* +** Enlarge a memory allocation. If an out-of-memory allocation occurs, +** then free the old allocation. +*/ +static void *fts3ReallocOrFree(void *pOrig, int nNew){ + void *pRet = sqlite3_realloc(pOrig, nNew); + if( !pRet ){ + sqlite3_free(pOrig); + } + return pRet; +} + +/* +** Buffer zInput, length nInput, contains the contents of a quoted string +** that appeared as part of an fts3 query expression. Neither quote character +** is included in the buffer. This function attempts to tokenize the entire +** input buffer and create an Fts3Expr structure of type FTSQUERY_PHRASE +** containing the results. +** +** If successful, SQLITE_OK is returned and *ppExpr set to point at the +** allocated Fts3Expr structure. Otherwise, either SQLITE_NOMEM (out of memory +** error) or SQLITE_ERROR (tokenization error) is returned and *ppExpr set +** to 0. +*/ +static int getNextString( + ParseContext *pParse, /* fts3 query parse context */ + const char *zInput, int nInput, /* Input string */ + Fts3Expr **ppExpr /* OUT: expression */ +){ + sqlite3_tokenizer *pTokenizer = pParse->pTokenizer; + sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; + int rc; + Fts3Expr *p = 0; + sqlite3_tokenizer_cursor *pCursor = 0; + char *zTemp = 0; + int nTemp = 0; + + const int nSpace = sizeof(Fts3Expr) + sizeof(Fts3Phrase); + int nToken = 0; + + /* The final Fts3Expr data structure, including the Fts3Phrase, + ** Fts3PhraseToken structures token buffers are all stored as a single + ** allocation so that the expression can be freed with a single call to + ** sqlite3_free(). Setting this up requires a two pass approach. + ** + ** The first pass, in the block below, uses a tokenizer cursor to iterate + ** through the tokens in the expression. This pass uses fts3ReallocOrFree() + ** to assemble data in two dynamic buffers: + ** + ** Buffer p: Points to the Fts3Expr structure, followed by the Fts3Phrase + ** structure, followed by the array of Fts3PhraseToken + ** structures. This pass only populates the Fts3PhraseToken array. + ** + ** Buffer zTemp: Contains copies of all tokens. + ** + ** The second pass, in the block that begins "if( rc==SQLITE_DONE )" below, + ** appends buffer zTemp to buffer p, and fills in the Fts3Expr and Fts3Phrase + ** structures. + */ + rc = sqlite3Fts3OpenTokenizer( + pTokenizer, pParse->iLangid, zInput, nInput, &pCursor); + if( rc==SQLITE_OK ){ + int ii; + for(ii=0; rc==SQLITE_OK; ii++){ + const char *zByte; + int nByte = 0, iBegin = 0, iEnd = 0, iPos = 0; + rc = pModule->xNext(pCursor, &zByte, &nByte, &iBegin, &iEnd, &iPos); + if( rc==SQLITE_OK ){ + Fts3PhraseToken *pToken; + + p = fts3ReallocOrFree(p, nSpace + ii*sizeof(Fts3PhraseToken)); + if( !p ) goto no_mem; + + zTemp = fts3ReallocOrFree(zTemp, nTemp + nByte); + if( !zTemp ) goto no_mem; + + assert( nToken==ii ); + pToken = &((Fts3Phrase *)(&p[1]))->aToken[ii]; + memset(pToken, 0, sizeof(Fts3PhraseToken)); + + memcpy(&zTemp[nTemp], zByte, nByte); + nTemp += nByte; + + pToken->n = nByte; + pToken->isPrefix = (iEndbFirst = (iBegin>0 && zInput[iBegin-1]=='^'); + nToken = ii+1; + } + } + + pModule->xClose(pCursor); + pCursor = 0; + } + + if( rc==SQLITE_DONE ){ + int jj; + char *zBuf = 0; + + p = fts3ReallocOrFree(p, nSpace + nToken*sizeof(Fts3PhraseToken) + nTemp); + if( !p ) goto no_mem; + memset(p, 0, (char *)&(((Fts3Phrase *)&p[1])->aToken[0])-(char *)p); + p->eType = FTSQUERY_PHRASE; + p->pPhrase = (Fts3Phrase *)&p[1]; + p->pPhrase->iColumn = pParse->iDefaultCol; + p->pPhrase->nToken = nToken; + + zBuf = (char *)&p->pPhrase->aToken[nToken]; + if( zTemp ){ + memcpy(zBuf, zTemp, nTemp); + sqlite3_free(zTemp); + }else{ + assert( nTemp==0 ); + } + + for(jj=0; jjpPhrase->nToken; jj++){ + p->pPhrase->aToken[jj].z = zBuf; + zBuf += p->pPhrase->aToken[jj].n; + } + rc = SQLITE_OK; + } + + *ppExpr = p; + return rc; +no_mem: + + if( pCursor ){ + pModule->xClose(pCursor); + } + sqlite3_free(zTemp); + sqlite3_free(p); + *ppExpr = 0; + return SQLITE_NOMEM; +} + +/* +** The output variable *ppExpr is populated with an allocated Fts3Expr +** structure, or set to 0 if the end of the input buffer is reached. +** +** Returns an SQLite error code. SQLITE_OK if everything works, SQLITE_NOMEM +** if a malloc failure occurs, or SQLITE_ERROR if a parse error is encountered. +** If SQLITE_ERROR is returned, pContext is populated with an error message. +*/ +static int getNextNode( + ParseContext *pParse, /* fts3 query parse context */ + const char *z, int n, /* Input string */ + Fts3Expr **ppExpr, /* OUT: expression */ + int *pnConsumed /* OUT: Number of bytes consumed */ +){ + static const struct Fts3Keyword { + char *z; /* Keyword text */ + unsigned char n; /* Length of the keyword */ + unsigned char parenOnly; /* Only valid in paren mode */ + unsigned char eType; /* Keyword code */ + } aKeyword[] = { + { "OR" , 2, 0, FTSQUERY_OR }, + { "AND", 3, 1, FTSQUERY_AND }, + { "NOT", 3, 1, FTSQUERY_NOT }, + { "NEAR", 4, 0, FTSQUERY_NEAR } + }; + int ii; + int iCol; + int iColLen; + int rc; + Fts3Expr *pRet = 0; + + const char *zInput = z; + int nInput = n; + + pParse->isNot = 0; + + /* Skip over any whitespace before checking for a keyword, an open or + ** close bracket, or a quoted string. + */ + while( nInput>0 && fts3isspace(*zInput) ){ + nInput--; + zInput++; + } + if( nInput==0 ){ + return SQLITE_DONE; + } + + /* See if we are dealing with a keyword. */ + for(ii=0; ii<(int)(sizeof(aKeyword)/sizeof(struct Fts3Keyword)); ii++){ + const struct Fts3Keyword *pKey = &aKeyword[ii]; + + if( (pKey->parenOnly & ~sqlite3_fts3_enable_parentheses)!=0 ){ + continue; + } + + if( nInput>=pKey->n && 0==memcmp(zInput, pKey->z, pKey->n) ){ + int nNear = SQLITE_FTS3_DEFAULT_NEAR_PARAM; + int nKey = pKey->n; + char cNext; + + /* If this is a "NEAR" keyword, check for an explicit nearness. */ + if( pKey->eType==FTSQUERY_NEAR ){ + assert( nKey==4 ); + if( zInput[4]=='/' && zInput[5]>='0' && zInput[5]<='9' ){ + nNear = 0; + for(nKey=5; zInput[nKey]>='0' && zInput[nKey]<='9'; nKey++){ + nNear = nNear * 10 + (zInput[nKey] - '0'); + } + } + } + + /* At this point this is probably a keyword. But for that to be true, + ** the next byte must contain either whitespace, an open or close + ** parenthesis, a quote character, or EOF. + */ + cNext = zInput[nKey]; + if( fts3isspace(cNext) + || cNext=='"' || cNext=='(' || cNext==')' || cNext==0 + ){ + pRet = (Fts3Expr *)fts3MallocZero(sizeof(Fts3Expr)); + if( !pRet ){ + return SQLITE_NOMEM; + } + pRet->eType = pKey->eType; + pRet->nNear = nNear; + *ppExpr = pRet; + *pnConsumed = (int)((zInput - z) + nKey); + return SQLITE_OK; + } + + /* Turns out that wasn't a keyword after all. This happens if the + ** user has supplied a token such as "ORacle". Continue. + */ + } + } + + /* See if we are dealing with a quoted phrase. If this is the case, then + ** search for the closing quote and pass the whole string to getNextString() + ** for processing. This is easy to do, as fts3 has no syntax for escaping + ** a quote character embedded in a string. + */ + if( *zInput=='"' ){ + for(ii=1; iinNest++; + rc = fts3ExprParse(pParse, zInput+1, nInput-1, ppExpr, &nConsumed); + if( rc==SQLITE_OK && !*ppExpr ){ rc = SQLITE_DONE; } + *pnConsumed = (int)(zInput - z) + 1 + nConsumed; + return rc; + }else if( *zInput==')' ){ + pParse->nNest--; + *pnConsumed = (int)((zInput - z) + 1); + *ppExpr = 0; + return SQLITE_DONE; + } + } + + /* If control flows to this point, this must be a regular token, or + ** the end of the input. Read a regular token using the sqlite3_tokenizer + ** interface. Before doing so, figure out if there is an explicit + ** column specifier for the token. + ** + ** TODO: Strangely, it is not possible to associate a column specifier + ** with a quoted phrase, only with a single token. Not sure if this was + ** an implementation artifact or an intentional decision when fts3 was + ** first implemented. Whichever it was, this module duplicates the + ** limitation. + */ + iCol = pParse->iDefaultCol; + iColLen = 0; + for(ii=0; iinCol; ii++){ + const char *zStr = pParse->azCol[ii]; + int nStr = (int)strlen(zStr); + if( nInput>nStr && zInput[nStr]==':' + && sqlite3_strnicmp(zStr, zInput, nStr)==0 + ){ + iCol = ii; + iColLen = (int)((zInput - z) + nStr + 1); + break; + } + } + rc = getNextToken(pParse, iCol, &z[iColLen], n-iColLen, ppExpr, pnConsumed); + *pnConsumed += iColLen; + return rc; +} + +/* +** The argument is an Fts3Expr structure for a binary operator (any type +** except an FTSQUERY_PHRASE). Return an integer value representing the +** precedence of the operator. Lower values have a higher precedence (i.e. +** group more tightly). For example, in the C language, the == operator +** groups more tightly than ||, and would therefore have a higher precedence. +** +** When using the new fts3 query syntax (when SQLITE_ENABLE_FTS3_PARENTHESIS +** is defined), the order of the operators in precedence from highest to +** lowest is: +** +** NEAR +** NOT +** AND (including implicit ANDs) +** OR +** +** Note that when using the old query syntax, the OR operator has a higher +** precedence than the AND operator. +*/ +static int opPrecedence(Fts3Expr *p){ + assert( p->eType!=FTSQUERY_PHRASE ); + if( sqlite3_fts3_enable_parentheses ){ + return p->eType; + }else if( p->eType==FTSQUERY_NEAR ){ + return 1; + }else if( p->eType==FTSQUERY_OR ){ + return 2; + } + assert( p->eType==FTSQUERY_AND ); + return 3; +} + +/* +** Argument ppHead contains a pointer to the current head of a query +** expression tree being parsed. pPrev is the expression node most recently +** inserted into the tree. This function adds pNew, which is always a binary +** operator node, into the expression tree based on the relative precedence +** of pNew and the existing nodes of the tree. This may result in the head +** of the tree changing, in which case *ppHead is set to the new root node. +*/ +static void insertBinaryOperator( + Fts3Expr **ppHead, /* Pointer to the root node of a tree */ + Fts3Expr *pPrev, /* Node most recently inserted into the tree */ + Fts3Expr *pNew /* New binary node to insert into expression tree */ +){ + Fts3Expr *pSplit = pPrev; + while( pSplit->pParent && opPrecedence(pSplit->pParent)<=opPrecedence(pNew) ){ + pSplit = pSplit->pParent; + } + + if( pSplit->pParent ){ + assert( pSplit->pParent->pRight==pSplit ); + pSplit->pParent->pRight = pNew; + pNew->pParent = pSplit->pParent; + }else{ + *ppHead = pNew; + } + pNew->pLeft = pSplit; + pSplit->pParent = pNew; +} + +/* +** Parse the fts3 query expression found in buffer z, length n. This function +** returns either when the end of the buffer is reached or an unmatched +** closing bracket - ')' - is encountered. +** +** If successful, SQLITE_OK is returned, *ppExpr is set to point to the +** parsed form of the expression and *pnConsumed is set to the number of +** bytes read from buffer z. Otherwise, *ppExpr is set to 0 and SQLITE_NOMEM +** (out of memory error) or SQLITE_ERROR (parse error) is returned. +*/ +static int fts3ExprParse( + ParseContext *pParse, /* fts3 query parse context */ + const char *z, int n, /* Text of MATCH query */ + Fts3Expr **ppExpr, /* OUT: Parsed query structure */ + int *pnConsumed /* OUT: Number of bytes consumed */ +){ + Fts3Expr *pRet = 0; + Fts3Expr *pPrev = 0; + Fts3Expr *pNotBranch = 0; /* Only used in legacy parse mode */ + int nIn = n; + const char *zIn = z; + int rc = SQLITE_OK; + int isRequirePhrase = 1; + + while( rc==SQLITE_OK ){ + Fts3Expr *p = 0; + int nByte = 0; + + rc = getNextNode(pParse, zIn, nIn, &p, &nByte); + assert( nByte>0 || (rc!=SQLITE_OK && p==0) ); + if( rc==SQLITE_OK ){ + if( p ){ + int isPhrase; + + if( !sqlite3_fts3_enable_parentheses + && p->eType==FTSQUERY_PHRASE && pParse->isNot + ){ + /* Create an implicit NOT operator. */ + Fts3Expr *pNot = fts3MallocZero(sizeof(Fts3Expr)); + if( !pNot ){ + sqlite3Fts3ExprFree(p); + rc = SQLITE_NOMEM; + goto exprparse_out; + } + pNot->eType = FTSQUERY_NOT; + pNot->pRight = p; + p->pParent = pNot; + if( pNotBranch ){ + pNot->pLeft = pNotBranch; + pNotBranch->pParent = pNot; + } + pNotBranch = pNot; + p = pPrev; + }else{ + int eType = p->eType; + isPhrase = (eType==FTSQUERY_PHRASE || p->pLeft); + + /* The isRequirePhrase variable is set to true if a phrase or + ** an expression contained in parenthesis is required. If a + ** binary operator (AND, OR, NOT or NEAR) is encounted when + ** isRequirePhrase is set, this is a syntax error. + */ + if( !isPhrase && isRequirePhrase ){ + sqlite3Fts3ExprFree(p); + rc = SQLITE_ERROR; + goto exprparse_out; + } + + if( isPhrase && !isRequirePhrase ){ + /* Insert an implicit AND operator. */ + Fts3Expr *pAnd; + assert( pRet && pPrev ); + pAnd = fts3MallocZero(sizeof(Fts3Expr)); + if( !pAnd ){ + sqlite3Fts3ExprFree(p); + rc = SQLITE_NOMEM; + goto exprparse_out; + } + pAnd->eType = FTSQUERY_AND; + insertBinaryOperator(&pRet, pPrev, pAnd); + pPrev = pAnd; + } + + /* This test catches attempts to make either operand of a NEAR + ** operator something other than a phrase. For example, either of + ** the following: + ** + ** (bracketed expression) NEAR phrase + ** phrase NEAR (bracketed expression) + ** + ** Return an error in either case. + */ + if( pPrev && ( + (eType==FTSQUERY_NEAR && !isPhrase && pPrev->eType!=FTSQUERY_PHRASE) + || (eType!=FTSQUERY_PHRASE && isPhrase && pPrev->eType==FTSQUERY_NEAR) + )){ + sqlite3Fts3ExprFree(p); + rc = SQLITE_ERROR; + goto exprparse_out; + } + + if( isPhrase ){ + if( pRet ){ + assert( pPrev && pPrev->pLeft && pPrev->pRight==0 ); + pPrev->pRight = p; + p->pParent = pPrev; + }else{ + pRet = p; + } + }else{ + insertBinaryOperator(&pRet, pPrev, p); + } + isRequirePhrase = !isPhrase; + } + pPrev = p; + } + assert( nByte>0 ); + } + assert( rc!=SQLITE_OK || (nByte>0 && nByte<=nIn) ); + nIn -= nByte; + zIn += nByte; + } + + if( rc==SQLITE_DONE && pRet && isRequirePhrase ){ + rc = SQLITE_ERROR; + } + + if( rc==SQLITE_DONE ){ + rc = SQLITE_OK; + if( !sqlite3_fts3_enable_parentheses && pNotBranch ){ + if( !pRet ){ + rc = SQLITE_ERROR; + }else{ + Fts3Expr *pIter = pNotBranch; + while( pIter->pLeft ){ + pIter = pIter->pLeft; + } + pIter->pLeft = pRet; + pRet->pParent = pIter; + pRet = pNotBranch; + } + } + } + *pnConsumed = n - nIn; + +exprparse_out: + if( rc!=SQLITE_OK ){ + sqlite3Fts3ExprFree(pRet); + sqlite3Fts3ExprFree(pNotBranch); + pRet = 0; + } + *ppExpr = pRet; + return rc; +} + +/* +** Return SQLITE_ERROR if the maximum depth of the expression tree passed +** as the only argument is more than nMaxDepth. +*/ +static int fts3ExprCheckDepth(Fts3Expr *p, int nMaxDepth){ + int rc = SQLITE_OK; + if( p ){ + if( nMaxDepth<0 ){ + rc = SQLITE_TOOBIG; + }else{ + rc = fts3ExprCheckDepth(p->pLeft, nMaxDepth-1); + if( rc==SQLITE_OK ){ + rc = fts3ExprCheckDepth(p->pRight, nMaxDepth-1); + } + } + } + return rc; +} + +/* +** This function attempts to transform the expression tree at (*pp) to +** an equivalent but more balanced form. The tree is modified in place. +** If successful, SQLITE_OK is returned and (*pp) set to point to the +** new root expression node. +** +** nMaxDepth is the maximum allowable depth of the balanced sub-tree. +** +** Otherwise, if an error occurs, an SQLite error code is returned and +** expression (*pp) freed. +*/ +static int fts3ExprBalance(Fts3Expr **pp, int nMaxDepth){ + int rc = SQLITE_OK; /* Return code */ + Fts3Expr *pRoot = *pp; /* Initial root node */ + Fts3Expr *pFree = 0; /* List of free nodes. Linked by pParent. */ + int eType = pRoot->eType; /* Type of node in this tree */ + + if( nMaxDepth==0 ){ + rc = SQLITE_ERROR; + } + + if( rc==SQLITE_OK && (eType==FTSQUERY_AND || eType==FTSQUERY_OR) ){ + Fts3Expr **apLeaf; + apLeaf = (Fts3Expr **)sqlite3_malloc(sizeof(Fts3Expr *) * nMaxDepth); + if( 0==apLeaf ){ + rc = SQLITE_NOMEM; + }else{ + memset(apLeaf, 0, sizeof(Fts3Expr *) * nMaxDepth); + } + + if( rc==SQLITE_OK ){ + int i; + Fts3Expr *p; + + /* Set $p to point to the left-most leaf in the tree of eType nodes. */ + for(p=pRoot; p->eType==eType; p=p->pLeft){ + assert( p->pParent==0 || p->pParent->pLeft==p ); + assert( p->pLeft && p->pRight ); + } + + /* This loop runs once for each leaf in the tree of eType nodes. */ + while( 1 ){ + int iLvl; + Fts3Expr *pParent = p->pParent; /* Current parent of p */ + + assert( pParent==0 || pParent->pLeft==p ); + p->pParent = 0; + if( pParent ){ + pParent->pLeft = 0; + }else{ + pRoot = 0; + } + rc = fts3ExprBalance(&p, nMaxDepth-1); + if( rc!=SQLITE_OK ) break; + + for(iLvl=0; p && iLvlpLeft = apLeaf[iLvl]; + pFree->pRight = p; + pFree->pLeft->pParent = pFree; + pFree->pRight->pParent = pFree; + + p = pFree; + pFree = pFree->pParent; + p->pParent = 0; + apLeaf[iLvl] = 0; + } + } + if( p ){ + sqlite3Fts3ExprFree(p); + rc = SQLITE_TOOBIG; + break; + } + + /* If that was the last leaf node, break out of the loop */ + if( pParent==0 ) break; + + /* Set $p to point to the next leaf in the tree of eType nodes */ + for(p=pParent->pRight; p->eType==eType; p=p->pLeft); + + /* Remove pParent from the original tree. */ + assert( pParent->pParent==0 || pParent->pParent->pLeft==pParent ); + pParent->pRight->pParent = pParent->pParent; + if( pParent->pParent ){ + pParent->pParent->pLeft = pParent->pRight; + }else{ + assert( pParent==pRoot ); + pRoot = pParent->pRight; + } + + /* Link pParent into the free node list. It will be used as an + ** internal node of the new tree. */ + pParent->pParent = pFree; + pFree = pParent; + } + + if( rc==SQLITE_OK ){ + p = 0; + for(i=0; ipParent = 0; + }else{ + assert( pFree!=0 ); + pFree->pRight = p; + pFree->pLeft = apLeaf[i]; + pFree->pLeft->pParent = pFree; + pFree->pRight->pParent = pFree; + + p = pFree; + pFree = pFree->pParent; + p->pParent = 0; + } + } + } + pRoot = p; + }else{ + /* An error occurred. Delete the contents of the apLeaf[] array + ** and pFree list. Everything else is cleaned up by the call to + ** sqlite3Fts3ExprFree(pRoot) below. */ + Fts3Expr *pDel; + for(i=0; ipParent; + sqlite3_free(pDel); + } + } + + assert( pFree==0 ); + sqlite3_free( apLeaf ); + } + } + + if( rc!=SQLITE_OK ){ + sqlite3Fts3ExprFree(pRoot); + pRoot = 0; + } + *pp = pRoot; + return rc; +} + +/* +** This function is similar to sqlite3Fts3ExprParse(), with the following +** differences: +** +** 1. It does not do expression rebalancing. +** 2. It does not check that the expression does not exceed the +** maximum allowable depth. +** 3. Even if it fails, *ppExpr may still be set to point to an +** expression tree. It should be deleted using sqlite3Fts3ExprFree() +** in this case. +*/ +static int fts3ExprParseUnbalanced( + sqlite3_tokenizer *pTokenizer, /* Tokenizer module */ + int iLangid, /* Language id for tokenizer */ + char **azCol, /* Array of column names for fts3 table */ + int bFts4, /* True to allow FTS4-only syntax */ + int nCol, /* Number of entries in azCol[] */ + int iDefaultCol, /* Default column to query */ + const char *z, int n, /* Text of MATCH query */ + Fts3Expr **ppExpr /* OUT: Parsed query structure */ +){ + int nParsed; + int rc; + ParseContext sParse; + + memset(&sParse, 0, sizeof(ParseContext)); + sParse.pTokenizer = pTokenizer; + sParse.iLangid = iLangid; + sParse.azCol = (const char **)azCol; + sParse.nCol = nCol; + sParse.iDefaultCol = iDefaultCol; + sParse.bFts4 = bFts4; + if( z==0 ){ + *ppExpr = 0; + return SQLITE_OK; + } + if( n<0 ){ + n = (int)strlen(z); + } + rc = fts3ExprParse(&sParse, z, n, ppExpr, &nParsed); + assert( rc==SQLITE_OK || *ppExpr==0 ); + + /* Check for mismatched parenthesis */ + if( rc==SQLITE_OK && sParse.nNest ){ + rc = SQLITE_ERROR; + } + + return rc; +} + +/* +** Parameters z and n contain a pointer to and length of a buffer containing +** an fts3 query expression, respectively. This function attempts to parse the +** query expression and create a tree of Fts3Expr structures representing the +** parsed expression. If successful, *ppExpr is set to point to the head +** of the parsed expression tree and SQLITE_OK is returned. If an error +** occurs, either SQLITE_NOMEM (out-of-memory error) or SQLITE_ERROR (parse +** error) is returned and *ppExpr is set to 0. +** +** If parameter n is a negative number, then z is assumed to point to a +** nul-terminated string and the length is determined using strlen(). +** +** The first parameter, pTokenizer, is passed the fts3 tokenizer module to +** use to normalize query tokens while parsing the expression. The azCol[] +** array, which is assumed to contain nCol entries, should contain the names +** of each column in the target fts3 table, in order from left to right. +** Column names must be nul-terminated strings. +** +** The iDefaultCol parameter should be passed the index of the table column +** that appears on the left-hand-side of the MATCH operator (the default +** column to match against for tokens for which a column name is not explicitly +** specified as part of the query string), or -1 if tokens may by default +** match any table column. +*/ +SQLITE_PRIVATE int sqlite3Fts3ExprParse( + sqlite3_tokenizer *pTokenizer, /* Tokenizer module */ + int iLangid, /* Language id for tokenizer */ + char **azCol, /* Array of column names for fts3 table */ + int bFts4, /* True to allow FTS4-only syntax */ + int nCol, /* Number of entries in azCol[] */ + int iDefaultCol, /* Default column to query */ + const char *z, int n, /* Text of MATCH query */ + Fts3Expr **ppExpr, /* OUT: Parsed query structure */ + char **pzErr /* OUT: Error message (sqlite3_malloc) */ +){ + int rc = fts3ExprParseUnbalanced( + pTokenizer, iLangid, azCol, bFts4, nCol, iDefaultCol, z, n, ppExpr + ); + + /* Rebalance the expression. And check that its depth does not exceed + ** SQLITE_FTS3_MAX_EXPR_DEPTH. */ + if( rc==SQLITE_OK && *ppExpr ){ + rc = fts3ExprBalance(ppExpr, SQLITE_FTS3_MAX_EXPR_DEPTH); + if( rc==SQLITE_OK ){ + rc = fts3ExprCheckDepth(*ppExpr, SQLITE_FTS3_MAX_EXPR_DEPTH); + } + } + + if( rc!=SQLITE_OK ){ + sqlite3Fts3ExprFree(*ppExpr); + *ppExpr = 0; + if( rc==SQLITE_TOOBIG ){ + sqlite3Fts3ErrMsg(pzErr, + "FTS expression tree is too large (maximum depth %d)", + SQLITE_FTS3_MAX_EXPR_DEPTH + ); + rc = SQLITE_ERROR; + }else if( rc==SQLITE_ERROR ){ + sqlite3Fts3ErrMsg(pzErr, "malformed MATCH expression: [%s]", z); + } + } + + return rc; +} + +/* +** Free a single node of an expression tree. +*/ +static void fts3FreeExprNode(Fts3Expr *p){ + assert( p->eType==FTSQUERY_PHRASE || p->pPhrase==0 ); + sqlite3Fts3EvalPhraseCleanup(p->pPhrase); + sqlite3_free(p->aMI); + sqlite3_free(p); +} + +/* +** Free a parsed fts3 query expression allocated by sqlite3Fts3ExprParse(). +** +** This function would be simpler if it recursively called itself. But +** that would mean passing a sufficiently large expression to ExprParse() +** could cause a stack overflow. +*/ +SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *pDel){ + Fts3Expr *p; + assert( pDel==0 || pDel->pParent==0 ); + for(p=pDel; p && (p->pLeft||p->pRight); p=(p->pLeft ? p->pLeft : p->pRight)){ + assert( p->pParent==0 || p==p->pParent->pRight || p==p->pParent->pLeft ); + } + while( p ){ + Fts3Expr *pParent = p->pParent; + fts3FreeExprNode(p); + if( pParent && p==pParent->pLeft && pParent->pRight ){ + p = pParent->pRight; + while( p && (p->pLeft || p->pRight) ){ + assert( p==p->pParent->pRight || p==p->pParent->pLeft ); + p = (p->pLeft ? p->pLeft : p->pRight); + } + }else{ + p = pParent; + } + } +} + +/**************************************************************************** +***************************************************************************** +** Everything after this point is just test code. +*/ + +#ifdef SQLITE_TEST + +/* #include */ + +/* +** Function to query the hash-table of tokenizers (see README.tokenizers). +*/ +static int queryTestTokenizer( + sqlite3 *db, + const char *zName, + const sqlite3_tokenizer_module **pp +){ + int rc; + sqlite3_stmt *pStmt; + const char zSql[] = "SELECT fts3_tokenizer(?)"; + + *pp = 0; + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + + sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){ + memcpy((void *)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp)); + } + } + + return sqlite3_finalize(pStmt); +} + +/* +** Return a pointer to a buffer containing a text representation of the +** expression passed as the first argument. The buffer is obtained from +** sqlite3_malloc(). It is the responsibility of the caller to use +** sqlite3_free() to release the memory. If an OOM condition is encountered, +** NULL is returned. +** +** If the second argument is not NULL, then its contents are prepended to +** the returned expression text and then freed using sqlite3_free(). +*/ +static char *exprToString(Fts3Expr *pExpr, char *zBuf){ + if( pExpr==0 ){ + return sqlite3_mprintf(""); + } + switch( pExpr->eType ){ + case FTSQUERY_PHRASE: { + Fts3Phrase *pPhrase = pExpr->pPhrase; + int i; + zBuf = sqlite3_mprintf( + "%zPHRASE %d 0", zBuf, pPhrase->iColumn); + for(i=0; zBuf && inToken; i++){ + zBuf = sqlite3_mprintf("%z %.*s%s", zBuf, + pPhrase->aToken[i].n, pPhrase->aToken[i].z, + (pPhrase->aToken[i].isPrefix?"+":"") + ); + } + return zBuf; + } + + case FTSQUERY_NEAR: + zBuf = sqlite3_mprintf("%zNEAR/%d ", zBuf, pExpr->nNear); + break; + case FTSQUERY_NOT: + zBuf = sqlite3_mprintf("%zNOT ", zBuf); + break; + case FTSQUERY_AND: + zBuf = sqlite3_mprintf("%zAND ", zBuf); + break; + case FTSQUERY_OR: + zBuf = sqlite3_mprintf("%zOR ", zBuf); + break; + } + + if( zBuf ) zBuf = sqlite3_mprintf("%z{", zBuf); + if( zBuf ) zBuf = exprToString(pExpr->pLeft, zBuf); + if( zBuf ) zBuf = sqlite3_mprintf("%z} {", zBuf); + + if( zBuf ) zBuf = exprToString(pExpr->pRight, zBuf); + if( zBuf ) zBuf = sqlite3_mprintf("%z}", zBuf); + + return zBuf; +} + +/* +** This is the implementation of a scalar SQL function used to test the +** expression parser. It should be called as follows: +** +** fts3_exprtest(, , , ...); +** +** The first argument, , is the name of the fts3 tokenizer used +** to parse the query expression (see README.tokenizers). The second argument +** is the query expression to parse. Each subsequent argument is the name +** of a column of the fts3 table that the query expression may refer to. +** For example: +** +** SELECT fts3_exprtest('simple', 'Bill col2:Bloggs', 'col1', 'col2'); +*/ +static void fts3ExprTest( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + sqlite3_tokenizer_module const *pModule = 0; + sqlite3_tokenizer *pTokenizer = 0; + int rc; + char **azCol = 0; + const char *zExpr; + int nExpr; + int nCol; + int ii; + Fts3Expr *pExpr; + char *zBuf = 0; + sqlite3 *db = sqlite3_context_db_handle(context); + + if( argc<3 ){ + sqlite3_result_error(context, + "Usage: fts3_exprtest(tokenizer, expr, col1, ...", -1 + ); + return; + } + + rc = queryTestTokenizer(db, + (const char *)sqlite3_value_text(argv[0]), &pModule); + if( rc==SQLITE_NOMEM ){ + sqlite3_result_error_nomem(context); + goto exprtest_out; + }else if( !pModule ){ + sqlite3_result_error(context, "No such tokenizer module", -1); + goto exprtest_out; + } + + rc = pModule->xCreate(0, 0, &pTokenizer); + assert( rc==SQLITE_NOMEM || rc==SQLITE_OK ); + if( rc==SQLITE_NOMEM ){ + sqlite3_result_error_nomem(context); + goto exprtest_out; + } + pTokenizer->pModule = pModule; + + zExpr = (const char *)sqlite3_value_text(argv[1]); + nExpr = sqlite3_value_bytes(argv[1]); + nCol = argc-2; + azCol = (char **)sqlite3_malloc(nCol*sizeof(char *)); + if( !azCol ){ + sqlite3_result_error_nomem(context); + goto exprtest_out; + } + for(ii=0; iixDestroy(pTokenizer); + } + sqlite3_free(azCol); +} + +/* +** Register the query expression parser test function fts3_exprtest() +** with database connection db. +*/ +SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3* db){ + int rc = sqlite3_create_function( + db, "fts3_exprtest", -1, SQLITE_UTF8, 0, fts3ExprTest, 0, 0 + ); + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "fts3_exprtest_rebalance", + -1, SQLITE_UTF8, (void *)1, fts3ExprTest, 0, 0 + ); + } + return rc; +} + +#endif +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_expr.c *******************************************/ +/************** Begin file fts3_hash.c ***************************************/ +/* +** 2001 September 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 is the implementation of generic hash-tables used in SQLite. +** We've modified it slightly to serve as a standalone hash table +** implementation for the full-text indexing module. +*/ + +/* +** The code in this file is only compiled if: +** +** * The FTS3 module is being built as an extension +** (in which case SQLITE_CORE is not defined), or +** +** * The FTS3 module is being built into the core of +** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). +*/ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ +/* #include */ + + +/* +** Malloc and Free functions +*/ +static void *fts3HashMalloc(int n){ + void *p = sqlite3_malloc(n); + if( p ){ + memset(p, 0, n); + } + return p; +} +static void fts3HashFree(void *p){ + sqlite3_free(p); +} + +/* Turn bulk memory into a hash table object by initializing the +** fields of the Hash structure. +** +** "pNew" is a pointer to the hash table that is to be initialized. +** keyClass is one of the constants +** FTS3_HASH_BINARY or FTS3_HASH_STRING. The value of keyClass +** determines what kind of key the hash table will use. "copyKey" is +** true if the hash table should make its own private copy of keys and +** false if it should just use the supplied pointer. +*/ +SQLITE_PRIVATE void sqlite3Fts3HashInit(Fts3Hash *pNew, char keyClass, char copyKey){ + assert( pNew!=0 ); + assert( keyClass>=FTS3_HASH_STRING && keyClass<=FTS3_HASH_BINARY ); + pNew->keyClass = keyClass; + pNew->copyKey = copyKey; + pNew->first = 0; + pNew->count = 0; + pNew->htsize = 0; + pNew->ht = 0; +} + +/* Remove all entries from a hash table. Reclaim all memory. +** Call this routine to delete a hash table or to reset a hash table +** to the empty state. +*/ +SQLITE_PRIVATE void sqlite3Fts3HashClear(Fts3Hash *pH){ + Fts3HashElem *elem; /* For looping over all elements of the table */ + + assert( pH!=0 ); + elem = pH->first; + pH->first = 0; + fts3HashFree(pH->ht); + pH->ht = 0; + pH->htsize = 0; + while( elem ){ + Fts3HashElem *next_elem = elem->next; + if( pH->copyKey && elem->pKey ){ + fts3HashFree(elem->pKey); + } + fts3HashFree(elem); + elem = next_elem; + } + pH->count = 0; +} + +/* +** Hash and comparison functions when the mode is FTS3_HASH_STRING +*/ +static int fts3StrHash(const void *pKey, int nKey){ + const char *z = (const char *)pKey; + unsigned h = 0; + if( nKey<=0 ) nKey = (int) strlen(z); + while( nKey > 0 ){ + h = (h<<3) ^ h ^ *z++; + nKey--; + } + return (int)(h & 0x7fffffff); +} +static int fts3StrCompare(const void *pKey1, int n1, const void *pKey2, int n2){ + if( n1!=n2 ) return 1; + return strncmp((const char*)pKey1,(const char*)pKey2,n1); +} + +/* +** Hash and comparison functions when the mode is FTS3_HASH_BINARY +*/ +static int fts3BinHash(const void *pKey, int nKey){ + int h = 0; + const char *z = (const char *)pKey; + while( nKey-- > 0 ){ + h = (h<<3) ^ h ^ *(z++); + } + return h & 0x7fffffff; +} +static int fts3BinCompare(const void *pKey1, int n1, const void *pKey2, int n2){ + if( n1!=n2 ) return 1; + return memcmp(pKey1,pKey2,n1); +} + +/* +** Return a pointer to the appropriate hash function given the key class. +** +** The C syntax in this function definition may be unfamilar to some +** programmers, so we provide the following additional explanation: +** +** The name of the function is "ftsHashFunction". The function takes a +** single parameter "keyClass". The return value of ftsHashFunction() +** is a pointer to another function. Specifically, the return value +** of ftsHashFunction() is a pointer to a function that takes two parameters +** with types "const void*" and "int" and returns an "int". +*/ +static int (*ftsHashFunction(int keyClass))(const void*,int){ + if( keyClass==FTS3_HASH_STRING ){ + return &fts3StrHash; + }else{ + assert( keyClass==FTS3_HASH_BINARY ); + return &fts3BinHash; + } +} + +/* +** Return a pointer to the appropriate hash function given the key class. +** +** For help in interpreted the obscure C code in the function definition, +** see the header comment on the previous function. +*/ +static int (*ftsCompareFunction(int keyClass))(const void*,int,const void*,int){ + if( keyClass==FTS3_HASH_STRING ){ + return &fts3StrCompare; + }else{ + assert( keyClass==FTS3_HASH_BINARY ); + return &fts3BinCompare; + } +} + +/* Link an element into the hash table +*/ +static void fts3HashInsertElement( + Fts3Hash *pH, /* The complete hash table */ + struct _fts3ht *pEntry, /* The entry into which pNew is inserted */ + Fts3HashElem *pNew /* The element to be inserted */ +){ + Fts3HashElem *pHead; /* First element already in pEntry */ + pHead = pEntry->chain; + if( pHead ){ + pNew->next = pHead; + pNew->prev = pHead->prev; + if( pHead->prev ){ pHead->prev->next = pNew; } + else { pH->first = pNew; } + pHead->prev = pNew; + }else{ + pNew->next = pH->first; + if( pH->first ){ pH->first->prev = pNew; } + pNew->prev = 0; + pH->first = pNew; + } + pEntry->count++; + pEntry->chain = pNew; +} + + +/* Resize the hash table so that it cantains "new_size" buckets. +** "new_size" must be a power of 2. The hash table might fail +** to resize if sqliteMalloc() fails. +** +** Return non-zero if a memory allocation error occurs. +*/ +static int fts3Rehash(Fts3Hash *pH, int new_size){ + struct _fts3ht *new_ht; /* The new hash table */ + Fts3HashElem *elem, *next_elem; /* For looping over existing elements */ + int (*xHash)(const void*,int); /* The hash function */ + + assert( (new_size & (new_size-1))==0 ); + new_ht = (struct _fts3ht *)fts3HashMalloc( new_size*sizeof(struct _fts3ht) ); + if( new_ht==0 ) return 1; + fts3HashFree(pH->ht); + pH->ht = new_ht; + pH->htsize = new_size; + xHash = ftsHashFunction(pH->keyClass); + for(elem=pH->first, pH->first=0; elem; elem = next_elem){ + int h = (*xHash)(elem->pKey, elem->nKey) & (new_size-1); + next_elem = elem->next; + fts3HashInsertElement(pH, &new_ht[h], elem); + } + return 0; +} + +/* This function (for internal use only) locates an element in an +** hash table that matches the given key. The hash for this key has +** already been computed and is passed as the 4th parameter. +*/ +static Fts3HashElem *fts3FindElementByHash( + const Fts3Hash *pH, /* The pH to be searched */ + const void *pKey, /* The key we are searching for */ + int nKey, + int h /* The hash for this key. */ +){ + Fts3HashElem *elem; /* Used to loop thru the element list */ + int count; /* Number of elements left to test */ + int (*xCompare)(const void*,int,const void*,int); /* comparison function */ + + if( pH->ht ){ + struct _fts3ht *pEntry = &pH->ht[h]; + elem = pEntry->chain; + count = pEntry->count; + xCompare = ftsCompareFunction(pH->keyClass); + while( count-- && elem ){ + if( (*xCompare)(elem->pKey,elem->nKey,pKey,nKey)==0 ){ + return elem; + } + elem = elem->next; + } + } + return 0; +} + +/* Remove a single entry from the hash table given a pointer to that +** element and a hash on the element's key. +*/ +static void fts3RemoveElementByHash( + Fts3Hash *pH, /* The pH containing "elem" */ + Fts3HashElem* elem, /* The element to be removed from the pH */ + int h /* Hash value for the element */ +){ + struct _fts3ht *pEntry; + if( elem->prev ){ + elem->prev->next = elem->next; + }else{ + pH->first = elem->next; + } + if( elem->next ){ + elem->next->prev = elem->prev; + } + pEntry = &pH->ht[h]; + if( pEntry->chain==elem ){ + pEntry->chain = elem->next; + } + pEntry->count--; + if( pEntry->count<=0 ){ + pEntry->chain = 0; + } + if( pH->copyKey && elem->pKey ){ + fts3HashFree(elem->pKey); + } + fts3HashFree( elem ); + pH->count--; + if( pH->count<=0 ){ + assert( pH->first==0 ); + assert( pH->count==0 ); + fts3HashClear(pH); + } +} + +SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem( + const Fts3Hash *pH, + const void *pKey, + int nKey +){ + int h; /* A hash on key */ + int (*xHash)(const void*,int); /* The hash function */ + + if( pH==0 || pH->ht==0 ) return 0; + xHash = ftsHashFunction(pH->keyClass); + assert( xHash!=0 ); + h = (*xHash)(pKey,nKey); + assert( (pH->htsize & (pH->htsize-1))==0 ); + return fts3FindElementByHash(pH,pKey,nKey, h & (pH->htsize-1)); +} + +/* +** 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. +*/ +SQLITE_PRIVATE void *sqlite3Fts3HashFind(const Fts3Hash *pH, const void *pKey, int nKey){ + Fts3HashElem *pElem; /* The element that matches key (if any) */ + + pElem = sqlite3Fts3HashFindElem(pH, pKey, nKey); + return pElem ? pElem->data : 0; +} + +/* Insert an element into the hash table pH. The key is pKey,nKey +** and the data is "data". +** +** If no element exists with a matching key, then a new +** element is created. A copy of the key is made if the copyKey +** flag is set. NULL is returned. +** +** If another element already exists with the same key, then the +** new data replaces the old data and the old data is returned. +** The key is not copied in this instance. If a malloc fails, then +** the new data is returned and the hash table is unchanged. +** +** If the "data" parameter to this function is NULL, then the +** element corresponding to "key" is removed from the hash table. +*/ +SQLITE_PRIVATE void *sqlite3Fts3HashInsert( + Fts3Hash *pH, /* The hash table to insert into */ + const void *pKey, /* The key */ + int nKey, /* Number of bytes in the key */ + void *data /* The data */ +){ + int hraw; /* Raw hash value of the key */ + int h; /* the hash of the key modulo hash table size */ + Fts3HashElem *elem; /* Used to loop thru the element list */ + Fts3HashElem *new_elem; /* New element added to the pH */ + int (*xHash)(const void*,int); /* The hash function */ + + assert( pH!=0 ); + xHash = ftsHashFunction(pH->keyClass); + assert( xHash!=0 ); + hraw = (*xHash)(pKey, nKey); + assert( (pH->htsize & (pH->htsize-1))==0 ); + h = hraw & (pH->htsize-1); + elem = fts3FindElementByHash(pH,pKey,nKey,h); + if( elem ){ + void *old_data = elem->data; + if( data==0 ){ + fts3RemoveElementByHash(pH,elem,h); + }else{ + elem->data = data; + } + return old_data; + } + if( data==0 ) return 0; + if( (pH->htsize==0 && fts3Rehash(pH,8)) + || (pH->count>=pH->htsize && fts3Rehash(pH, pH->htsize*2)) + ){ + pH->count = 0; + return data; + } + assert( pH->htsize>0 ); + new_elem = (Fts3HashElem*)fts3HashMalloc( sizeof(Fts3HashElem) ); + if( new_elem==0 ) return data; + if( pH->copyKey && pKey!=0 ){ + new_elem->pKey = fts3HashMalloc( nKey ); + if( new_elem->pKey==0 ){ + fts3HashFree(new_elem); + return data; + } + memcpy((void*)new_elem->pKey, pKey, nKey); + }else{ + new_elem->pKey = (void*)pKey; + } + new_elem->nKey = nKey; + pH->count++; + assert( pH->htsize>0 ); + assert( (pH->htsize & (pH->htsize-1))==0 ); + h = hraw & (pH->htsize-1); + fts3HashInsertElement(pH, &pH->ht[h], new_elem); + new_elem->data = data; + return 0; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_hash.c *******************************************/ +/************** Begin file fts3_porter.c *************************************/ +/* +** 2006 September 30 +** +** 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. +** +************************************************************************* +** Implementation of the full-text-search tokenizer that implements +** a Porter stemmer. +*/ + +/* +** The code in this file is only compiled if: +** +** * The FTS3 module is being built as an extension +** (in which case SQLITE_CORE is not defined), or +** +** * The FTS3 module is being built into the core of +** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). +*/ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ +/* #include */ +/* #include */ + + +/* +** Class derived from sqlite3_tokenizer +*/ +typedef struct porter_tokenizer { + sqlite3_tokenizer base; /* Base class */ +} porter_tokenizer; + +/* +** Class derived from sqlite3_tokenizer_cursor +*/ +typedef struct porter_tokenizer_cursor { + sqlite3_tokenizer_cursor base; + const char *zInput; /* input we are tokenizing */ + int nInput; /* size of the input */ + int iOffset; /* current position in zInput */ + int iToken; /* index of next token to be returned */ + char *zToken; /* storage for current token */ + int nAllocated; /* space allocated to zToken buffer */ +} porter_tokenizer_cursor; + + +/* +** Create a new tokenizer instance. +*/ +static int porterCreate( + int argc, const char * const *argv, + sqlite3_tokenizer **ppTokenizer +){ + porter_tokenizer *t; + + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(argv); + + t = (porter_tokenizer *) sqlite3_malloc(sizeof(*t)); + if( t==NULL ) return SQLITE_NOMEM; + memset(t, 0, sizeof(*t)); + *ppTokenizer = &t->base; + return SQLITE_OK; +} + +/* +** Destroy a tokenizer +*/ +static int porterDestroy(sqlite3_tokenizer *pTokenizer){ + sqlite3_free(pTokenizer); + return SQLITE_OK; +} + +/* +** Prepare to begin tokenizing a particular string. The input +** string to be tokenized is zInput[0..nInput-1]. A cursor +** used to incrementally tokenize this string is returned in +** *ppCursor. +*/ +static int porterOpen( + sqlite3_tokenizer *pTokenizer, /* The tokenizer */ + const char *zInput, int nInput, /* String to be tokenized */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */ +){ + porter_tokenizer_cursor *c; + + UNUSED_PARAMETER(pTokenizer); + + c = (porter_tokenizer_cursor *) sqlite3_malloc(sizeof(*c)); + if( c==NULL ) return SQLITE_NOMEM; + + c->zInput = zInput; + if( zInput==0 ){ + c->nInput = 0; + }else if( nInput<0 ){ + c->nInput = (int)strlen(zInput); + }else{ + c->nInput = nInput; + } + c->iOffset = 0; /* start tokenizing at the beginning */ + c->iToken = 0; + c->zToken = NULL; /* no space allocated, yet. */ + c->nAllocated = 0; + + *ppCursor = &c->base; + return SQLITE_OK; +} + +/* +** Close a tokenization cursor previously opened by a call to +** porterOpen() above. +*/ +static int porterClose(sqlite3_tokenizer_cursor *pCursor){ + porter_tokenizer_cursor *c = (porter_tokenizer_cursor *) pCursor; + sqlite3_free(c->zToken); + sqlite3_free(c); + return SQLITE_OK; +} +/* +** Vowel or consonant +*/ +static const char cType[] = { + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 2, 1 +}; + +/* +** isConsonant() and isVowel() determine if their first character in +** the string they point to is a consonant or a vowel, according +** to Porter ruls. +** +** A consonate is any letter other than 'a', 'e', 'i', 'o', or 'u'. +** 'Y' is a consonant unless it follows another consonant, +** in which case it is a vowel. +** +** In these routine, the letters are in reverse order. So the 'y' rule +** is that 'y' is a consonant unless it is followed by another +** consonent. +*/ +static int isVowel(const char*); +static int isConsonant(const char *z){ + int j; + char x = *z; + if( x==0 ) return 0; + assert( x>='a' && x<='z' ); + j = cType[x-'a']; + if( j<2 ) return j; + return z[1]==0 || isVowel(z + 1); +} +static int isVowel(const char *z){ + int j; + char x = *z; + if( x==0 ) return 0; + assert( x>='a' && x<='z' ); + j = cType[x-'a']; + if( j<2 ) return 1-j; + return isConsonant(z + 1); +} + +/* +** Let any sequence of one or more vowels be represented by V and let +** C be sequence of one or more consonants. Then every word can be +** represented as: +** +** [C] (VC){m} [V] +** +** In prose: A word is an optional consonant followed by zero or +** vowel-consonant pairs followed by an optional vowel. "m" is the +** number of vowel consonant pairs. This routine computes the value +** of m for the first i bytes of a word. +** +** Return true if the m-value for z is 1 or more. In other words, +** return true if z contains at least one vowel that is followed +** by a consonant. +** +** In this routine z[] is in reverse order. So we are really looking +** for an instance of a consonant followed by a vowel. +*/ +static int m_gt_0(const char *z){ + while( isVowel(z) ){ z++; } + if( *z==0 ) return 0; + while( isConsonant(z) ){ z++; } + return *z!=0; +} + +/* Like mgt0 above except we are looking for a value of m which is +** exactly 1 +*/ +static int m_eq_1(const char *z){ + while( isVowel(z) ){ z++; } + if( *z==0 ) return 0; + while( isConsonant(z) ){ z++; } + if( *z==0 ) return 0; + while( isVowel(z) ){ z++; } + if( *z==0 ) return 1; + while( isConsonant(z) ){ z++; } + return *z==0; +} + +/* Like mgt0 above except we are looking for a value of m>1 instead +** or m>0 +*/ +static int m_gt_1(const char *z){ + while( isVowel(z) ){ z++; } + if( *z==0 ) return 0; + while( isConsonant(z) ){ z++; } + if( *z==0 ) return 0; + while( isVowel(z) ){ z++; } + if( *z==0 ) return 0; + while( isConsonant(z) ){ z++; } + return *z!=0; +} + +/* +** Return TRUE if there is a vowel anywhere within z[0..n-1] +*/ +static int hasVowel(const char *z){ + while( isConsonant(z) ){ z++; } + return *z!=0; +} + +/* +** Return TRUE if the word ends in a double consonant. +** +** The text is reversed here. So we are really looking at +** the first two characters of z[]. +*/ +static int doubleConsonant(const char *z){ + return isConsonant(z) && z[0]==z[1]; +} + +/* +** Return TRUE if the word ends with three letters which +** are consonant-vowel-consonent and where the final consonant +** is not 'w', 'x', or 'y'. +** +** The word is reversed here. So we are really checking the +** first three letters and the first one cannot be in [wxy]. +*/ +static int star_oh(const char *z){ + return + isConsonant(z) && + z[0]!='w' && z[0]!='x' && z[0]!='y' && + isVowel(z+1) && + isConsonant(z+2); +} + +/* +** If the word ends with zFrom and xCond() is true for the stem +** of the word that preceeds the zFrom ending, then change the +** ending to zTo. +** +** The input word *pz and zFrom are both in reverse order. zTo +** is in normal order. +** +** Return TRUE if zFrom matches. Return FALSE if zFrom does not +** match. Not that TRUE is returned even if xCond() fails and +** no substitution occurs. +*/ +static int stem( + char **pz, /* The word being stemmed (Reversed) */ + const char *zFrom, /* If the ending matches this... (Reversed) */ + const char *zTo, /* ... change the ending to this (not reversed) */ + int (*xCond)(const char*) /* Condition that must be true */ +){ + char *z = *pz; + while( *zFrom && *zFrom==*z ){ z++; zFrom++; } + if( *zFrom!=0 ) return 0; + if( xCond && !xCond(z) ) return 1; + while( *zTo ){ + *(--z) = *(zTo++); + } + *pz = z; + return 1; +} + +/* +** This is the fallback stemmer used when the porter stemmer is +** inappropriate. The input word is copied into the output with +** US-ASCII case folding. If the input word is too long (more +** than 20 bytes if it contains no digits or more than 6 bytes if +** it contains digits) then word is truncated to 20 or 6 bytes +** by taking 10 or 3 bytes from the beginning and end. +*/ +static void copy_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){ + int i, mx, j; + int hasDigit = 0; + for(i=0; i='A' && c<='Z' ){ + zOut[i] = c - 'A' + 'a'; + }else{ + if( c>='0' && c<='9' ) hasDigit = 1; + zOut[i] = c; + } + } + mx = hasDigit ? 3 : 10; + if( nIn>mx*2 ){ + for(j=mx, i=nIn-mx; i=(int)sizeof(zReverse)-7 ){ + /* The word is too big or too small for the porter stemmer. + ** Fallback to the copy stemmer */ + copy_stemmer(zIn, nIn, zOut, pnOut); + return; + } + for(i=0, j=sizeof(zReverse)-6; i='A' && c<='Z' ){ + zReverse[j] = c + 'a' - 'A'; + }else if( c>='a' && c<='z' ){ + zReverse[j] = c; + }else{ + /* The use of a character not in [a-zA-Z] means that we fallback + ** to the copy stemmer */ + copy_stemmer(zIn, nIn, zOut, pnOut); + return; + } + } + memset(&zReverse[sizeof(zReverse)-5], 0, 5); + z = &zReverse[j+1]; + + + /* Step 1a */ + if( z[0]=='s' ){ + if( + !stem(&z, "sess", "ss", 0) && + !stem(&z, "sei", "i", 0) && + !stem(&z, "ss", "ss", 0) + ){ + z++; + } + } + + /* Step 1b */ + z2 = z; + if( stem(&z, "dee", "ee", m_gt_0) ){ + /* Do nothing. The work was all in the test */ + }else if( + (stem(&z, "gni", "", hasVowel) || stem(&z, "de", "", hasVowel)) + && z!=z2 + ){ + if( stem(&z, "ta", "ate", 0) || + stem(&z, "lb", "ble", 0) || + stem(&z, "zi", "ize", 0) ){ + /* Do nothing. The work was all in the test */ + }else if( doubleConsonant(z) && (*z!='l' && *z!='s' && *z!='z') ){ + z++; + }else if( m_eq_1(z) && star_oh(z) ){ + *(--z) = 'e'; + } + } + + /* Step 1c */ + if( z[0]=='y' && hasVowel(z+1) ){ + z[0] = 'i'; + } + + /* Step 2 */ + switch( z[1] ){ + case 'a': + if( !stem(&z, "lanoita", "ate", m_gt_0) ){ + stem(&z, "lanoit", "tion", m_gt_0); + } + break; + case 'c': + if( !stem(&z, "icne", "ence", m_gt_0) ){ + stem(&z, "icna", "ance", m_gt_0); + } + break; + case 'e': + stem(&z, "rezi", "ize", m_gt_0); + break; + case 'g': + stem(&z, "igol", "log", m_gt_0); + break; + case 'l': + if( !stem(&z, "ilb", "ble", m_gt_0) + && !stem(&z, "illa", "al", m_gt_0) + && !stem(&z, "iltne", "ent", m_gt_0) + && !stem(&z, "ile", "e", m_gt_0) + ){ + stem(&z, "ilsuo", "ous", m_gt_0); + } + break; + case 'o': + if( !stem(&z, "noitazi", "ize", m_gt_0) + && !stem(&z, "noita", "ate", m_gt_0) + ){ + stem(&z, "rota", "ate", m_gt_0); + } + break; + case 's': + if( !stem(&z, "msila", "al", m_gt_0) + && !stem(&z, "ssenevi", "ive", m_gt_0) + && !stem(&z, "ssenluf", "ful", m_gt_0) + ){ + stem(&z, "ssensuo", "ous", m_gt_0); + } + break; + case 't': + if( !stem(&z, "itila", "al", m_gt_0) + && !stem(&z, "itivi", "ive", m_gt_0) + ){ + stem(&z, "itilib", "ble", m_gt_0); + } + break; + } + + /* Step 3 */ + switch( z[0] ){ + case 'e': + if( !stem(&z, "etaci", "ic", m_gt_0) + && !stem(&z, "evita", "", m_gt_0) + ){ + stem(&z, "ezila", "al", m_gt_0); + } + break; + case 'i': + stem(&z, "itici", "ic", m_gt_0); + break; + case 'l': + if( !stem(&z, "laci", "ic", m_gt_0) ){ + stem(&z, "luf", "", m_gt_0); + } + break; + case 's': + stem(&z, "ssen", "", m_gt_0); + break; + } + + /* Step 4 */ + switch( z[1] ){ + case 'a': + if( z[0]=='l' && m_gt_1(z+2) ){ + z += 2; + } + break; + case 'c': + if( z[0]=='e' && z[2]=='n' && (z[3]=='a' || z[3]=='e') && m_gt_1(z+4) ){ + z += 4; + } + break; + case 'e': + if( z[0]=='r' && m_gt_1(z+2) ){ + z += 2; + } + break; + case 'i': + if( z[0]=='c' && m_gt_1(z+2) ){ + z += 2; + } + break; + case 'l': + if( z[0]=='e' && z[2]=='b' && (z[3]=='a' || z[3]=='i') && m_gt_1(z+4) ){ + z += 4; + } + break; + case 'n': + if( z[0]=='t' ){ + if( z[2]=='a' ){ + if( m_gt_1(z+3) ){ + z += 3; + } + }else if( z[2]=='e' ){ + if( !stem(&z, "tneme", "", m_gt_1) + && !stem(&z, "tnem", "", m_gt_1) + ){ + stem(&z, "tne", "", m_gt_1); + } + } + } + break; + case 'o': + if( z[0]=='u' ){ + if( m_gt_1(z+2) ){ + z += 2; + } + }else if( z[3]=='s' || z[3]=='t' ){ + stem(&z, "noi", "", m_gt_1); + } + break; + case 's': + if( z[0]=='m' && z[2]=='i' && m_gt_1(z+3) ){ + z += 3; + } + break; + case 't': + if( !stem(&z, "eta", "", m_gt_1) ){ + stem(&z, "iti", "", m_gt_1); + } + break; + case 'u': + if( z[0]=='s' && z[2]=='o' && m_gt_1(z+3) ){ + z += 3; + } + break; + case 'v': + case 'z': + if( z[0]=='e' && z[2]=='i' && m_gt_1(z+3) ){ + z += 3; + } + break; + } + + /* Step 5a */ + if( z[0]=='e' ){ + if( m_gt_1(z+1) ){ + z++; + }else if( m_eq_1(z+1) && !star_oh(z+1) ){ + z++; + } + } + + /* Step 5b */ + if( m_gt_1(z) && z[0]=='l' && z[1]=='l' ){ + z++; + } + + /* z[] is now the stemmed word in reverse order. Flip it back + ** around into forward order and return. + */ + *pnOut = i = (int)strlen(z); + zOut[i] = 0; + while( *z ){ + zOut[--i] = *(z++); + } +} + +/* +** Characters that can be part of a token. We assume any character +** whose value is greater than 0x80 (any UTF character) can be +** part of a token. In other words, delimiters all must have +** values of 0x7f or lower. +*/ +static const char porterIdChar[] = { +/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ + 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 isDelim(C) (((ch=C)&0x80)==0 && (ch<0x30 || !porterIdChar[ch-0x30])) + +/* +** Extract the next token from a tokenization cursor. The cursor must +** have been opened by a prior call to porterOpen(). +*/ +static int porterNext( + sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by porterOpen */ + const char **pzToken, /* OUT: *pzToken is the token text */ + int *pnBytes, /* OUT: Number of bytes in token */ + int *piStartOffset, /* OUT: Starting offset of token */ + int *piEndOffset, /* OUT: Ending offset of token */ + int *piPosition /* OUT: Position integer of token */ +){ + porter_tokenizer_cursor *c = (porter_tokenizer_cursor *) pCursor; + const char *z = c->zInput; + + while( c->iOffsetnInput ){ + int iStartOffset, ch; + + /* Scan past delimiter characters */ + while( c->iOffsetnInput && isDelim(z[c->iOffset]) ){ + c->iOffset++; + } + + /* Count non-delimiter characters. */ + iStartOffset = c->iOffset; + while( c->iOffsetnInput && !isDelim(z[c->iOffset]) ){ + c->iOffset++; + } + + if( c->iOffset>iStartOffset ){ + int n = c->iOffset-iStartOffset; + if( n>c->nAllocated ){ + char *pNew; + c->nAllocated = n+20; + pNew = sqlite3_realloc(c->zToken, c->nAllocated); + if( !pNew ) return SQLITE_NOMEM; + c->zToken = pNew; + } + porter_stemmer(&z[iStartOffset], n, c->zToken, pnBytes); + *pzToken = c->zToken; + *piStartOffset = iStartOffset; + *piEndOffset = c->iOffset; + *piPosition = c->iToken++; + return SQLITE_OK; + } + } + return SQLITE_DONE; +} + +/* +** The set of routines that implement the porter-stemmer tokenizer +*/ +static const sqlite3_tokenizer_module porterTokenizerModule = { + 0, + porterCreate, + porterDestroy, + porterOpen, + porterClose, + porterNext, + 0 +}; + +/* +** Allocate a new porter tokenizer. Return a pointer to the new +** tokenizer in *ppModule +*/ +SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule( + sqlite3_tokenizer_module const**ppModule +){ + *ppModule = &porterTokenizerModule; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_porter.c *****************************************/ +/************** Begin file fts3_tokenizer.c **********************************/ +/* +** 2007 June 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 is part of an SQLite module implementing full-text search. +** This particular file implements the generic tokenizer interface. +*/ + +/* +** The code in this file is only compiled if: +** +** * The FTS3 module is being built as an extension +** (in which case SQLITE_CORE is not defined), or +** +** * The FTS3 module is being built into the core of +** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). +*/ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ + +/* +** Implementation of the SQL scalar function for accessing the underlying +** hash table. This function may be called as follows: +** +** SELECT (); +** SELECT (, ); +** +** where is the name passed as the second argument +** to the sqlite3Fts3InitHashTable() function (e.g. 'fts3_tokenizer'). +** +** If the argument is specified, it must be a blob value +** containing a pointer to be stored as the hash data corresponding +** to the string . If is not specified, then +** the string must already exist in the has table. Otherwise, +** an error is returned. +** +** Whether or not the argument is specified, the value returned +** is a blob containing the pointer stored as the hash data corresponding +** to string (after the hash-table is updated, if applicable). +*/ +static void scalarFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + Fts3Hash *pHash; + void *pPtr = 0; + const unsigned char *zName; + int nName; + + assert( argc==1 || argc==2 ); + + pHash = (Fts3Hash *)sqlite3_user_data(context); + + zName = sqlite3_value_text(argv[0]); + nName = sqlite3_value_bytes(argv[0])+1; + + if( argc==2 ){ + void *pOld; + int n = sqlite3_value_bytes(argv[1]); + if( zName==0 || n!=sizeof(pPtr) ){ + sqlite3_result_error(context, "argument type mismatch", -1); + return; + } + pPtr = *(void **)sqlite3_value_blob(argv[1]); + pOld = sqlite3Fts3HashInsert(pHash, (void *)zName, nName, pPtr); + if( pOld==pPtr ){ + sqlite3_result_error(context, "out of memory", -1); + return; + } + }else{ + if( zName ){ + pPtr = sqlite3Fts3HashFind(pHash, zName, nName); + } + if( !pPtr ){ + char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName); + sqlite3_result_error(context, zErr, -1); + sqlite3_free(zErr); + return; + } + } + + sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT); +} + +SQLITE_PRIVATE int sqlite3Fts3IsIdChar(char c){ + static const char isFtsIdChar[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */ + 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 */ + }; + return (c&0x80 || isFtsIdChar[(int)(c)]); +} + +SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *zStr, int *pn){ + const char *z1; + const char *z2 = 0; + + /* Find the start of the next token. */ + z1 = zStr; + while( z2==0 ){ + char c = *z1; + switch( c ){ + case '\0': return 0; /* No more tokens here */ + case '\'': + case '"': + case '`': { + z2 = z1; + while( *++z2 && (*z2!=c || *++z2==c) ); + break; + } + case '[': + z2 = &z1[1]; + while( *z2 && z2[0]!=']' ) z2++; + if( *z2 ) z2++; + break; + + default: + if( sqlite3Fts3IsIdChar(*z1) ){ + z2 = &z1[1]; + while( sqlite3Fts3IsIdChar(*z2) ) z2++; + }else{ + z1++; + } + } + } + + *pn = (int)(z2-z1); + return z1; +} + +SQLITE_PRIVATE int sqlite3Fts3InitTokenizer( + Fts3Hash *pHash, /* Tokenizer hash table */ + const char *zArg, /* Tokenizer name */ + sqlite3_tokenizer **ppTok, /* OUT: Tokenizer (if applicable) */ + char **pzErr /* OUT: Set to malloced error message */ +){ + int rc; + char *z = (char *)zArg; + int n = 0; + char *zCopy; + char *zEnd; /* Pointer to nul-term of zCopy */ + sqlite3_tokenizer_module *m; + + zCopy = sqlite3_mprintf("%s", zArg); + if( !zCopy ) return SQLITE_NOMEM; + zEnd = &zCopy[strlen(zCopy)]; + + z = (char *)sqlite3Fts3NextToken(zCopy, &n); + if( z==0 ){ + assert( n==0 ); + z = zCopy; + } + z[n] = '\0'; + sqlite3Fts3Dequote(z); + + m = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash,z,(int)strlen(z)+1); + if( !m ){ + sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", z); + rc = SQLITE_ERROR; + }else{ + char const **aArg = 0; + int iArg = 0; + z = &z[n+1]; + while( zxCreate(iArg, aArg, ppTok); + assert( rc!=SQLITE_OK || *ppTok ); + if( rc!=SQLITE_OK ){ + sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer"); + }else{ + (*ppTok)->pModule = m; + } + sqlite3_free((void *)aArg); + } + + sqlite3_free(zCopy); + return rc; +} + + +#ifdef SQLITE_TEST + +#include +/* #include */ + +/* +** Implementation of a special SQL scalar function for testing tokenizers +** designed to be used in concert with the Tcl testing framework. This +** function must be called with two or more arguments: +** +** SELECT (, ..., ); +** +** where is the name passed as the second argument +** to the sqlite3Fts3InitHashTable() function (e.g. 'fts3_tokenizer') +** concatenated with the string '_test' (e.g. 'fts3_tokenizer_test'). +** +** The return value is a string that may be interpreted as a Tcl +** list. For each token in the , three elements are +** added to the returned list. The first is the token position, the +** second is the token text (folded, stemmed, etc.) and the third is the +** substring of associated with the token. For example, +** using the built-in "simple" tokenizer: +** +** SELECT fts_tokenizer_test('simple', 'I don't see how'); +** +** will return the string: +** +** "{0 i I 1 dont don't 2 see see 3 how how}" +** +*/ +static void testFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + Fts3Hash *pHash; + sqlite3_tokenizer_module *p; + sqlite3_tokenizer *pTokenizer = 0; + sqlite3_tokenizer_cursor *pCsr = 0; + + const char *zErr = 0; + + const char *zName; + int nName; + const char *zInput; + int nInput; + + const char *azArg[64]; + + const char *zToken; + int nToken = 0; + int iStart = 0; + int iEnd = 0; + int iPos = 0; + int i; + + Tcl_Obj *pRet; + + if( argc<2 ){ + sqlite3_result_error(context, "insufficient arguments", -1); + return; + } + + nName = sqlite3_value_bytes(argv[0]); + zName = (const char *)sqlite3_value_text(argv[0]); + nInput = sqlite3_value_bytes(argv[argc-1]); + zInput = (const char *)sqlite3_value_text(argv[argc-1]); + + pHash = (Fts3Hash *)sqlite3_user_data(context); + p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1); + + if( !p ){ + char *zErr2 = sqlite3_mprintf("unknown tokenizer: %s", zName); + sqlite3_result_error(context, zErr2, -1); + sqlite3_free(zErr2); + return; + } + + pRet = Tcl_NewObj(); + Tcl_IncrRefCount(pRet); + + for(i=1; ixCreate(argc-2, azArg, &pTokenizer) ){ + zErr = "error in xCreate()"; + goto finish; + } + pTokenizer->pModule = p; + if( sqlite3Fts3OpenTokenizer(pTokenizer, 0, zInput, nInput, &pCsr) ){ + zErr = "error in xOpen()"; + goto finish; + } + + while( SQLITE_OK==p->xNext(pCsr, &zToken, &nToken, &iStart, &iEnd, &iPos) ){ + Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(iPos)); + Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zToken, nToken)); + zToken = &zInput[iStart]; + nToken = iEnd-iStart; + Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zToken, nToken)); + } + + if( SQLITE_OK!=p->xClose(pCsr) ){ + zErr = "error in xClose()"; + goto finish; + } + if( SQLITE_OK!=p->xDestroy(pTokenizer) ){ + zErr = "error in xDestroy()"; + goto finish; + } + +finish: + if( zErr ){ + sqlite3_result_error(context, zErr, -1); + }else{ + sqlite3_result_text(context, Tcl_GetString(pRet), -1, SQLITE_TRANSIENT); + } + Tcl_DecrRefCount(pRet); +} + +static +int registerTokenizer( + sqlite3 *db, + char *zName, + const sqlite3_tokenizer_module *p +){ + int rc; + sqlite3_stmt *pStmt; + const char zSql[] = "SELECT fts3_tokenizer(?, ?)"; + + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + + sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); + sqlite3_bind_blob(pStmt, 2, &p, sizeof(p), SQLITE_STATIC); + sqlite3_step(pStmt); + + return sqlite3_finalize(pStmt); +} + +static +int queryTokenizer( + sqlite3 *db, + char *zName, + const sqlite3_tokenizer_module **pp +){ + int rc; + sqlite3_stmt *pStmt; + const char zSql[] = "SELECT fts3_tokenizer(?)"; + + *pp = 0; + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + + sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){ + memcpy((void *)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp)); + } + } + + return sqlite3_finalize(pStmt); +} + +SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule); + +/* +** Implementation of the scalar function fts3_tokenizer_internal_test(). +** This function is used for testing only, it is not included in the +** build unless SQLITE_TEST is defined. +** +** The purpose of this is to test that the fts3_tokenizer() function +** can be used as designed by the C-code in the queryTokenizer and +** registerTokenizer() functions above. These two functions are repeated +** in the README.tokenizer file as an example, so it is important to +** test them. +** +** To run the tests, evaluate the fts3_tokenizer_internal_test() scalar +** function with no arguments. An assert() will fail if a problem is +** detected. i.e.: +** +** SELECT fts3_tokenizer_internal_test(); +** +*/ +static void intTestFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int rc; + const sqlite3_tokenizer_module *p1; + const sqlite3_tokenizer_module *p2; + sqlite3 *db = (sqlite3 *)sqlite3_user_data(context); + + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(argv); + + /* Test the query function */ + sqlite3Fts3SimpleTokenizerModule(&p1); + rc = queryTokenizer(db, "simple", &p2); + assert( rc==SQLITE_OK ); + assert( p1==p2 ); + rc = queryTokenizer(db, "nosuchtokenizer", &p2); + assert( rc==SQLITE_ERROR ); + assert( p2==0 ); + assert( 0==strcmp(sqlite3_errmsg(db), "unknown tokenizer: nosuchtokenizer") ); + + /* Test the storage function */ + rc = registerTokenizer(db, "nosuchtokenizer", p1); + assert( rc==SQLITE_OK ); + rc = queryTokenizer(db, "nosuchtokenizer", &p2); + assert( rc==SQLITE_OK ); + assert( p2==p1 ); + + sqlite3_result_text(context, "ok", -1, SQLITE_STATIC); +} + +#endif + +/* +** Set up SQL objects in database db used to access the contents of +** the hash table pointed to by argument pHash. The hash table must +** been initialized to use string keys, and to take a private copy +** of the key when a value is inserted. i.e. by a call similar to: +** +** sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1); +** +** This function adds a scalar function (see header comment above +** scalarFunc() in this file for details) and, if ENABLE_TABLE is +** defined at compilation time, a temporary virtual table (see header +** comment above struct HashTableVtab) to the database schema. Both +** provide read/write access to the contents of *pHash. +** +** The third argument to this function, zName, is used as the name +** of both the scalar and, if created, the virtual table. +*/ +SQLITE_PRIVATE int sqlite3Fts3InitHashTable( + sqlite3 *db, + Fts3Hash *pHash, + const char *zName +){ + int rc = SQLITE_OK; + void *p = (void *)pHash; + const int any = SQLITE_ANY; + +#ifdef SQLITE_TEST + char *zTest = 0; + char *zTest2 = 0; + void *pdb = (void *)db; + zTest = sqlite3_mprintf("%s_test", zName); + zTest2 = sqlite3_mprintf("%s_internal_test", zName); + if( !zTest || !zTest2 ){ + rc = SQLITE_NOMEM; + } +#endif + + if( SQLITE_OK==rc ){ + rc = sqlite3_create_function(db, zName, 1, any, p, scalarFunc, 0, 0); + } + if( SQLITE_OK==rc ){ + rc = sqlite3_create_function(db, zName, 2, any, p, scalarFunc, 0, 0); + } +#ifdef SQLITE_TEST + if( SQLITE_OK==rc ){ + rc = sqlite3_create_function(db, zTest, -1, any, p, testFunc, 0, 0); + } + if( SQLITE_OK==rc ){ + rc = sqlite3_create_function(db, zTest2, 0, any, pdb, intTestFunc, 0, 0); + } +#endif + +#ifdef SQLITE_TEST + sqlite3_free(zTest); + sqlite3_free(zTest2); +#endif + + return rc; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_tokenizer.c **************************************/ +/************** Begin file fts3_tokenizer1.c *********************************/ +/* +** 2006 Oct 10 +** +** 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. +** +****************************************************************************** +** +** Implementation of the "simple" full-text-search tokenizer. +*/ + +/* +** The code in this file is only compiled if: +** +** * The FTS3 module is being built as an extension +** (in which case SQLITE_CORE is not defined), or +** +** * The FTS3 module is being built into the core of +** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). +*/ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ +/* #include */ +/* #include */ + + +typedef struct simple_tokenizer { + sqlite3_tokenizer base; + char delim[128]; /* flag ASCII delimiters */ +} simple_tokenizer; + +typedef struct simple_tokenizer_cursor { + sqlite3_tokenizer_cursor base; + const char *pInput; /* input we are tokenizing */ + int nBytes; /* size of the input */ + int iOffset; /* current position in pInput */ + int iToken; /* index of next token to be returned */ + char *pToken; /* storage for current token */ + int nTokenAllocated; /* space allocated to zToken buffer */ +} simple_tokenizer_cursor; + + +static int simpleDelim(simple_tokenizer *t, unsigned char c){ + return c<0x80 && t->delim[c]; +} +static int fts3_isalnum(int x){ + return (x>='0' && x<='9') || (x>='A' && x<='Z') || (x>='a' && x<='z'); +} + +/* +** Create a new tokenizer instance. +*/ +static int simpleCreate( + int argc, const char * const *argv, + sqlite3_tokenizer **ppTokenizer +){ + simple_tokenizer *t; + + t = (simple_tokenizer *) sqlite3_malloc(sizeof(*t)); + if( t==NULL ) return SQLITE_NOMEM; + memset(t, 0, sizeof(*t)); + + /* TODO(shess) Delimiters need to remain the same from run to run, + ** else we need to reindex. One solution would be a meta-table to + ** track such information in the database, then we'd only want this + ** information on the initial create. + */ + if( argc>1 ){ + int i, n = (int)strlen(argv[1]); + for(i=0; i=0x80 ){ + sqlite3_free(t); + return SQLITE_ERROR; + } + t->delim[ch] = 1; + } + } else { + /* Mark non-alphanumeric ASCII characters as delimiters */ + int i; + for(i=1; i<0x80; i++){ + t->delim[i] = !fts3_isalnum(i) ? -1 : 0; + } + } + + *ppTokenizer = &t->base; + return SQLITE_OK; +} + +/* +** Destroy a tokenizer +*/ +static int simpleDestroy(sqlite3_tokenizer *pTokenizer){ + sqlite3_free(pTokenizer); + return SQLITE_OK; +} + +/* +** Prepare to begin tokenizing a particular string. The input +** string to be tokenized is pInput[0..nBytes-1]. A cursor +** used to incrementally tokenize this string is returned in +** *ppCursor. +*/ +static int simpleOpen( + sqlite3_tokenizer *pTokenizer, /* The tokenizer */ + const char *pInput, int nBytes, /* String to be tokenized */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */ +){ + simple_tokenizer_cursor *c; + + UNUSED_PARAMETER(pTokenizer); + + c = (simple_tokenizer_cursor *) sqlite3_malloc(sizeof(*c)); + if( c==NULL ) return SQLITE_NOMEM; + + c->pInput = pInput; + if( pInput==0 ){ + c->nBytes = 0; + }else if( nBytes<0 ){ + c->nBytes = (int)strlen(pInput); + }else{ + c->nBytes = nBytes; + } + c->iOffset = 0; /* start tokenizing at the beginning */ + c->iToken = 0; + c->pToken = NULL; /* no space allocated, yet. */ + c->nTokenAllocated = 0; + + *ppCursor = &c->base; + return SQLITE_OK; +} + +/* +** Close a tokenization cursor previously opened by a call to +** simpleOpen() above. +*/ +static int simpleClose(sqlite3_tokenizer_cursor *pCursor){ + simple_tokenizer_cursor *c = (simple_tokenizer_cursor *) pCursor; + sqlite3_free(c->pToken); + sqlite3_free(c); + return SQLITE_OK; +} + +/* +** Extract the next token from a tokenization cursor. The cursor must +** have been opened by a prior call to simpleOpen(). +*/ +static int simpleNext( + sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by simpleOpen */ + const char **ppToken, /* OUT: *ppToken is the token text */ + int *pnBytes, /* OUT: Number of bytes in token */ + int *piStartOffset, /* OUT: Starting offset of token */ + int *piEndOffset, /* OUT: Ending offset of token */ + int *piPosition /* OUT: Position integer of token */ +){ + simple_tokenizer_cursor *c = (simple_tokenizer_cursor *) pCursor; + simple_tokenizer *t = (simple_tokenizer *) pCursor->pTokenizer; + unsigned char *p = (unsigned char *)c->pInput; + + while( c->iOffsetnBytes ){ + int iStartOffset; + + /* Scan past delimiter characters */ + while( c->iOffsetnBytes && simpleDelim(t, p[c->iOffset]) ){ + c->iOffset++; + } + + /* Count non-delimiter characters. */ + iStartOffset = c->iOffset; + while( c->iOffsetnBytes && !simpleDelim(t, p[c->iOffset]) ){ + c->iOffset++; + } + + if( c->iOffset>iStartOffset ){ + int i, n = c->iOffset-iStartOffset; + if( n>c->nTokenAllocated ){ + char *pNew; + c->nTokenAllocated = n+20; + pNew = sqlite3_realloc(c->pToken, c->nTokenAllocated); + if( !pNew ) return SQLITE_NOMEM; + c->pToken = pNew; + } + for(i=0; ipToken[i] = (char)((ch>='A' && ch<='Z') ? ch-'A'+'a' : ch); + } + *ppToken = c->pToken; + *pnBytes = n; + *piStartOffset = iStartOffset; + *piEndOffset = c->iOffset; + *piPosition = c->iToken++; + + return SQLITE_OK; + } + } + return SQLITE_DONE; +} + +/* +** The set of routines that implement the simple tokenizer +*/ +static const sqlite3_tokenizer_module simpleTokenizerModule = { + 0, + simpleCreate, + simpleDestroy, + simpleOpen, + simpleClose, + simpleNext, + 0, +}; + +/* +** Allocate a new simple tokenizer. Return a pointer to the new +** tokenizer in *ppModule +*/ +SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule( + sqlite3_tokenizer_module const**ppModule +){ + *ppModule = &simpleTokenizerModule; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_tokenizer1.c *************************************/ +/************** Begin file fts3_tokenize_vtab.c ******************************/ +/* +** 2013 Apr 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 file contains code for the "fts3tokenize" virtual table module. +** An fts3tokenize virtual table is created as follows: +** +** CREATE VIRTUAL TABLE USING fts3tokenize( +** , , ... +** ); +** +** The table created has the following schema: +** +** CREATE TABLE (input, token, start, end, position) +** +** When queried, the query must include a WHERE clause of type: +** +** input = +** +** The virtual table module tokenizes this , using the FTS3 +** tokenizer specified by the arguments to the CREATE VIRTUAL TABLE +** statement and returns one row for each token in the result. With +** fields set as follows: +** +** input: Always set to a copy of +** token: A token from the input. +** start: Byte offset of the token within the input . +** end: Byte offset of the byte immediately following the end of the +** token within the input string. +** pos: Token offset of token within input. +** +*/ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ + +typedef struct Fts3tokTable Fts3tokTable; +typedef struct Fts3tokCursor Fts3tokCursor; + +/* +** Virtual table structure. +*/ +struct Fts3tokTable { + sqlite3_vtab base; /* Base class used by SQLite core */ + const sqlite3_tokenizer_module *pMod; + sqlite3_tokenizer *pTok; +}; + +/* +** Virtual table cursor structure. +*/ +struct Fts3tokCursor { + sqlite3_vtab_cursor base; /* Base class used by SQLite core */ + char *zInput; /* Input string */ + sqlite3_tokenizer_cursor *pCsr; /* Cursor to iterate through zInput */ + int iRowid; /* Current 'rowid' value */ + const char *zToken; /* Current 'token' value */ + int nToken; /* Size of zToken in bytes */ + int iStart; /* Current 'start' value */ + int iEnd; /* Current 'end' value */ + int iPos; /* Current 'pos' value */ +}; + +/* +** Query FTS for the tokenizer implementation named zName. +*/ +static int fts3tokQueryTokenizer( + Fts3Hash *pHash, + const char *zName, + const sqlite3_tokenizer_module **pp, + char **pzErr +){ + sqlite3_tokenizer_module *p; + int nName = (int)strlen(zName); + + p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1); + if( !p ){ + sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", zName); + return SQLITE_ERROR; + } + + *pp = p; + return SQLITE_OK; +} + +/* +** The second argument, argv[], is an array of pointers to nul-terminated +** strings. This function makes a copy of the array and strings into a +** single block of memory. It then dequotes any of the strings that appear +** to be quoted. +** +** If successful, output parameter *pazDequote is set to point at the +** array of dequoted strings and SQLITE_OK is returned. The caller is +** responsible for eventually calling sqlite3_free() to free the array +** in this case. Or, if an error occurs, an SQLite error code is returned. +** The final value of *pazDequote is undefined in this case. +*/ +static int fts3tokDequoteArray( + int argc, /* Number of elements in argv[] */ + const char * const *argv, /* Input array */ + char ***pazDequote /* Output array */ +){ + int rc = SQLITE_OK; /* Return code */ + if( argc==0 ){ + *pazDequote = 0; + }else{ + int i; + int nByte = 0; + char **azDequote; + + for(i=0; ixCreate((nDequote>1 ? nDequote-1 : 0), azArg, &pTok); + } + + if( rc==SQLITE_OK ){ + pTab = (Fts3tokTable *)sqlite3_malloc(sizeof(Fts3tokTable)); + if( pTab==0 ){ + rc = SQLITE_NOMEM; + } + } + + if( rc==SQLITE_OK ){ + memset(pTab, 0, sizeof(Fts3tokTable)); + pTab->pMod = pMod; + pTab->pTok = pTok; + *ppVtab = &pTab->base; + }else{ + if( pTok ){ + pMod->xDestroy(pTok); + } + } + + sqlite3_free(azDequote); + return rc; +} + +/* +** This function does the work for both the xDisconnect and xDestroy methods. +** These tables have no persistent representation of their own, so xDisconnect +** and xDestroy are identical operations. +*/ +static int fts3tokDisconnectMethod(sqlite3_vtab *pVtab){ + Fts3tokTable *pTab = (Fts3tokTable *)pVtab; + + pTab->pMod->xDestroy(pTab->pTok); + sqlite3_free(pTab); + return SQLITE_OK; +} + +/* +** xBestIndex - Analyze a WHERE and ORDER BY clause. +*/ +static int fts3tokBestIndexMethod( + sqlite3_vtab *pVTab, + sqlite3_index_info *pInfo +){ + int i; + UNUSED_PARAMETER(pVTab); + + for(i=0; inConstraint; i++){ + if( pInfo->aConstraint[i].usable + && pInfo->aConstraint[i].iColumn==0 + && pInfo->aConstraint[i].op==SQLITE_INDEX_CONSTRAINT_EQ + ){ + pInfo->idxNum = 1; + pInfo->aConstraintUsage[i].argvIndex = 1; + pInfo->aConstraintUsage[i].omit = 1; + pInfo->estimatedCost = 1; + return SQLITE_OK; + } + } + + pInfo->idxNum = 0; + assert( pInfo->estimatedCost>1000000.0 ); + + return SQLITE_OK; +} + +/* +** xOpen - Open a cursor. +*/ +static int fts3tokOpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ + Fts3tokCursor *pCsr; + UNUSED_PARAMETER(pVTab); + + pCsr = (Fts3tokCursor *)sqlite3_malloc(sizeof(Fts3tokCursor)); + if( pCsr==0 ){ + return SQLITE_NOMEM; + } + memset(pCsr, 0, sizeof(Fts3tokCursor)); + + *ppCsr = (sqlite3_vtab_cursor *)pCsr; + return SQLITE_OK; +} + +/* +** Reset the tokenizer cursor passed as the only argument. As if it had +** just been returned by fts3tokOpenMethod(). +*/ +static void fts3tokResetCursor(Fts3tokCursor *pCsr){ + if( pCsr->pCsr ){ + Fts3tokTable *pTab = (Fts3tokTable *)(pCsr->base.pVtab); + pTab->pMod->xClose(pCsr->pCsr); + pCsr->pCsr = 0; + } + sqlite3_free(pCsr->zInput); + pCsr->zInput = 0; + pCsr->zToken = 0; + pCsr->nToken = 0; + pCsr->iStart = 0; + pCsr->iEnd = 0; + pCsr->iPos = 0; + pCsr->iRowid = 0; +} + +/* +** xClose - Close a cursor. +*/ +static int fts3tokCloseMethod(sqlite3_vtab_cursor *pCursor){ + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; + + fts3tokResetCursor(pCsr); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* +** xNext - Advance the cursor to the next row, if any. +*/ +static int fts3tokNextMethod(sqlite3_vtab_cursor *pCursor){ + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; + Fts3tokTable *pTab = (Fts3tokTable *)(pCursor->pVtab); + int rc; /* Return code */ + + pCsr->iRowid++; + rc = pTab->pMod->xNext(pCsr->pCsr, + &pCsr->zToken, &pCsr->nToken, + &pCsr->iStart, &pCsr->iEnd, &pCsr->iPos + ); + + if( rc!=SQLITE_OK ){ + fts3tokResetCursor(pCsr); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + } + + return rc; +} + +/* +** xFilter - Initialize a cursor to point at the start of its data. +*/ +static int fts3tokFilterMethod( + sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ + int idxNum, /* Strategy index */ + const char *idxStr, /* Unused */ + int nVal, /* Number of elements in apVal */ + sqlite3_value **apVal /* Arguments for the indexing scheme */ +){ + int rc = SQLITE_ERROR; + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; + Fts3tokTable *pTab = (Fts3tokTable *)(pCursor->pVtab); + UNUSED_PARAMETER(idxStr); + UNUSED_PARAMETER(nVal); + + fts3tokResetCursor(pCsr); + if( idxNum==1 ){ + const char *zByte = (const char *)sqlite3_value_text(apVal[0]); + int nByte = sqlite3_value_bytes(apVal[0]); + pCsr->zInput = sqlite3_malloc(nByte+1); + if( pCsr->zInput==0 ){ + rc = SQLITE_NOMEM; + }else{ + memcpy(pCsr->zInput, zByte, nByte); + pCsr->zInput[nByte] = 0; + rc = pTab->pMod->xOpen(pTab->pTok, pCsr->zInput, nByte, &pCsr->pCsr); + if( rc==SQLITE_OK ){ + pCsr->pCsr->pTokenizer = pTab->pTok; + } + } + } + + if( rc!=SQLITE_OK ) return rc; + return fts3tokNextMethod(pCursor); +} + +/* +** xEof - Return true if the cursor is at EOF, or false otherwise. +*/ +static int fts3tokEofMethod(sqlite3_vtab_cursor *pCursor){ + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; + return (pCsr->zToken==0); +} + +/* +** xColumn - Return a column value. +*/ +static int fts3tokColumnMethod( + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ + int iCol /* Index of column to read value from */ +){ + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; + + /* CREATE TABLE x(input, token, start, end, position) */ + switch( iCol ){ + case 0: + sqlite3_result_text(pCtx, pCsr->zInput, -1, SQLITE_TRANSIENT); + break; + case 1: + sqlite3_result_text(pCtx, pCsr->zToken, pCsr->nToken, SQLITE_TRANSIENT); + break; + case 2: + sqlite3_result_int(pCtx, pCsr->iStart); + break; + case 3: + sqlite3_result_int(pCtx, pCsr->iEnd); + break; + default: + assert( iCol==4 ); + sqlite3_result_int(pCtx, pCsr->iPos); + break; + } + return SQLITE_OK; +} + +/* +** xRowid - Return the current rowid for the cursor. +*/ +static int fts3tokRowidMethod( + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite_int64 *pRowid /* OUT: Rowid value */ +){ + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; + *pRowid = (sqlite3_int64)pCsr->iRowid; + return SQLITE_OK; +} + +/* +** Register the fts3tok module with database connection db. Return SQLITE_OK +** if successful or an error code if sqlite3_create_module() fails. +*/ +SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash){ + static const sqlite3_module fts3tok_module = { + 0, /* iVersion */ + fts3tokConnectMethod, /* xCreate */ + fts3tokConnectMethod, /* xConnect */ + fts3tokBestIndexMethod, /* xBestIndex */ + fts3tokDisconnectMethod, /* xDisconnect */ + fts3tokDisconnectMethod, /* xDestroy */ + fts3tokOpenMethod, /* xOpen */ + fts3tokCloseMethod, /* xClose */ + fts3tokFilterMethod, /* xFilter */ + fts3tokNextMethod, /* xNext */ + fts3tokEofMethod, /* xEof */ + fts3tokColumnMethod, /* xColumn */ + fts3tokRowidMethod, /* xRowid */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindFunction */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0 /* xRollbackTo */ + }; + int rc; /* Return code */ + + rc = sqlite3_create_module(db, "fts3tokenize", &fts3tok_module, (void*)pHash); + return rc; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_tokenize_vtab.c **********************************/ +/************** Begin file fts3_write.c **************************************/ +/* +** 2009 Oct 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 is part of the SQLite FTS3 extension module. Specifically, +** this file contains code to insert, update and delete rows from FTS3 +** tables. It also contains code to merge FTS3 b-tree segments. Some +** of the sub-routines used to merge segments are also used by the query +** code in fts3.c. +*/ + +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ +/* #include */ + + +#define FTS_MAX_APPENDABLE_HEIGHT 16 + +/* +** When full-text index nodes are loaded from disk, the buffer that they +** are loaded into has the following number of bytes of padding at the end +** of it. i.e. if a full-text index node is 900 bytes in size, then a buffer +** of 920 bytes is allocated for it. +** +** This means that if we have a pointer into a buffer containing node data, +** it is always safe to read up to two varints from it without risking an +** overread, even if the node data is corrupted. +*/ +#define FTS3_NODE_PADDING (FTS3_VARINT_MAX*2) + +/* +** Under certain circumstances, b-tree nodes (doclists) can be loaded into +** memory incrementally instead of all at once. This can be a big performance +** win (reduced IO and CPU) if SQLite stops calling the virtual table xNext() +** method before retrieving all query results (as may happen, for example, +** if a query has a LIMIT clause). +** +** Incremental loading is used for b-tree nodes FTS3_NODE_CHUNK_THRESHOLD +** bytes and larger. Nodes are loaded in chunks of FTS3_NODE_CHUNKSIZE bytes. +** The code is written so that the hard lower-limit for each of these values +** is 1. Clearly such small values would be inefficient, but can be useful +** for testing purposes. +** +** If this module is built with SQLITE_TEST defined, these constants may +** be overridden at runtime for testing purposes. File fts3_test.c contains +** a Tcl interface to read and write the values. +*/ +#ifdef SQLITE_TEST +int test_fts3_node_chunksize = (4*1024); +int test_fts3_node_chunk_threshold = (4*1024)*4; +# define FTS3_NODE_CHUNKSIZE test_fts3_node_chunksize +# define FTS3_NODE_CHUNK_THRESHOLD test_fts3_node_chunk_threshold +#else +# define FTS3_NODE_CHUNKSIZE (4*1024) +# define FTS3_NODE_CHUNK_THRESHOLD (FTS3_NODE_CHUNKSIZE*4) +#endif + +/* +** The two values that may be meaningfully bound to the :1 parameter in +** statements SQL_REPLACE_STAT and SQL_SELECT_STAT. +*/ +#define FTS_STAT_DOCTOTAL 0 +#define FTS_STAT_INCRMERGEHINT 1 +#define FTS_STAT_AUTOINCRMERGE 2 + +/* +** If FTS_LOG_MERGES is defined, call sqlite3_log() to report each automatic +** and incremental merge operation that takes place. This is used for +** debugging FTS only, it should not usually be turned on in production +** systems. +*/ +#ifdef FTS3_LOG_MERGES +static void fts3LogMerge(int nMerge, sqlite3_int64 iAbsLevel){ + sqlite3_log(SQLITE_OK, "%d-way merge from level %d", nMerge, (int)iAbsLevel); +} +#else +#define fts3LogMerge(x, y) +#endif + + +typedef struct PendingList PendingList; +typedef struct SegmentNode SegmentNode; +typedef struct SegmentWriter SegmentWriter; + +/* +** An instance of the following data structure is used to build doclists +** incrementally. See function fts3PendingListAppend() for details. +*/ +struct PendingList { + int nData; + char *aData; + int nSpace; + sqlite3_int64 iLastDocid; + sqlite3_int64 iLastCol; + sqlite3_int64 iLastPos; +}; + + +/* +** Each cursor has a (possibly empty) linked list of the following objects. +*/ +struct Fts3DeferredToken { + Fts3PhraseToken *pToken; /* Pointer to corresponding expr token */ + int iCol; /* Column token must occur in */ + Fts3DeferredToken *pNext; /* Next in list of deferred tokens */ + PendingList *pList; /* Doclist is assembled here */ +}; + +/* +** An instance of this structure is used to iterate through the terms on +** a contiguous set of segment b-tree leaf nodes. Although the details of +** this structure are only manipulated by code in this file, opaque handles +** of type Fts3SegReader* are also used by code in fts3.c to iterate through +** terms when querying the full-text index. See functions: +** +** sqlite3Fts3SegReaderNew() +** sqlite3Fts3SegReaderFree() +** sqlite3Fts3SegReaderIterate() +** +** Methods used to manipulate Fts3SegReader structures: +** +** fts3SegReaderNext() +** fts3SegReaderFirstDocid() +** fts3SegReaderNextDocid() +*/ +struct Fts3SegReader { + int iIdx; /* Index within level, or 0x7FFFFFFF for PT */ + u8 bLookup; /* True for a lookup only */ + u8 rootOnly; /* True for a root-only reader */ + + sqlite3_int64 iStartBlock; /* Rowid of first leaf block to traverse */ + sqlite3_int64 iLeafEndBlock; /* Rowid of final leaf block to traverse */ + sqlite3_int64 iEndBlock; /* Rowid of final block in segment (or 0) */ + sqlite3_int64 iCurrentBlock; /* Current leaf block (or 0) */ + + char *aNode; /* Pointer to node data (or NULL) */ + int nNode; /* Size of buffer at aNode (or 0) */ + int nPopulate; /* If >0, bytes of buffer aNode[] loaded */ + sqlite3_blob *pBlob; /* If not NULL, blob handle to read node */ + + Fts3HashElem **ppNextElem; + + /* Variables set by fts3SegReaderNext(). These may be read directly + ** by the caller. They are valid from the time SegmentReaderNew() returns + ** until SegmentReaderNext() returns something other than SQLITE_OK + ** (i.e. SQLITE_DONE). + */ + int nTerm; /* Number of bytes in current term */ + char *zTerm; /* Pointer to current term */ + int nTermAlloc; /* Allocated size of zTerm buffer */ + char *aDoclist; /* Pointer to doclist of current entry */ + int nDoclist; /* Size of doclist in current entry */ + + /* The following variables are used by fts3SegReaderNextDocid() to iterate + ** through the current doclist (aDoclist/nDoclist). + */ + char *pOffsetList; + int nOffsetList; /* For descending pending seg-readers only */ + sqlite3_int64 iDocid; +}; + +#define fts3SegReaderIsPending(p) ((p)->ppNextElem!=0) +#define fts3SegReaderIsRootOnly(p) ((p)->rootOnly!=0) + +/* +** An instance of this structure is used to create a segment b-tree in the +** database. The internal details of this type are only accessed by the +** following functions: +** +** fts3SegWriterAdd() +** fts3SegWriterFlush() +** fts3SegWriterFree() +*/ +struct SegmentWriter { + SegmentNode *pTree; /* Pointer to interior tree structure */ + sqlite3_int64 iFirst; /* First slot in %_segments written */ + sqlite3_int64 iFree; /* Next free slot in %_segments */ + char *zTerm; /* Pointer to previous term buffer */ + int nTerm; /* Number of bytes in zTerm */ + int nMalloc; /* Size of malloc'd buffer at zMalloc */ + char *zMalloc; /* Malloc'd space (possibly) used for zTerm */ + int nSize; /* Size of allocation at aData */ + int nData; /* Bytes of data in aData */ + char *aData; /* Pointer to block from malloc() */ + i64 nLeafData; /* Number of bytes of leaf data written */ +}; + +/* +** Type SegmentNode is used by the following three functions to create +** the interior part of the segment b+-tree structures (everything except +** the leaf nodes). These functions and type are only ever used by code +** within the fts3SegWriterXXX() family of functions described above. +** +** fts3NodeAddTerm() +** fts3NodeWrite() +** fts3NodeFree() +** +** When a b+tree is written to the database (either as a result of a merge +** or the pending-terms table being flushed), leaves are written into the +** database file as soon as they are completely populated. The interior of +** the tree is assembled in memory and written out only once all leaves have +** been populated and stored. This is Ok, as the b+-tree fanout is usually +** very large, meaning that the interior of the tree consumes relatively +** little memory. +*/ +struct SegmentNode { + SegmentNode *pParent; /* Parent node (or NULL for root node) */ + SegmentNode *pRight; /* Pointer to right-sibling */ + SegmentNode *pLeftmost; /* Pointer to left-most node of this depth */ + int nEntry; /* Number of terms written to node so far */ + char *zTerm; /* Pointer to previous term buffer */ + int nTerm; /* Number of bytes in zTerm */ + int nMalloc; /* Size of malloc'd buffer at zMalloc */ + char *zMalloc; /* Malloc'd space (possibly) used for zTerm */ + int nData; /* Bytes of valid data so far */ + char *aData; /* Node data */ +}; + +/* +** Valid values for the second argument to fts3SqlStmt(). +*/ +#define SQL_DELETE_CONTENT 0 +#define SQL_IS_EMPTY 1 +#define SQL_DELETE_ALL_CONTENT 2 +#define SQL_DELETE_ALL_SEGMENTS 3 +#define SQL_DELETE_ALL_SEGDIR 4 +#define SQL_DELETE_ALL_DOCSIZE 5 +#define SQL_DELETE_ALL_STAT 6 +#define SQL_SELECT_CONTENT_BY_ROWID 7 +#define SQL_NEXT_SEGMENT_INDEX 8 +#define SQL_INSERT_SEGMENTS 9 +#define SQL_NEXT_SEGMENTS_ID 10 +#define SQL_INSERT_SEGDIR 11 +#define SQL_SELECT_LEVEL 12 +#define SQL_SELECT_LEVEL_RANGE 13 +#define SQL_SELECT_LEVEL_COUNT 14 +#define SQL_SELECT_SEGDIR_MAX_LEVEL 15 +#define SQL_DELETE_SEGDIR_LEVEL 16 +#define SQL_DELETE_SEGMENTS_RANGE 17 +#define SQL_CONTENT_INSERT 18 +#define SQL_DELETE_DOCSIZE 19 +#define SQL_REPLACE_DOCSIZE 20 +#define SQL_SELECT_DOCSIZE 21 +#define SQL_SELECT_STAT 22 +#define SQL_REPLACE_STAT 23 + +#define SQL_SELECT_ALL_PREFIX_LEVEL 24 +#define SQL_DELETE_ALL_TERMS_SEGDIR 25 +#define SQL_DELETE_SEGDIR_RANGE 26 +#define SQL_SELECT_ALL_LANGID 27 +#define SQL_FIND_MERGE_LEVEL 28 +#define SQL_MAX_LEAF_NODE_ESTIMATE 29 +#define SQL_DELETE_SEGDIR_ENTRY 30 +#define SQL_SHIFT_SEGDIR_ENTRY 31 +#define SQL_SELECT_SEGDIR 32 +#define SQL_CHOMP_SEGDIR 33 +#define SQL_SEGMENT_IS_APPENDABLE 34 +#define SQL_SELECT_INDEXES 35 +#define SQL_SELECT_MXLEVEL 36 + +#define SQL_SELECT_LEVEL_RANGE2 37 +#define SQL_UPDATE_LEVEL_IDX 38 +#define SQL_UPDATE_LEVEL 39 + +/* +** This function is used to obtain an SQLite prepared statement handle +** for the statement identified by the second argument. If successful, +** *pp is set to the requested statement handle and SQLITE_OK returned. +** Otherwise, an SQLite error code is returned and *pp is set to 0. +** +** If argument apVal is not NULL, then it must point to an array with +** at least as many entries as the requested statement has bound +** parameters. The values are bound to the statements parameters before +** returning. +*/ +static int fts3SqlStmt( + Fts3Table *p, /* Virtual table handle */ + int eStmt, /* One of the SQL_XXX constants above */ + sqlite3_stmt **pp, /* OUT: Statement handle */ + sqlite3_value **apVal /* Values to bind to statement */ +){ + const char *azSql[] = { +/* 0 */ "DELETE FROM %Q.'%q_content' WHERE rowid = ?", +/* 1 */ "SELECT NOT EXISTS(SELECT docid FROM %Q.'%q_content' WHERE rowid!=?)", +/* 2 */ "DELETE FROM %Q.'%q_content'", +/* 3 */ "DELETE FROM %Q.'%q_segments'", +/* 4 */ "DELETE FROM %Q.'%q_segdir'", +/* 5 */ "DELETE FROM %Q.'%q_docsize'", +/* 6 */ "DELETE FROM %Q.'%q_stat'", +/* 7 */ "SELECT %s WHERE rowid=?", +/* 8 */ "SELECT (SELECT max(idx) FROM %Q.'%q_segdir' WHERE level = ?) + 1", +/* 9 */ "REPLACE INTO %Q.'%q_segments'(blockid, block) VALUES(?, ?)", +/* 10 */ "SELECT coalesce((SELECT max(blockid) FROM %Q.'%q_segments') + 1, 1)", +/* 11 */ "REPLACE INTO %Q.'%q_segdir' VALUES(?,?,?,?,?,?)", + + /* Return segments in order from oldest to newest.*/ +/* 12 */ "SELECT idx, start_block, leaves_end_block, end_block, root " + "FROM %Q.'%q_segdir' WHERE level = ? ORDER BY idx ASC", +/* 13 */ "SELECT idx, start_block, leaves_end_block, end_block, root " + "FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?" + "ORDER BY level DESC, idx ASC", + +/* 14 */ "SELECT count(*) FROM %Q.'%q_segdir' WHERE level = ?", +/* 15 */ "SELECT max(level) FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?", + +/* 16 */ "DELETE FROM %Q.'%q_segdir' WHERE level = ?", +/* 17 */ "DELETE FROM %Q.'%q_segments' WHERE blockid BETWEEN ? AND ?", +/* 18 */ "INSERT INTO %Q.'%q_content' VALUES(%s)", +/* 19 */ "DELETE FROM %Q.'%q_docsize' WHERE docid = ?", +/* 20 */ "REPLACE INTO %Q.'%q_docsize' VALUES(?,?)", +/* 21 */ "SELECT size FROM %Q.'%q_docsize' WHERE docid=?", +/* 22 */ "SELECT value FROM %Q.'%q_stat' WHERE id=?", +/* 23 */ "REPLACE INTO %Q.'%q_stat' VALUES(?,?)", +/* 24 */ "", +/* 25 */ "", + +/* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?", +/* 27 */ "SELECT ? UNION SELECT level / (1024 * ?) FROM %Q.'%q_segdir'", + +/* This statement is used to determine which level to read the input from +** when performing an incremental merge. It returns the absolute level number +** of the oldest level in the db that contains at least ? segments. Or, +** if no level in the FTS index contains more than ? segments, the statement +** returns zero rows. */ +/* 28 */ "SELECT level FROM %Q.'%q_segdir' GROUP BY level HAVING count(*)>=?" + " ORDER BY (level %% 1024) ASC LIMIT 1", + +/* Estimate the upper limit on the number of leaf nodes in a new segment +** created by merging the oldest :2 segments from absolute level :1. See +** function sqlite3Fts3Incrmerge() for details. */ +/* 29 */ "SELECT 2 * total(1 + leaves_end_block - start_block) " + " FROM %Q.'%q_segdir' WHERE level = ? AND idx < ?", + +/* SQL_DELETE_SEGDIR_ENTRY +** Delete the %_segdir entry on absolute level :1 with index :2. */ +/* 30 */ "DELETE FROM %Q.'%q_segdir' WHERE level = ? AND idx = ?", + +/* SQL_SHIFT_SEGDIR_ENTRY +** Modify the idx value for the segment with idx=:3 on absolute level :2 +** to :1. */ +/* 31 */ "UPDATE %Q.'%q_segdir' SET idx = ? WHERE level=? AND idx=?", + +/* SQL_SELECT_SEGDIR +** Read a single entry from the %_segdir table. The entry from absolute +** level :1 with index value :2. */ +/* 32 */ "SELECT idx, start_block, leaves_end_block, end_block, root " + "FROM %Q.'%q_segdir' WHERE level = ? AND idx = ?", + +/* SQL_CHOMP_SEGDIR +** Update the start_block (:1) and root (:2) fields of the %_segdir +** entry located on absolute level :3 with index :4. */ +/* 33 */ "UPDATE %Q.'%q_segdir' SET start_block = ?, root = ?" + "WHERE level = ? AND idx = ?", + +/* SQL_SEGMENT_IS_APPENDABLE +** Return a single row if the segment with end_block=? is appendable. Or +** no rows otherwise. */ +/* 34 */ "SELECT 1 FROM %Q.'%q_segments' WHERE blockid=? AND block IS NULL", + +/* SQL_SELECT_INDEXES +** Return the list of valid segment indexes for absolute level ? */ +/* 35 */ "SELECT idx FROM %Q.'%q_segdir' WHERE level=? ORDER BY 1 ASC", + +/* SQL_SELECT_MXLEVEL +** Return the largest relative level in the FTS index or indexes. */ +/* 36 */ "SELECT max( level %% 1024 ) FROM %Q.'%q_segdir'", + + /* Return segments in order from oldest to newest.*/ +/* 37 */ "SELECT level, idx, end_block " + "FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ? " + "ORDER BY level DESC, idx ASC", + + /* Update statements used while promoting segments */ +/* 38 */ "UPDATE OR FAIL %Q.'%q_segdir' SET level=-1,idx=? " + "WHERE level=? AND idx=?", +/* 39 */ "UPDATE OR FAIL %Q.'%q_segdir' SET level=? WHERE level=-1" + + }; + int rc = SQLITE_OK; + sqlite3_stmt *pStmt; + + assert( SizeofArray(azSql)==SizeofArray(p->aStmt) ); + assert( eStmt=0 ); + + pStmt = p->aStmt[eStmt]; + if( !pStmt ){ + char *zSql; + if( eStmt==SQL_CONTENT_INSERT ){ + zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist); + }else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){ + zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist); + }else{ + zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName); + } + if( !zSql ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, NULL); + sqlite3_free(zSql); + assert( rc==SQLITE_OK || pStmt==0 ); + p->aStmt[eStmt] = pStmt; + } + } + if( apVal ){ + int i; + int nParam = sqlite3_bind_parameter_count(pStmt); + for(i=0; rc==SQLITE_OK && inPendingData==0 ){ + sqlite3_stmt *pStmt; + rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_LEVEL, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_null(pStmt, 1); + sqlite3_step(pStmt); + rc = sqlite3_reset(pStmt); + } + } + + return rc; +} + +/* +** FTS maintains a separate indexes for each language-id (a 32-bit integer). +** Within each language id, a separate index is maintained to store the +** document terms, and each configured prefix size (configured the FTS +** "prefix=" option). And each index consists of multiple levels ("relative +** levels"). +** +** All three of these values (the language id, the specific index and the +** level within the index) are encoded in 64-bit integer values stored +** in the %_segdir table on disk. This function is used to convert three +** separate component values into the single 64-bit integer value that +** can be used to query the %_segdir table. +** +** Specifically, each language-id/index combination is allocated 1024 +** 64-bit integer level values ("absolute levels"). The main terms index +** for language-id 0 is allocate values 0-1023. The first prefix index +** (if any) for language-id 0 is allocated values 1024-2047. And so on. +** Language 1 indexes are allocated immediately following language 0. +** +** So, for a system with nPrefix prefix indexes configured, the block of +** absolute levels that corresponds to language-id iLangid and index +** iIndex starts at absolute level ((iLangid * (nPrefix+1) + iIndex) * 1024). +*/ +static sqlite3_int64 getAbsoluteLevel( + Fts3Table *p, /* FTS3 table handle */ + int iLangid, /* Language id */ + int iIndex, /* Index in p->aIndex[] */ + int iLevel /* Level of segments */ +){ + sqlite3_int64 iBase; /* First absolute level for iLangid/iIndex */ + assert( iLangid>=0 ); + assert( p->nIndex>0 ); + assert( iIndex>=0 && iIndexnIndex ); + + iBase = ((sqlite3_int64)iLangid * p->nIndex + iIndex) * FTS3_SEGDIR_MAXLEVEL; + return iBase + iLevel; +} + +/* +** Set *ppStmt to a statement handle that may be used to iterate through +** all rows in the %_segdir table, from oldest to newest. If successful, +** return SQLITE_OK. If an error occurs while preparing the statement, +** return an SQLite error code. +** +** There is only ever one instance of this SQL statement compiled for +** each FTS3 table. +** +** The statement returns the following columns from the %_segdir table: +** +** 0: idx +** 1: start_block +** 2: leaves_end_block +** 3: end_block +** 4: root +*/ +SQLITE_PRIVATE int sqlite3Fts3AllSegdirs( + Fts3Table *p, /* FTS3 table */ + int iLangid, /* Language being queried */ + int iIndex, /* Index for p->aIndex[] */ + int iLevel, /* Level to select (relative level) */ + sqlite3_stmt **ppStmt /* OUT: Compiled statement */ +){ + int rc; + sqlite3_stmt *pStmt = 0; + + assert( iLevel==FTS3_SEGCURSOR_ALL || iLevel>=0 ); + assert( iLevel=0 && iIndexnIndex ); + + if( iLevel<0 ){ + /* "SELECT * FROM %_segdir WHERE level BETWEEN ? AND ? ORDER BY ..." */ + rc = fts3SqlStmt(p, SQL_SELECT_LEVEL_RANGE, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex, 0)); + sqlite3_bind_int64(pStmt, 2, + getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1) + ); + } + }else{ + /* "SELECT * FROM %_segdir WHERE level = ? ORDER BY ..." */ + rc = fts3SqlStmt(p, SQL_SELECT_LEVEL, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex,iLevel)); + } + } + *ppStmt = pStmt; + return rc; +} + + +/* +** Append a single varint to a PendingList buffer. SQLITE_OK is returned +** if successful, or an SQLite error code otherwise. +** +** This function also serves to allocate the PendingList structure itself. +** For example, to create a new PendingList structure containing two +** varints: +** +** PendingList *p = 0; +** fts3PendingListAppendVarint(&p, 1); +** fts3PendingListAppendVarint(&p, 2); +*/ +static int fts3PendingListAppendVarint( + PendingList **pp, /* IN/OUT: Pointer to PendingList struct */ + sqlite3_int64 i /* Value to append to data */ +){ + PendingList *p = *pp; + + /* Allocate or grow the PendingList as required. */ + if( !p ){ + p = sqlite3_malloc(sizeof(*p) + 100); + if( !p ){ + return SQLITE_NOMEM; + } + p->nSpace = 100; + p->aData = (char *)&p[1]; + p->nData = 0; + } + else if( p->nData+FTS3_VARINT_MAX+1>p->nSpace ){ + int nNew = p->nSpace * 2; + p = sqlite3_realloc(p, sizeof(*p) + nNew); + if( !p ){ + sqlite3_free(*pp); + *pp = 0; + return SQLITE_NOMEM; + } + p->nSpace = nNew; + p->aData = (char *)&p[1]; + } + + /* Append the new serialized varint to the end of the list. */ + p->nData += sqlite3Fts3PutVarint(&p->aData[p->nData], i); + p->aData[p->nData] = '\0'; + *pp = p; + return SQLITE_OK; +} + +/* +** Add a docid/column/position entry to a PendingList structure. Non-zero +** is returned if the structure is sqlite3_realloced as part of adding +** the entry. Otherwise, zero. +** +** If an OOM error occurs, *pRc is set to SQLITE_NOMEM before returning. +** Zero is always returned in this case. Otherwise, if no OOM error occurs, +** it is set to SQLITE_OK. +*/ +static int fts3PendingListAppend( + PendingList **pp, /* IN/OUT: PendingList structure */ + sqlite3_int64 iDocid, /* Docid for entry to add */ + sqlite3_int64 iCol, /* Column for entry to add */ + sqlite3_int64 iPos, /* Position of term for entry to add */ + int *pRc /* OUT: Return code */ +){ + PendingList *p = *pp; + int rc = SQLITE_OK; + + assert( !p || p->iLastDocid<=iDocid ); + + if( !p || p->iLastDocid!=iDocid ){ + sqlite3_int64 iDelta = iDocid - (p ? p->iLastDocid : 0); + if( p ){ + assert( p->nDatanSpace ); + assert( p->aData[p->nData]==0 ); + p->nData++; + } + if( SQLITE_OK!=(rc = fts3PendingListAppendVarint(&p, iDelta)) ){ + goto pendinglistappend_out; + } + p->iLastCol = -1; + p->iLastPos = 0; + p->iLastDocid = iDocid; + } + if( iCol>0 && p->iLastCol!=iCol ){ + if( SQLITE_OK!=(rc = fts3PendingListAppendVarint(&p, 1)) + || SQLITE_OK!=(rc = fts3PendingListAppendVarint(&p, iCol)) + ){ + goto pendinglistappend_out; + } + p->iLastCol = iCol; + p->iLastPos = 0; + } + if( iCol>=0 ){ + assert( iPos>p->iLastPos || (iPos==0 && p->iLastPos==0) ); + rc = fts3PendingListAppendVarint(&p, 2+iPos-p->iLastPos); + if( rc==SQLITE_OK ){ + p->iLastPos = iPos; + } + } + + pendinglistappend_out: + *pRc = rc; + if( p!=*pp ){ + *pp = p; + return 1; + } + return 0; +} + +/* +** Free a PendingList object allocated by fts3PendingListAppend(). +*/ +static void fts3PendingListDelete(PendingList *pList){ + sqlite3_free(pList); +} + +/* +** Add an entry to one of the pending-terms hash tables. +*/ +static int fts3PendingTermsAddOne( + Fts3Table *p, + int iCol, + int iPos, + Fts3Hash *pHash, /* Pending terms hash table to add entry to */ + const char *zToken, + int nToken +){ + PendingList *pList; + int rc = SQLITE_OK; + + pList = (PendingList *)fts3HashFind(pHash, zToken, nToken); + if( pList ){ + p->nPendingData -= (pList->nData + nToken + sizeof(Fts3HashElem)); + } + if( fts3PendingListAppend(&pList, p->iPrevDocid, iCol, iPos, &rc) ){ + if( pList==fts3HashInsert(pHash, zToken, nToken, pList) ){ + /* Malloc failed while inserting the new entry. This can only + ** happen if there was no previous entry for this token. + */ + assert( 0==fts3HashFind(pHash, zToken, nToken) ); + sqlite3_free(pList); + rc = SQLITE_NOMEM; + } + } + if( rc==SQLITE_OK ){ + p->nPendingData += (pList->nData + nToken + sizeof(Fts3HashElem)); + } + return rc; +} + +/* +** Tokenize the nul-terminated string zText and add all tokens to the +** pending-terms hash-table. The docid used is that currently stored in +** p->iPrevDocid, and the column is specified by argument iCol. +** +** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code. +*/ +static int fts3PendingTermsAdd( + Fts3Table *p, /* Table into which text will be inserted */ + int iLangid, /* Language id to use */ + const char *zText, /* Text of document to be inserted */ + int iCol, /* Column into which text is being inserted */ + u32 *pnWord /* IN/OUT: Incr. by number tokens inserted */ +){ + int rc; + int iStart = 0; + int iEnd = 0; + int iPos = 0; + int nWord = 0; + + char const *zToken; + int nToken = 0; + + sqlite3_tokenizer *pTokenizer = p->pTokenizer; + sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; + sqlite3_tokenizer_cursor *pCsr; + int (*xNext)(sqlite3_tokenizer_cursor *pCursor, + const char**,int*,int*,int*,int*); + + assert( pTokenizer && pModule ); + + /* If the user has inserted a NULL value, this function may be called with + ** zText==0. In this case, add zero token entries to the hash table and + ** return early. */ + if( zText==0 ){ + *pnWord = 0; + return SQLITE_OK; + } + + rc = sqlite3Fts3OpenTokenizer(pTokenizer, iLangid, zText, -1, &pCsr); + if( rc!=SQLITE_OK ){ + return rc; + } + + xNext = pModule->xNext; + while( SQLITE_OK==rc + && SQLITE_OK==(rc = xNext(pCsr, &zToken, &nToken, &iStart, &iEnd, &iPos)) + ){ + int i; + if( iPos>=nWord ) nWord = iPos+1; + + /* Positions cannot be negative; we use -1 as a terminator internally. + ** Tokens must have a non-zero length. + */ + if( iPos<0 || !zToken || nToken<=0 ){ + rc = SQLITE_ERROR; + break; + } + + /* Add the term to the terms index */ + rc = fts3PendingTermsAddOne( + p, iCol, iPos, &p->aIndex[0].hPending, zToken, nToken + ); + + /* Add the term to each of the prefix indexes that it is not too + ** short for. */ + for(i=1; rc==SQLITE_OK && inIndex; i++){ + struct Fts3Index *pIndex = &p->aIndex[i]; + if( nTokennPrefix ) continue; + rc = fts3PendingTermsAddOne( + p, iCol, iPos, &pIndex->hPending, zToken, pIndex->nPrefix + ); + } + } + + pModule->xClose(pCsr); + *pnWord += nWord; + return (rc==SQLITE_DONE ? SQLITE_OK : rc); +} + +/* +** Calling this function indicates that subsequent calls to +** fts3PendingTermsAdd() are to add term/position-list pairs for the +** contents of the document with docid iDocid. +*/ +static int fts3PendingTermsDocid( + Fts3Table *p, /* Full-text table handle */ + int iLangid, /* Language id of row being written */ + sqlite_int64 iDocid /* Docid of row being written */ +){ + assert( iLangid>=0 ); + + /* TODO(shess) Explore whether partially flushing the buffer on + ** forced-flush would provide better performance. I suspect that if + ** we ordered the doclists by size and flushed the largest until the + ** buffer was half empty, that would let the less frequent terms + ** generate longer doclists. + */ + if( iDocid<=p->iPrevDocid + || p->iPrevLangid!=iLangid + || p->nPendingData>p->nMaxPendingData + ){ + int rc = sqlite3Fts3PendingTermsFlush(p); + if( rc!=SQLITE_OK ) return rc; + } + p->iPrevDocid = iDocid; + p->iPrevLangid = iLangid; + return SQLITE_OK; +} + +/* +** Discard the contents of the pending-terms hash tables. +*/ +SQLITE_PRIVATE void sqlite3Fts3PendingTermsClear(Fts3Table *p){ + int i; + for(i=0; inIndex; i++){ + Fts3HashElem *pElem; + Fts3Hash *pHash = &p->aIndex[i].hPending; + for(pElem=fts3HashFirst(pHash); pElem; pElem=fts3HashNext(pElem)){ + PendingList *pList = (PendingList *)fts3HashData(pElem); + fts3PendingListDelete(pList); + } + fts3HashClear(pHash); + } + p->nPendingData = 0; +} + +/* +** This function is called by the xUpdate() method as part of an INSERT +** operation. It adds entries for each term in the new record to the +** pendingTerms hash table. +** +** Argument apVal is the same as the similarly named argument passed to +** fts3InsertData(). Parameter iDocid is the docid of the new row. +*/ +static int fts3InsertTerms( + Fts3Table *p, + int iLangid, + sqlite3_value **apVal, + u32 *aSz +){ + int i; /* Iterator variable */ + for(i=2; inColumn+2; i++){ + int iCol = i-2; + if( p->abNotindexed[iCol]==0 ){ + const char *zText = (const char *)sqlite3_value_text(apVal[i]); + int rc = fts3PendingTermsAdd(p, iLangid, zText, iCol, &aSz[iCol]); + if( rc!=SQLITE_OK ){ + return rc; + } + aSz[p->nColumn] += sqlite3_value_bytes(apVal[i]); + } + } + return SQLITE_OK; +} + +/* +** This function is called by the xUpdate() method for an INSERT operation. +** The apVal parameter is passed a copy of the apVal argument passed by +** SQLite to the xUpdate() method. i.e: +** +** apVal[0] Not used for INSERT. +** apVal[1] rowid +** apVal[2] Left-most user-defined column +** ... +** apVal[p->nColumn+1] Right-most user-defined column +** apVal[p->nColumn+2] Hidden column with same name as table +** apVal[p->nColumn+3] Hidden "docid" column (alias for rowid) +** apVal[p->nColumn+4] Hidden languageid column +*/ +static int fts3InsertData( + Fts3Table *p, /* Full-text table */ + sqlite3_value **apVal, /* Array of values to insert */ + sqlite3_int64 *piDocid /* OUT: Docid for row just inserted */ +){ + int rc; /* Return code */ + sqlite3_stmt *pContentInsert; /* INSERT INTO %_content VALUES(...) */ + + if( p->zContentTbl ){ + sqlite3_value *pRowid = apVal[p->nColumn+3]; + if( sqlite3_value_type(pRowid)==SQLITE_NULL ){ + pRowid = apVal[1]; + } + if( sqlite3_value_type(pRowid)!=SQLITE_INTEGER ){ + return SQLITE_CONSTRAINT; + } + *piDocid = sqlite3_value_int64(pRowid); + return SQLITE_OK; + } + + /* Locate the statement handle used to insert data into the %_content + ** table. The SQL for this statement is: + ** + ** INSERT INTO %_content VALUES(?, ?, ?, ...) + ** + ** The statement features N '?' variables, where N is the number of user + ** defined columns in the FTS3 table, plus one for the docid field. + */ + rc = fts3SqlStmt(p, SQL_CONTENT_INSERT, &pContentInsert, &apVal[1]); + if( rc==SQLITE_OK && p->zLanguageid ){ + rc = sqlite3_bind_int( + pContentInsert, p->nColumn+2, + sqlite3_value_int(apVal[p->nColumn+4]) + ); + } + if( rc!=SQLITE_OK ) return rc; + + /* There is a quirk here. The users INSERT statement may have specified + ** a value for the "rowid" field, for the "docid" field, or for both. + ** Which is a problem, since "rowid" and "docid" are aliases for the + ** same value. For example: + ** + ** INSERT INTO fts3tbl(rowid, docid) VALUES(1, 2); + ** + ** In FTS3, this is an error. It is an error to specify non-NULL values + ** for both docid and some other rowid alias. + */ + if( SQLITE_NULL!=sqlite3_value_type(apVal[3+p->nColumn]) ){ + if( SQLITE_NULL==sqlite3_value_type(apVal[0]) + && SQLITE_NULL!=sqlite3_value_type(apVal[1]) + ){ + /* A rowid/docid conflict. */ + return SQLITE_ERROR; + } + rc = sqlite3_bind_value(pContentInsert, 1, apVal[3+p->nColumn]); + if( rc!=SQLITE_OK ) return rc; + } + + /* Execute the statement to insert the record. Set *piDocid to the + ** new docid value. + */ + sqlite3_step(pContentInsert); + rc = sqlite3_reset(pContentInsert); + + *piDocid = sqlite3_last_insert_rowid(p->db); + return rc; +} + + + +/* +** Remove all data from the FTS3 table. Clear the hash table containing +** pending terms. +*/ +static int fts3DeleteAll(Fts3Table *p, int bContent){ + int rc = SQLITE_OK; /* Return code */ + + /* Discard the contents of the pending-terms hash table. */ + sqlite3Fts3PendingTermsClear(p); + + /* Delete everything from the shadow tables. Except, leave %_content as + ** is if bContent is false. */ + assert( p->zContentTbl==0 || bContent==0 ); + if( bContent ) fts3SqlExec(&rc, p, SQL_DELETE_ALL_CONTENT, 0); + fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGMENTS, 0); + fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGDIR, 0); + if( p->bHasDocsize ){ + fts3SqlExec(&rc, p, SQL_DELETE_ALL_DOCSIZE, 0); + } + if( p->bHasStat ){ + fts3SqlExec(&rc, p, SQL_DELETE_ALL_STAT, 0); + } + return rc; +} + +/* +** +*/ +static int langidFromSelect(Fts3Table *p, sqlite3_stmt *pSelect){ + int iLangid = 0; + if( p->zLanguageid ) iLangid = sqlite3_column_int(pSelect, p->nColumn+1); + return iLangid; +} + +/* +** The first element in the apVal[] array is assumed to contain the docid +** (an integer) of a row about to be deleted. Remove all terms from the +** full-text index. +*/ +static void fts3DeleteTerms( + int *pRC, /* Result code */ + Fts3Table *p, /* The FTS table to delete from */ + sqlite3_value *pRowid, /* The docid to be deleted */ + u32 *aSz, /* Sizes of deleted document written here */ + int *pbFound /* OUT: Set to true if row really does exist */ +){ + int rc; + sqlite3_stmt *pSelect; + + assert( *pbFound==0 ); + if( *pRC ) return; + rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pSelect, &pRowid); + if( rc==SQLITE_OK ){ + if( SQLITE_ROW==sqlite3_step(pSelect) ){ + int i; + int iLangid = langidFromSelect(p, pSelect); + rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pSelect, 0)); + for(i=1; rc==SQLITE_OK && i<=p->nColumn; i++){ + int iCol = i-1; + if( p->abNotindexed[iCol]==0 ){ + const char *zText = (const char *)sqlite3_column_text(pSelect, i); + rc = fts3PendingTermsAdd(p, iLangid, zText, -1, &aSz[iCol]); + aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i); + } + } + if( rc!=SQLITE_OK ){ + sqlite3_reset(pSelect); + *pRC = rc; + return; + } + *pbFound = 1; + } + rc = sqlite3_reset(pSelect); + }else{ + sqlite3_reset(pSelect); + } + *pRC = rc; +} + +/* +** Forward declaration to account for the circular dependency between +** functions fts3SegmentMerge() and fts3AllocateSegdirIdx(). +*/ +static int fts3SegmentMerge(Fts3Table *, int, int, int); + +/* +** This function allocates a new level iLevel index in the segdir table. +** Usually, indexes are allocated within a level sequentially starting +** with 0, so the allocated index is one greater than the value returned +** by: +** +** SELECT max(idx) FROM %_segdir WHERE level = :iLevel +** +** However, if there are already FTS3_MERGE_COUNT indexes at the requested +** level, they are merged into a single level (iLevel+1) segment and the +** allocated index is 0. +** +** If successful, *piIdx is set to the allocated index slot and SQLITE_OK +** returned. Otherwise, an SQLite error code is returned. +*/ +static int fts3AllocateSegdirIdx( + Fts3Table *p, + int iLangid, /* Language id */ + int iIndex, /* Index for p->aIndex */ + int iLevel, + int *piIdx +){ + int rc; /* Return Code */ + sqlite3_stmt *pNextIdx; /* Query for next idx at level iLevel */ + int iNext = 0; /* Result of query pNextIdx */ + + assert( iLangid>=0 ); + assert( p->nIndex>=1 ); + + /* Set variable iNext to the next available segdir index at level iLevel. */ + rc = fts3SqlStmt(p, SQL_NEXT_SEGMENT_INDEX, &pNextIdx, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64( + pNextIdx, 1, getAbsoluteLevel(p, iLangid, iIndex, iLevel) + ); + if( SQLITE_ROW==sqlite3_step(pNextIdx) ){ + iNext = sqlite3_column_int(pNextIdx, 0); + } + rc = sqlite3_reset(pNextIdx); + } + + if( rc==SQLITE_OK ){ + /* If iNext is FTS3_MERGE_COUNT, indicating that level iLevel is already + ** full, merge all segments in level iLevel into a single iLevel+1 + ** segment and allocate (newly freed) index 0 at level iLevel. Otherwise, + ** if iNext is less than FTS3_MERGE_COUNT, allocate index iNext. + */ + if( iNext>=FTS3_MERGE_COUNT ){ + fts3LogMerge(16, getAbsoluteLevel(p, iLangid, iIndex, iLevel)); + rc = fts3SegmentMerge(p, iLangid, iIndex, iLevel); + *piIdx = 0; + }else{ + *piIdx = iNext; + } + } + + return rc; +} + +/* +** The %_segments table is declared as follows: +** +** CREATE TABLE %_segments(blockid INTEGER PRIMARY KEY, block BLOB) +** +** This function reads data from a single row of the %_segments table. The +** specific row is identified by the iBlockid parameter. If paBlob is not +** NULL, then a buffer is allocated using sqlite3_malloc() and populated +** with the contents of the blob stored in the "block" column of the +** identified table row is. Whether or not paBlob is NULL, *pnBlob is set +** to the size of the blob in bytes before returning. +** +** If an error occurs, or the table does not contain the specified row, +** an SQLite error code is returned. Otherwise, SQLITE_OK is returned. If +** paBlob is non-NULL, then it is the responsibility of the caller to +** eventually free the returned buffer. +** +** This function may leave an open sqlite3_blob* handle in the +** Fts3Table.pSegments variable. This handle is reused by subsequent calls +** to this function. The handle may be closed by calling the +** sqlite3Fts3SegmentsClose() function. Reusing a blob handle is a handy +** performance improvement, but the blob handle should always be closed +** before control is returned to the user (to prevent a lock being held +** on the database file for longer than necessary). Thus, any virtual table +** method (xFilter etc.) that may directly or indirectly call this function +** must call sqlite3Fts3SegmentsClose() before returning. +*/ +SQLITE_PRIVATE int sqlite3Fts3ReadBlock( + Fts3Table *p, /* FTS3 table handle */ + sqlite3_int64 iBlockid, /* Access the row with blockid=$iBlockid */ + char **paBlob, /* OUT: Blob data in malloc'd buffer */ + int *pnBlob, /* OUT: Size of blob data */ + int *pnLoad /* OUT: Bytes actually loaded */ +){ + int rc; /* Return code */ + + /* pnBlob must be non-NULL. paBlob may be NULL or non-NULL. */ + assert( pnBlob ); + + if( p->pSegments ){ + rc = sqlite3_blob_reopen(p->pSegments, iBlockid); + }else{ + if( 0==p->zSegmentsTbl ){ + p->zSegmentsTbl = sqlite3_mprintf("%s_segments", p->zName); + if( 0==p->zSegmentsTbl ) return SQLITE_NOMEM; + } + rc = sqlite3_blob_open( + p->db, p->zDb, p->zSegmentsTbl, "block", iBlockid, 0, &p->pSegments + ); + } + + if( rc==SQLITE_OK ){ + int nByte = sqlite3_blob_bytes(p->pSegments); + *pnBlob = nByte; + if( paBlob ){ + char *aByte = sqlite3_malloc(nByte + FTS3_NODE_PADDING); + if( !aByte ){ + rc = SQLITE_NOMEM; + }else{ + if( pnLoad && nByte>(FTS3_NODE_CHUNK_THRESHOLD) ){ + nByte = FTS3_NODE_CHUNKSIZE; + *pnLoad = nByte; + } + rc = sqlite3_blob_read(p->pSegments, aByte, nByte, 0); + memset(&aByte[nByte], 0, FTS3_NODE_PADDING); + if( rc!=SQLITE_OK ){ + sqlite3_free(aByte); + aByte = 0; + } + } + *paBlob = aByte; + } + } + + return rc; +} + +/* +** Close the blob handle at p->pSegments, if it is open. See comments above +** the sqlite3Fts3ReadBlock() function for details. +*/ +SQLITE_PRIVATE void sqlite3Fts3SegmentsClose(Fts3Table *p){ + sqlite3_blob_close(p->pSegments); + p->pSegments = 0; +} + +static int fts3SegReaderIncrRead(Fts3SegReader *pReader){ + int nRead; /* Number of bytes to read */ + int rc; /* Return code */ + + nRead = MIN(pReader->nNode - pReader->nPopulate, FTS3_NODE_CHUNKSIZE); + rc = sqlite3_blob_read( + pReader->pBlob, + &pReader->aNode[pReader->nPopulate], + nRead, + pReader->nPopulate + ); + + if( rc==SQLITE_OK ){ + pReader->nPopulate += nRead; + memset(&pReader->aNode[pReader->nPopulate], 0, FTS3_NODE_PADDING); + if( pReader->nPopulate==pReader->nNode ){ + sqlite3_blob_close(pReader->pBlob); + pReader->pBlob = 0; + pReader->nPopulate = 0; + } + } + return rc; +} + +static int fts3SegReaderRequire(Fts3SegReader *pReader, char *pFrom, int nByte){ + int rc = SQLITE_OK; + assert( !pReader->pBlob + || (pFrom>=pReader->aNode && pFrom<&pReader->aNode[pReader->nNode]) + ); + while( pReader->pBlob && rc==SQLITE_OK + && (pFrom - pReader->aNode + nByte)>pReader->nPopulate + ){ + rc = fts3SegReaderIncrRead(pReader); + } + return rc; +} + +/* +** Set an Fts3SegReader cursor to point at EOF. +*/ +static void fts3SegReaderSetEof(Fts3SegReader *pSeg){ + if( !fts3SegReaderIsRootOnly(pSeg) ){ + sqlite3_free(pSeg->aNode); + sqlite3_blob_close(pSeg->pBlob); + pSeg->pBlob = 0; + } + pSeg->aNode = 0; +} + +/* +** Move the iterator passed as the first argument to the next term in the +** segment. If successful, SQLITE_OK is returned. If there is no next term, +** SQLITE_DONE. Otherwise, an SQLite error code. +*/ +static int fts3SegReaderNext( + Fts3Table *p, + Fts3SegReader *pReader, + int bIncr +){ + int rc; /* Return code of various sub-routines */ + char *pNext; /* Cursor variable */ + int nPrefix; /* Number of bytes in term prefix */ + int nSuffix; /* Number of bytes in term suffix */ + + if( !pReader->aDoclist ){ + pNext = pReader->aNode; + }else{ + pNext = &pReader->aDoclist[pReader->nDoclist]; + } + + if( !pNext || pNext>=&pReader->aNode[pReader->nNode] ){ + + if( fts3SegReaderIsPending(pReader) ){ + Fts3HashElem *pElem = *(pReader->ppNextElem); + if( pElem==0 ){ + pReader->aNode = 0; + }else{ + PendingList *pList = (PendingList *)fts3HashData(pElem); + pReader->zTerm = (char *)fts3HashKey(pElem); + pReader->nTerm = fts3HashKeysize(pElem); + pReader->nNode = pReader->nDoclist = pList->nData + 1; + pReader->aNode = pReader->aDoclist = pList->aData; + pReader->ppNextElem++; + assert( pReader->aNode ); + } + return SQLITE_OK; + } + + fts3SegReaderSetEof(pReader); + + /* If iCurrentBlock>=iLeafEndBlock, this is an EOF condition. All leaf + ** blocks have already been traversed. */ + assert( pReader->iCurrentBlock<=pReader->iLeafEndBlock ); + if( pReader->iCurrentBlock>=pReader->iLeafEndBlock ){ + return SQLITE_OK; + } + + rc = sqlite3Fts3ReadBlock( + p, ++pReader->iCurrentBlock, &pReader->aNode, &pReader->nNode, + (bIncr ? &pReader->nPopulate : 0) + ); + if( rc!=SQLITE_OK ) return rc; + assert( pReader->pBlob==0 ); + if( bIncr && pReader->nPopulatenNode ){ + pReader->pBlob = p->pSegments; + p->pSegments = 0; + } + pNext = pReader->aNode; + } + + assert( !fts3SegReaderIsPending(pReader) ); + + rc = fts3SegReaderRequire(pReader, pNext, FTS3_VARINT_MAX*2); + if( rc!=SQLITE_OK ) return rc; + + /* Because of the FTS3_NODE_PADDING bytes of padding, the following is + ** safe (no risk of overread) even if the node data is corrupted. */ + pNext += fts3GetVarint32(pNext, &nPrefix); + pNext += fts3GetVarint32(pNext, &nSuffix); + if( nPrefix<0 || nSuffix<=0 + || &pNext[nSuffix]>&pReader->aNode[pReader->nNode] + ){ + return FTS_CORRUPT_VTAB; + } + + if( nPrefix+nSuffix>pReader->nTermAlloc ){ + int nNew = (nPrefix+nSuffix)*2; + char *zNew = sqlite3_realloc(pReader->zTerm, nNew); + if( !zNew ){ + return SQLITE_NOMEM; + } + pReader->zTerm = zNew; + pReader->nTermAlloc = nNew; + } + + rc = fts3SegReaderRequire(pReader, pNext, nSuffix+FTS3_VARINT_MAX); + if( rc!=SQLITE_OK ) return rc; + + memcpy(&pReader->zTerm[nPrefix], pNext, nSuffix); + pReader->nTerm = nPrefix+nSuffix; + pNext += nSuffix; + pNext += fts3GetVarint32(pNext, &pReader->nDoclist); + pReader->aDoclist = pNext; + pReader->pOffsetList = 0; + + /* Check that the doclist does not appear to extend past the end of the + ** b-tree node. And that the final byte of the doclist is 0x00. If either + ** of these statements is untrue, then the data structure is corrupt. + */ + if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode] + || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1]) + ){ + return FTS_CORRUPT_VTAB; + } + return SQLITE_OK; +} + +/* +** Set the SegReader to point to the first docid in the doclist associated +** with the current term. +*/ +static int fts3SegReaderFirstDocid(Fts3Table *pTab, Fts3SegReader *pReader){ + int rc = SQLITE_OK; + assert( pReader->aDoclist ); + assert( !pReader->pOffsetList ); + if( pTab->bDescIdx && fts3SegReaderIsPending(pReader) ){ + u8 bEof = 0; + pReader->iDocid = 0; + pReader->nOffsetList = 0; + sqlite3Fts3DoclistPrev(0, + pReader->aDoclist, pReader->nDoclist, &pReader->pOffsetList, + &pReader->iDocid, &pReader->nOffsetList, &bEof + ); + }else{ + rc = fts3SegReaderRequire(pReader, pReader->aDoclist, FTS3_VARINT_MAX); + if( rc==SQLITE_OK ){ + int n = sqlite3Fts3GetVarint(pReader->aDoclist, &pReader->iDocid); + pReader->pOffsetList = &pReader->aDoclist[n]; + } + } + return rc; +} + +/* +** Advance the SegReader to point to the next docid in the doclist +** associated with the current term. +** +** If arguments ppOffsetList and pnOffsetList are not NULL, then +** *ppOffsetList is set to point to the first column-offset list +** in the doclist entry (i.e. immediately past the docid varint). +** *pnOffsetList is set to the length of the set of column-offset +** lists, not including the nul-terminator byte. For example: +*/ +static int fts3SegReaderNextDocid( + Fts3Table *pTab, + Fts3SegReader *pReader, /* Reader to advance to next docid */ + char **ppOffsetList, /* OUT: Pointer to current position-list */ + int *pnOffsetList /* OUT: Length of *ppOffsetList in bytes */ +){ + int rc = SQLITE_OK; + char *p = pReader->pOffsetList; + char c = 0; + + assert( p ); + + if( pTab->bDescIdx && fts3SegReaderIsPending(pReader) ){ + /* A pending-terms seg-reader for an FTS4 table that uses order=desc. + ** Pending-terms doclists are always built up in ascending order, so + ** we have to iterate through them backwards here. */ + u8 bEof = 0; + if( ppOffsetList ){ + *ppOffsetList = pReader->pOffsetList; + *pnOffsetList = pReader->nOffsetList - 1; + } + sqlite3Fts3DoclistPrev(0, + pReader->aDoclist, pReader->nDoclist, &p, &pReader->iDocid, + &pReader->nOffsetList, &bEof + ); + if( bEof ){ + pReader->pOffsetList = 0; + }else{ + pReader->pOffsetList = p; + } + }else{ + char *pEnd = &pReader->aDoclist[pReader->nDoclist]; + + /* Pointer p currently points at the first byte of an offset list. The + ** following block advances it to point one byte past the end of + ** the same offset list. */ + while( 1 ){ + + /* The following line of code (and the "p++" below the while() loop) is + ** normally all that is required to move pointer p to the desired + ** position. The exception is if this node is being loaded from disk + ** incrementally and pointer "p" now points to the first byte past + ** the populated part of pReader->aNode[]. + */ + while( *p | c ) c = *p++ & 0x80; + assert( *p==0 ); + + if( pReader->pBlob==0 || p<&pReader->aNode[pReader->nPopulate] ) break; + rc = fts3SegReaderIncrRead(pReader); + if( rc!=SQLITE_OK ) return rc; + } + p++; + + /* If required, populate the output variables with a pointer to and the + ** size of the previous offset-list. + */ + if( ppOffsetList ){ + *ppOffsetList = pReader->pOffsetList; + *pnOffsetList = (int)(p - pReader->pOffsetList - 1); + } + + /* List may have been edited in place by fts3EvalNearTrim() */ + while( p=pEnd ){ + pReader->pOffsetList = 0; + }else{ + rc = fts3SegReaderRequire(pReader, p, FTS3_VARINT_MAX); + if( rc==SQLITE_OK ){ + sqlite3_int64 iDelta; + pReader->pOffsetList = p + sqlite3Fts3GetVarint(p, &iDelta); + if( pTab->bDescIdx ){ + pReader->iDocid -= iDelta; + }else{ + pReader->iDocid += iDelta; + } + } + } + } + + return SQLITE_OK; +} + + +SQLITE_PRIVATE int sqlite3Fts3MsrOvfl( + Fts3Cursor *pCsr, + Fts3MultiSegReader *pMsr, + int *pnOvfl +){ + Fts3Table *p = (Fts3Table*)pCsr->base.pVtab; + int nOvfl = 0; + int ii; + int rc = SQLITE_OK; + int pgsz = p->nPgsz; + + assert( p->bFts4 ); + assert( pgsz>0 ); + + for(ii=0; rc==SQLITE_OK && iinSegment; ii++){ + Fts3SegReader *pReader = pMsr->apSegment[ii]; + if( !fts3SegReaderIsPending(pReader) + && !fts3SegReaderIsRootOnly(pReader) + ){ + sqlite3_int64 jj; + for(jj=pReader->iStartBlock; jj<=pReader->iLeafEndBlock; jj++){ + int nBlob; + rc = sqlite3Fts3ReadBlock(p, jj, 0, &nBlob, 0); + if( rc!=SQLITE_OK ) break; + if( (nBlob+35)>pgsz ){ + nOvfl += (nBlob + 34)/pgsz; + } + } + } + } + *pnOvfl = nOvfl; + return rc; +} + +/* +** Free all allocations associated with the iterator passed as the +** second argument. +*/ +SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *pReader){ + if( pReader && !fts3SegReaderIsPending(pReader) ){ + sqlite3_free(pReader->zTerm); + if( !fts3SegReaderIsRootOnly(pReader) ){ + sqlite3_free(pReader->aNode); + sqlite3_blob_close(pReader->pBlob); + } + } + sqlite3_free(pReader); +} + +/* +** Allocate a new SegReader object. +*/ +SQLITE_PRIVATE int sqlite3Fts3SegReaderNew( + int iAge, /* Segment "age". */ + int bLookup, /* True for a lookup only */ + sqlite3_int64 iStartLeaf, /* First leaf to traverse */ + sqlite3_int64 iEndLeaf, /* Final leaf to traverse */ + sqlite3_int64 iEndBlock, /* Final block of segment */ + const char *zRoot, /* Buffer containing root node */ + int nRoot, /* Size of buffer containing root node */ + Fts3SegReader **ppReader /* OUT: Allocated Fts3SegReader */ +){ + Fts3SegReader *pReader; /* Newly allocated SegReader object */ + int nExtra = 0; /* Bytes to allocate segment root node */ + + assert( iStartLeaf<=iEndLeaf ); + if( iStartLeaf==0 ){ + nExtra = nRoot + FTS3_NODE_PADDING; + } + + pReader = (Fts3SegReader *)sqlite3_malloc(sizeof(Fts3SegReader) + nExtra); + if( !pReader ){ + return SQLITE_NOMEM; + } + memset(pReader, 0, sizeof(Fts3SegReader)); + pReader->iIdx = iAge; + pReader->bLookup = bLookup!=0; + pReader->iStartBlock = iStartLeaf; + pReader->iLeafEndBlock = iEndLeaf; + pReader->iEndBlock = iEndBlock; + + if( nExtra ){ + /* The entire segment is stored in the root node. */ + pReader->aNode = (char *)&pReader[1]; + pReader->rootOnly = 1; + pReader->nNode = nRoot; + memcpy(pReader->aNode, zRoot, nRoot); + memset(&pReader->aNode[nRoot], 0, FTS3_NODE_PADDING); + }else{ + pReader->iCurrentBlock = iStartLeaf-1; + } + *ppReader = pReader; + return SQLITE_OK; +} + +/* +** This is a comparison function used as a qsort() callback when sorting +** an array of pending terms by term. This occurs as part of flushing +** the contents of the pending-terms hash table to the database. +*/ +static int SQLITE_CDECL fts3CompareElemByTerm( + const void *lhs, + const void *rhs +){ + char *z1 = fts3HashKey(*(Fts3HashElem **)lhs); + char *z2 = fts3HashKey(*(Fts3HashElem **)rhs); + int n1 = fts3HashKeysize(*(Fts3HashElem **)lhs); + int n2 = fts3HashKeysize(*(Fts3HashElem **)rhs); + + int n = (n1aIndex */ + const char *zTerm, /* Term to search for */ + int nTerm, /* Size of buffer zTerm */ + int bPrefix, /* True for a prefix iterator */ + Fts3SegReader **ppReader /* OUT: SegReader for pending-terms */ +){ + Fts3SegReader *pReader = 0; /* Fts3SegReader object to return */ + Fts3HashElem *pE; /* Iterator variable */ + Fts3HashElem **aElem = 0; /* Array of term hash entries to scan */ + int nElem = 0; /* Size of array at aElem */ + int rc = SQLITE_OK; /* Return Code */ + Fts3Hash *pHash; + + pHash = &p->aIndex[iIndex].hPending; + if( bPrefix ){ + int nAlloc = 0; /* Size of allocated array at aElem */ + + for(pE=fts3HashFirst(pHash); pE; pE=fts3HashNext(pE)){ + char *zKey = (char *)fts3HashKey(pE); + int nKey = fts3HashKeysize(pE); + if( nTerm==0 || (nKey>=nTerm && 0==memcmp(zKey, zTerm, nTerm)) ){ + if( nElem==nAlloc ){ + Fts3HashElem **aElem2; + nAlloc += 16; + aElem2 = (Fts3HashElem **)sqlite3_realloc( + aElem, nAlloc*sizeof(Fts3HashElem *) + ); + if( !aElem2 ){ + rc = SQLITE_NOMEM; + nElem = 0; + break; + } + aElem = aElem2; + } + + aElem[nElem++] = pE; + } + } + + /* If more than one term matches the prefix, sort the Fts3HashElem + ** objects in term order using qsort(). This uses the same comparison + ** callback as is used when flushing terms to disk. + */ + if( nElem>1 ){ + qsort(aElem, nElem, sizeof(Fts3HashElem *), fts3CompareElemByTerm); + } + + }else{ + /* The query is a simple term lookup that matches at most one term in + ** the index. All that is required is a straight hash-lookup. + ** + ** Because the stack address of pE may be accessed via the aElem pointer + ** below, the "Fts3HashElem *pE" must be declared so that it is valid + ** within this entire function, not just this "else{...}" block. + */ + pE = fts3HashFindElem(pHash, zTerm, nTerm); + if( pE ){ + aElem = &pE; + nElem = 1; + } + } + + if( nElem>0 ){ + int nByte = sizeof(Fts3SegReader) + (nElem+1)*sizeof(Fts3HashElem *); + pReader = (Fts3SegReader *)sqlite3_malloc(nByte); + if( !pReader ){ + rc = SQLITE_NOMEM; + }else{ + memset(pReader, 0, nByte); + pReader->iIdx = 0x7FFFFFFF; + pReader->ppNextElem = (Fts3HashElem **)&pReader[1]; + memcpy(pReader->ppNextElem, aElem, nElem*sizeof(Fts3HashElem *)); + } + } + + if( bPrefix ){ + sqlite3_free(aElem); + } + *ppReader = pReader; + return rc; +} + +/* +** Compare the entries pointed to by two Fts3SegReader structures. +** Comparison is as follows: +** +** 1) EOF is greater than not EOF. +** +** 2) The current terms (if any) are compared using memcmp(). If one +** term is a prefix of another, the longer term is considered the +** larger. +** +** 3) By segment age. An older segment is considered larger. +*/ +static int fts3SegReaderCmp(Fts3SegReader *pLhs, Fts3SegReader *pRhs){ + int rc; + if( pLhs->aNode && pRhs->aNode ){ + int rc2 = pLhs->nTerm - pRhs->nTerm; + if( rc2<0 ){ + rc = memcmp(pLhs->zTerm, pRhs->zTerm, pLhs->nTerm); + }else{ + rc = memcmp(pLhs->zTerm, pRhs->zTerm, pRhs->nTerm); + } + if( rc==0 ){ + rc = rc2; + } + }else{ + rc = (pLhs->aNode==0) - (pRhs->aNode==0); + } + if( rc==0 ){ + rc = pRhs->iIdx - pLhs->iIdx; + } + assert( rc!=0 ); + return rc; +} + +/* +** A different comparison function for SegReader structures. In this +** version, it is assumed that each SegReader points to an entry in +** a doclist for identical terms. Comparison is made as follows: +** +** 1) EOF (end of doclist in this case) is greater than not EOF. +** +** 2) By current docid. +** +** 3) By segment age. An older segment is considered larger. +*/ +static int fts3SegReaderDoclistCmp(Fts3SegReader *pLhs, Fts3SegReader *pRhs){ + int rc = (pLhs->pOffsetList==0)-(pRhs->pOffsetList==0); + if( rc==0 ){ + if( pLhs->iDocid==pRhs->iDocid ){ + rc = pRhs->iIdx - pLhs->iIdx; + }else{ + rc = (pLhs->iDocid > pRhs->iDocid) ? 1 : -1; + } + } + assert( pLhs->aNode && pRhs->aNode ); + return rc; +} +static int fts3SegReaderDoclistCmpRev(Fts3SegReader *pLhs, Fts3SegReader *pRhs){ + int rc = (pLhs->pOffsetList==0)-(pRhs->pOffsetList==0); + if( rc==0 ){ + if( pLhs->iDocid==pRhs->iDocid ){ + rc = pRhs->iIdx - pLhs->iIdx; + }else{ + rc = (pLhs->iDocid < pRhs->iDocid) ? 1 : -1; + } + } + assert( pLhs->aNode && pRhs->aNode ); + return rc; +} + +/* +** Compare the term that the Fts3SegReader object passed as the first argument +** points to with the term specified by arguments zTerm and nTerm. +** +** If the pSeg iterator is already at EOF, return 0. Otherwise, return +** -ve if the pSeg term is less than zTerm/nTerm, 0 if the two terms are +** equal, or +ve if the pSeg term is greater than zTerm/nTerm. +*/ +static int fts3SegReaderTermCmp( + Fts3SegReader *pSeg, /* Segment reader object */ + const char *zTerm, /* Term to compare to */ + int nTerm /* Size of term zTerm in bytes */ +){ + int res = 0; + if( pSeg->aNode ){ + if( pSeg->nTerm>nTerm ){ + res = memcmp(pSeg->zTerm, zTerm, nTerm); + }else{ + res = memcmp(pSeg->zTerm, zTerm, pSeg->nTerm); + } + if( res==0 ){ + res = pSeg->nTerm-nTerm; + } + } + return res; +} + +/* +** Argument apSegment is an array of nSegment elements. It is known that +** the final (nSegment-nSuspect) members are already in sorted order +** (according to the comparison function provided). This function shuffles +** the array around until all entries are in sorted order. +*/ +static void fts3SegReaderSort( + Fts3SegReader **apSegment, /* Array to sort entries of */ + int nSegment, /* Size of apSegment array */ + int nSuspect, /* Unsorted entry count */ + int (*xCmp)(Fts3SegReader *, Fts3SegReader *) /* Comparison function */ +){ + int i; /* Iterator variable */ + + assert( nSuspect<=nSegment ); + + if( nSuspect==nSegment ) nSuspect--; + for(i=nSuspect-1; i>=0; i--){ + int j; + for(j=i; j<(nSegment-1); j++){ + Fts3SegReader *pTmp; + if( xCmp(apSegment[j], apSegment[j+1])<0 ) break; + pTmp = apSegment[j+1]; + apSegment[j+1] = apSegment[j]; + apSegment[j] = pTmp; + } + } + +#ifndef NDEBUG + /* Check that the list really is sorted now. */ + for(i=0; i<(nSuspect-1); i++){ + assert( xCmp(apSegment[i], apSegment[i+1])<0 ); + } +#endif +} + +/* +** Insert a record into the %_segments table. +*/ +static int fts3WriteSegment( + Fts3Table *p, /* Virtual table handle */ + sqlite3_int64 iBlock, /* Block id for new block */ + char *z, /* Pointer to buffer containing block data */ + int n /* Size of buffer z in bytes */ +){ + sqlite3_stmt *pStmt; + int rc = fts3SqlStmt(p, SQL_INSERT_SEGMENTS, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pStmt, 1, iBlock); + sqlite3_bind_blob(pStmt, 2, z, n, SQLITE_STATIC); + sqlite3_step(pStmt); + rc = sqlite3_reset(pStmt); + } + return rc; +} + +/* +** Find the largest relative level number in the table. If successful, set +** *pnMax to this value and return SQLITE_OK. Otherwise, if an error occurs, +** set *pnMax to zero and return an SQLite error code. +*/ +SQLITE_PRIVATE int sqlite3Fts3MaxLevel(Fts3Table *p, int *pnMax){ + int rc; + int mxLevel = 0; + sqlite3_stmt *pStmt = 0; + + rc = fts3SqlStmt(p, SQL_SELECT_MXLEVEL, &pStmt, 0); + if( rc==SQLITE_OK ){ + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + mxLevel = sqlite3_column_int(pStmt, 0); + } + rc = sqlite3_reset(pStmt); + } + *pnMax = mxLevel; + return rc; +} + +/* +** Insert a record into the %_segdir table. +*/ +static int fts3WriteSegdir( + Fts3Table *p, /* Virtual table handle */ + sqlite3_int64 iLevel, /* Value for "level" field (absolute level) */ + int iIdx, /* Value for "idx" field */ + sqlite3_int64 iStartBlock, /* Value for "start_block" field */ + sqlite3_int64 iLeafEndBlock, /* Value for "leaves_end_block" field */ + sqlite3_int64 iEndBlock, /* Value for "end_block" field */ + sqlite3_int64 nLeafData, /* Bytes of leaf data in segment */ + char *zRoot, /* Blob value for "root" field */ + int nRoot /* Number of bytes in buffer zRoot */ +){ + sqlite3_stmt *pStmt; + int rc = fts3SqlStmt(p, SQL_INSERT_SEGDIR, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pStmt, 1, iLevel); + sqlite3_bind_int(pStmt, 2, iIdx); + sqlite3_bind_int64(pStmt, 3, iStartBlock); + sqlite3_bind_int64(pStmt, 4, iLeafEndBlock); + if( nLeafData==0 ){ + sqlite3_bind_int64(pStmt, 5, iEndBlock); + }else{ + char *zEnd = sqlite3_mprintf("%lld %lld", iEndBlock, nLeafData); + if( !zEnd ) return SQLITE_NOMEM; + sqlite3_bind_text(pStmt, 5, zEnd, -1, sqlite3_free); + } + sqlite3_bind_blob(pStmt, 6, zRoot, nRoot, SQLITE_STATIC); + sqlite3_step(pStmt); + rc = sqlite3_reset(pStmt); + } + return rc; +} + +/* +** Return the size of the common prefix (if any) shared by zPrev and +** zNext, in bytes. For example, +** +** fts3PrefixCompress("abc", 3, "abcdef", 6) // returns 3 +** fts3PrefixCompress("abX", 3, "abcdef", 6) // returns 2 +** fts3PrefixCompress("abX", 3, "Xbcdef", 6) // returns 0 +*/ +static int fts3PrefixCompress( + const char *zPrev, /* Buffer containing previous term */ + int nPrev, /* Size of buffer zPrev in bytes */ + const char *zNext, /* Buffer containing next term */ + int nNext /* Size of buffer zNext in bytes */ +){ + int n; + UNUSED_PARAMETER(nNext); + for(n=0; nnData; /* Current size of node in bytes */ + int nReq = nData; /* Required space after adding zTerm */ + int nPrefix; /* Number of bytes of prefix compression */ + int nSuffix; /* Suffix length */ + + nPrefix = fts3PrefixCompress(pTree->zTerm, pTree->nTerm, zTerm, nTerm); + nSuffix = nTerm-nPrefix; + + nReq += sqlite3Fts3VarintLen(nPrefix)+sqlite3Fts3VarintLen(nSuffix)+nSuffix; + if( nReq<=p->nNodeSize || !pTree->zTerm ){ + + if( nReq>p->nNodeSize ){ + /* An unusual case: this is the first term to be added to the node + ** and the static node buffer (p->nNodeSize bytes) is not large + ** enough. Use a separately malloced buffer instead This wastes + ** p->nNodeSize bytes, but since this scenario only comes about when + ** the database contain two terms that share a prefix of almost 2KB, + ** this is not expected to be a serious problem. + */ + assert( pTree->aData==(char *)&pTree[1] ); + pTree->aData = (char *)sqlite3_malloc(nReq); + if( !pTree->aData ){ + return SQLITE_NOMEM; + } + } + + if( pTree->zTerm ){ + /* There is no prefix-length field for first term in a node */ + nData += sqlite3Fts3PutVarint(&pTree->aData[nData], nPrefix); + } + + nData += sqlite3Fts3PutVarint(&pTree->aData[nData], nSuffix); + memcpy(&pTree->aData[nData], &zTerm[nPrefix], nSuffix); + pTree->nData = nData + nSuffix; + pTree->nEntry++; + + if( isCopyTerm ){ + if( pTree->nMalloczMalloc, nTerm*2); + if( !zNew ){ + return SQLITE_NOMEM; + } + pTree->nMalloc = nTerm*2; + pTree->zMalloc = zNew; + } + pTree->zTerm = pTree->zMalloc; + memcpy(pTree->zTerm, zTerm, nTerm); + pTree->nTerm = nTerm; + }else{ + pTree->zTerm = (char *)zTerm; + pTree->nTerm = nTerm; + } + return SQLITE_OK; + } + } + + /* If control flows to here, it was not possible to append zTerm to the + ** current node. Create a new node (a right-sibling of the current node). + ** If this is the first node in the tree, the term is added to it. + ** + ** Otherwise, the term is not added to the new node, it is left empty for + ** now. Instead, the term is inserted into the parent of pTree. If pTree + ** has no parent, one is created here. + */ + pNew = (SegmentNode *)sqlite3_malloc(sizeof(SegmentNode) + p->nNodeSize); + if( !pNew ){ + return SQLITE_NOMEM; + } + memset(pNew, 0, sizeof(SegmentNode)); + pNew->nData = 1 + FTS3_VARINT_MAX; + pNew->aData = (char *)&pNew[1]; + + if( pTree ){ + SegmentNode *pParent = pTree->pParent; + rc = fts3NodeAddTerm(p, &pParent, isCopyTerm, zTerm, nTerm); + if( pTree->pParent==0 ){ + pTree->pParent = pParent; + } + pTree->pRight = pNew; + pNew->pLeftmost = pTree->pLeftmost; + pNew->pParent = pParent; + pNew->zMalloc = pTree->zMalloc; + pNew->nMalloc = pTree->nMalloc; + pTree->zMalloc = 0; + }else{ + pNew->pLeftmost = pNew; + rc = fts3NodeAddTerm(p, &pNew, isCopyTerm, zTerm, nTerm); + } + + *ppTree = pNew; + return rc; +} + +/* +** Helper function for fts3NodeWrite(). +*/ +static int fts3TreeFinishNode( + SegmentNode *pTree, + int iHeight, + sqlite3_int64 iLeftChild +){ + int nStart; + assert( iHeight>=1 && iHeight<128 ); + nStart = FTS3_VARINT_MAX - sqlite3Fts3VarintLen(iLeftChild); + pTree->aData[nStart] = (char)iHeight; + sqlite3Fts3PutVarint(&pTree->aData[nStart+1], iLeftChild); + return nStart; +} + +/* +** Write the buffer for the segment node pTree and all of its peers to the +** database. Then call this function recursively to write the parent of +** pTree and its peers to the database. +** +** Except, if pTree is a root node, do not write it to the database. Instead, +** set output variables *paRoot and *pnRoot to contain the root node. +** +** If successful, SQLITE_OK is returned and output variable *piLast is +** set to the largest blockid written to the database (or zero if no +** blocks were written to the db). Otherwise, an SQLite error code is +** returned. +*/ +static int fts3NodeWrite( + Fts3Table *p, /* Virtual table handle */ + SegmentNode *pTree, /* SegmentNode handle */ + int iHeight, /* Height of this node in tree */ + sqlite3_int64 iLeaf, /* Block id of first leaf node */ + sqlite3_int64 iFree, /* Block id of next free slot in %_segments */ + sqlite3_int64 *piLast, /* OUT: Block id of last entry written */ + char **paRoot, /* OUT: Data for root node */ + int *pnRoot /* OUT: Size of root node in bytes */ +){ + int rc = SQLITE_OK; + + if( !pTree->pParent ){ + /* Root node of the tree. */ + int nStart = fts3TreeFinishNode(pTree, iHeight, iLeaf); + *piLast = iFree-1; + *pnRoot = pTree->nData - nStart; + *paRoot = &pTree->aData[nStart]; + }else{ + SegmentNode *pIter; + sqlite3_int64 iNextFree = iFree; + sqlite3_int64 iNextLeaf = iLeaf; + for(pIter=pTree->pLeftmost; pIter && rc==SQLITE_OK; pIter=pIter->pRight){ + int nStart = fts3TreeFinishNode(pIter, iHeight, iNextLeaf); + int nWrite = pIter->nData - nStart; + + rc = fts3WriteSegment(p, iNextFree, &pIter->aData[nStart], nWrite); + iNextFree++; + iNextLeaf += (pIter->nEntry+1); + } + if( rc==SQLITE_OK ){ + assert( iNextLeaf==iFree ); + rc = fts3NodeWrite( + p, pTree->pParent, iHeight+1, iFree, iNextFree, piLast, paRoot, pnRoot + ); + } + } + + return rc; +} + +/* +** Free all memory allocations associated with the tree pTree. +*/ +static void fts3NodeFree(SegmentNode *pTree){ + if( pTree ){ + SegmentNode *p = pTree->pLeftmost; + fts3NodeFree(p->pParent); + while( p ){ + SegmentNode *pRight = p->pRight; + if( p->aData!=(char *)&p[1] ){ + sqlite3_free(p->aData); + } + assert( pRight==0 || p->zMalloc==0 ); + sqlite3_free(p->zMalloc); + sqlite3_free(p); + p = pRight; + } + } +} + +/* +** Add a term to the segment being constructed by the SegmentWriter object +** *ppWriter. When adding the first term to a segment, *ppWriter should +** be passed NULL. This function will allocate a new SegmentWriter object +** and return it via the input/output variable *ppWriter in this case. +** +** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code. +*/ +static int fts3SegWriterAdd( + Fts3Table *p, /* Virtual table handle */ + SegmentWriter **ppWriter, /* IN/OUT: SegmentWriter handle */ + int isCopyTerm, /* True if buffer zTerm must be copied */ + const char *zTerm, /* Pointer to buffer containing term */ + int nTerm, /* Size of term in bytes */ + const char *aDoclist, /* Pointer to buffer containing doclist */ + int nDoclist /* Size of doclist in bytes */ +){ + int nPrefix; /* Size of term prefix in bytes */ + int nSuffix; /* Size of term suffix in bytes */ + int nReq; /* Number of bytes required on leaf page */ + int nData; + SegmentWriter *pWriter = *ppWriter; + + if( !pWriter ){ + int rc; + sqlite3_stmt *pStmt; + + /* Allocate the SegmentWriter structure */ + pWriter = (SegmentWriter *)sqlite3_malloc(sizeof(SegmentWriter)); + if( !pWriter ) return SQLITE_NOMEM; + memset(pWriter, 0, sizeof(SegmentWriter)); + *ppWriter = pWriter; + + /* Allocate a buffer in which to accumulate data */ + pWriter->aData = (char *)sqlite3_malloc(p->nNodeSize); + if( !pWriter->aData ) return SQLITE_NOMEM; + pWriter->nSize = p->nNodeSize; + + /* Find the next free blockid in the %_segments table */ + rc = fts3SqlStmt(p, SQL_NEXT_SEGMENTS_ID, &pStmt, 0); + if( rc!=SQLITE_OK ) return rc; + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + pWriter->iFree = sqlite3_column_int64(pStmt, 0); + pWriter->iFirst = pWriter->iFree; + } + rc = sqlite3_reset(pStmt); + if( rc!=SQLITE_OK ) return rc; + } + nData = pWriter->nData; + + nPrefix = fts3PrefixCompress(pWriter->zTerm, pWriter->nTerm, zTerm, nTerm); + nSuffix = nTerm-nPrefix; + + /* Figure out how many bytes are required by this new entry */ + nReq = sqlite3Fts3VarintLen(nPrefix) + /* varint containing prefix size */ + sqlite3Fts3VarintLen(nSuffix) + /* varint containing suffix size */ + nSuffix + /* Term suffix */ + sqlite3Fts3VarintLen(nDoclist) + /* Size of doclist */ + nDoclist; /* Doclist data */ + + if( nData>0 && nData+nReq>p->nNodeSize ){ + int rc; + + /* The current leaf node is full. Write it out to the database. */ + rc = fts3WriteSegment(p, pWriter->iFree++, pWriter->aData, nData); + if( rc!=SQLITE_OK ) return rc; + p->nLeafAdd++; + + /* Add the current term to the interior node tree. The term added to + ** the interior tree must: + ** + ** a) be greater than the largest term on the leaf node just written + ** to the database (still available in pWriter->zTerm), and + ** + ** b) be less than or equal to the term about to be added to the new + ** leaf node (zTerm/nTerm). + ** + ** In other words, it must be the prefix of zTerm 1 byte longer than + ** the common prefix (if any) of zTerm and pWriter->zTerm. + */ + assert( nPrefixpTree, isCopyTerm, zTerm, nPrefix+1); + if( rc!=SQLITE_OK ) return rc; + + nData = 0; + pWriter->nTerm = 0; + + nPrefix = 0; + nSuffix = nTerm; + nReq = 1 + /* varint containing prefix size */ + sqlite3Fts3VarintLen(nTerm) + /* varint containing suffix size */ + nTerm + /* Term suffix */ + sqlite3Fts3VarintLen(nDoclist) + /* Size of doclist */ + nDoclist; /* Doclist data */ + } + + /* Increase the total number of bytes written to account for the new entry. */ + pWriter->nLeafData += nReq; + + /* If the buffer currently allocated is too small for this entry, realloc + ** the buffer to make it large enough. + */ + if( nReq>pWriter->nSize ){ + char *aNew = sqlite3_realloc(pWriter->aData, nReq); + if( !aNew ) return SQLITE_NOMEM; + pWriter->aData = aNew; + pWriter->nSize = nReq; + } + assert( nData+nReq<=pWriter->nSize ); + + /* Append the prefix-compressed term and doclist to the buffer. */ + nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nPrefix); + nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nSuffix); + memcpy(&pWriter->aData[nData], &zTerm[nPrefix], nSuffix); + nData += nSuffix; + nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nDoclist); + memcpy(&pWriter->aData[nData], aDoclist, nDoclist); + pWriter->nData = nData + nDoclist; + + /* Save the current term so that it can be used to prefix-compress the next. + ** If the isCopyTerm parameter is true, then the buffer pointed to by + ** zTerm is transient, so take a copy of the term data. Otherwise, just + ** store a copy of the pointer. + */ + if( isCopyTerm ){ + if( nTerm>pWriter->nMalloc ){ + char *zNew = sqlite3_realloc(pWriter->zMalloc, nTerm*2); + if( !zNew ){ + return SQLITE_NOMEM; + } + pWriter->nMalloc = nTerm*2; + pWriter->zMalloc = zNew; + pWriter->zTerm = zNew; + } + assert( pWriter->zTerm==pWriter->zMalloc ); + memcpy(pWriter->zTerm, zTerm, nTerm); + }else{ + pWriter->zTerm = (char *)zTerm; + } + pWriter->nTerm = nTerm; + + return SQLITE_OK; +} + +/* +** Flush all data associated with the SegmentWriter object pWriter to the +** database. This function must be called after all terms have been added +** to the segment using fts3SegWriterAdd(). If successful, SQLITE_OK is +** returned. Otherwise, an SQLite error code. +*/ +static int fts3SegWriterFlush( + Fts3Table *p, /* Virtual table handle */ + SegmentWriter *pWriter, /* SegmentWriter to flush to the db */ + sqlite3_int64 iLevel, /* Value for 'level' column of %_segdir */ + int iIdx /* Value for 'idx' column of %_segdir */ +){ + int rc; /* Return code */ + if( pWriter->pTree ){ + sqlite3_int64 iLast = 0; /* Largest block id written to database */ + sqlite3_int64 iLastLeaf; /* Largest leaf block id written to db */ + char *zRoot = NULL; /* Pointer to buffer containing root node */ + int nRoot = 0; /* Size of buffer zRoot */ + + iLastLeaf = pWriter->iFree; + rc = fts3WriteSegment(p, pWriter->iFree++, pWriter->aData, pWriter->nData); + if( rc==SQLITE_OK ){ + rc = fts3NodeWrite(p, pWriter->pTree, 1, + pWriter->iFirst, pWriter->iFree, &iLast, &zRoot, &nRoot); + } + if( rc==SQLITE_OK ){ + rc = fts3WriteSegdir(p, iLevel, iIdx, + pWriter->iFirst, iLastLeaf, iLast, pWriter->nLeafData, zRoot, nRoot); + } + }else{ + /* The entire tree fits on the root node. Write it to the segdir table. */ + rc = fts3WriteSegdir(p, iLevel, iIdx, + 0, 0, 0, pWriter->nLeafData, pWriter->aData, pWriter->nData); + } + p->nLeafAdd++; + return rc; +} + +/* +** Release all memory held by the SegmentWriter object passed as the +** first argument. +*/ +static void fts3SegWriterFree(SegmentWriter *pWriter){ + if( pWriter ){ + sqlite3_free(pWriter->aData); + sqlite3_free(pWriter->zMalloc); + fts3NodeFree(pWriter->pTree); + sqlite3_free(pWriter); + } +} + +/* +** The first value in the apVal[] array is assumed to contain an integer. +** This function tests if there exist any documents with docid values that +** are different from that integer. i.e. if deleting the document with docid +** pRowid would mean the FTS3 table were empty. +** +** If successful, *pisEmpty is set to true if the table is empty except for +** document pRowid, or false otherwise, and SQLITE_OK is returned. If an +** error occurs, an SQLite error code is returned. +*/ +static int fts3IsEmpty(Fts3Table *p, sqlite3_value *pRowid, int *pisEmpty){ + sqlite3_stmt *pStmt; + int rc; + if( p->zContentTbl ){ + /* If using the content=xxx option, assume the table is never empty */ + *pisEmpty = 0; + rc = SQLITE_OK; + }else{ + rc = fts3SqlStmt(p, SQL_IS_EMPTY, &pStmt, &pRowid); + if( rc==SQLITE_OK ){ + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + *pisEmpty = sqlite3_column_int(pStmt, 0); + } + rc = sqlite3_reset(pStmt); + } + } + return rc; +} + +/* +** Set *pnMax to the largest segment level in the database for the index +** iIndex. +** +** Segment levels are stored in the 'level' column of the %_segdir table. +** +** Return SQLITE_OK if successful, or an SQLite error code if not. +*/ +static int fts3SegmentMaxLevel( + Fts3Table *p, + int iLangid, + int iIndex, + sqlite3_int64 *pnMax +){ + sqlite3_stmt *pStmt; + int rc; + assert( iIndex>=0 && iIndexnIndex ); + + /* Set pStmt to the compiled version of: + ** + ** SELECT max(level) FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ? + ** + ** (1024 is actually the value of macro FTS3_SEGDIR_PREFIXLEVEL_STR). + */ + rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR_MAX_LEVEL, &pStmt, 0); + if( rc!=SQLITE_OK ) return rc; + sqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex, 0)); + sqlite3_bind_int64(pStmt, 2, + getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1) + ); + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + *pnMax = sqlite3_column_int64(pStmt, 0); + } + return sqlite3_reset(pStmt); +} + +/* +** iAbsLevel is an absolute level that may be assumed to exist within +** the database. This function checks if it is the largest level number +** within its index. Assuming no error occurs, *pbMax is set to 1 if +** iAbsLevel is indeed the largest level, or 0 otherwise, and SQLITE_OK +** is returned. If an error occurs, an error code is returned and the +** final value of *pbMax is undefined. +*/ +static int fts3SegmentIsMaxLevel(Fts3Table *p, i64 iAbsLevel, int *pbMax){ + + /* Set pStmt to the compiled version of: + ** + ** SELECT max(level) FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ? + ** + ** (1024 is actually the value of macro FTS3_SEGDIR_PREFIXLEVEL_STR). + */ + sqlite3_stmt *pStmt; + int rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR_MAX_LEVEL, &pStmt, 0); + if( rc!=SQLITE_OK ) return rc; + sqlite3_bind_int64(pStmt, 1, iAbsLevel+1); + sqlite3_bind_int64(pStmt, 2, + ((iAbsLevel/FTS3_SEGDIR_MAXLEVEL)+1) * FTS3_SEGDIR_MAXLEVEL + ); + + *pbMax = 0; + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + *pbMax = sqlite3_column_type(pStmt, 0)==SQLITE_NULL; + } + return sqlite3_reset(pStmt); +} + +/* +** Delete all entries in the %_segments table associated with the segment +** opened with seg-reader pSeg. This function does not affect the contents +** of the %_segdir table. +*/ +static int fts3DeleteSegment( + Fts3Table *p, /* FTS table handle */ + Fts3SegReader *pSeg /* Segment to delete */ +){ + int rc = SQLITE_OK; /* Return code */ + if( pSeg->iStartBlock ){ + sqlite3_stmt *pDelete; /* SQL statement to delete rows */ + rc = fts3SqlStmt(p, SQL_DELETE_SEGMENTS_RANGE, &pDelete, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pDelete, 1, pSeg->iStartBlock); + sqlite3_bind_int64(pDelete, 2, pSeg->iEndBlock); + sqlite3_step(pDelete); + rc = sqlite3_reset(pDelete); + } + } + return rc; +} + +/* +** This function is used after merging multiple segments into a single large +** segment to delete the old, now redundant, segment b-trees. Specifically, +** it: +** +** 1) Deletes all %_segments entries for the segments associated with +** each of the SegReader objects in the array passed as the third +** argument, and +** +** 2) deletes all %_segdir entries with level iLevel, or all %_segdir +** entries regardless of level if (iLevel<0). +** +** SQLITE_OK is returned if successful, otherwise an SQLite error code. +*/ +static int fts3DeleteSegdir( + Fts3Table *p, /* Virtual table handle */ + int iLangid, /* Language id */ + int iIndex, /* Index for p->aIndex */ + int iLevel, /* Level of %_segdir entries to delete */ + Fts3SegReader **apSegment, /* Array of SegReader objects */ + int nReader /* Size of array apSegment */ +){ + int rc = SQLITE_OK; /* Return Code */ + int i; /* Iterator variable */ + sqlite3_stmt *pDelete = 0; /* SQL statement to delete rows */ + + for(i=0; rc==SQLITE_OK && i=0 || iLevel==FTS3_SEGCURSOR_ALL ); + if( iLevel==FTS3_SEGCURSOR_ALL ){ + rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_RANGE, &pDelete, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pDelete, 1, getAbsoluteLevel(p, iLangid, iIndex, 0)); + sqlite3_bind_int64(pDelete, 2, + getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1) + ); + } + }else{ + rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_LEVEL, &pDelete, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64( + pDelete, 1, getAbsoluteLevel(p, iLangid, iIndex, iLevel) + ); + } + } + + if( rc==SQLITE_OK ){ + sqlite3_step(pDelete); + rc = sqlite3_reset(pDelete); + } + + return rc; +} + +/* +** When this function is called, buffer *ppList (size *pnList bytes) contains +** a position list that may (or may not) feature multiple columns. This +** function adjusts the pointer *ppList and the length *pnList so that they +** identify the subset of the position list that corresponds to column iCol. +** +** If there are no entries in the input position list for column iCol, then +** *pnList is set to zero before returning. +** +** If parameter bZero is non-zero, then any part of the input list following +** the end of the output list is zeroed before returning. +*/ +static void fts3ColumnFilter( + int iCol, /* Column to filter on */ + int bZero, /* Zero out anything following *ppList */ + char **ppList, /* IN/OUT: Pointer to position list */ + int *pnList /* IN/OUT: Size of buffer *ppList in bytes */ +){ + char *pList = *ppList; + int nList = *pnList; + char *pEnd = &pList[nList]; + int iCurrent = 0; + char *p = pList; + + assert( iCol>=0 ); + while( 1 ){ + char c = 0; + while( ppMsr->nBuffer ){ + char *pNew; + pMsr->nBuffer = nList*2; + pNew = (char *)sqlite3_realloc(pMsr->aBuffer, pMsr->nBuffer); + if( !pNew ) return SQLITE_NOMEM; + pMsr->aBuffer = pNew; + } + + memcpy(pMsr->aBuffer, pList, nList); + return SQLITE_OK; +} + +SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext( + Fts3Table *p, /* Virtual table handle */ + Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */ + sqlite3_int64 *piDocid, /* OUT: Docid value */ + char **paPoslist, /* OUT: Pointer to position list */ + int *pnPoslist /* OUT: Size of position list in bytes */ +){ + int nMerge = pMsr->nAdvance; + Fts3SegReader **apSegment = pMsr->apSegment; + int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = ( + p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp + ); + + if( nMerge==0 ){ + *paPoslist = 0; + return SQLITE_OK; + } + + while( 1 ){ + Fts3SegReader *pSeg; + pSeg = pMsr->apSegment[0]; + + if( pSeg->pOffsetList==0 ){ + *paPoslist = 0; + break; + }else{ + int rc; + char *pList; + int nList; + int j; + sqlite3_int64 iDocid = apSegment[0]->iDocid; + + rc = fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList); + j = 1; + while( rc==SQLITE_OK + && jpOffsetList + && apSegment[j]->iDocid==iDocid + ){ + rc = fts3SegReaderNextDocid(p, apSegment[j], 0, 0); + j++; + } + if( rc!=SQLITE_OK ) return rc; + fts3SegReaderSort(pMsr->apSegment, nMerge, j, xCmp); + + if( nList>0 && fts3SegReaderIsPending(apSegment[0]) ){ + rc = fts3MsrBufferData(pMsr, pList, nList+1); + if( rc!=SQLITE_OK ) return rc; + assert( (pMsr->aBuffer[nList] & 0xFE)==0x00 ); + pList = pMsr->aBuffer; + } + + if( pMsr->iColFilter>=0 ){ + fts3ColumnFilter(pMsr->iColFilter, 1, &pList, &nList); + } + + if( nList>0 ){ + *paPoslist = pList; + *piDocid = iDocid; + *pnPoslist = nList; + break; + } + } + } + + return SQLITE_OK; +} + +static int fts3SegReaderStart( + Fts3Table *p, /* Virtual table handle */ + Fts3MultiSegReader *pCsr, /* Cursor object */ + const char *zTerm, /* Term searched for (or NULL) */ + int nTerm /* Length of zTerm in bytes */ +){ + int i; + int nSeg = pCsr->nSegment; + + /* If the Fts3SegFilter defines a specific term (or term prefix) to search + ** for, then advance each segment iterator until it points to a term of + ** equal or greater value than the specified term. This prevents many + ** unnecessary merge/sort operations for the case where single segment + ** b-tree leaf nodes contain more than one term. + */ + for(i=0; pCsr->bRestart==0 && inSegment; i++){ + int res = 0; + Fts3SegReader *pSeg = pCsr->apSegment[i]; + do { + int rc = fts3SegReaderNext(p, pSeg, 0); + if( rc!=SQLITE_OK ) return rc; + }while( zTerm && (res = fts3SegReaderTermCmp(pSeg, zTerm, nTerm))<0 ); + + if( pSeg->bLookup && res!=0 ){ + fts3SegReaderSetEof(pSeg); + } + } + fts3SegReaderSort(pCsr->apSegment, nSeg, nSeg, fts3SegReaderCmp); + + return SQLITE_OK; +} + +SQLITE_PRIVATE int sqlite3Fts3SegReaderStart( + Fts3Table *p, /* Virtual table handle */ + Fts3MultiSegReader *pCsr, /* Cursor object */ + Fts3SegFilter *pFilter /* Restrictions on range of iteration */ +){ + pCsr->pFilter = pFilter; + return fts3SegReaderStart(p, pCsr, pFilter->zTerm, pFilter->nTerm); +} + +SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart( + Fts3Table *p, /* Virtual table handle */ + Fts3MultiSegReader *pCsr, /* Cursor object */ + int iCol, /* Column to match on. */ + const char *zTerm, /* Term to iterate through a doclist for */ + int nTerm /* Number of bytes in zTerm */ +){ + int i; + int rc; + int nSegment = pCsr->nSegment; + int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = ( + p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp + ); + + assert( pCsr->pFilter==0 ); + assert( zTerm && nTerm>0 ); + + /* Advance each segment iterator until it points to the term zTerm/nTerm. */ + rc = fts3SegReaderStart(p, pCsr, zTerm, nTerm); + if( rc!=SQLITE_OK ) return rc; + + /* Determine how many of the segments actually point to zTerm/nTerm. */ + for(i=0; iapSegment[i]; + if( !pSeg->aNode || fts3SegReaderTermCmp(pSeg, zTerm, nTerm) ){ + break; + } + } + pCsr->nAdvance = i; + + /* Advance each of the segments to point to the first docid. */ + for(i=0; inAdvance; i++){ + rc = fts3SegReaderFirstDocid(p, pCsr->apSegment[i]); + if( rc!=SQLITE_OK ) return rc; + } + fts3SegReaderSort(pCsr->apSegment, i, i, xCmp); + + assert( iCol<0 || iColnColumn ); + pCsr->iColFilter = iCol; + + return SQLITE_OK; +} + +/* +** This function is called on a MultiSegReader that has been started using +** sqlite3Fts3MsrIncrStart(). One or more calls to MsrIncrNext() may also +** have been made. Calling this function puts the MultiSegReader in such +** a state that if the next two calls are: +** +** sqlite3Fts3SegReaderStart() +** sqlite3Fts3SegReaderStep() +** +** then the entire doclist for the term is available in +** MultiSegReader.aDoclist/nDoclist. +*/ +SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr){ + int i; /* Used to iterate through segment-readers */ + + assert( pCsr->zTerm==0 ); + assert( pCsr->nTerm==0 ); + assert( pCsr->aDoclist==0 ); + assert( pCsr->nDoclist==0 ); + + pCsr->nAdvance = 0; + pCsr->bRestart = 1; + for(i=0; inSegment; i++){ + pCsr->apSegment[i]->pOffsetList = 0; + pCsr->apSegment[i]->nOffsetList = 0; + pCsr->apSegment[i]->iDocid = 0; + } + + return SQLITE_OK; +} + + +SQLITE_PRIVATE int sqlite3Fts3SegReaderStep( + Fts3Table *p, /* Virtual table handle */ + Fts3MultiSegReader *pCsr /* Cursor object */ +){ + int rc = SQLITE_OK; + + int isIgnoreEmpty = (pCsr->pFilter->flags & FTS3_SEGMENT_IGNORE_EMPTY); + int isRequirePos = (pCsr->pFilter->flags & FTS3_SEGMENT_REQUIRE_POS); + int isColFilter = (pCsr->pFilter->flags & FTS3_SEGMENT_COLUMN_FILTER); + int isPrefix = (pCsr->pFilter->flags & FTS3_SEGMENT_PREFIX); + int isScan = (pCsr->pFilter->flags & FTS3_SEGMENT_SCAN); + int isFirst = (pCsr->pFilter->flags & FTS3_SEGMENT_FIRST); + + Fts3SegReader **apSegment = pCsr->apSegment; + int nSegment = pCsr->nSegment; + Fts3SegFilter *pFilter = pCsr->pFilter; + int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = ( + p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp + ); + + if( pCsr->nSegment==0 ) return SQLITE_OK; + + do { + int nMerge; + int i; + + /* Advance the first pCsr->nAdvance entries in the apSegment[] array + ** forward. Then sort the list in order of current term again. + */ + for(i=0; inAdvance; i++){ + Fts3SegReader *pSeg = apSegment[i]; + if( pSeg->bLookup ){ + fts3SegReaderSetEof(pSeg); + }else{ + rc = fts3SegReaderNext(p, pSeg, 0); + } + if( rc!=SQLITE_OK ) return rc; + } + fts3SegReaderSort(apSegment, nSegment, pCsr->nAdvance, fts3SegReaderCmp); + pCsr->nAdvance = 0; + + /* If all the seg-readers are at EOF, we're finished. return SQLITE_OK. */ + assert( rc==SQLITE_OK ); + if( apSegment[0]->aNode==0 ) break; + + pCsr->nTerm = apSegment[0]->nTerm; + pCsr->zTerm = apSegment[0]->zTerm; + + /* If this is a prefix-search, and if the term that apSegment[0] points + ** to does not share a suffix with pFilter->zTerm/nTerm, then all + ** required callbacks have been made. In this case exit early. + ** + ** Similarly, if this is a search for an exact match, and the first term + ** of segment apSegment[0] is not a match, exit early. + */ + if( pFilter->zTerm && !isScan ){ + if( pCsr->nTermnTerm + || (!isPrefix && pCsr->nTerm>pFilter->nTerm) + || memcmp(pCsr->zTerm, pFilter->zTerm, pFilter->nTerm) + ){ + break; + } + } + + nMerge = 1; + while( nMergeaNode + && apSegment[nMerge]->nTerm==pCsr->nTerm + && 0==memcmp(pCsr->zTerm, apSegment[nMerge]->zTerm, pCsr->nTerm) + ){ + nMerge++; + } + + assert( isIgnoreEmpty || (isRequirePos && !isColFilter) ); + if( nMerge==1 + && !isIgnoreEmpty + && !isFirst + && (p->bDescIdx==0 || fts3SegReaderIsPending(apSegment[0])==0) + ){ + pCsr->nDoclist = apSegment[0]->nDoclist; + if( fts3SegReaderIsPending(apSegment[0]) ){ + rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, pCsr->nDoclist); + pCsr->aDoclist = pCsr->aBuffer; + }else{ + pCsr->aDoclist = apSegment[0]->aDoclist; + } + if( rc==SQLITE_OK ) rc = SQLITE_ROW; + }else{ + int nDoclist = 0; /* Size of doclist */ + sqlite3_int64 iPrev = 0; /* Previous docid stored in doclist */ + + /* The current term of the first nMerge entries in the array + ** of Fts3SegReader objects is the same. The doclists must be merged + ** and a single term returned with the merged doclist. + */ + for(i=0; ipOffsetList ){ + int j; /* Number of segments that share a docid */ + char *pList = 0; + int nList = 0; + int nByte; + sqlite3_int64 iDocid = apSegment[0]->iDocid; + fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList); + j = 1; + while( jpOffsetList + && apSegment[j]->iDocid==iDocid + ){ + fts3SegReaderNextDocid(p, apSegment[j], 0, 0); + j++; + } + + if( isColFilter ){ + fts3ColumnFilter(pFilter->iCol, 0, &pList, &nList); + } + + if( !isIgnoreEmpty || nList>0 ){ + + /* Calculate the 'docid' delta value to write into the merged + ** doclist. */ + sqlite3_int64 iDelta; + if( p->bDescIdx && nDoclist>0 ){ + iDelta = iPrev - iDocid; + }else{ + iDelta = iDocid - iPrev; + } + assert( iDelta>0 || (nDoclist==0 && iDelta==iDocid) ); + assert( nDoclist>0 || iDelta==iDocid ); + + nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0); + if( nDoclist+nByte>pCsr->nBuffer ){ + char *aNew; + pCsr->nBuffer = (nDoclist+nByte)*2; + aNew = sqlite3_realloc(pCsr->aBuffer, pCsr->nBuffer); + if( !aNew ){ + return SQLITE_NOMEM; + } + pCsr->aBuffer = aNew; + } + + if( isFirst ){ + char *a = &pCsr->aBuffer[nDoclist]; + int nWrite; + + nWrite = sqlite3Fts3FirstFilter(iDelta, pList, nList, a); + if( nWrite ){ + iPrev = iDocid; + nDoclist += nWrite; + } + }else{ + nDoclist += sqlite3Fts3PutVarint(&pCsr->aBuffer[nDoclist], iDelta); + iPrev = iDocid; + if( isRequirePos ){ + memcpy(&pCsr->aBuffer[nDoclist], pList, nList); + nDoclist += nList; + pCsr->aBuffer[nDoclist++] = '\0'; + } + } + } + + fts3SegReaderSort(apSegment, nMerge, j, xCmp); + } + if( nDoclist>0 ){ + pCsr->aDoclist = pCsr->aBuffer; + pCsr->nDoclist = nDoclist; + rc = SQLITE_ROW; + } + } + pCsr->nAdvance = nMerge; + }while( rc==SQLITE_OK ); + + return rc; +} + + +SQLITE_PRIVATE void sqlite3Fts3SegReaderFinish( + Fts3MultiSegReader *pCsr /* Cursor object */ +){ + if( pCsr ){ + int i; + for(i=0; inSegment; i++){ + sqlite3Fts3SegReaderFree(pCsr->apSegment[i]); + } + sqlite3_free(pCsr->apSegment); + sqlite3_free(pCsr->aBuffer); + + pCsr->nSegment = 0; + pCsr->apSegment = 0; + pCsr->aBuffer = 0; + } +} + +/* +** Decode the "end_block" field, selected by column iCol of the SELECT +** statement passed as the first argument. +** +** The "end_block" field may contain either an integer, or a text field +** containing the text representation of two non-negative integers separated +** by one or more space (0x20) characters. In the first case, set *piEndBlock +** to the integer value and *pnByte to zero before returning. In the second, +** set *piEndBlock to the first value and *pnByte to the second. +*/ +static void fts3ReadEndBlockField( + sqlite3_stmt *pStmt, + int iCol, + i64 *piEndBlock, + i64 *pnByte +){ + const unsigned char *zText = sqlite3_column_text(pStmt, iCol); + if( zText ){ + int i; + int iMul = 1; + i64 iVal = 0; + for(i=0; zText[i]>='0' && zText[i]<='9'; i++){ + iVal = iVal*10 + (zText[i] - '0'); + } + *piEndBlock = iVal; + while( zText[i]==' ' ) i++; + iVal = 0; + if( zText[i]=='-' ){ + i++; + iMul = -1; + } + for(/* no-op */; zText[i]>='0' && zText[i]<='9'; i++){ + iVal = iVal*10 + (zText[i] - '0'); + } + *pnByte = (iVal * (i64)iMul); + } +} + + +/* +** A segment of size nByte bytes has just been written to absolute level +** iAbsLevel. Promote any segments that should be promoted as a result. +*/ +static int fts3PromoteSegments( + Fts3Table *p, /* FTS table handle */ + sqlite3_int64 iAbsLevel, /* Absolute level just updated */ + sqlite3_int64 nByte /* Size of new segment at iAbsLevel */ +){ + int rc = SQLITE_OK; + sqlite3_stmt *pRange; + + rc = fts3SqlStmt(p, SQL_SELECT_LEVEL_RANGE2, &pRange, 0); + + if( rc==SQLITE_OK ){ + int bOk = 0; + i64 iLast = (iAbsLevel/FTS3_SEGDIR_MAXLEVEL + 1) * FTS3_SEGDIR_MAXLEVEL - 1; + i64 nLimit = (nByte*3)/2; + + /* Loop through all entries in the %_segdir table corresponding to + ** segments in this index on levels greater than iAbsLevel. If there is + ** at least one such segment, and it is possible to determine that all + ** such segments are smaller than nLimit bytes in size, they will be + ** promoted to level iAbsLevel. */ + sqlite3_bind_int64(pRange, 1, iAbsLevel+1); + sqlite3_bind_int64(pRange, 2, iLast); + while( SQLITE_ROW==sqlite3_step(pRange) ){ + i64 nSize = 0, dummy; + fts3ReadEndBlockField(pRange, 2, &dummy, &nSize); + if( nSize<=0 || nSize>nLimit ){ + /* If nSize==0, then the %_segdir.end_block field does not not + ** contain a size value. This happens if it was written by an + ** old version of FTS. In this case it is not possible to determine + ** the size of the segment, and so segment promotion does not + ** take place. */ + bOk = 0; + break; + } + bOk = 1; + } + rc = sqlite3_reset(pRange); + + if( bOk ){ + int iIdx = 0; + sqlite3_stmt *pUpdate1 = 0; + sqlite3_stmt *pUpdate2 = 0; + + if( rc==SQLITE_OK ){ + rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL_IDX, &pUpdate1, 0); + } + if( rc==SQLITE_OK ){ + rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL, &pUpdate2, 0); + } + + if( rc==SQLITE_OK ){ + + /* Loop through all %_segdir entries for segments in this index with + ** levels equal to or greater than iAbsLevel. As each entry is visited, + ** updated it to set (level = -1) and (idx = N), where N is 0 for the + ** oldest segment in the range, 1 for the next oldest, and so on. + ** + ** In other words, move all segments being promoted to level -1, + ** setting the "idx" fields as appropriate to keep them in the same + ** order. The contents of level -1 (which is never used, except + ** transiently here), will be moved back to level iAbsLevel below. */ + sqlite3_bind_int64(pRange, 1, iAbsLevel); + while( SQLITE_ROW==sqlite3_step(pRange) ){ + sqlite3_bind_int(pUpdate1, 1, iIdx++); + sqlite3_bind_int(pUpdate1, 2, sqlite3_column_int(pRange, 0)); + sqlite3_bind_int(pUpdate1, 3, sqlite3_column_int(pRange, 1)); + sqlite3_step(pUpdate1); + rc = sqlite3_reset(pUpdate1); + if( rc!=SQLITE_OK ){ + sqlite3_reset(pRange); + break; + } + } + } + if( rc==SQLITE_OK ){ + rc = sqlite3_reset(pRange); + } + + /* Move level -1 to level iAbsLevel */ + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pUpdate2, 1, iAbsLevel); + sqlite3_step(pUpdate2); + rc = sqlite3_reset(pUpdate2); + } + } + } + + + return rc; +} + +/* +** Merge all level iLevel segments in the database into a single +** iLevel+1 segment. Or, if iLevel<0, merge all segments into a +** single segment with a level equal to the numerically largest level +** currently present in the database. +** +** If this function is called with iLevel<0, but there is only one +** segment in the database, SQLITE_DONE is returned immediately. +** Otherwise, if successful, SQLITE_OK is returned. If an error occurs, +** an SQLite error code is returned. +*/ +static int fts3SegmentMerge( + Fts3Table *p, + int iLangid, /* Language id to merge */ + int iIndex, /* Index in p->aIndex[] to merge */ + int iLevel /* Level to merge */ +){ + int rc; /* Return code */ + int iIdx = 0; /* Index of new segment */ + sqlite3_int64 iNewLevel = 0; /* Level/index to create new segment at */ + SegmentWriter *pWriter = 0; /* Used to write the new, merged, segment */ + Fts3SegFilter filter; /* Segment term filter condition */ + Fts3MultiSegReader csr; /* Cursor to iterate through level(s) */ + int bIgnoreEmpty = 0; /* True to ignore empty segments */ + i64 iMaxLevel = 0; /* Max level number for this index/langid */ + + assert( iLevel==FTS3_SEGCURSOR_ALL + || iLevel==FTS3_SEGCURSOR_PENDING + || iLevel>=0 + ); + assert( iLevel=0 && iIndexnIndex ); + + rc = sqlite3Fts3SegReaderCursor(p, iLangid, iIndex, iLevel, 0, 0, 1, 0, &csr); + if( rc!=SQLITE_OK || csr.nSegment==0 ) goto finished; + + if( iLevel!=FTS3_SEGCURSOR_PENDING ){ + rc = fts3SegmentMaxLevel(p, iLangid, iIndex, &iMaxLevel); + if( rc!=SQLITE_OK ) goto finished; + } + + if( iLevel==FTS3_SEGCURSOR_ALL ){ + /* This call is to merge all segments in the database to a single + ** segment. The level of the new segment is equal to the numerically + ** greatest segment level currently present in the database for this + ** index. The idx of the new segment is always 0. */ + if( csr.nSegment==1 ){ + rc = SQLITE_DONE; + goto finished; + } + iNewLevel = iMaxLevel; + bIgnoreEmpty = 1; + + }else{ + /* This call is to merge all segments at level iLevel. find the next + ** available segment index at level iLevel+1. The call to + ** fts3AllocateSegdirIdx() will merge the segments at level iLevel+1 to + ** a single iLevel+2 segment if necessary. */ + assert( FTS3_SEGCURSOR_PENDING==-1 ); + iNewLevel = getAbsoluteLevel(p, iLangid, iIndex, iLevel+1); + rc = fts3AllocateSegdirIdx(p, iLangid, iIndex, iLevel+1, &iIdx); + bIgnoreEmpty = (iLevel!=FTS3_SEGCURSOR_PENDING) && (iNewLevel>iMaxLevel); + } + if( rc!=SQLITE_OK ) goto finished; + + assert( csr.nSegment>0 ); + assert( iNewLevel>=getAbsoluteLevel(p, iLangid, iIndex, 0) ); + assert( iNewLevelnLeafData); + } + } + } + + finished: + fts3SegWriterFree(pWriter); + sqlite3Fts3SegReaderFinish(&csr); + return rc; +} + + +/* +** Flush the contents of pendingTerms to level 0 segments. +*/ +SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *p){ + int rc = SQLITE_OK; + int i; + + for(i=0; rc==SQLITE_OK && inIndex; i++){ + rc = fts3SegmentMerge(p, p->iPrevLangid, i, FTS3_SEGCURSOR_PENDING); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + } + sqlite3Fts3PendingTermsClear(p); + + /* Determine the auto-incr-merge setting if unknown. If enabled, + ** estimate the number of leaf blocks of content to be written + */ + if( rc==SQLITE_OK && p->bHasStat + && p->nAutoincrmerge==0xff && p->nLeafAdd>0 + ){ + sqlite3_stmt *pStmt = 0; + rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE); + rc = sqlite3_step(pStmt); + if( rc==SQLITE_ROW ){ + p->nAutoincrmerge = sqlite3_column_int(pStmt, 0); + if( p->nAutoincrmerge==1 ) p->nAutoincrmerge = 8; + }else if( rc==SQLITE_DONE ){ + p->nAutoincrmerge = 0; + } + rc = sqlite3_reset(pStmt); + } + } + return rc; +} + +/* +** Encode N integers as varints into a blob. +*/ +static void fts3EncodeIntArray( + int N, /* The number of integers to encode */ + u32 *a, /* The integer values */ + char *zBuf, /* Write the BLOB here */ + int *pNBuf /* Write number of bytes if zBuf[] used here */ +){ + int i, j; + for(i=j=0; iiPrevDocid. The sizes are encoded as +** a blob of varints. +*/ +static void fts3InsertDocsize( + int *pRC, /* Result code */ + Fts3Table *p, /* Table into which to insert */ + u32 *aSz /* Sizes of each column, in tokens */ +){ + char *pBlob; /* The BLOB encoding of the document size */ + int nBlob; /* Number of bytes in the BLOB */ + sqlite3_stmt *pStmt; /* Statement used to insert the encoding */ + int rc; /* Result code from subfunctions */ + + if( *pRC ) return; + pBlob = sqlite3_malloc( 10*p->nColumn ); + if( pBlob==0 ){ + *pRC = SQLITE_NOMEM; + return; + } + fts3EncodeIntArray(p->nColumn, aSz, pBlob, &nBlob); + rc = fts3SqlStmt(p, SQL_REPLACE_DOCSIZE, &pStmt, 0); + if( rc ){ + sqlite3_free(pBlob); + *pRC = rc; + return; + } + sqlite3_bind_int64(pStmt, 1, p->iPrevDocid); + sqlite3_bind_blob(pStmt, 2, pBlob, nBlob, sqlite3_free); + sqlite3_step(pStmt); + *pRC = sqlite3_reset(pStmt); +} + +/* +** Record 0 of the %_stat table contains a blob consisting of N varints, +** where N is the number of user defined columns in the fts3 table plus +** two. If nCol is the number of user defined columns, then values of the +** varints are set as follows: +** +** Varint 0: Total number of rows in the table. +** +** Varint 1..nCol: For each column, the total number of tokens stored in +** the column for all rows of the table. +** +** Varint 1+nCol: The total size, in bytes, of all text values in all +** columns of all rows of the table. +** +*/ +static void fts3UpdateDocTotals( + int *pRC, /* The result code */ + Fts3Table *p, /* Table being updated */ + u32 *aSzIns, /* Size increases */ + u32 *aSzDel, /* Size decreases */ + int nChng /* Change in the number of documents */ +){ + char *pBlob; /* Storage for BLOB written into %_stat */ + int nBlob; /* Size of BLOB written into %_stat */ + u32 *a; /* Array of integers that becomes the BLOB */ + sqlite3_stmt *pStmt; /* Statement for reading and writing */ + int i; /* Loop counter */ + int rc; /* Result code from subfunctions */ + + const int nStat = p->nColumn+2; + + if( *pRC ) return; + a = sqlite3_malloc( (sizeof(u32)+10)*nStat ); + if( a==0 ){ + *pRC = SQLITE_NOMEM; + return; + } + pBlob = (char*)&a[nStat]; + rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pStmt, 0); + if( rc ){ + sqlite3_free(a); + *pRC = rc; + return; + } + sqlite3_bind_int(pStmt, 1, FTS_STAT_DOCTOTAL); + if( sqlite3_step(pStmt)==SQLITE_ROW ){ + fts3DecodeIntArray(nStat, a, + sqlite3_column_blob(pStmt, 0), + sqlite3_column_bytes(pStmt, 0)); + }else{ + memset(a, 0, sizeof(u32)*(nStat) ); + } + rc = sqlite3_reset(pStmt); + if( rc!=SQLITE_OK ){ + sqlite3_free(a); + *pRC = rc; + return; + } + if( nChng<0 && a[0]<(u32)(-nChng) ){ + a[0] = 0; + }else{ + a[0] += nChng; + } + for(i=0; inColumn+1; i++){ + u32 x = a[i+1]; + if( x+aSzIns[i] < aSzDel[i] ){ + x = 0; + }else{ + x = x + aSzIns[i] - aSzDel[i]; + } + a[i+1] = x; + } + fts3EncodeIntArray(nStat, a, pBlob, &nBlob); + rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pStmt, 0); + if( rc ){ + sqlite3_free(a); + *pRC = rc; + return; + } + sqlite3_bind_int(pStmt, 1, FTS_STAT_DOCTOTAL); + sqlite3_bind_blob(pStmt, 2, pBlob, nBlob, SQLITE_STATIC); + sqlite3_step(pStmt); + *pRC = sqlite3_reset(pStmt); + sqlite3_free(a); +} + +/* +** Merge the entire database so that there is one segment for each +** iIndex/iLangid combination. +*/ +static int fts3DoOptimize(Fts3Table *p, int bReturnDone){ + int bSeenDone = 0; + int rc; + sqlite3_stmt *pAllLangid = 0; + + rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); + if( rc==SQLITE_OK ){ + int rc2; + sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid); + sqlite3_bind_int(pAllLangid, 2, p->nIndex); + while( sqlite3_step(pAllLangid)==SQLITE_ROW ){ + int i; + int iLangid = sqlite3_column_int(pAllLangid, 0); + for(i=0; rc==SQLITE_OK && inIndex; i++){ + rc = fts3SegmentMerge(p, iLangid, i, FTS3_SEGCURSOR_ALL); + if( rc==SQLITE_DONE ){ + bSeenDone = 1; + rc = SQLITE_OK; + } + } + } + rc2 = sqlite3_reset(pAllLangid); + if( rc==SQLITE_OK ) rc = rc2; + } + + sqlite3Fts3SegmentsClose(p); + sqlite3Fts3PendingTermsClear(p); + + return (rc==SQLITE_OK && bReturnDone && bSeenDone) ? SQLITE_DONE : rc; +} + +/* +** This function is called when the user executes the following statement: +** +** INSERT INTO () VALUES('rebuild'); +** +** The entire FTS index is discarded and rebuilt. If the table is one +** created using the content=xxx option, then the new index is based on +** the current contents of the xxx table. Otherwise, it is rebuilt based +** on the contents of the %_content table. +*/ +static int fts3DoRebuild(Fts3Table *p){ + int rc; /* Return Code */ + + rc = fts3DeleteAll(p, 0); + if( rc==SQLITE_OK ){ + u32 *aSz = 0; + u32 *aSzIns = 0; + u32 *aSzDel = 0; + sqlite3_stmt *pStmt = 0; + int nEntry = 0; + + /* Compose and prepare an SQL statement to loop through the content table */ + char *zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist); + if( !zSql ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + } + + if( rc==SQLITE_OK ){ + int nByte = sizeof(u32) * (p->nColumn+1)*3; + aSz = (u32 *)sqlite3_malloc(nByte); + if( aSz==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(aSz, 0, nByte); + aSzIns = &aSz[p->nColumn+1]; + aSzDel = &aSzIns[p->nColumn+1]; + } + } + + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + int iCol; + int iLangid = langidFromSelect(p, pStmt); + rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pStmt, 0)); + memset(aSz, 0, sizeof(aSz[0]) * (p->nColumn+1)); + for(iCol=0; rc==SQLITE_OK && iColnColumn; iCol++){ + if( p->abNotindexed[iCol]==0 ){ + const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1); + rc = fts3PendingTermsAdd(p, iLangid, z, iCol, &aSz[iCol]); + aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1); + } + } + if( p->bHasDocsize ){ + fts3InsertDocsize(&rc, p, aSz); + } + if( rc!=SQLITE_OK ){ + sqlite3_finalize(pStmt); + pStmt = 0; + }else{ + nEntry++; + for(iCol=0; iCol<=p->nColumn; iCol++){ + aSzIns[iCol] += aSz[iCol]; + } + } + } + if( p->bFts4 ){ + fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nEntry); + } + sqlite3_free(aSz); + + if( pStmt ){ + int rc2 = sqlite3_finalize(pStmt); + if( rc==SQLITE_OK ){ + rc = rc2; + } + } + } + + return rc; +} + + +/* +** This function opens a cursor used to read the input data for an +** incremental merge operation. Specifically, it opens a cursor to scan +** the oldest nSeg segments (idx=0 through idx=(nSeg-1)) in absolute +** level iAbsLevel. +*/ +static int fts3IncrmergeCsr( + Fts3Table *p, /* FTS3 table handle */ + sqlite3_int64 iAbsLevel, /* Absolute level to open */ + int nSeg, /* Number of segments to merge */ + Fts3MultiSegReader *pCsr /* Cursor object to populate */ +){ + int rc; /* Return Code */ + sqlite3_stmt *pStmt = 0; /* Statement used to read %_segdir entry */ + int nByte; /* Bytes allocated at pCsr->apSegment[] */ + + /* Allocate space for the Fts3MultiSegReader.aCsr[] array */ + memset(pCsr, 0, sizeof(*pCsr)); + nByte = sizeof(Fts3SegReader *) * nSeg; + pCsr->apSegment = (Fts3SegReader **)sqlite3_malloc(nByte); + + if( pCsr->apSegment==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(pCsr->apSegment, 0, nByte); + rc = fts3SqlStmt(p, SQL_SELECT_LEVEL, &pStmt, 0); + } + if( rc==SQLITE_OK ){ + int i; + int rc2; + sqlite3_bind_int64(pStmt, 1, iAbsLevel); + assert( pCsr->nSegment==0 ); + for(i=0; rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW && iapSegment[i] + ); + pCsr->nSegment++; + } + rc2 = sqlite3_reset(pStmt); + if( rc==SQLITE_OK ) rc = rc2; + } + + return rc; +} + +typedef struct IncrmergeWriter IncrmergeWriter; +typedef struct NodeWriter NodeWriter; +typedef struct Blob Blob; +typedef struct NodeReader NodeReader; + +/* +** An instance of the following structure is used as a dynamic buffer +** to build up nodes or other blobs of data in. +** +** The function blobGrowBuffer() is used to extend the allocation. +*/ +struct Blob { + char *a; /* Pointer to allocation */ + int n; /* Number of valid bytes of data in a[] */ + int nAlloc; /* Allocated size of a[] (nAlloc>=n) */ +}; + +/* +** This structure is used to build up buffers containing segment b-tree +** nodes (blocks). +*/ +struct NodeWriter { + sqlite3_int64 iBlock; /* Current block id */ + Blob key; /* Last key written to the current block */ + Blob block; /* Current block image */ +}; + +/* +** An object of this type contains the state required to create or append +** to an appendable b-tree segment. +*/ +struct IncrmergeWriter { + int nLeafEst; /* Space allocated for leaf blocks */ + int nWork; /* Number of leaf pages flushed */ + sqlite3_int64 iAbsLevel; /* Absolute level of input segments */ + int iIdx; /* Index of *output* segment in iAbsLevel+1 */ + sqlite3_int64 iStart; /* Block number of first allocated block */ + sqlite3_int64 iEnd; /* Block number of last allocated block */ + sqlite3_int64 nLeafData; /* Bytes of leaf page data so far */ + u8 bNoLeafData; /* If true, store 0 for segment size */ + NodeWriter aNodeWriter[FTS_MAX_APPENDABLE_HEIGHT]; +}; + +/* +** An object of the following type is used to read data from a single +** FTS segment node. See the following functions: +** +** nodeReaderInit() +** nodeReaderNext() +** nodeReaderRelease() +*/ +struct NodeReader { + const char *aNode; + int nNode; + int iOff; /* Current offset within aNode[] */ + + /* Output variables. Containing the current node entry. */ + sqlite3_int64 iChild; /* Pointer to child node */ + Blob term; /* Current term */ + const char *aDoclist; /* Pointer to doclist */ + int nDoclist; /* Size of doclist in bytes */ +}; + +/* +** If *pRc is not SQLITE_OK when this function is called, it is a no-op. +** Otherwise, if the allocation at pBlob->a is not already at least nMin +** bytes in size, extend (realloc) it to be so. +** +** If an OOM error occurs, set *pRc to SQLITE_NOMEM and leave pBlob->a +** unmodified. Otherwise, if the allocation succeeds, update pBlob->nAlloc +** to reflect the new size of the pBlob->a[] buffer. +*/ +static void blobGrowBuffer(Blob *pBlob, int nMin, int *pRc){ + if( *pRc==SQLITE_OK && nMin>pBlob->nAlloc ){ + int nAlloc = nMin; + char *a = (char *)sqlite3_realloc(pBlob->a, nAlloc); + if( a ){ + pBlob->nAlloc = nAlloc; + pBlob->a = a; + }else{ + *pRc = SQLITE_NOMEM; + } + } +} + +/* +** Attempt to advance the node-reader object passed as the first argument to +** the next entry on the node. +** +** Return an error code if an error occurs (SQLITE_NOMEM is possible). +** Otherwise return SQLITE_OK. If there is no next entry on the node +** (e.g. because the current entry is the last) set NodeReader->aNode to +** NULL to indicate EOF. Otherwise, populate the NodeReader structure output +** variables for the new entry. +*/ +static int nodeReaderNext(NodeReader *p){ + int bFirst = (p->term.n==0); /* True for first term on the node */ + int nPrefix = 0; /* Bytes to copy from previous term */ + int nSuffix = 0; /* Bytes to append to the prefix */ + int rc = SQLITE_OK; /* Return code */ + + assert( p->aNode ); + if( p->iChild && bFirst==0 ) p->iChild++; + if( p->iOff>=p->nNode ){ + /* EOF */ + p->aNode = 0; + }else{ + if( bFirst==0 ){ + p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nPrefix); + } + p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix); + + blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc); + if( rc==SQLITE_OK ){ + memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix); + p->term.n = nPrefix+nSuffix; + p->iOff += nSuffix; + if( p->iChild==0 ){ + p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist); + p->aDoclist = &p->aNode[p->iOff]; + p->iOff += p->nDoclist; + } + } + } + + assert( p->iOff<=p->nNode ); + + return rc; +} + +/* +** Release all dynamic resources held by node-reader object *p. +*/ +static void nodeReaderRelease(NodeReader *p){ + sqlite3_free(p->term.a); +} + +/* +** Initialize a node-reader object to read the node in buffer aNode/nNode. +** +** If successful, SQLITE_OK is returned and the NodeReader object set to +** point to the first entry on the node (if any). Otherwise, an SQLite +** error code is returned. +*/ +static int nodeReaderInit(NodeReader *p, const char *aNode, int nNode){ + memset(p, 0, sizeof(NodeReader)); + p->aNode = aNode; + p->nNode = nNode; + + /* Figure out if this is a leaf or an internal node. */ + if( p->aNode[0] ){ + /* An internal node. */ + p->iOff = 1 + sqlite3Fts3GetVarint(&p->aNode[1], &p->iChild); + }else{ + p->iOff = 1; + } + + return nodeReaderNext(p); +} + +/* +** This function is called while writing an FTS segment each time a leaf o +** node is finished and written to disk. The key (zTerm/nTerm) is guaranteed +** to be greater than the largest key on the node just written, but smaller +** than or equal to the first key that will be written to the next leaf +** node. +** +** The block id of the leaf node just written to disk may be found in +** (pWriter->aNodeWriter[0].iBlock) when this function is called. +*/ +static int fts3IncrmergePush( + Fts3Table *p, /* Fts3 table handle */ + IncrmergeWriter *pWriter, /* Writer object */ + const char *zTerm, /* Term to write to internal node */ + int nTerm /* Bytes at zTerm */ +){ + sqlite3_int64 iPtr = pWriter->aNodeWriter[0].iBlock; + int iLayer; + + assert( nTerm>0 ); + for(iLayer=1; ALWAYS(iLayeraNodeWriter[iLayer]; + int rc = SQLITE_OK; + int nPrefix; + int nSuffix; + int nSpace; + + /* Figure out how much space the key will consume if it is written to + ** the current node of layer iLayer. Due to the prefix compression, + ** the space required changes depending on which node the key is to + ** be added to. */ + nPrefix = fts3PrefixCompress(pNode->key.a, pNode->key.n, zTerm, nTerm); + nSuffix = nTerm - nPrefix; + nSpace = sqlite3Fts3VarintLen(nPrefix); + nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; + + if( pNode->key.n==0 || (pNode->block.n + nSpace)<=p->nNodeSize ){ + /* If the current node of layer iLayer contains zero keys, or if adding + ** the key to it will not cause it to grow to larger than nNodeSize + ** bytes in size, write the key here. */ + + Blob *pBlk = &pNode->block; + if( pBlk->n==0 ){ + blobGrowBuffer(pBlk, p->nNodeSize, &rc); + if( rc==SQLITE_OK ){ + pBlk->a[0] = (char)iLayer; + pBlk->n = 1 + sqlite3Fts3PutVarint(&pBlk->a[1], iPtr); + } + } + blobGrowBuffer(pBlk, pBlk->n + nSpace, &rc); + blobGrowBuffer(&pNode->key, nTerm, &rc); + + if( rc==SQLITE_OK ){ + if( pNode->key.n ){ + pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nPrefix); + } + pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nSuffix); + memcpy(&pBlk->a[pBlk->n], &zTerm[nPrefix], nSuffix); + pBlk->n += nSuffix; + + memcpy(pNode->key.a, zTerm, nTerm); + pNode->key.n = nTerm; + } + }else{ + /* Otherwise, flush the current node of layer iLayer to disk. + ** Then allocate a new, empty sibling node. The key will be written + ** into the parent of this node. */ + rc = fts3WriteSegment(p, pNode->iBlock, pNode->block.a, pNode->block.n); + + assert( pNode->block.nAlloc>=p->nNodeSize ); + pNode->block.a[0] = (char)iLayer; + pNode->block.n = 1 + sqlite3Fts3PutVarint(&pNode->block.a[1], iPtr+1); + + iNextPtr = pNode->iBlock; + pNode->iBlock++; + pNode->key.n = 0; + } + + if( rc!=SQLITE_OK || iNextPtr==0 ) return rc; + iPtr = iNextPtr; + } + + assert( 0 ); + return 0; +} + +/* +** Append a term and (optionally) doclist to the FTS segment node currently +** stored in blob *pNode. The node need not contain any terms, but the +** header must be written before this function is called. +** +** A node header is a single 0x00 byte for a leaf node, or a height varint +** followed by the left-hand-child varint for an internal node. +** +** The term to be appended is passed via arguments zTerm/nTerm. For a +** leaf node, the doclist is passed as aDoclist/nDoclist. For an internal +** node, both aDoclist and nDoclist must be passed 0. +** +** If the size of the value in blob pPrev is zero, then this is the first +** term written to the node. Otherwise, pPrev contains a copy of the +** previous term. Before this function returns, it is updated to contain a +** copy of zTerm/nTerm. +** +** It is assumed that the buffer associated with pNode is already large +** enough to accommodate the new entry. The buffer associated with pPrev +** is extended by this function if requrired. +** +** If an error (i.e. OOM condition) occurs, an SQLite error code is +** returned. Otherwise, SQLITE_OK. +*/ +static int fts3AppendToNode( + Blob *pNode, /* Current node image to append to */ + Blob *pPrev, /* Buffer containing previous term written */ + const char *zTerm, /* New term to write */ + int nTerm, /* Size of zTerm in bytes */ + const char *aDoclist, /* Doclist (or NULL) to write */ + int nDoclist /* Size of aDoclist in bytes */ +){ + int rc = SQLITE_OK; /* Return code */ + int bFirst = (pPrev->n==0); /* True if this is the first term written */ + int nPrefix; /* Size of term prefix in bytes */ + int nSuffix; /* Size of term suffix in bytes */ + + /* Node must have already been started. There must be a doclist for a + ** leaf node, and there must not be a doclist for an internal node. */ + assert( pNode->n>0 ); + assert( (pNode->a[0]=='\0')==(aDoclist!=0) ); + + blobGrowBuffer(pPrev, nTerm, &rc); + if( rc!=SQLITE_OK ) return rc; + + nPrefix = fts3PrefixCompress(pPrev->a, pPrev->n, zTerm, nTerm); + nSuffix = nTerm - nPrefix; + memcpy(pPrev->a, zTerm, nTerm); + pPrev->n = nTerm; + + if( bFirst==0 ){ + pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nPrefix); + } + pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nSuffix); + memcpy(&pNode->a[pNode->n], &zTerm[nPrefix], nSuffix); + pNode->n += nSuffix; + + if( aDoclist ){ + pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nDoclist); + memcpy(&pNode->a[pNode->n], aDoclist, nDoclist); + pNode->n += nDoclist; + } + + assert( pNode->n<=pNode->nAlloc ); + + return SQLITE_OK; +} + +/* +** Append the current term and doclist pointed to by cursor pCsr to the +** appendable b-tree segment opened for writing by pWriter. +** +** Return SQLITE_OK if successful, or an SQLite error code otherwise. +*/ +static int fts3IncrmergeAppend( + Fts3Table *p, /* Fts3 table handle */ + IncrmergeWriter *pWriter, /* Writer object */ + Fts3MultiSegReader *pCsr /* Cursor containing term and doclist */ +){ + const char *zTerm = pCsr->zTerm; + int nTerm = pCsr->nTerm; + const char *aDoclist = pCsr->aDoclist; + int nDoclist = pCsr->nDoclist; + int rc = SQLITE_OK; /* Return code */ + int nSpace; /* Total space in bytes required on leaf */ + int nPrefix; /* Size of prefix shared with previous term */ + int nSuffix; /* Size of suffix (nTerm - nPrefix) */ + NodeWriter *pLeaf; /* Object used to write leaf nodes */ + + pLeaf = &pWriter->aNodeWriter[0]; + nPrefix = fts3PrefixCompress(pLeaf->key.a, pLeaf->key.n, zTerm, nTerm); + nSuffix = nTerm - nPrefix; + + nSpace = sqlite3Fts3VarintLen(nPrefix); + nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; + nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist; + + /* If the current block is not empty, and if adding this term/doclist + ** to the current block would make it larger than Fts3Table.nNodeSize + ** bytes, write this block out to the database. */ + if( pLeaf->block.n>0 && (pLeaf->block.n + nSpace)>p->nNodeSize ){ + rc = fts3WriteSegment(p, pLeaf->iBlock, pLeaf->block.a, pLeaf->block.n); + pWriter->nWork++; + + /* Add the current term to the parent node. The term added to the + ** parent must: + ** + ** a) be greater than the largest term on the leaf node just written + ** to the database (still available in pLeaf->key), and + ** + ** b) be less than or equal to the term about to be added to the new + ** leaf node (zTerm/nTerm). + ** + ** In other words, it must be the prefix of zTerm 1 byte longer than + ** the common prefix (if any) of zTerm and pWriter->zTerm. + */ + if( rc==SQLITE_OK ){ + rc = fts3IncrmergePush(p, pWriter, zTerm, nPrefix+1); + } + + /* Advance to the next output block */ + pLeaf->iBlock++; + pLeaf->key.n = 0; + pLeaf->block.n = 0; + + nSuffix = nTerm; + nSpace = 1; + nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; + nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist; + } + + pWriter->nLeafData += nSpace; + blobGrowBuffer(&pLeaf->block, pLeaf->block.n + nSpace, &rc); + if( rc==SQLITE_OK ){ + if( pLeaf->block.n==0 ){ + pLeaf->block.n = 1; + pLeaf->block.a[0] = '\0'; + } + rc = fts3AppendToNode( + &pLeaf->block, &pLeaf->key, zTerm, nTerm, aDoclist, nDoclist + ); + } + + return rc; +} + +/* +** This function is called to release all dynamic resources held by the +** merge-writer object pWriter, and if no error has occurred, to flush +** all outstanding node buffers held by pWriter to disk. +** +** If *pRc is not SQLITE_OK when this function is called, then no attempt +** is made to write any data to disk. Instead, this function serves only +** to release outstanding resources. +** +** Otherwise, if *pRc is initially SQLITE_OK and an error occurs while +** flushing buffers to disk, *pRc is set to an SQLite error code before +** returning. +*/ +static void fts3IncrmergeRelease( + Fts3Table *p, /* FTS3 table handle */ + IncrmergeWriter *pWriter, /* Merge-writer object */ + int *pRc /* IN/OUT: Error code */ +){ + int i; /* Used to iterate through non-root layers */ + int iRoot; /* Index of root in pWriter->aNodeWriter */ + NodeWriter *pRoot; /* NodeWriter for root node */ + int rc = *pRc; /* Error code */ + + /* Set iRoot to the index in pWriter->aNodeWriter[] of the output segment + ** root node. If the segment fits entirely on a single leaf node, iRoot + ** will be set to 0. If the root node is the parent of the leaves, iRoot + ** will be 1. And so on. */ + for(iRoot=FTS_MAX_APPENDABLE_HEIGHT-1; iRoot>=0; iRoot--){ + NodeWriter *pNode = &pWriter->aNodeWriter[iRoot]; + if( pNode->block.n>0 ) break; + assert( *pRc || pNode->block.nAlloc==0 ); + assert( *pRc || pNode->key.nAlloc==0 ); + sqlite3_free(pNode->block.a); + sqlite3_free(pNode->key.a); + } + + /* Empty output segment. This is a no-op. */ + if( iRoot<0 ) return; + + /* The entire output segment fits on a single node. Normally, this means + ** the node would be stored as a blob in the "root" column of the %_segdir + ** table. However, this is not permitted in this case. The problem is that + ** space has already been reserved in the %_segments table, and so the + ** start_block and end_block fields of the %_segdir table must be populated. + ** And, by design or by accident, released versions of FTS cannot handle + ** segments that fit entirely on the root node with start_block!=0. + ** + ** Instead, create a synthetic root node that contains nothing but a + ** pointer to the single content node. So that the segment consists of a + ** single leaf and a single interior (root) node. + ** + ** Todo: Better might be to defer allocating space in the %_segments + ** table until we are sure it is needed. + */ + if( iRoot==0 ){ + Blob *pBlock = &pWriter->aNodeWriter[1].block; + blobGrowBuffer(pBlock, 1 + FTS3_VARINT_MAX, &rc); + if( rc==SQLITE_OK ){ + pBlock->a[0] = 0x01; + pBlock->n = 1 + sqlite3Fts3PutVarint( + &pBlock->a[1], pWriter->aNodeWriter[0].iBlock + ); + } + iRoot = 1; + } + pRoot = &pWriter->aNodeWriter[iRoot]; + + /* Flush all currently outstanding nodes to disk. */ + for(i=0; iaNodeWriter[i]; + if( pNode->block.n>0 && rc==SQLITE_OK ){ + rc = fts3WriteSegment(p, pNode->iBlock, pNode->block.a, pNode->block.n); + } + sqlite3_free(pNode->block.a); + sqlite3_free(pNode->key.a); + } + + /* Write the %_segdir record. */ + if( rc==SQLITE_OK ){ + rc = fts3WriteSegdir(p, + pWriter->iAbsLevel+1, /* level */ + pWriter->iIdx, /* idx */ + pWriter->iStart, /* start_block */ + pWriter->aNodeWriter[0].iBlock, /* leaves_end_block */ + pWriter->iEnd, /* end_block */ + (pWriter->bNoLeafData==0 ? pWriter->nLeafData : 0), /* end_block */ + pRoot->block.a, pRoot->block.n /* root */ + ); + } + sqlite3_free(pRoot->block.a); + sqlite3_free(pRoot->key.a); + + *pRc = rc; +} + +/* +** Compare the term in buffer zLhs (size in bytes nLhs) with that in +** zRhs (size in bytes nRhs) using memcmp. If one term is a prefix of +** the other, it is considered to be smaller than the other. +** +** Return -ve if zLhs is smaller than zRhs, 0 if it is equal, or +ve +** if it is greater. +*/ +static int fts3TermCmp( + const char *zLhs, int nLhs, /* LHS of comparison */ + const char *zRhs, int nRhs /* RHS of comparison */ +){ + int nCmp = MIN(nLhs, nRhs); + int res; + + res = memcmp(zLhs, zRhs, nCmp); + if( res==0 ) res = nLhs - nRhs; + + return res; +} + + +/* +** Query to see if the entry in the %_segments table with blockid iEnd is +** NULL. If no error occurs and the entry is NULL, set *pbRes 1 before +** returning. Otherwise, set *pbRes to 0. +** +** Or, if an error occurs while querying the database, return an SQLite +** error code. The final value of *pbRes is undefined in this case. +** +** This is used to test if a segment is an "appendable" segment. If it +** is, then a NULL entry has been inserted into the %_segments table +** with blockid %_segdir.end_block. +*/ +static int fts3IsAppendable(Fts3Table *p, sqlite3_int64 iEnd, int *pbRes){ + int bRes = 0; /* Result to set *pbRes to */ + sqlite3_stmt *pCheck = 0; /* Statement to query database with */ + int rc; /* Return code */ + + rc = fts3SqlStmt(p, SQL_SEGMENT_IS_APPENDABLE, &pCheck, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pCheck, 1, iEnd); + if( SQLITE_ROW==sqlite3_step(pCheck) ) bRes = 1; + rc = sqlite3_reset(pCheck); + } + + *pbRes = bRes; + return rc; +} + +/* +** This function is called when initializing an incremental-merge operation. +** It checks if the existing segment with index value iIdx at absolute level +** (iAbsLevel+1) can be appended to by the incremental merge. If it can, the +** merge-writer object *pWriter is initialized to write to it. +** +** An existing segment can be appended to by an incremental merge if: +** +** * It was initially created as an appendable segment (with all required +** space pre-allocated), and +** +** * The first key read from the input (arguments zKey and nKey) is +** greater than the largest key currently stored in the potential +** output segment. +*/ +static int fts3IncrmergeLoad( + Fts3Table *p, /* Fts3 table handle */ + sqlite3_int64 iAbsLevel, /* Absolute level of input segments */ + int iIdx, /* Index of candidate output segment */ + const char *zKey, /* First key to write */ + int nKey, /* Number of bytes in nKey */ + IncrmergeWriter *pWriter /* Populate this object */ +){ + int rc; /* Return code */ + sqlite3_stmt *pSelect = 0; /* SELECT to read %_segdir entry */ + + rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR, &pSelect, 0); + if( rc==SQLITE_OK ){ + sqlite3_int64 iStart = 0; /* Value of %_segdir.start_block */ + sqlite3_int64 iLeafEnd = 0; /* Value of %_segdir.leaves_end_block */ + sqlite3_int64 iEnd = 0; /* Value of %_segdir.end_block */ + const char *aRoot = 0; /* Pointer to %_segdir.root buffer */ + int nRoot = 0; /* Size of aRoot[] in bytes */ + int rc2; /* Return code from sqlite3_reset() */ + int bAppendable = 0; /* Set to true if segment is appendable */ + + /* Read the %_segdir entry for index iIdx absolute level (iAbsLevel+1) */ + sqlite3_bind_int64(pSelect, 1, iAbsLevel+1); + sqlite3_bind_int(pSelect, 2, iIdx); + if( sqlite3_step(pSelect)==SQLITE_ROW ){ + iStart = sqlite3_column_int64(pSelect, 1); + iLeafEnd = sqlite3_column_int64(pSelect, 2); + fts3ReadEndBlockField(pSelect, 3, &iEnd, &pWriter->nLeafData); + if( pWriter->nLeafData<0 ){ + pWriter->nLeafData = pWriter->nLeafData * -1; + } + pWriter->bNoLeafData = (pWriter->nLeafData==0); + nRoot = sqlite3_column_bytes(pSelect, 4); + aRoot = sqlite3_column_blob(pSelect, 4); + }else{ + return sqlite3_reset(pSelect); + } + + /* Check for the zero-length marker in the %_segments table */ + rc = fts3IsAppendable(p, iEnd, &bAppendable); + + /* Check that zKey/nKey is larger than the largest key the candidate */ + if( rc==SQLITE_OK && bAppendable ){ + char *aLeaf = 0; + int nLeaf = 0; + + rc = sqlite3Fts3ReadBlock(p, iLeafEnd, &aLeaf, &nLeaf, 0); + if( rc==SQLITE_OK ){ + NodeReader reader; + for(rc = nodeReaderInit(&reader, aLeaf, nLeaf); + rc==SQLITE_OK && reader.aNode; + rc = nodeReaderNext(&reader) + ){ + assert( reader.aNode ); + } + if( fts3TermCmp(zKey, nKey, reader.term.a, reader.term.n)<=0 ){ + bAppendable = 0; + } + nodeReaderRelease(&reader); + } + sqlite3_free(aLeaf); + } + + if( rc==SQLITE_OK && bAppendable ){ + /* It is possible to append to this segment. Set up the IncrmergeWriter + ** object to do so. */ + int i; + int nHeight = (int)aRoot[0]; + NodeWriter *pNode; + + pWriter->nLeafEst = (int)((iEnd - iStart) + 1)/FTS_MAX_APPENDABLE_HEIGHT; + pWriter->iStart = iStart; + pWriter->iEnd = iEnd; + pWriter->iAbsLevel = iAbsLevel; + pWriter->iIdx = iIdx; + + for(i=nHeight+1; iaNodeWriter[i].iBlock = pWriter->iStart + i*pWriter->nLeafEst; + } + + pNode = &pWriter->aNodeWriter[nHeight]; + pNode->iBlock = pWriter->iStart + pWriter->nLeafEst*nHeight; + blobGrowBuffer(&pNode->block, MAX(nRoot, p->nNodeSize), &rc); + if( rc==SQLITE_OK ){ + memcpy(pNode->block.a, aRoot, nRoot); + pNode->block.n = nRoot; + } + + for(i=nHeight; i>=0 && rc==SQLITE_OK; i--){ + NodeReader reader; + pNode = &pWriter->aNodeWriter[i]; + + rc = nodeReaderInit(&reader, pNode->block.a, pNode->block.n); + while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader); + blobGrowBuffer(&pNode->key, reader.term.n, &rc); + if( rc==SQLITE_OK ){ + memcpy(pNode->key.a, reader.term.a, reader.term.n); + pNode->key.n = reader.term.n; + if( i>0 ){ + char *aBlock = 0; + int nBlock = 0; + pNode = &pWriter->aNodeWriter[i-1]; + pNode->iBlock = reader.iChild; + rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock, 0); + blobGrowBuffer(&pNode->block, MAX(nBlock, p->nNodeSize), &rc); + if( rc==SQLITE_OK ){ + memcpy(pNode->block.a, aBlock, nBlock); + pNode->block.n = nBlock; + } + sqlite3_free(aBlock); + } + } + nodeReaderRelease(&reader); + } + } + + rc2 = sqlite3_reset(pSelect); + if( rc==SQLITE_OK ) rc = rc2; + } + + return rc; +} + +/* +** Determine the largest segment index value that exists within absolute +** level iAbsLevel+1. If no error occurs, set *piIdx to this value plus +** one before returning SQLITE_OK. Or, if there are no segments at all +** within level iAbsLevel, set *piIdx to zero. +** +** If an error occurs, return an SQLite error code. The final value of +** *piIdx is undefined in this case. +*/ +static int fts3IncrmergeOutputIdx( + Fts3Table *p, /* FTS Table handle */ + sqlite3_int64 iAbsLevel, /* Absolute index of input segments */ + int *piIdx /* OUT: Next free index at iAbsLevel+1 */ +){ + int rc; + sqlite3_stmt *pOutputIdx = 0; /* SQL used to find output index */ + + rc = fts3SqlStmt(p, SQL_NEXT_SEGMENT_INDEX, &pOutputIdx, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pOutputIdx, 1, iAbsLevel+1); + sqlite3_step(pOutputIdx); + *piIdx = sqlite3_column_int(pOutputIdx, 0); + rc = sqlite3_reset(pOutputIdx); + } + + return rc; +} + +/* +** Allocate an appendable output segment on absolute level iAbsLevel+1 +** with idx value iIdx. +** +** In the %_segdir table, a segment is defined by the values in three +** columns: +** +** start_block +** leaves_end_block +** end_block +** +** When an appendable segment is allocated, it is estimated that the +** maximum number of leaf blocks that may be required is the sum of the +** number of leaf blocks consumed by the input segments, plus the number +** of input segments, multiplied by two. This value is stored in stack +** variable nLeafEst. +** +** A total of 16*nLeafEst blocks are allocated when an appendable segment +** is created ((1 + end_block - start_block)==16*nLeafEst). The contiguous +** array of leaf nodes starts at the first block allocated. The array +** of interior nodes that are parents of the leaf nodes start at block +** (start_block + (1 + end_block - start_block) / 16). And so on. +** +** In the actual code below, the value "16" is replaced with the +** pre-processor macro FTS_MAX_APPENDABLE_HEIGHT. +*/ +static int fts3IncrmergeWriter( + Fts3Table *p, /* Fts3 table handle */ + sqlite3_int64 iAbsLevel, /* Absolute level of input segments */ + int iIdx, /* Index of new output segment */ + Fts3MultiSegReader *pCsr, /* Cursor that data will be read from */ + IncrmergeWriter *pWriter /* Populate this object */ +){ + int rc; /* Return Code */ + int i; /* Iterator variable */ + int nLeafEst = 0; /* Blocks allocated for leaf nodes */ + sqlite3_stmt *pLeafEst = 0; /* SQL used to determine nLeafEst */ + sqlite3_stmt *pFirstBlock = 0; /* SQL used to determine first block */ + + /* Calculate nLeafEst. */ + rc = fts3SqlStmt(p, SQL_MAX_LEAF_NODE_ESTIMATE, &pLeafEst, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pLeafEst, 1, iAbsLevel); + sqlite3_bind_int64(pLeafEst, 2, pCsr->nSegment); + if( SQLITE_ROW==sqlite3_step(pLeafEst) ){ + nLeafEst = sqlite3_column_int(pLeafEst, 0); + } + rc = sqlite3_reset(pLeafEst); + } + if( rc!=SQLITE_OK ) return rc; + + /* Calculate the first block to use in the output segment */ + rc = fts3SqlStmt(p, SQL_NEXT_SEGMENTS_ID, &pFirstBlock, 0); + if( rc==SQLITE_OK ){ + if( SQLITE_ROW==sqlite3_step(pFirstBlock) ){ + pWriter->iStart = sqlite3_column_int64(pFirstBlock, 0); + pWriter->iEnd = pWriter->iStart - 1; + pWriter->iEnd += nLeafEst * FTS_MAX_APPENDABLE_HEIGHT; + } + rc = sqlite3_reset(pFirstBlock); + } + if( rc!=SQLITE_OK ) return rc; + + /* Insert the marker in the %_segments table to make sure nobody tries + ** to steal the space just allocated. This is also used to identify + ** appendable segments. */ + rc = fts3WriteSegment(p, pWriter->iEnd, 0, 0); + if( rc!=SQLITE_OK ) return rc; + + pWriter->iAbsLevel = iAbsLevel; + pWriter->nLeafEst = nLeafEst; + pWriter->iIdx = iIdx; + + /* Set up the array of NodeWriter objects */ + for(i=0; iaNodeWriter[i].iBlock = pWriter->iStart + i*pWriter->nLeafEst; + } + return SQLITE_OK; +} + +/* +** Remove an entry from the %_segdir table. This involves running the +** following two statements: +** +** DELETE FROM %_segdir WHERE level = :iAbsLevel AND idx = :iIdx +** UPDATE %_segdir SET idx = idx - 1 WHERE level = :iAbsLevel AND idx > :iIdx +** +** The DELETE statement removes the specific %_segdir level. The UPDATE +** statement ensures that the remaining segments have contiguously allocated +** idx values. +*/ +static int fts3RemoveSegdirEntry( + Fts3Table *p, /* FTS3 table handle */ + sqlite3_int64 iAbsLevel, /* Absolute level to delete from */ + int iIdx /* Index of %_segdir entry to delete */ +){ + int rc; /* Return code */ + sqlite3_stmt *pDelete = 0; /* DELETE statement */ + + rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_ENTRY, &pDelete, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pDelete, 1, iAbsLevel); + sqlite3_bind_int(pDelete, 2, iIdx); + sqlite3_step(pDelete); + rc = sqlite3_reset(pDelete); + } + + return rc; +} + +/* +** One or more segments have just been removed from absolute level iAbsLevel. +** Update the 'idx' values of the remaining segments in the level so that +** the idx values are a contiguous sequence starting from 0. +*/ +static int fts3RepackSegdirLevel( + Fts3Table *p, /* FTS3 table handle */ + sqlite3_int64 iAbsLevel /* Absolute level to repack */ +){ + int rc; /* Return code */ + int *aIdx = 0; /* Array of remaining idx values */ + int nIdx = 0; /* Valid entries in aIdx[] */ + int nAlloc = 0; /* Allocated size of aIdx[] */ + int i; /* Iterator variable */ + sqlite3_stmt *pSelect = 0; /* Select statement to read idx values */ + sqlite3_stmt *pUpdate = 0; /* Update statement to modify idx values */ + + rc = fts3SqlStmt(p, SQL_SELECT_INDEXES, &pSelect, 0); + if( rc==SQLITE_OK ){ + int rc2; + sqlite3_bind_int64(pSelect, 1, iAbsLevel); + while( SQLITE_ROW==sqlite3_step(pSelect) ){ + if( nIdx>=nAlloc ){ + int *aNew; + nAlloc += 16; + aNew = sqlite3_realloc(aIdx, nAlloc*sizeof(int)); + if( !aNew ){ + rc = SQLITE_NOMEM; + break; + } + aIdx = aNew; + } + aIdx[nIdx++] = sqlite3_column_int(pSelect, 0); + } + rc2 = sqlite3_reset(pSelect); + if( rc==SQLITE_OK ) rc = rc2; + } + + if( rc==SQLITE_OK ){ + rc = fts3SqlStmt(p, SQL_SHIFT_SEGDIR_ENTRY, &pUpdate, 0); + } + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pUpdate, 2, iAbsLevel); + } + + assert( p->bIgnoreSavepoint==0 ); + p->bIgnoreSavepoint = 1; + for(i=0; rc==SQLITE_OK && ibIgnoreSavepoint = 0; + + sqlite3_free(aIdx); + return rc; +} + +static void fts3StartNode(Blob *pNode, int iHeight, sqlite3_int64 iChild){ + pNode->a[0] = (char)iHeight; + if( iChild ){ + assert( pNode->nAlloc>=1+sqlite3Fts3VarintLen(iChild) ); + pNode->n = 1 + sqlite3Fts3PutVarint(&pNode->a[1], iChild); + }else{ + assert( pNode->nAlloc>=1 ); + pNode->n = 1; + } +} + +/* +** The first two arguments are a pointer to and the size of a segment b-tree +** node. The node may be a leaf or an internal node. +** +** This function creates a new node image in blob object *pNew by copying +** all terms that are greater than or equal to zTerm/nTerm (for leaf nodes) +** or greater than zTerm/nTerm (for internal nodes) from aNode/nNode. +*/ +static int fts3TruncateNode( + const char *aNode, /* Current node image */ + int nNode, /* Size of aNode in bytes */ + Blob *pNew, /* OUT: Write new node image here */ + const char *zTerm, /* Omit all terms smaller than this */ + int nTerm, /* Size of zTerm in bytes */ + sqlite3_int64 *piBlock /* OUT: Block number in next layer down */ +){ + NodeReader reader; /* Reader object */ + Blob prev = {0, 0, 0}; /* Previous term written to new node */ + int rc = SQLITE_OK; /* Return code */ + int bLeaf = aNode[0]=='\0'; /* True for a leaf node */ + + /* Allocate required output space */ + blobGrowBuffer(pNew, nNode, &rc); + if( rc!=SQLITE_OK ) return rc; + pNew->n = 0; + + /* Populate new node buffer */ + for(rc = nodeReaderInit(&reader, aNode, nNode); + rc==SQLITE_OK && reader.aNode; + rc = nodeReaderNext(&reader) + ){ + if( pNew->n==0 ){ + int res = fts3TermCmp(reader.term.a, reader.term.n, zTerm, nTerm); + if( res<0 || (bLeaf==0 && res==0) ) continue; + fts3StartNode(pNew, (int)aNode[0], reader.iChild); + *piBlock = reader.iChild; + } + rc = fts3AppendToNode( + pNew, &prev, reader.term.a, reader.term.n, + reader.aDoclist, reader.nDoclist + ); + if( rc!=SQLITE_OK ) break; + } + if( pNew->n==0 ){ + fts3StartNode(pNew, (int)aNode[0], reader.iChild); + *piBlock = reader.iChild; + } + assert( pNew->n<=pNew->nAlloc ); + + nodeReaderRelease(&reader); + sqlite3_free(prev.a); + return rc; +} + +/* +** Remove all terms smaller than zTerm/nTerm from segment iIdx in absolute +** level iAbsLevel. This may involve deleting entries from the %_segments +** table, and modifying existing entries in both the %_segments and %_segdir +** tables. +** +** SQLITE_OK is returned if the segment is updated successfully. Or an +** SQLite error code otherwise. +*/ +static int fts3TruncateSegment( + Fts3Table *p, /* FTS3 table handle */ + sqlite3_int64 iAbsLevel, /* Absolute level of segment to modify */ + int iIdx, /* Index within level of segment to modify */ + const char *zTerm, /* Remove terms smaller than this */ + int nTerm /* Number of bytes in buffer zTerm */ +){ + int rc = SQLITE_OK; /* Return code */ + Blob root = {0,0,0}; /* New root page image */ + Blob block = {0,0,0}; /* Buffer used for any other block */ + sqlite3_int64 iBlock = 0; /* Block id */ + sqlite3_int64 iNewStart = 0; /* New value for iStartBlock */ + sqlite3_int64 iOldStart = 0; /* Old value for iStartBlock */ + sqlite3_stmt *pFetch = 0; /* Statement used to fetch segdir */ + + rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR, &pFetch, 0); + if( rc==SQLITE_OK ){ + int rc2; /* sqlite3_reset() return code */ + sqlite3_bind_int64(pFetch, 1, iAbsLevel); + sqlite3_bind_int(pFetch, 2, iIdx); + if( SQLITE_ROW==sqlite3_step(pFetch) ){ + const char *aRoot = sqlite3_column_blob(pFetch, 4); + int nRoot = sqlite3_column_bytes(pFetch, 4); + iOldStart = sqlite3_column_int64(pFetch, 1); + rc = fts3TruncateNode(aRoot, nRoot, &root, zTerm, nTerm, &iBlock); + } + rc2 = sqlite3_reset(pFetch); + if( rc==SQLITE_OK ) rc = rc2; + } + + while( rc==SQLITE_OK && iBlock ){ + char *aBlock = 0; + int nBlock = 0; + iNewStart = iBlock; + + rc = sqlite3Fts3ReadBlock(p, iBlock, &aBlock, &nBlock, 0); + if( rc==SQLITE_OK ){ + rc = fts3TruncateNode(aBlock, nBlock, &block, zTerm, nTerm, &iBlock); + } + if( rc==SQLITE_OK ){ + rc = fts3WriteSegment(p, iNewStart, block.a, block.n); + } + sqlite3_free(aBlock); + } + + /* Variable iNewStart now contains the first valid leaf node. */ + if( rc==SQLITE_OK && iNewStart ){ + sqlite3_stmt *pDel = 0; + rc = fts3SqlStmt(p, SQL_DELETE_SEGMENTS_RANGE, &pDel, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pDel, 1, iOldStart); + sqlite3_bind_int64(pDel, 2, iNewStart-1); + sqlite3_step(pDel); + rc = sqlite3_reset(pDel); + } + } + + if( rc==SQLITE_OK ){ + sqlite3_stmt *pChomp = 0; + rc = fts3SqlStmt(p, SQL_CHOMP_SEGDIR, &pChomp, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pChomp, 1, iNewStart); + sqlite3_bind_blob(pChomp, 2, root.a, root.n, SQLITE_STATIC); + sqlite3_bind_int64(pChomp, 3, iAbsLevel); + sqlite3_bind_int(pChomp, 4, iIdx); + sqlite3_step(pChomp); + rc = sqlite3_reset(pChomp); + } + } + + sqlite3_free(root.a); + sqlite3_free(block.a); + return rc; +} + +/* +** This function is called after an incrmental-merge operation has run to +** merge (or partially merge) two or more segments from absolute level +** iAbsLevel. +** +** Each input segment is either removed from the db completely (if all of +** its data was copied to the output segment by the incrmerge operation) +** or modified in place so that it no longer contains those entries that +** have been duplicated in the output segment. +*/ +static int fts3IncrmergeChomp( + Fts3Table *p, /* FTS table handle */ + sqlite3_int64 iAbsLevel, /* Absolute level containing segments */ + Fts3MultiSegReader *pCsr, /* Chomp all segments opened by this cursor */ + int *pnRem /* Number of segments not deleted */ +){ + int i; + int nRem = 0; + int rc = SQLITE_OK; + + for(i=pCsr->nSegment-1; i>=0 && rc==SQLITE_OK; i--){ + Fts3SegReader *pSeg = 0; + int j; + + /* Find the Fts3SegReader object with Fts3SegReader.iIdx==i. It is hiding + ** somewhere in the pCsr->apSegment[] array. */ + for(j=0; ALWAYS(jnSegment); j++){ + pSeg = pCsr->apSegment[j]; + if( pSeg->iIdx==i ) break; + } + assert( jnSegment && pSeg->iIdx==i ); + + if( pSeg->aNode==0 ){ + /* Seg-reader is at EOF. Remove the entire input segment. */ + rc = fts3DeleteSegment(p, pSeg); + if( rc==SQLITE_OK ){ + rc = fts3RemoveSegdirEntry(p, iAbsLevel, pSeg->iIdx); + } + *pnRem = 0; + }else{ + /* The incremental merge did not copy all the data from this + ** segment to the upper level. The segment is modified in place + ** so that it contains no keys smaller than zTerm/nTerm. */ + const char *zTerm = pSeg->zTerm; + int nTerm = pSeg->nTerm; + rc = fts3TruncateSegment(p, iAbsLevel, pSeg->iIdx, zTerm, nTerm); + nRem++; + } + } + + if( rc==SQLITE_OK && nRem!=pCsr->nSegment ){ + rc = fts3RepackSegdirLevel(p, iAbsLevel); + } + + *pnRem = nRem; + return rc; +} + +/* +** Store an incr-merge hint in the database. +*/ +static int fts3IncrmergeHintStore(Fts3Table *p, Blob *pHint){ + sqlite3_stmt *pReplace = 0; + int rc; /* Return code */ + + rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pReplace, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int(pReplace, 1, FTS_STAT_INCRMERGEHINT); + sqlite3_bind_blob(pReplace, 2, pHint->a, pHint->n, SQLITE_STATIC); + sqlite3_step(pReplace); + rc = sqlite3_reset(pReplace); + } + + return rc; +} + +/* +** Load an incr-merge hint from the database. The incr-merge hint, if one +** exists, is stored in the rowid==1 row of the %_stat table. +** +** If successful, populate blob *pHint with the value read from the %_stat +** table and return SQLITE_OK. Otherwise, if an error occurs, return an +** SQLite error code. +*/ +static int fts3IncrmergeHintLoad(Fts3Table *p, Blob *pHint){ + sqlite3_stmt *pSelect = 0; + int rc; + + pHint->n = 0; + rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pSelect, 0); + if( rc==SQLITE_OK ){ + int rc2; + sqlite3_bind_int(pSelect, 1, FTS_STAT_INCRMERGEHINT); + if( SQLITE_ROW==sqlite3_step(pSelect) ){ + const char *aHint = sqlite3_column_blob(pSelect, 0); + int nHint = sqlite3_column_bytes(pSelect, 0); + if( aHint ){ + blobGrowBuffer(pHint, nHint, &rc); + if( rc==SQLITE_OK ){ + memcpy(pHint->a, aHint, nHint); + pHint->n = nHint; + } + } + } + rc2 = sqlite3_reset(pSelect); + if( rc==SQLITE_OK ) rc = rc2; + } + + return rc; +} + +/* +** If *pRc is not SQLITE_OK when this function is called, it is a no-op. +** Otherwise, append an entry to the hint stored in blob *pHint. Each entry +** consists of two varints, the absolute level number of the input segments +** and the number of input segments. +** +** If successful, leave *pRc set to SQLITE_OK and return. If an error occurs, +** set *pRc to an SQLite error code before returning. +*/ +static void fts3IncrmergeHintPush( + Blob *pHint, /* Hint blob to append to */ + i64 iAbsLevel, /* First varint to store in hint */ + int nInput, /* Second varint to store in hint */ + int *pRc /* IN/OUT: Error code */ +){ + blobGrowBuffer(pHint, pHint->n + 2*FTS3_VARINT_MAX, pRc); + if( *pRc==SQLITE_OK ){ + pHint->n += sqlite3Fts3PutVarint(&pHint->a[pHint->n], iAbsLevel); + pHint->n += sqlite3Fts3PutVarint(&pHint->a[pHint->n], (i64)nInput); + } +} + +/* +** Read the last entry (most recently pushed) from the hint blob *pHint +** and then remove the entry. Write the two values read to *piAbsLevel and +** *pnInput before returning. +** +** If no error occurs, return SQLITE_OK. If the hint blob in *pHint does +** not contain at least two valid varints, return SQLITE_CORRUPT_VTAB. +*/ +static int fts3IncrmergeHintPop(Blob *pHint, i64 *piAbsLevel, int *pnInput){ + const int nHint = pHint->n; + int i; + + i = pHint->n-2; + while( i>0 && (pHint->a[i-1] & 0x80) ) i--; + while( i>0 && (pHint->a[i-1] & 0x80) ) i--; + + pHint->n = i; + i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel); + i += fts3GetVarint32(&pHint->a[i], pnInput); + if( i!=nHint ) return FTS_CORRUPT_VTAB; + + return SQLITE_OK; +} + + +/* +** Attempt an incremental merge that writes nMerge leaf blocks. +** +** Incremental merges happen nMin segments at a time. The segments +** to be merged are the nMin oldest segments (the ones with the smallest +** values for the _segdir.idx field) in the highest level that contains +** at least nMin segments. Multiple merges might occur in an attempt to +** write the quota of nMerge leaf blocks. +*/ +SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ + int rc; /* Return code */ + int nRem = nMerge; /* Number of leaf pages yet to be written */ + Fts3MultiSegReader *pCsr; /* Cursor used to read input data */ + Fts3SegFilter *pFilter; /* Filter used with cursor pCsr */ + IncrmergeWriter *pWriter; /* Writer object */ + int nSeg = 0; /* Number of input segments */ + sqlite3_int64 iAbsLevel = 0; /* Absolute level number to work on */ + Blob hint = {0, 0, 0}; /* Hint read from %_stat table */ + int bDirtyHint = 0; /* True if blob 'hint' has been modified */ + + /* Allocate space for the cursor, filter and writer objects */ + const int nAlloc = sizeof(*pCsr) + sizeof(*pFilter) + sizeof(*pWriter); + pWriter = (IncrmergeWriter *)sqlite3_malloc(nAlloc); + if( !pWriter ) return SQLITE_NOMEM; + pFilter = (Fts3SegFilter *)&pWriter[1]; + pCsr = (Fts3MultiSegReader *)&pFilter[1]; + + rc = fts3IncrmergeHintLoad(p, &hint); + while( rc==SQLITE_OK && nRem>0 ){ + const i64 nMod = FTS3_SEGDIR_MAXLEVEL * p->nIndex; + sqlite3_stmt *pFindLevel = 0; /* SQL used to determine iAbsLevel */ + int bUseHint = 0; /* True if attempting to append */ + int iIdx = 0; /* Largest idx in level (iAbsLevel+1) */ + + /* Search the %_segdir table for the absolute level with the smallest + ** relative level number that contains at least nMin segments, if any. + ** If one is found, set iAbsLevel to the absolute level number and + ** nSeg to nMin. If no level with at least nMin segments can be found, + ** set nSeg to -1. + */ + rc = fts3SqlStmt(p, SQL_FIND_MERGE_LEVEL, &pFindLevel, 0); + sqlite3_bind_int(pFindLevel, 1, nMin); + if( sqlite3_step(pFindLevel)==SQLITE_ROW ){ + iAbsLevel = sqlite3_column_int64(pFindLevel, 0); + nSeg = nMin; + }else{ + nSeg = -1; + } + rc = sqlite3_reset(pFindLevel); + + /* If the hint read from the %_stat table is not empty, check if the + ** last entry in it specifies a relative level smaller than or equal + ** to the level identified by the block above (if any). If so, this + ** iteration of the loop will work on merging at the hinted level. + */ + if( rc==SQLITE_OK && hint.n ){ + int nHint = hint.n; + sqlite3_int64 iHintAbsLevel = 0; /* Hint level */ + int nHintSeg = 0; /* Hint number of segments */ + + rc = fts3IncrmergeHintPop(&hint, &iHintAbsLevel, &nHintSeg); + if( nSeg<0 || (iAbsLevel % nMod) >= (iHintAbsLevel % nMod) ){ + iAbsLevel = iHintAbsLevel; + nSeg = nHintSeg; + bUseHint = 1; + bDirtyHint = 1; + }else{ + /* This undoes the effect of the HintPop() above - so that no entry + ** is removed from the hint blob. */ + hint.n = nHint; + } + } + + /* If nSeg is less that zero, then there is no level with at least + ** nMin segments and no hint in the %_stat table. No work to do. + ** Exit early in this case. */ + if( nSeg<0 ) break; + + /* Open a cursor to iterate through the contents of the oldest nSeg + ** indexes of absolute level iAbsLevel. If this cursor is opened using + ** the 'hint' parameters, it is possible that there are less than nSeg + ** segments available in level iAbsLevel. In this case, no work is + ** done on iAbsLevel - fall through to the next iteration of the loop + ** to start work on some other level. */ + memset(pWriter, 0, nAlloc); + pFilter->flags = FTS3_SEGMENT_REQUIRE_POS; + + if( rc==SQLITE_OK ){ + rc = fts3IncrmergeOutputIdx(p, iAbsLevel, &iIdx); + assert( bUseHint==1 || bUseHint==0 ); + if( iIdx==0 || (bUseHint && iIdx==1) ){ + int bIgnore = 0; + rc = fts3SegmentIsMaxLevel(p, iAbsLevel+1, &bIgnore); + if( bIgnore ){ + pFilter->flags |= FTS3_SEGMENT_IGNORE_EMPTY; + } + } + } + + if( rc==SQLITE_OK ){ + rc = fts3IncrmergeCsr(p, iAbsLevel, nSeg, pCsr); + } + if( SQLITE_OK==rc && pCsr->nSegment==nSeg + && SQLITE_OK==(rc = sqlite3Fts3SegReaderStart(p, pCsr, pFilter)) + && SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, pCsr)) + ){ + if( bUseHint && iIdx>0 ){ + const char *zKey = pCsr->zTerm; + int nKey = pCsr->nTerm; + rc = fts3IncrmergeLoad(p, iAbsLevel, iIdx-1, zKey, nKey, pWriter); + }else{ + rc = fts3IncrmergeWriter(p, iAbsLevel, iIdx, pCsr, pWriter); + } + + if( rc==SQLITE_OK && pWriter->nLeafEst ){ + fts3LogMerge(nSeg, iAbsLevel); + do { + rc = fts3IncrmergeAppend(p, pWriter, pCsr); + if( rc==SQLITE_OK ) rc = sqlite3Fts3SegReaderStep(p, pCsr); + if( pWriter->nWork>=nRem && rc==SQLITE_ROW ) rc = SQLITE_OK; + }while( rc==SQLITE_ROW ); + + /* Update or delete the input segments */ + if( rc==SQLITE_OK ){ + nRem -= (1 + pWriter->nWork); + rc = fts3IncrmergeChomp(p, iAbsLevel, pCsr, &nSeg); + if( nSeg!=0 ){ + bDirtyHint = 1; + fts3IncrmergeHintPush(&hint, iAbsLevel, nSeg, &rc); + } + } + } + + if( nSeg!=0 ){ + pWriter->nLeafData = pWriter->nLeafData * -1; + } + fts3IncrmergeRelease(p, pWriter, &rc); + if( nSeg==0 && pWriter->bNoLeafData==0 ){ + fts3PromoteSegments(p, iAbsLevel+1, pWriter->nLeafData); + } + } + + sqlite3Fts3SegReaderFinish(pCsr); + } + + /* Write the hint values into the %_stat table for the next incr-merger */ + if( bDirtyHint && rc==SQLITE_OK ){ + rc = fts3IncrmergeHintStore(p, &hint); + } + + sqlite3_free(pWriter); + sqlite3_free(hint.a); + return rc; +} + +/* +** Convert the text beginning at *pz into an integer and return +** its value. Advance *pz to point to the first character past +** the integer. +*/ +static int fts3Getint(const char **pz){ + const char *z = *pz; + int i = 0; + while( (*z)>='0' && (*z)<='9' ) i = 10*i + *(z++) - '0'; + *pz = z; + return i; +} + +/* +** Process statements of the form: +** +** INSERT INTO table(table) VALUES('merge=A,B'); +** +** A and B are integers that decode to be the number of leaf pages +** written for the merge, and the minimum number of segments on a level +** before it will be selected for a merge, respectively. +*/ +static int fts3DoIncrmerge( + Fts3Table *p, /* FTS3 table handle */ + const char *zParam /* Nul-terminated string containing "A,B" */ +){ + int rc; + int nMin = (FTS3_MERGE_COUNT / 2); + int nMerge = 0; + const char *z = zParam; + + /* Read the first integer value */ + nMerge = fts3Getint(&z); + + /* If the first integer value is followed by a ',', read the second + ** integer value. */ + if( z[0]==',' && z[1]!='\0' ){ + z++; + nMin = fts3Getint(&z); + } + + if( z[0]!='\0' || nMin<2 ){ + rc = SQLITE_ERROR; + }else{ + rc = SQLITE_OK; + if( !p->bHasStat ){ + assert( p->bFts4==0 ); + sqlite3Fts3CreateStatTable(&rc, p); + } + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3Incrmerge(p, nMerge, nMin); + } + sqlite3Fts3SegmentsClose(p); + } + return rc; +} + +/* +** Process statements of the form: +** +** INSERT INTO table(table) VALUES('automerge=X'); +** +** where X is an integer. X==0 means to turn automerge off. X!=0 means +** turn it on. The setting is persistent. +*/ +static int fts3DoAutoincrmerge( + Fts3Table *p, /* FTS3 table handle */ + const char *zParam /* Nul-terminated string containing boolean */ +){ + int rc = SQLITE_OK; + sqlite3_stmt *pStmt = 0; + p->nAutoincrmerge = fts3Getint(&zParam); + if( p->nAutoincrmerge==1 || p->nAutoincrmerge>FTS3_MERGE_COUNT ){ + p->nAutoincrmerge = 8; + } + if( !p->bHasStat ){ + assert( p->bFts4==0 ); + sqlite3Fts3CreateStatTable(&rc, p); + if( rc ) return rc; + } + rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pStmt, 0); + if( rc ) return rc; + sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE); + sqlite3_bind_int(pStmt, 2, p->nAutoincrmerge); + sqlite3_step(pStmt); + rc = sqlite3_reset(pStmt); + return rc; +} + +/* +** Return a 64-bit checksum for the FTS index entry specified by the +** arguments to this function. +*/ +static u64 fts3ChecksumEntry( + const char *zTerm, /* Pointer to buffer containing term */ + int nTerm, /* Size of zTerm in bytes */ + int iLangid, /* Language id for current row */ + int iIndex, /* Index (0..Fts3Table.nIndex-1) */ + i64 iDocid, /* Docid for current row. */ + int iCol, /* Column number */ + int iPos /* Position */ +){ + int i; + u64 ret = (u64)iDocid; + + ret += (ret<<3) + iLangid; + ret += (ret<<3) + iIndex; + ret += (ret<<3) + iCol; + ret += (ret<<3) + iPos; + for(i=0; inIndex-1) */ + int *pRc /* OUT: Return code */ +){ + Fts3SegFilter filter; + Fts3MultiSegReader csr; + int rc; + u64 cksum = 0; + + assert( *pRc==SQLITE_OK ); + + memset(&filter, 0, sizeof(filter)); + memset(&csr, 0, sizeof(csr)); + filter.flags = FTS3_SEGMENT_REQUIRE_POS|FTS3_SEGMENT_IGNORE_EMPTY; + filter.flags |= FTS3_SEGMENT_SCAN; + + rc = sqlite3Fts3SegReaderCursor( + p, iLangid, iIndex, FTS3_SEGCURSOR_ALL, 0, 0, 0, 1,&csr + ); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3SegReaderStart(p, &csr, &filter); + } + + if( rc==SQLITE_OK ){ + while( SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, &csr)) ){ + char *pCsr = csr.aDoclist; + char *pEnd = &pCsr[csr.nDoclist]; + + i64 iDocid = 0; + i64 iCol = 0; + i64 iPos = 0; + + pCsr += sqlite3Fts3GetVarint(pCsr, &iDocid); + while( pCsriPrevLangid); + sqlite3_bind_int(pAllLangid, 2, p->nIndex); + while( rc==SQLITE_OK && sqlite3_step(pAllLangid)==SQLITE_ROW ){ + int iLangid = sqlite3_column_int(pAllLangid, 0); + int i; + for(i=0; inIndex; i++){ + cksum1 = cksum1 ^ fts3ChecksumIndex(p, iLangid, i, &rc); + } + } + rc2 = sqlite3_reset(pAllLangid); + if( rc==SQLITE_OK ) rc = rc2; + } + + /* This block calculates the checksum according to the %_content table */ + if( rc==SQLITE_OK ){ + sqlite3_tokenizer_module const *pModule = p->pTokenizer->pModule; + sqlite3_stmt *pStmt = 0; + char *zSql; + + zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist); + if( !zSql ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + } + + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + i64 iDocid = sqlite3_column_int64(pStmt, 0); + int iLang = langidFromSelect(p, pStmt); + int iCol; + + for(iCol=0; rc==SQLITE_OK && iColnColumn; iCol++){ + if( p->abNotindexed[iCol]==0 ){ + const char *zText = (const char *)sqlite3_column_text(pStmt, iCol+1); + int nText = sqlite3_column_bytes(pStmt, iCol+1); + sqlite3_tokenizer_cursor *pT = 0; + + rc = sqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, nText,&pT); + while( rc==SQLITE_OK ){ + char const *zToken; /* Buffer containing token */ + int nToken = 0; /* Number of bytes in token */ + int iDum1 = 0, iDum2 = 0; /* Dummy variables */ + int iPos = 0; /* Position of token in zText */ + + rc = pModule->xNext(pT, &zToken, &nToken, &iDum1, &iDum2, &iPos); + if( rc==SQLITE_OK ){ + int i; + cksum2 = cksum2 ^ fts3ChecksumEntry( + zToken, nToken, iLang, 0, iDocid, iCol, iPos + ); + for(i=1; inIndex; i++){ + if( p->aIndex[i].nPrefix<=nToken ){ + cksum2 = cksum2 ^ fts3ChecksumEntry( + zToken, p->aIndex[i].nPrefix, iLang, i, iDocid, iCol, iPos + ); + } + } + } + } + if( pT ) pModule->xClose(pT); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + } + } + } + + sqlite3_finalize(pStmt); + } + + *pbOk = (cksum1==cksum2); + return rc; +} + +/* +** Run the integrity-check. If no error occurs and the current contents of +** the FTS index are correct, return SQLITE_OK. Or, if the contents of the +** FTS index are incorrect, return SQLITE_CORRUPT_VTAB. +** +** Or, if an error (e.g. an OOM or IO error) occurs, return an SQLite +** error code. +** +** The integrity-check works as follows. For each token and indexed token +** prefix in the document set, a 64-bit checksum is calculated (by code +** in fts3ChecksumEntry()) based on the following: +** +** + The index number (0 for the main index, 1 for the first prefix +** index etc.), +** + The token (or token prefix) text itself, +** + The language-id of the row it appears in, +** + The docid of the row it appears in, +** + The column it appears in, and +** + The tokens position within that column. +** +** The checksums for all entries in the index are XORed together to create +** a single checksum for the entire index. +** +** The integrity-check code calculates the same checksum in two ways: +** +** 1. By scanning the contents of the FTS index, and +** 2. By scanning and tokenizing the content table. +** +** If the two checksums are identical, the integrity-check is deemed to have +** passed. +*/ +static int fts3DoIntegrityCheck( + Fts3Table *p /* FTS3 table handle */ +){ + int rc; + int bOk = 0; + rc = fts3IntegrityCheck(p, &bOk); + if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB; + return rc; +} + +/* +** Handle a 'special' INSERT of the form: +** +** "INSERT INTO tbl(tbl) VALUES()" +** +** Argument pVal contains the result of . Currently the only +** meaningful value to insert is the text 'optimize'. +*/ +static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ + int rc; /* Return Code */ + const char *zVal = (const char *)sqlite3_value_text(pVal); + int nVal = sqlite3_value_bytes(pVal); + + if( !zVal ){ + return SQLITE_NOMEM; + }else if( nVal==8 && 0==sqlite3_strnicmp(zVal, "optimize", 8) ){ + rc = fts3DoOptimize(p, 0); + }else if( nVal==7 && 0==sqlite3_strnicmp(zVal, "rebuild", 7) ){ + rc = fts3DoRebuild(p); + }else if( nVal==15 && 0==sqlite3_strnicmp(zVal, "integrity-check", 15) ){ + rc = fts3DoIntegrityCheck(p); + }else if( nVal>6 && 0==sqlite3_strnicmp(zVal, "merge=", 6) ){ + rc = fts3DoIncrmerge(p, &zVal[6]); + }else if( nVal>10 && 0==sqlite3_strnicmp(zVal, "automerge=", 10) ){ + rc = fts3DoAutoincrmerge(p, &zVal[10]); +#ifdef SQLITE_TEST + }else if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){ + p->nNodeSize = atoi(&zVal[9]); + rc = SQLITE_OK; + }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){ + p->nMaxPendingData = atoi(&zVal[11]); + rc = SQLITE_OK; + }else if( nVal>21 && 0==sqlite3_strnicmp(zVal, "test-no-incr-doclist=", 21) ){ + p->bNoIncrDoclist = atoi(&zVal[21]); + rc = SQLITE_OK; +#endif + }else{ + rc = SQLITE_ERROR; + } + + return rc; +} + +#ifndef SQLITE_DISABLE_FTS4_DEFERRED +/* +** Delete all cached deferred doclists. Deferred doclists are cached +** (allocated) by the sqlite3Fts3CacheDeferredDoclists() function. +*/ +SQLITE_PRIVATE void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *pCsr){ + Fts3DeferredToken *pDef; + for(pDef=pCsr->pDeferred; pDef; pDef=pDef->pNext){ + fts3PendingListDelete(pDef->pList); + pDef->pList = 0; + } +} + +/* +** Free all entries in the pCsr->pDeffered list. Entries are added to +** this list using sqlite3Fts3DeferToken(). +*/ +SQLITE_PRIVATE void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *pCsr){ + Fts3DeferredToken *pDef; + Fts3DeferredToken *pNext; + for(pDef=pCsr->pDeferred; pDef; pDef=pNext){ + pNext = pDef->pNext; + fts3PendingListDelete(pDef->pList); + sqlite3_free(pDef); + } + pCsr->pDeferred = 0; +} + +/* +** Generate deferred-doclists for all tokens in the pCsr->pDeferred list +** based on the row that pCsr currently points to. +** +** A deferred-doclist is like any other doclist with position information +** included, except that it only contains entries for a single row of the +** table, not for all rows. +*/ +SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *pCsr){ + int rc = SQLITE_OK; /* Return code */ + if( pCsr->pDeferred ){ + int i; /* Used to iterate through table columns */ + sqlite3_int64 iDocid; /* Docid of the row pCsr points to */ + Fts3DeferredToken *pDef; /* Used to iterate through deferred tokens */ + + Fts3Table *p = (Fts3Table *)pCsr->base.pVtab; + sqlite3_tokenizer *pT = p->pTokenizer; + sqlite3_tokenizer_module const *pModule = pT->pModule; + + assert( pCsr->isRequireSeek==0 ); + iDocid = sqlite3_column_int64(pCsr->pStmt, 0); + + for(i=0; inColumn && rc==SQLITE_OK; i++){ + if( p->abNotindexed[i]==0 ){ + const char *zText = (const char *)sqlite3_column_text(pCsr->pStmt, i+1); + sqlite3_tokenizer_cursor *pTC = 0; + + rc = sqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC); + while( rc==SQLITE_OK ){ + char const *zToken; /* Buffer containing token */ + int nToken = 0; /* Number of bytes in token */ + int iDum1 = 0, iDum2 = 0; /* Dummy variables */ + int iPos = 0; /* Position of token in zText */ + + rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos); + for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ + Fts3PhraseToken *pPT = pDef->pToken; + if( (pDef->iCol>=p->nColumn || pDef->iCol==i) + && (pPT->bFirst==0 || iPos==0) + && (pPT->n==nToken || (pPT->isPrefix && pPT->nz, pPT->n)) + ){ + fts3PendingListAppend(&pDef->pList, iDocid, i, iPos, &rc); + } + } + } + if( pTC ) pModule->xClose(pTC); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + } + } + + for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ + if( pDef->pList ){ + rc = fts3PendingListAppendVarint(&pDef->pList, 0); + } + } + } + + return rc; +} + +SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList( + Fts3DeferredToken *p, + char **ppData, + int *pnData +){ + char *pRet; + int nSkip; + sqlite3_int64 dummy; + + *ppData = 0; + *pnData = 0; + + if( p->pList==0 ){ + return SQLITE_OK; + } + + pRet = (char *)sqlite3_malloc(p->pList->nData); + if( !pRet ) return SQLITE_NOMEM; + + nSkip = sqlite3Fts3GetVarint(p->pList->aData, &dummy); + *pnData = p->pList->nData - nSkip; + *ppData = pRet; + + memcpy(pRet, &p->pList->aData[nSkip], *pnData); + return SQLITE_OK; +} + +/* +** Add an entry for token pToken to the pCsr->pDeferred list. +*/ +SQLITE_PRIVATE int sqlite3Fts3DeferToken( + Fts3Cursor *pCsr, /* Fts3 table cursor */ + Fts3PhraseToken *pToken, /* Token to defer */ + int iCol /* Column that token must appear in (or -1) */ +){ + Fts3DeferredToken *pDeferred; + pDeferred = sqlite3_malloc(sizeof(*pDeferred)); + if( !pDeferred ){ + return SQLITE_NOMEM; + } + memset(pDeferred, 0, sizeof(*pDeferred)); + pDeferred->pToken = pToken; + pDeferred->pNext = pCsr->pDeferred; + pDeferred->iCol = iCol; + pCsr->pDeferred = pDeferred; + + assert( pToken->pDeferred==0 ); + pToken->pDeferred = pDeferred; + + return SQLITE_OK; +} +#endif + +/* +** SQLite value pRowid contains the rowid of a row that may or may not be +** present in the FTS3 table. If it is, delete it and adjust the contents +** of subsiduary data structures accordingly. +*/ +static int fts3DeleteByRowid( + Fts3Table *p, + sqlite3_value *pRowid, + int *pnChng, /* IN/OUT: Decrement if row is deleted */ + u32 *aSzDel +){ + int rc = SQLITE_OK; /* Return code */ + int bFound = 0; /* True if *pRowid really is in the table */ + + fts3DeleteTerms(&rc, p, pRowid, aSzDel, &bFound); + if( bFound && rc==SQLITE_OK ){ + int isEmpty = 0; /* Deleting *pRowid leaves the table empty */ + rc = fts3IsEmpty(p, pRowid, &isEmpty); + if( rc==SQLITE_OK ){ + if( isEmpty ){ + /* Deleting this row means the whole table is empty. In this case + ** delete the contents of all three tables and throw away any + ** data in the pendingTerms hash table. */ + rc = fts3DeleteAll(p, 1); + *pnChng = 0; + memset(aSzDel, 0, sizeof(u32) * (p->nColumn+1) * 2); + }else{ + *pnChng = *pnChng - 1; + if( p->zContentTbl==0 ){ + fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid); + } + if( p->bHasDocsize ){ + fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, &pRowid); + } + } + } + } + + return rc; +} + +/* +** This function does the work for the xUpdate method of FTS3 virtual +** tables. The schema of the virtual table being: +** +** CREATE TABLE
    ( +** , +**
    HIDDEN, +** docid HIDDEN, +** HIDDEN +** ); +** +** +*/ +SQLITE_PRIVATE int sqlite3Fts3UpdateMethod( + sqlite3_vtab *pVtab, /* FTS3 vtab object */ + int nArg, /* Size of argument array */ + sqlite3_value **apVal, /* Array of arguments */ + sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */ +){ + Fts3Table *p = (Fts3Table *)pVtab; + int rc = SQLITE_OK; /* Return Code */ + int isRemove = 0; /* True for an UPDATE or DELETE */ + u32 *aSzIns = 0; /* Sizes of inserted documents */ + u32 *aSzDel = 0; /* Sizes of deleted documents */ + int nChng = 0; /* Net change in number of documents */ + int bInsertDone = 0; + + /* At this point it must be known if the %_stat table exists or not. + ** So bHasStat may not be 2. */ + assert( p->bHasStat==0 || p->bHasStat==1 ); + + assert( p->pSegments==0 ); + assert( + nArg==1 /* DELETE operations */ + || nArg==(2 + p->nColumn + 3) /* INSERT or UPDATE operations */ + ); + + /* Check for a "special" INSERT operation. One of the form: + ** + ** INSERT INTO xyz(xyz) VALUES('command'); + */ + if( nArg>1 + && sqlite3_value_type(apVal[0])==SQLITE_NULL + && sqlite3_value_type(apVal[p->nColumn+2])!=SQLITE_NULL + ){ + rc = fts3SpecialInsert(p, apVal[p->nColumn+2]); + goto update_out; + } + + if( nArg>1 && sqlite3_value_int(apVal[2 + p->nColumn + 2])<0 ){ + rc = SQLITE_CONSTRAINT; + goto update_out; + } + + /* Allocate space to hold the change in document sizes */ + aSzDel = sqlite3_malloc( sizeof(aSzDel[0])*(p->nColumn+1)*2 ); + if( aSzDel==0 ){ + rc = SQLITE_NOMEM; + goto update_out; + } + aSzIns = &aSzDel[p->nColumn+1]; + memset(aSzDel, 0, sizeof(aSzDel[0])*(p->nColumn+1)*2); + + rc = fts3Writelock(p); + if( rc!=SQLITE_OK ) goto update_out; + + /* If this is an INSERT operation, or an UPDATE that modifies the rowid + ** value, then this operation requires constraint handling. + ** + ** If the on-conflict mode is REPLACE, this means that the existing row + ** should be deleted from the database before inserting the new row. Or, + ** if the on-conflict mode is other than REPLACE, then this method must + ** detect the conflict and return SQLITE_CONSTRAINT before beginning to + ** modify the database file. + */ + if( nArg>1 && p->zContentTbl==0 ){ + /* Find the value object that holds the new rowid value. */ + sqlite3_value *pNewRowid = apVal[3+p->nColumn]; + if( sqlite3_value_type(pNewRowid)==SQLITE_NULL ){ + pNewRowid = apVal[1]; + } + + if( sqlite3_value_type(pNewRowid)!=SQLITE_NULL && ( + sqlite3_value_type(apVal[0])==SQLITE_NULL + || sqlite3_value_int64(apVal[0])!=sqlite3_value_int64(pNewRowid) + )){ + /* The new rowid is not NULL (in this case the rowid will be + ** automatically assigned and there is no chance of a conflict), and + ** the statement is either an INSERT or an UPDATE that modifies the + ** rowid column. So if the conflict mode is REPLACE, then delete any + ** existing row with rowid=pNewRowid. + ** + ** Or, if the conflict mode is not REPLACE, insert the new record into + ** the %_content table. If we hit the duplicate rowid constraint (or any + ** other error) while doing so, return immediately. + ** + ** This branch may also run if pNewRowid contains a value that cannot + ** be losslessly converted to an integer. In this case, the eventual + ** call to fts3InsertData() (either just below or further on in this + ** function) will return SQLITE_MISMATCH. If fts3DeleteByRowid is + ** invoked, it will delete zero rows (since no row will have + ** docid=$pNewRowid if $pNewRowid is not an integer value). + */ + if( sqlite3_vtab_on_conflict(p->db)==SQLITE_REPLACE ){ + rc = fts3DeleteByRowid(p, pNewRowid, &nChng, aSzDel); + }else{ + rc = fts3InsertData(p, apVal, pRowid); + bInsertDone = 1; + } + } + } + if( rc!=SQLITE_OK ){ + goto update_out; + } + + /* If this is a DELETE or UPDATE operation, remove the old record. */ + if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){ + assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER ); + rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel); + isRemove = 1; + } + + /* If this is an INSERT or UPDATE operation, insert the new record. */ + if( nArg>1 && rc==SQLITE_OK ){ + int iLangid = sqlite3_value_int(apVal[2 + p->nColumn + 2]); + if( bInsertDone==0 ){ + rc = fts3InsertData(p, apVal, pRowid); + if( rc==SQLITE_CONSTRAINT && p->zContentTbl==0 ){ + rc = FTS_CORRUPT_VTAB; + } + } + if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){ + rc = fts3PendingTermsDocid(p, iLangid, *pRowid); + } + if( rc==SQLITE_OK ){ + assert( p->iPrevDocid==*pRowid ); + rc = fts3InsertTerms(p, iLangid, apVal, aSzIns); + } + if( p->bHasDocsize ){ + fts3InsertDocsize(&rc, p, aSzIns); + } + nChng++; + } + + if( p->bFts4 ){ + fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nChng); + } + + update_out: + sqlite3_free(aSzDel); + sqlite3Fts3SegmentsClose(p); + return rc; +} + +/* +** Flush any data in the pending-terms hash table to disk. If successful, +** merge all segments in the database (including the new segment, if +** there was any data to flush) into a single segment. +*/ +SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *p){ + int rc; + rc = sqlite3_exec(p->db, "SAVEPOINT fts3", 0, 0, 0); + if( rc==SQLITE_OK ){ + rc = fts3DoOptimize(p, 1); + if( rc==SQLITE_OK || rc==SQLITE_DONE ){ + int rc2 = sqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0); + if( rc2!=SQLITE_OK ) rc = rc2; + }else{ + sqlite3_exec(p->db, "ROLLBACK TO fts3", 0, 0, 0); + sqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0); + } + } + sqlite3Fts3SegmentsClose(p); + return rc; +} + +#endif + +/************** End of fts3_write.c ******************************************/ +/************** Begin file fts3_snippet.c ************************************/ +/* +** 2009 Oct 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. +** +****************************************************************************** +*/ + +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ + +/* +** Characters that may appear in the second argument to matchinfo(). +*/ +#define FTS3_MATCHINFO_NPHRASE 'p' /* 1 value */ +#define FTS3_MATCHINFO_NCOL 'c' /* 1 value */ +#define FTS3_MATCHINFO_NDOC 'n' /* 1 value */ +#define FTS3_MATCHINFO_AVGLENGTH 'a' /* nCol values */ +#define FTS3_MATCHINFO_LENGTH 'l' /* nCol values */ +#define FTS3_MATCHINFO_LCS 's' /* nCol values */ +#define FTS3_MATCHINFO_HITS 'x' /* 3*nCol*nPhrase values */ +#define FTS3_MATCHINFO_LHITS 'y' /* nCol*nPhrase values */ + +/* +** The default value for the second argument to matchinfo(). +*/ +#define FTS3_MATCHINFO_DEFAULT "pcx" + + +/* +** Used as an fts3ExprIterate() context when loading phrase doclists to +** Fts3Expr.aDoclist[]/nDoclist. +*/ +typedef struct LoadDoclistCtx LoadDoclistCtx; +struct LoadDoclistCtx { + Fts3Cursor *pCsr; /* FTS3 Cursor */ + int nPhrase; /* Number of phrases seen so far */ + int nToken; /* Number of tokens seen so far */ +}; + +/* +** The following types are used as part of the implementation of the +** fts3BestSnippet() routine. +*/ +typedef struct SnippetIter SnippetIter; +typedef struct SnippetPhrase SnippetPhrase; +typedef struct SnippetFragment SnippetFragment; + +struct SnippetIter { + Fts3Cursor *pCsr; /* Cursor snippet is being generated from */ + int iCol; /* Extract snippet from this column */ + int nSnippet; /* Requested snippet length (in tokens) */ + int nPhrase; /* Number of phrases in query */ + SnippetPhrase *aPhrase; /* Array of size nPhrase */ + int iCurrent; /* First token of current snippet */ +}; + +struct SnippetPhrase { + int nToken; /* Number of tokens in phrase */ + char *pList; /* Pointer to start of phrase position list */ + int iHead; /* Next value in position list */ + char *pHead; /* Position list data following iHead */ + int iTail; /* Next value in trailing position list */ + char *pTail; /* Position list data following iTail */ +}; + +struct SnippetFragment { + int iCol; /* Column snippet is extracted from */ + int iPos; /* Index of first token in snippet */ + u64 covered; /* Mask of query phrases covered */ + u64 hlmask; /* Mask of snippet terms to highlight */ +}; + +/* +** This type is used as an fts3ExprIterate() context object while +** accumulating the data returned by the matchinfo() function. +*/ +typedef struct MatchInfo MatchInfo; +struct MatchInfo { + Fts3Cursor *pCursor; /* FTS3 Cursor */ + int nCol; /* Number of columns in table */ + int nPhrase; /* Number of matchable phrases in query */ + sqlite3_int64 nDoc; /* Number of docs in database */ + u32 *aMatchinfo; /* Pre-allocated buffer */ +}; + + + +/* +** The snippet() and offsets() functions both return text values. An instance +** of the following structure is used to accumulate those values while the +** functions are running. See fts3StringAppend() for details. +*/ +typedef struct StrBuffer StrBuffer; +struct StrBuffer { + char *z; /* Pointer to buffer containing string */ + int n; /* Length of z in bytes (excl. nul-term) */ + int nAlloc; /* Allocated size of buffer z in bytes */ +}; + + +/* +** This function is used to help iterate through a position-list. A position +** list is a list of unique integers, sorted from smallest to largest. Each +** element of the list is represented by an FTS3 varint that takes the value +** of the difference between the current element and the previous one plus +** two. For example, to store the position-list: +** +** 4 9 113 +** +** the three varints: +** +** 6 7 106 +** +** are encoded. +** +** When this function is called, *pp points to the start of an element of +** the list. *piPos contains the value of the previous entry in the list. +** After it returns, *piPos contains the value of the next element of the +** list and *pp is advanced to the following varint. +*/ +static void fts3GetDeltaPosition(char **pp, int *piPos){ + int iVal; + *pp += fts3GetVarint32(*pp, &iVal); + *piPos += (iVal-2); +} + +/* +** Helper function for fts3ExprIterate() (see below). +*/ +static int fts3ExprIterate2( + Fts3Expr *pExpr, /* Expression to iterate phrases of */ + int *piPhrase, /* Pointer to phrase counter */ + int (*x)(Fts3Expr*,int,void*), /* Callback function to invoke for phrases */ + void *pCtx /* Second argument to pass to callback */ +){ + int rc; /* Return code */ + int eType = pExpr->eType; /* Type of expression node pExpr */ + + if( eType!=FTSQUERY_PHRASE ){ + assert( pExpr->pLeft && pExpr->pRight ); + rc = fts3ExprIterate2(pExpr->pLeft, piPhrase, x, pCtx); + if( rc==SQLITE_OK && eType!=FTSQUERY_NOT ){ + rc = fts3ExprIterate2(pExpr->pRight, piPhrase, x, pCtx); + } + }else{ + rc = x(pExpr, *piPhrase, pCtx); + (*piPhrase)++; + } + return rc; +} + +/* +** Iterate through all phrase nodes in an FTS3 query, except those that +** are part of a sub-tree that is the right-hand-side of a NOT operator. +** For each phrase node found, the supplied callback function is invoked. +** +** If the callback function returns anything other than SQLITE_OK, +** the iteration is abandoned and the error code returned immediately. +** Otherwise, SQLITE_OK is returned after a callback has been made for +** all eligible phrase nodes. +*/ +static int fts3ExprIterate( + Fts3Expr *pExpr, /* Expression to iterate phrases of */ + int (*x)(Fts3Expr*,int,void*), /* Callback function to invoke for phrases */ + void *pCtx /* Second argument to pass to callback */ +){ + int iPhrase = 0; /* Variable used as the phrase counter */ + return fts3ExprIterate2(pExpr, &iPhrase, x, pCtx); +} + +/* +** This is an fts3ExprIterate() callback used while loading the doclists +** for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also +** fts3ExprLoadDoclists(). +*/ +static int fts3ExprLoadDoclistsCb(Fts3Expr *pExpr, int iPhrase, void *ctx){ + int rc = SQLITE_OK; + Fts3Phrase *pPhrase = pExpr->pPhrase; + LoadDoclistCtx *p = (LoadDoclistCtx *)ctx; + + UNUSED_PARAMETER(iPhrase); + + p->nPhrase++; + p->nToken += pPhrase->nToken; + + return rc; +} + +/* +** Load the doclists for each phrase in the query associated with FTS3 cursor +** pCsr. +** +** If pnPhrase is not NULL, then *pnPhrase is set to the number of matchable +** phrases in the expression (all phrases except those directly or +** indirectly descended from the right-hand-side of a NOT operator). If +** pnToken is not NULL, then it is set to the number of tokens in all +** matchable phrases of the expression. +*/ +static int fts3ExprLoadDoclists( + Fts3Cursor *pCsr, /* Fts3 cursor for current query */ + int *pnPhrase, /* OUT: Number of phrases in query */ + int *pnToken /* OUT: Number of tokens in query */ +){ + int rc; /* Return Code */ + LoadDoclistCtx sCtx = {0,0,0}; /* Context for fts3ExprIterate() */ + sCtx.pCsr = pCsr; + rc = fts3ExprIterate(pCsr->pExpr, fts3ExprLoadDoclistsCb, (void *)&sCtx); + if( pnPhrase ) *pnPhrase = sCtx.nPhrase; + if( pnToken ) *pnToken = sCtx.nToken; + return rc; +} + +static int fts3ExprPhraseCountCb(Fts3Expr *pExpr, int iPhrase, void *ctx){ + (*(int *)ctx)++; + UNUSED_PARAMETER(pExpr); + UNUSED_PARAMETER(iPhrase); + return SQLITE_OK; +} +static int fts3ExprPhraseCount(Fts3Expr *pExpr){ + int nPhrase = 0; + (void)fts3ExprIterate(pExpr, fts3ExprPhraseCountCb, (void *)&nPhrase); + return nPhrase; +} + +/* +** Advance the position list iterator specified by the first two +** arguments so that it points to the first element with a value greater +** than or equal to parameter iNext. +*/ +static void fts3SnippetAdvance(char **ppIter, int *piIter, int iNext){ + char *pIter = *ppIter; + if( pIter ){ + int iIter = *piIter; + + while( iIteriCurrent<0 ){ + /* The SnippetIter object has just been initialized. The first snippet + ** candidate always starts at offset 0 (even if this candidate has a + ** score of 0.0). + */ + pIter->iCurrent = 0; + + /* Advance the 'head' iterator of each phrase to the first offset that + ** is greater than or equal to (iNext+nSnippet). + */ + for(i=0; inPhrase; i++){ + SnippetPhrase *pPhrase = &pIter->aPhrase[i]; + fts3SnippetAdvance(&pPhrase->pHead, &pPhrase->iHead, pIter->nSnippet); + } + }else{ + int iStart; + int iEnd = 0x7FFFFFFF; + + for(i=0; inPhrase; i++){ + SnippetPhrase *pPhrase = &pIter->aPhrase[i]; + if( pPhrase->pHead && pPhrase->iHeadiHead; + } + } + if( iEnd==0x7FFFFFFF ){ + return 1; + } + + pIter->iCurrent = iStart = iEnd - pIter->nSnippet + 1; + for(i=0; inPhrase; i++){ + SnippetPhrase *pPhrase = &pIter->aPhrase[i]; + fts3SnippetAdvance(&pPhrase->pHead, &pPhrase->iHead, iEnd+1); + fts3SnippetAdvance(&pPhrase->pTail, &pPhrase->iTail, iStart); + } + } + + return 0; +} + +/* +** Retrieve information about the current candidate snippet of snippet +** iterator pIter. +*/ +static void fts3SnippetDetails( + SnippetIter *pIter, /* Snippet iterator */ + u64 mCovered, /* Bitmask of phrases already covered */ + int *piToken, /* OUT: First token of proposed snippet */ + int *piScore, /* OUT: "Score" for this snippet */ + u64 *pmCover, /* OUT: Bitmask of phrases covered */ + u64 *pmHighlight /* OUT: Bitmask of terms to highlight */ +){ + int iStart = pIter->iCurrent; /* First token of snippet */ + int iScore = 0; /* Score of this snippet */ + int i; /* Loop counter */ + u64 mCover = 0; /* Mask of phrases covered by this snippet */ + u64 mHighlight = 0; /* Mask of tokens to highlight in snippet */ + + for(i=0; inPhrase; i++){ + SnippetPhrase *pPhrase = &pIter->aPhrase[i]; + if( pPhrase->pTail ){ + char *pCsr = pPhrase->pTail; + int iCsr = pPhrase->iTail; + + while( iCsr<(iStart+pIter->nSnippet) ){ + int j; + u64 mPhrase = (u64)1 << i; + u64 mPos = (u64)1 << (iCsr - iStart); + assert( iCsr>=iStart ); + if( (mCover|mCovered)&mPhrase ){ + iScore++; + }else{ + iScore += 1000; + } + mCover |= mPhrase; + + for(j=0; jnToken; j++){ + mHighlight |= (mPos>>j); + } + + if( 0==(*pCsr & 0x0FE) ) break; + fts3GetDeltaPosition(&pCsr, &iCsr); + } + } + } + + /* Set the output variables before returning. */ + *piToken = iStart; + *piScore = iScore; + *pmCover = mCover; + *pmHighlight = mHighlight; +} + +/* +** This function is an fts3ExprIterate() callback used by fts3BestSnippet(). +** Each invocation populates an element of the SnippetIter.aPhrase[] array. +*/ +static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){ + SnippetIter *p = (SnippetIter *)ctx; + SnippetPhrase *pPhrase = &p->aPhrase[iPhrase]; + char *pCsr; + int rc; + + pPhrase->nToken = pExpr->pPhrase->nToken; + rc = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol, &pCsr); + assert( rc==SQLITE_OK || pCsr==0 ); + if( pCsr ){ + int iFirst = 0; + pPhrase->pList = pCsr; + fts3GetDeltaPosition(&pCsr, &iFirst); + assert( iFirst>=0 ); + pPhrase->pHead = pCsr; + pPhrase->pTail = pCsr; + pPhrase->iHead = iFirst; + pPhrase->iTail = iFirst; + }else{ + assert( rc!=SQLITE_OK || ( + pPhrase->pList==0 && pPhrase->pHead==0 && pPhrase->pTail==0 + )); + } + + return rc; +} + +/* +** Select the fragment of text consisting of nFragment contiguous tokens +** from column iCol that represent the "best" snippet. The best snippet +** is the snippet with the highest score, where scores are calculated +** by adding: +** +** (a) +1 point for each occurrence of a matchable phrase in the snippet. +** +** (b) +1000 points for the first occurrence of each matchable phrase in +** the snippet for which the corresponding mCovered bit is not set. +** +** The selected snippet parameters are stored in structure *pFragment before +** returning. The score of the selected snippet is stored in *piScore +** before returning. +*/ +static int fts3BestSnippet( + int nSnippet, /* Desired snippet length */ + Fts3Cursor *pCsr, /* Cursor to create snippet for */ + int iCol, /* Index of column to create snippet from */ + u64 mCovered, /* Mask of phrases already covered */ + u64 *pmSeen, /* IN/OUT: Mask of phrases seen */ + SnippetFragment *pFragment, /* OUT: Best snippet found */ + int *piScore /* OUT: Score of snippet pFragment */ +){ + int rc; /* Return Code */ + int nList; /* Number of phrases in expression */ + SnippetIter sIter; /* Iterates through snippet candidates */ + int nByte; /* Number of bytes of space to allocate */ + int iBestScore = -1; /* Best snippet score found so far */ + int i; /* Loop counter */ + + memset(&sIter, 0, sizeof(sIter)); + + /* Iterate through the phrases in the expression to count them. The same + ** callback makes sure the doclists are loaded for each phrase. + */ + rc = fts3ExprLoadDoclists(pCsr, &nList, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + + /* Now that it is known how many phrases there are, allocate and zero + ** the required space using malloc(). + */ + nByte = sizeof(SnippetPhrase) * nList; + sIter.aPhrase = (SnippetPhrase *)sqlite3_malloc(nByte); + if( !sIter.aPhrase ){ + return SQLITE_NOMEM; + } + memset(sIter.aPhrase, 0, nByte); + + /* Initialize the contents of the SnippetIter object. Then iterate through + ** the set of phrases in the expression to populate the aPhrase[] array. + */ + sIter.pCsr = pCsr; + sIter.iCol = iCol; + sIter.nSnippet = nSnippet; + sIter.nPhrase = nList; + sIter.iCurrent = -1; + rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void *)&sIter); + if( rc==SQLITE_OK ){ + + /* Set the *pmSeen output variable. */ + for(i=0; iiCol = iCol; + while( !fts3SnippetNextCandidate(&sIter) ){ + int iPos; + int iScore; + u64 mCover; + u64 mHighlite; + fts3SnippetDetails(&sIter, mCovered, &iPos, &iScore, &mCover,&mHighlite); + assert( iScore>=0 ); + if( iScore>iBestScore ){ + pFragment->iPos = iPos; + pFragment->hlmask = mHighlite; + pFragment->covered = mCover; + iBestScore = iScore; + } + } + + *piScore = iBestScore; + } + sqlite3_free(sIter.aPhrase); + return rc; +} + + +/* +** Append a string to the string-buffer passed as the first argument. +** +** If nAppend is negative, then the length of the string zAppend is +** determined using strlen(). +*/ +static int fts3StringAppend( + StrBuffer *pStr, /* Buffer to append to */ + const char *zAppend, /* Pointer to data to append to buffer */ + int nAppend /* Size of zAppend in bytes (or -1) */ +){ + if( nAppend<0 ){ + nAppend = (int)strlen(zAppend); + } + + /* If there is insufficient space allocated at StrBuffer.z, use realloc() + ** to grow the buffer until so that it is big enough to accomadate the + ** appended data. + */ + if( pStr->n+nAppend+1>=pStr->nAlloc ){ + int nAlloc = pStr->nAlloc+nAppend+100; + char *zNew = sqlite3_realloc(pStr->z, nAlloc); + if( !zNew ){ + return SQLITE_NOMEM; + } + pStr->z = zNew; + pStr->nAlloc = nAlloc; + } + assert( pStr->z!=0 && (pStr->nAlloc >= pStr->n+nAppend+1) ); + + /* Append the data to the string buffer. */ + memcpy(&pStr->z[pStr->n], zAppend, nAppend); + pStr->n += nAppend; + pStr->z[pStr->n] = '\0'; + + return SQLITE_OK; +} + +/* +** The fts3BestSnippet() function often selects snippets that end with a +** query term. That is, the final term of the snippet is always a term +** that requires highlighting. For example, if 'X' is a highlighted term +** and '.' is a non-highlighted term, BestSnippet() may select: +** +** ........X.....X +** +** This function "shifts" the beginning of the snippet forward in the +** document so that there are approximately the same number of +** non-highlighted terms to the right of the final highlighted term as there +** are to the left of the first highlighted term. For example, to this: +** +** ....X.....X.... +** +** This is done as part of extracting the snippet text, not when selecting +** the snippet. Snippet selection is done based on doclists only, so there +** is no way for fts3BestSnippet() to know whether or not the document +** actually contains terms that follow the final highlighted term. +*/ +static int fts3SnippetShift( + Fts3Table *pTab, /* FTS3 table snippet comes from */ + int iLangid, /* Language id to use in tokenizing */ + int nSnippet, /* Number of tokens desired for snippet */ + const char *zDoc, /* Document text to extract snippet from */ + int nDoc, /* Size of buffer zDoc in bytes */ + int *piPos, /* IN/OUT: First token of snippet */ + u64 *pHlmask /* IN/OUT: Mask of tokens to highlight */ +){ + u64 hlmask = *pHlmask; /* Local copy of initial highlight-mask */ + + if( hlmask ){ + int nLeft; /* Tokens to the left of first highlight */ + int nRight; /* Tokens to the right of last highlight */ + int nDesired; /* Ideal number of tokens to shift forward */ + + for(nLeft=0; !(hlmask & ((u64)1 << nLeft)); nLeft++); + for(nRight=0; !(hlmask & ((u64)1 << (nSnippet-1-nRight))); nRight++); + nDesired = (nLeft-nRight)/2; + + /* Ideally, the start of the snippet should be pushed forward in the + ** document nDesired tokens. This block checks if there are actually + ** nDesired tokens to the right of the snippet. If so, *piPos and + ** *pHlMask are updated to shift the snippet nDesired tokens to the + ** right. Otherwise, the snippet is shifted by the number of tokens + ** available. + */ + if( nDesired>0 ){ + int nShift; /* Number of tokens to shift snippet by */ + int iCurrent = 0; /* Token counter */ + int rc; /* Return Code */ + sqlite3_tokenizer_module *pMod; + sqlite3_tokenizer_cursor *pC; + pMod = (sqlite3_tokenizer_module *)pTab->pTokenizer->pModule; + + /* Open a cursor on zDoc/nDoc. Check if there are (nSnippet+nDesired) + ** or more tokens in zDoc/nDoc. + */ + rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, iLangid, zDoc, nDoc, &pC); + if( rc!=SQLITE_OK ){ + return rc; + } + while( rc==SQLITE_OK && iCurrent<(nSnippet+nDesired) ){ + const char *ZDUMMY; int DUMMY1 = 0, DUMMY2 = 0, DUMMY3 = 0; + rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &DUMMY2, &DUMMY3, &iCurrent); + } + pMod->xClose(pC); + if( rc!=SQLITE_OK && rc!=SQLITE_DONE ){ return rc; } + + nShift = (rc==SQLITE_DONE)+iCurrent-nSnippet; + assert( nShift<=nDesired ); + if( nShift>0 ){ + *piPos += nShift; + *pHlmask = hlmask >> nShift; + } + } + } + return SQLITE_OK; +} + +/* +** Extract the snippet text for fragment pFragment from cursor pCsr and +** append it to string buffer pOut. +*/ +static int fts3SnippetText( + Fts3Cursor *pCsr, /* FTS3 Cursor */ + SnippetFragment *pFragment, /* Snippet to extract */ + int iFragment, /* Fragment number */ + int isLast, /* True for final fragment in snippet */ + int nSnippet, /* Number of tokens in extracted snippet */ + const char *zOpen, /* String inserted before highlighted term */ + const char *zClose, /* String inserted after highlighted term */ + const char *zEllipsis, /* String inserted between snippets */ + StrBuffer *pOut /* Write output here */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int rc; /* Return code */ + const char *zDoc; /* Document text to extract snippet from */ + int nDoc; /* Size of zDoc in bytes */ + int iCurrent = 0; /* Current token number of document */ + int iEnd = 0; /* Byte offset of end of current token */ + int isShiftDone = 0; /* True after snippet is shifted */ + int iPos = pFragment->iPos; /* First token of snippet */ + u64 hlmask = pFragment->hlmask; /* Highlight-mask for snippet */ + int iCol = pFragment->iCol+1; /* Query column to extract text from */ + sqlite3_tokenizer_module *pMod; /* Tokenizer module methods object */ + sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor open on zDoc/nDoc */ + + zDoc = (const char *)sqlite3_column_text(pCsr->pStmt, iCol); + if( zDoc==0 ){ + if( sqlite3_column_type(pCsr->pStmt, iCol)!=SQLITE_NULL ){ + return SQLITE_NOMEM; + } + return SQLITE_OK; + } + nDoc = sqlite3_column_bytes(pCsr->pStmt, iCol); + + /* Open a token cursor on the document. */ + pMod = (sqlite3_tokenizer_module *)pTab->pTokenizer->pModule; + rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, pCsr->iLangid, zDoc,nDoc,&pC); + if( rc!=SQLITE_OK ){ + return rc; + } + + while( rc==SQLITE_OK ){ + const char *ZDUMMY; /* Dummy argument used with tokenizer */ + int DUMMY1 = -1; /* Dummy argument used with tokenizer */ + int iBegin = 0; /* Offset in zDoc of start of token */ + int iFin = 0; /* Offset in zDoc of end of token */ + int isHighlight = 0; /* True for highlighted terms */ + + /* Variable DUMMY1 is initialized to a negative value above. Elsewhere + ** in the FTS code the variable that the third argument to xNext points to + ** is initialized to zero before the first (*but not necessarily + ** subsequent*) call to xNext(). This is done for a particular application + ** that needs to know whether or not the tokenizer is being used for + ** snippet generation or for some other purpose. + ** + ** Extreme care is required when writing code to depend on this + ** initialization. It is not a documented part of the tokenizer interface. + ** If a tokenizer is used directly by any code outside of FTS, this + ** convention might not be respected. */ + rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &iBegin, &iFin, &iCurrent); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_DONE ){ + /* Special case - the last token of the snippet is also the last token + ** of the column. Append any punctuation that occurred between the end + ** of the previous token and the end of the document to the output. + ** Then break out of the loop. */ + rc = fts3StringAppend(pOut, &zDoc[iEnd], -1); + } + break; + } + if( iCurrentiLangid, nSnippet, &zDoc[iBegin], n, &iPos, &hlmask + ); + isShiftDone = 1; + + /* Now that the shift has been done, check if the initial "..." are + ** required. They are required if (a) this is not the first fragment, + ** or (b) this fragment does not begin at position 0 of its column. + */ + if( rc==SQLITE_OK ){ + if( iPos>0 || iFragment>0 ){ + rc = fts3StringAppend(pOut, zEllipsis, -1); + }else if( iBegin ){ + rc = fts3StringAppend(pOut, zDoc, iBegin); + } + } + if( rc!=SQLITE_OK || iCurrent=(iPos+nSnippet) ){ + if( isLast ){ + rc = fts3StringAppend(pOut, zEllipsis, -1); + } + break; + } + + /* Set isHighlight to true if this term should be highlighted. */ + isHighlight = (hlmask & ((u64)1 << (iCurrent-iPos)))!=0; + + if( iCurrent>iPos ) rc = fts3StringAppend(pOut, &zDoc[iEnd], iBegin-iEnd); + if( rc==SQLITE_OK && isHighlight ) rc = fts3StringAppend(pOut, zOpen, -1); + if( rc==SQLITE_OK ) rc = fts3StringAppend(pOut, &zDoc[iBegin], iFin-iBegin); + if( rc==SQLITE_OK && isHighlight ) rc = fts3StringAppend(pOut, zClose, -1); + + iEnd = iFin; + } + + pMod->xClose(pC); + return rc; +} + + +/* +** This function is used to count the entries in a column-list (a +** delta-encoded list of term offsets within a single column of a single +** row). When this function is called, *ppCollist should point to the +** beginning of the first varint in the column-list (the varint that +** contains the position of the first matching term in the column data). +** Before returning, *ppCollist is set to point to the first byte after +** the last varint in the column-list (either the 0x00 signifying the end +** of the position-list, or the 0x01 that precedes the column number of +** the next column in the position-list). +** +** The number of elements in the column-list is returned. +*/ +static int fts3ColumnlistCount(char **ppCollist){ + char *pEnd = *ppCollist; + char c = 0; + int nEntry = 0; + + /* A column-list is terminated by either a 0x01 or 0x00. */ + while( 0xFE & (*pEnd | c) ){ + c = *pEnd++ & 0x80; + if( !c ) nEntry++; + } + + *ppCollist = pEnd; + return nEntry; +} + +/* +** fts3ExprIterate() callback used to collect the "global" matchinfo stats +** for a single query. +** +** fts3ExprIterate() callback to load the 'global' elements of a +** FTS3_MATCHINFO_HITS matchinfo array. The global stats are those elements +** of the matchinfo array that are constant for all rows returned by the +** current query. +** +** Argument pCtx is actually a pointer to a struct of type MatchInfo. This +** function populates Matchinfo.aMatchinfo[] as follows: +** +** for(iCol=0; iColpCursor, pExpr, &p->aMatchinfo[3*iPhrase*p->nCol] + ); +} + +/* +** fts3ExprIterate() callback used to collect the "local" part of the +** FTS3_MATCHINFO_HITS array. The local stats are those elements of the +** array that are different for each row returned by the query. +*/ +static int fts3ExprLocalHitsCb( + Fts3Expr *pExpr, /* Phrase expression node */ + int iPhrase, /* Phrase number */ + void *pCtx /* Pointer to MatchInfo structure */ +){ + int rc = SQLITE_OK; + MatchInfo *p = (MatchInfo *)pCtx; + int iStart = iPhrase * p->nCol * 3; + int i; + + for(i=0; inCol && rc==SQLITE_OK; i++){ + char *pCsr; + rc = sqlite3Fts3EvalPhrasePoslist(p->pCursor, pExpr, i, &pCsr); + if( pCsr ){ + p->aMatchinfo[iStart+i*3] = fts3ColumnlistCount(&pCsr); + }else{ + p->aMatchinfo[iStart+i*3] = 0; + } + } + + return rc; +} + +/* +** fts3ExprIterate() callback used to gather information for the matchinfo +** directive 'y'. +*/ +static int fts3ExprLHitsCb( + Fts3Expr *pExpr, /* Phrase expression node */ + int iPhrase, /* Phrase number */ + void *pCtx /* Pointer to MatchInfo structure */ +){ + MatchInfo *p = (MatchInfo *)pCtx; + Fts3Table *pTab = (Fts3Table *)p->pCursor->base.pVtab; + int rc = SQLITE_OK; + int iStart = iPhrase * p->nCol; + Fts3Expr *pEof; /* Ancestor node already at EOF */ + + /* This must be a phrase */ + assert( pExpr->pPhrase ); + + /* Initialize all output integers to zero. */ + memset(&p->aMatchinfo[iStart], 0, sizeof(u32) * p->nCol); + + /* Check if this or any parent node is at EOF. If so, then all output + ** values are zero. */ + for(pEof=pExpr; pEof && pEof->bEof==0; pEof=pEof->pParent); + + if( pEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){ + Fts3Phrase *pPhrase = pExpr->pPhrase; + char *pIter = pPhrase->doclist.pList; + int iCol = 0; + + while( 1 ){ + int nHit = fts3ColumnlistCount(&pIter); + if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){ + p->aMatchinfo[iStart + iCol] = (u32)nHit; + } + assert( *pIter==0x00 || *pIter==0x01 ); + if( *pIter!=0x01 ) break; + pIter++; + pIter += fts3GetVarint32(pIter, &iCol); + } + } + + return rc; +} + +static int fts3MatchinfoCheck( + Fts3Table *pTab, + char cArg, + char **pzErr +){ + if( (cArg==FTS3_MATCHINFO_NPHRASE) + || (cArg==FTS3_MATCHINFO_NCOL) + || (cArg==FTS3_MATCHINFO_NDOC && pTab->bFts4) + || (cArg==FTS3_MATCHINFO_AVGLENGTH && pTab->bFts4) + || (cArg==FTS3_MATCHINFO_LENGTH && pTab->bHasDocsize) + || (cArg==FTS3_MATCHINFO_LCS) + || (cArg==FTS3_MATCHINFO_HITS) + || (cArg==FTS3_MATCHINFO_LHITS) + ){ + return SQLITE_OK; + } + sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo request: %c", cArg); + return SQLITE_ERROR; +} + +static int fts3MatchinfoSize(MatchInfo *pInfo, char cArg){ + int nVal; /* Number of integers output by cArg */ + + switch( cArg ){ + case FTS3_MATCHINFO_NDOC: + case FTS3_MATCHINFO_NPHRASE: + case FTS3_MATCHINFO_NCOL: + nVal = 1; + break; + + case FTS3_MATCHINFO_AVGLENGTH: + case FTS3_MATCHINFO_LENGTH: + case FTS3_MATCHINFO_LCS: + nVal = pInfo->nCol; + break; + + case FTS3_MATCHINFO_LHITS: + nVal = pInfo->nCol * pInfo->nPhrase; + break; + + default: + assert( cArg==FTS3_MATCHINFO_HITS ); + nVal = pInfo->nCol * pInfo->nPhrase * 3; + break; + } + + return nVal; +} + +static int fts3MatchinfoSelectDoctotal( + Fts3Table *pTab, + sqlite3_stmt **ppStmt, + sqlite3_int64 *pnDoc, + const char **paLen +){ + sqlite3_stmt *pStmt; + const char *a; + sqlite3_int64 nDoc; + + if( !*ppStmt ){ + int rc = sqlite3Fts3SelectDoctotal(pTab, ppStmt); + if( rc!=SQLITE_OK ) return rc; + } + pStmt = *ppStmt; + assert( sqlite3_data_count(pStmt)==1 ); + + a = sqlite3_column_blob(pStmt, 0); + a += sqlite3Fts3GetVarint(a, &nDoc); + if( nDoc==0 ) return FTS_CORRUPT_VTAB; + *pnDoc = (u32)nDoc; + + if( paLen ) *paLen = a; + return SQLITE_OK; +} + +/* +** An instance of the following structure is used to store state while +** iterating through a multi-column position-list corresponding to the +** hits for a single phrase on a single row in order to calculate the +** values for a matchinfo() FTS3_MATCHINFO_LCS request. +*/ +typedef struct LcsIterator LcsIterator; +struct LcsIterator { + Fts3Expr *pExpr; /* Pointer to phrase expression */ + int iPosOffset; /* Tokens count up to end of this phrase */ + char *pRead; /* Cursor used to iterate through aDoclist */ + int iPos; /* Current position */ +}; + +/* +** If LcsIterator.iCol is set to the following value, the iterator has +** finished iterating through all offsets for all columns. +*/ +#define LCS_ITERATOR_FINISHED 0x7FFFFFFF; + +static int fts3MatchinfoLcsCb( + Fts3Expr *pExpr, /* Phrase expression node */ + int iPhrase, /* Phrase number (numbered from zero) */ + void *pCtx /* Pointer to MatchInfo structure */ +){ + LcsIterator *aIter = (LcsIterator *)pCtx; + aIter[iPhrase].pExpr = pExpr; + return SQLITE_OK; +} + +/* +** Advance the iterator passed as an argument to the next position. Return +** 1 if the iterator is at EOF or if it now points to the start of the +** position list for the next column. +*/ +static int fts3LcsIteratorAdvance(LcsIterator *pIter){ + char *pRead = pIter->pRead; + sqlite3_int64 iRead; + int rc = 0; + + pRead += sqlite3Fts3GetVarint(pRead, &iRead); + if( iRead==0 || iRead==1 ){ + pRead = 0; + rc = 1; + }else{ + pIter->iPos += (int)(iRead-2); + } + + pIter->pRead = pRead; + return rc; +} + +/* +** This function implements the FTS3_MATCHINFO_LCS matchinfo() flag. +** +** If the call is successful, the longest-common-substring lengths for each +** column are written into the first nCol elements of the pInfo->aMatchinfo[] +** array before returning. SQLITE_OK is returned in this case. +** +** Otherwise, if an error occurs, an SQLite error code is returned and the +** data written to the first nCol elements of pInfo->aMatchinfo[] is +** undefined. +*/ +static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){ + LcsIterator *aIter; + int i; + int iCol; + int nToken = 0; + + /* Allocate and populate the array of LcsIterator objects. The array + ** contains one element for each matchable phrase in the query. + **/ + aIter = sqlite3_malloc(sizeof(LcsIterator) * pCsr->nPhrase); + if( !aIter ) return SQLITE_NOMEM; + memset(aIter, 0, sizeof(LcsIterator) * pCsr->nPhrase); + (void)fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter); + + for(i=0; inPhrase; i++){ + LcsIterator *pIter = &aIter[i]; + nToken -= pIter->pExpr->pPhrase->nToken; + pIter->iPosOffset = nToken; + } + + for(iCol=0; iColnCol; iCol++){ + int nLcs = 0; /* LCS value for this column */ + int nLive = 0; /* Number of iterators in aIter not at EOF */ + + for(i=0; inPhrase; i++){ + int rc; + LcsIterator *pIt = &aIter[i]; + rc = sqlite3Fts3EvalPhrasePoslist(pCsr, pIt->pExpr, iCol, &pIt->pRead); + if( rc!=SQLITE_OK ) return rc; + if( pIt->pRead ){ + pIt->iPos = pIt->iPosOffset; + fts3LcsIteratorAdvance(&aIter[i]); + nLive++; + } + } + + while( nLive>0 ){ + LcsIterator *pAdv = 0; /* The iterator to advance by one position */ + int nThisLcs = 0; /* LCS for the current iterator positions */ + + for(i=0; inPhrase; i++){ + LcsIterator *pIter = &aIter[i]; + if( pIter->pRead==0 ){ + /* This iterator is already at EOF for this column. */ + nThisLcs = 0; + }else{ + if( pAdv==0 || pIter->iPosiPos ){ + pAdv = pIter; + } + if( nThisLcs==0 || pIter->iPos==pIter[-1].iPos ){ + nThisLcs++; + }else{ + nThisLcs = 1; + } + if( nThisLcs>nLcs ) nLcs = nThisLcs; + } + } + if( fts3LcsIteratorAdvance(pAdv) ) nLive--; + } + + pInfo->aMatchinfo[iCol] = nLcs; + } + + sqlite3_free(aIter); + return SQLITE_OK; +} + +/* +** Populate the buffer pInfo->aMatchinfo[] with an array of integers to +** be returned by the matchinfo() function. Argument zArg contains the +** format string passed as the second argument to matchinfo (or the +** default value "pcx" if no second argument was specified). The format +** string has already been validated and the pInfo->aMatchinfo[] array +** is guaranteed to be large enough for the output. +** +** If bGlobal is true, then populate all fields of the matchinfo() output. +** If it is false, then assume that those fields that do not change between +** rows (i.e. FTS3_MATCHINFO_NPHRASE, NCOL, NDOC, AVGLENGTH and part of HITS) +** have already been populated. +** +** Return SQLITE_OK if successful, or an SQLite error code if an error +** occurs. If a value other than SQLITE_OK is returned, the state the +** pInfo->aMatchinfo[] buffer is left in is undefined. +*/ +static int fts3MatchinfoValues( + Fts3Cursor *pCsr, /* FTS3 cursor object */ + int bGlobal, /* True to grab the global stats */ + MatchInfo *pInfo, /* Matchinfo context object */ + const char *zArg /* Matchinfo format string */ +){ + int rc = SQLITE_OK; + int i; + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + sqlite3_stmt *pSelect = 0; + + for(i=0; rc==SQLITE_OK && zArg[i]; i++){ + + switch( zArg[i] ){ + case FTS3_MATCHINFO_NPHRASE: + if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nPhrase; + break; + + case FTS3_MATCHINFO_NCOL: + if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nCol; + break; + + case FTS3_MATCHINFO_NDOC: + if( bGlobal ){ + sqlite3_int64 nDoc = 0; + rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, 0); + pInfo->aMatchinfo[0] = (u32)nDoc; + } + break; + + case FTS3_MATCHINFO_AVGLENGTH: + if( bGlobal ){ + sqlite3_int64 nDoc; /* Number of rows in table */ + const char *a; /* Aggregate column length array */ + + rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, &a); + if( rc==SQLITE_OK ){ + int iCol; + for(iCol=0; iColnCol; iCol++){ + u32 iVal; + sqlite3_int64 nToken; + a += sqlite3Fts3GetVarint(a, &nToken); + iVal = (u32)(((u32)(nToken&0xffffffff)+nDoc/2)/nDoc); + pInfo->aMatchinfo[iCol] = iVal; + } + } + } + break; + + case FTS3_MATCHINFO_LENGTH: { + sqlite3_stmt *pSelectDocsize = 0; + rc = sqlite3Fts3SelectDocsize(pTab, pCsr->iPrevId, &pSelectDocsize); + if( rc==SQLITE_OK ){ + int iCol; + const char *a = sqlite3_column_blob(pSelectDocsize, 0); + for(iCol=0; iColnCol; iCol++){ + sqlite3_int64 nToken; + a += sqlite3Fts3GetVarint(a, &nToken); + pInfo->aMatchinfo[iCol] = (u32)nToken; + } + } + sqlite3_reset(pSelectDocsize); + break; + } + + case FTS3_MATCHINFO_LCS: + rc = fts3ExprLoadDoclists(pCsr, 0, 0); + if( rc==SQLITE_OK ){ + rc = fts3MatchinfoLcs(pCsr, pInfo); + } + break; + + case FTS3_MATCHINFO_LHITS: + (void)fts3ExprIterate(pCsr->pExpr, fts3ExprLHitsCb, (void*)pInfo); + break; + + default: { + Fts3Expr *pExpr; + assert( zArg[i]==FTS3_MATCHINFO_HITS ); + pExpr = pCsr->pExpr; + rc = fts3ExprLoadDoclists(pCsr, 0, 0); + if( rc!=SQLITE_OK ) break; + if( bGlobal ){ + if( pCsr->pDeferred ){ + rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &pInfo->nDoc, 0); + if( rc!=SQLITE_OK ) break; + } + rc = fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo); + if( rc!=SQLITE_OK ) break; + } + (void)fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo); + break; + } + } + + pInfo->aMatchinfo += fts3MatchinfoSize(pInfo, zArg[i]); + } + + sqlite3_reset(pSelect); + return rc; +} + + +/* +** Populate pCsr->aMatchinfo[] with data for the current row. The +** 'matchinfo' data is an array of 32-bit unsigned integers (C type u32). +*/ +static int fts3GetMatchinfo( + Fts3Cursor *pCsr, /* FTS3 Cursor object */ + const char *zArg /* Second argument to matchinfo() function */ +){ + MatchInfo sInfo; + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int rc = SQLITE_OK; + int bGlobal = 0; /* Collect 'global' stats as well as local */ + + memset(&sInfo, 0, sizeof(MatchInfo)); + sInfo.pCursor = pCsr; + sInfo.nCol = pTab->nColumn; + + /* If there is cached matchinfo() data, but the format string for the + ** cache does not match the format string for this request, discard + ** the cached data. */ + if( pCsr->zMatchinfo && strcmp(pCsr->zMatchinfo, zArg) ){ + assert( pCsr->aMatchinfo ); + sqlite3_free(pCsr->aMatchinfo); + pCsr->zMatchinfo = 0; + pCsr->aMatchinfo = 0; + } + + /* If Fts3Cursor.aMatchinfo[] is NULL, then this is the first time the + ** matchinfo function has been called for this query. In this case + ** allocate the array used to accumulate the matchinfo data and + ** initialize those elements that are constant for every row. + */ + if( pCsr->aMatchinfo==0 ){ + int nMatchinfo = 0; /* Number of u32 elements in match-info */ + int nArg; /* Bytes in zArg */ + int i; /* Used to iterate through zArg */ + + /* Determine the number of phrases in the query */ + pCsr->nPhrase = fts3ExprPhraseCount(pCsr->pExpr); + sInfo.nPhrase = pCsr->nPhrase; + + /* Determine the number of integers in the buffer returned by this call. */ + for(i=0; zArg[i]; i++){ + nMatchinfo += fts3MatchinfoSize(&sInfo, zArg[i]); + } + + /* Allocate space for Fts3Cursor.aMatchinfo[] and Fts3Cursor.zMatchinfo. */ + nArg = (int)strlen(zArg); + pCsr->aMatchinfo = (u32 *)sqlite3_malloc(sizeof(u32)*nMatchinfo + nArg + 1); + if( !pCsr->aMatchinfo ) return SQLITE_NOMEM; + + pCsr->zMatchinfo = (char *)&pCsr->aMatchinfo[nMatchinfo]; + pCsr->nMatchinfo = nMatchinfo; + memcpy(pCsr->zMatchinfo, zArg, nArg+1); + memset(pCsr->aMatchinfo, 0, sizeof(u32)*nMatchinfo); + pCsr->isMatchinfoNeeded = 1; + bGlobal = 1; + } + + sInfo.aMatchinfo = pCsr->aMatchinfo; + sInfo.nPhrase = pCsr->nPhrase; + if( pCsr->isMatchinfoNeeded ){ + rc = fts3MatchinfoValues(pCsr, bGlobal, &sInfo, zArg); + pCsr->isMatchinfoNeeded = 0; + } + + return rc; +} + +/* +** Implementation of snippet() function. +*/ +SQLITE_PRIVATE void sqlite3Fts3Snippet( + sqlite3_context *pCtx, /* SQLite function call context */ + Fts3Cursor *pCsr, /* Cursor object */ + const char *zStart, /* Snippet start text - "" */ + const char *zEnd, /* Snippet end text - "" */ + const char *zEllipsis, /* Snippet ellipsis text - "..." */ + int iCol, /* Extract snippet from this column */ + int nToken /* Approximate number of tokens in snippet */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int rc = SQLITE_OK; + int i; + StrBuffer res = {0, 0, 0}; + + /* The returned text includes up to four fragments of text extracted from + ** the data in the current row. The first iteration of the for(...) loop + ** below attempts to locate a single fragment of text nToken tokens in + ** size that contains at least one instance of all phrases in the query + ** expression that appear in the current row. If such a fragment of text + ** cannot be found, the second iteration of the loop attempts to locate + ** a pair of fragments, and so on. + */ + int nSnippet = 0; /* Number of fragments in this snippet */ + SnippetFragment aSnippet[4]; /* Maximum of 4 fragments per snippet */ + int nFToken = -1; /* Number of tokens in each fragment */ + + if( !pCsr->pExpr ){ + sqlite3_result_text(pCtx, "", 0, SQLITE_STATIC); + return; + } + + for(nSnippet=1; 1; nSnippet++){ + + int iSnip; /* Loop counter 0..nSnippet-1 */ + u64 mCovered = 0; /* Bitmask of phrases covered by snippet */ + u64 mSeen = 0; /* Bitmask of phrases seen by BestSnippet() */ + + if( nToken>=0 ){ + nFToken = (nToken+nSnippet-1) / nSnippet; + }else{ + nFToken = -1 * nToken; + } + + for(iSnip=0; iSnipnColumn; iRead++){ + SnippetFragment sF = {0, 0, 0, 0}; + int iS = 0; + if( iCol>=0 && iRead!=iCol ) continue; + + /* Find the best snippet of nFToken tokens in column iRead. */ + rc = fts3BestSnippet(nFToken, pCsr, iRead, mCovered, &mSeen, &sF, &iS); + if( rc!=SQLITE_OK ){ + goto snippet_out; + } + if( iS>iBestScore ){ + *pFragment = sF; + iBestScore = iS; + } + } + + mCovered |= pFragment->covered; + } + + /* If all query phrases seen by fts3BestSnippet() are present in at least + ** one of the nSnippet snippet fragments, break out of the loop. + */ + assert( (mCovered&mSeen)==mCovered ); + if( mSeen==mCovered || nSnippet==SizeofArray(aSnippet) ) break; + } + + assert( nFToken>0 ); + + for(i=0; ipCsr, pExpr, p->iCol, &pList); + nTerm = pExpr->pPhrase->nToken; + if( pList ){ + fts3GetDeltaPosition(&pList, &iPos); + assert( iPos>=0 ); + } + + for(iTerm=0; iTermaTerm[p->iTerm++]; + pT->iOff = nTerm-iTerm-1; + pT->pList = pList; + pT->iPos = iPos; + } + + return rc; +} + +/* +** Implementation of offsets() function. +*/ +SQLITE_PRIVATE void sqlite3Fts3Offsets( + sqlite3_context *pCtx, /* SQLite function call context */ + Fts3Cursor *pCsr /* Cursor object */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + sqlite3_tokenizer_module const *pMod = pTab->pTokenizer->pModule; + int rc; /* Return Code */ + int nToken; /* Number of tokens in query */ + int iCol; /* Column currently being processed */ + StrBuffer res = {0, 0, 0}; /* Result string */ + TermOffsetCtx sCtx; /* Context for fts3ExprTermOffsetInit() */ + + if( !pCsr->pExpr ){ + sqlite3_result_text(pCtx, "", 0, SQLITE_STATIC); + return; + } + + memset(&sCtx, 0, sizeof(sCtx)); + assert( pCsr->isRequireSeek==0 ); + + /* Count the number of terms in the query */ + rc = fts3ExprLoadDoclists(pCsr, 0, &nToken); + if( rc!=SQLITE_OK ) goto offsets_out; + + /* Allocate the array of TermOffset iterators. */ + sCtx.aTerm = (TermOffset *)sqlite3_malloc(sizeof(TermOffset)*nToken); + if( 0==sCtx.aTerm ){ + rc = SQLITE_NOMEM; + goto offsets_out; + } + sCtx.iDocid = pCsr->iPrevId; + sCtx.pCsr = pCsr; + + /* Loop through the table columns, appending offset information to + ** string-buffer res for each column. + */ + for(iCol=0; iColnColumn; iCol++){ + sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor */ + const char *ZDUMMY; /* Dummy argument used with xNext() */ + int NDUMMY = 0; /* Dummy argument used with xNext() */ + int iStart = 0; + int iEnd = 0; + int iCurrent = 0; + const char *zDoc; + int nDoc; + + /* Initialize the contents of sCtx.aTerm[] for column iCol. There is + ** no way that this operation can fail, so the return code from + ** fts3ExprIterate() can be discarded. + */ + sCtx.iCol = iCol; + sCtx.iTerm = 0; + (void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void *)&sCtx); + + /* Retreive the text stored in column iCol. If an SQL NULL is stored + ** in column iCol, jump immediately to the next iteration of the loop. + ** If an OOM occurs while retrieving the data (this can happen if SQLite + ** needs to transform the data from utf-16 to utf-8), return SQLITE_NOMEM + ** to the caller. + */ + zDoc = (const char *)sqlite3_column_text(pCsr->pStmt, iCol+1); + nDoc = sqlite3_column_bytes(pCsr->pStmt, iCol+1); + if( zDoc==0 ){ + if( sqlite3_column_type(pCsr->pStmt, iCol+1)==SQLITE_NULL ){ + continue; + } + rc = SQLITE_NOMEM; + goto offsets_out; + } + + /* Initialize a tokenizer iterator to iterate through column iCol. */ + rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, pCsr->iLangid, + zDoc, nDoc, &pC + ); + if( rc!=SQLITE_OK ) goto offsets_out; + + rc = pMod->xNext(pC, &ZDUMMY, &NDUMMY, &iStart, &iEnd, &iCurrent); + while( rc==SQLITE_OK ){ + int i; /* Used to loop through terms */ + int iMinPos = 0x7FFFFFFF; /* Position of next token */ + TermOffset *pTerm = 0; /* TermOffset associated with next token */ + + for(i=0; ipList && (pT->iPos-pT->iOff)iPos-pT->iOff; + pTerm = pT; + } + } + + if( !pTerm ){ + /* All offsets for this column have been gathered. */ + rc = SQLITE_DONE; + }else{ + assert( iCurrent<=iMinPos ); + if( 0==(0xFE&*pTerm->pList) ){ + pTerm->pList = 0; + }else{ + fts3GetDeltaPosition(&pTerm->pList, &pTerm->iPos); + } + while( rc==SQLITE_OK && iCurrentxNext(pC, &ZDUMMY, &NDUMMY, &iStart, &iEnd, &iCurrent); + } + if( rc==SQLITE_OK ){ + char aBuffer[64]; + sqlite3_snprintf(sizeof(aBuffer), aBuffer, + "%d %d %d %d ", iCol, pTerm-sCtx.aTerm, iStart, iEnd-iStart + ); + rc = fts3StringAppend(&res, aBuffer, -1); + }else if( rc==SQLITE_DONE && pTab->zContentTbl==0 ){ + rc = FTS_CORRUPT_VTAB; + } + } + } + if( rc==SQLITE_DONE ){ + rc = SQLITE_OK; + } + + pMod->xClose(pC); + if( rc!=SQLITE_OK ) goto offsets_out; + } + + offsets_out: + sqlite3_free(sCtx.aTerm); + assert( rc!=SQLITE_DONE ); + sqlite3Fts3SegmentsClose(pTab); + if( rc!=SQLITE_OK ){ + sqlite3_result_error_code(pCtx, rc); + sqlite3_free(res.z); + }else{ + sqlite3_result_text(pCtx, res.z, res.n-1, sqlite3_free); + } + return; +} + +/* +** Implementation of matchinfo() function. +*/ +SQLITE_PRIVATE void sqlite3Fts3Matchinfo( + sqlite3_context *pContext, /* Function call context */ + Fts3Cursor *pCsr, /* FTS3 table cursor */ + const char *zArg /* Second arg to matchinfo() function */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int rc; + int i; + const char *zFormat; + + if( zArg ){ + for(i=0; zArg[i]; i++){ + char *zErr = 0; + if( fts3MatchinfoCheck(pTab, zArg[i], &zErr) ){ + sqlite3_result_error(pContext, zErr, -1); + sqlite3_free(zErr); + return; + } + } + zFormat = zArg; + }else{ + zFormat = FTS3_MATCHINFO_DEFAULT; + } + + if( !pCsr->pExpr ){ + sqlite3_result_blob(pContext, "", 0, SQLITE_STATIC); + return; + } + + /* Retrieve matchinfo() data. */ + rc = fts3GetMatchinfo(pCsr, zFormat); + sqlite3Fts3SegmentsClose(pTab); + + if( rc!=SQLITE_OK ){ + sqlite3_result_error_code(pContext, rc); + }else{ + int n = pCsr->nMatchinfo * sizeof(u32); + sqlite3_result_blob(pContext, pCsr->aMatchinfo, n, SQLITE_TRANSIENT); + } +} + +#endif + +/************** End of fts3_snippet.c ****************************************/ +/************** Begin file fts3_unicode.c ************************************/ +/* +** 2012 May 24 +** +** 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. +** +****************************************************************************** +** +** Implementation of the "unicode" full-text-search tokenizer. +*/ + +#ifndef SQLITE_DISABLE_FTS3_UNICODE + +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ +/* #include */ +/* #include */ + + +/* +** The following two macros - READ_UTF8 and WRITE_UTF8 - have been copied +** from the sqlite3 source file utf.c. If this file is compiled as part +** of the amalgamation, they are not required. +*/ +#ifndef SQLITE_AMALGAMATION + +static const unsigned char sqlite3Utf8Trans1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00, +}; + +#define READ_UTF8(zIn, zTerm, c) \ + c = *(zIn++); \ + if( c>=0xc0 ){ \ + c = sqlite3Utf8Trans1[c-0xc0]; \ + while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \ + c = (c<<6) + (0x3f & *(zIn++)); \ + } \ + if( c<0x80 \ + || (c&0xFFFFF800)==0xD800 \ + || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \ + } + +#define WRITE_UTF8(zOut, c) { \ + if( c<0x00080 ){ \ + *zOut++ = (u8)(c&0xFF); \ + } \ + else if( c<0x00800 ){ \ + *zOut++ = 0xC0 + (u8)((c>>6)&0x1F); \ + *zOut++ = 0x80 + (u8)(c & 0x3F); \ + } \ + else if( c<0x10000 ){ \ + *zOut++ = 0xE0 + (u8)((c>>12)&0x0F); \ + *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \ + *zOut++ = 0x80 + (u8)(c & 0x3F); \ + }else{ \ + *zOut++ = 0xF0 + (u8)((c>>18) & 0x07); \ + *zOut++ = 0x80 + (u8)((c>>12) & 0x3F); \ + *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \ + *zOut++ = 0x80 + (u8)(c & 0x3F); \ + } \ +} + +#endif /* ifndef SQLITE_AMALGAMATION */ + +typedef struct unicode_tokenizer unicode_tokenizer; +typedef struct unicode_cursor unicode_cursor; + +struct unicode_tokenizer { + sqlite3_tokenizer base; + int bRemoveDiacritic; + int nException; + int *aiException; +}; + +struct unicode_cursor { + sqlite3_tokenizer_cursor base; + const unsigned char *aInput; /* Input text being tokenized */ + int nInput; /* Size of aInput[] in bytes */ + int iOff; /* Current offset within aInput[] */ + int iToken; /* Index of next token to be returned */ + char *zToken; /* storage for current token */ + int nAlloc; /* space allocated at zToken */ +}; + + +/* +** Destroy a tokenizer allocated by unicodeCreate(). +*/ +static int unicodeDestroy(sqlite3_tokenizer *pTokenizer){ + if( pTokenizer ){ + unicode_tokenizer *p = (unicode_tokenizer *)pTokenizer; + sqlite3_free(p->aiException); + sqlite3_free(p); + } + return SQLITE_OK; +} + +/* +** As part of a tokenchars= or separators= option, the CREATE VIRTUAL TABLE +** statement has specified that the tokenizer for this table shall consider +** all characters in string zIn/nIn to be separators (if bAlnum==0) or +** token characters (if bAlnum==1). +** +** For each codepoint in the zIn/nIn string, this function checks if the +** sqlite3FtsUnicodeIsalnum() function already returns the desired result. +** If so, no action is taken. Otherwise, the codepoint is added to the +** unicode_tokenizer.aiException[] array. For the purposes of tokenization, +** the return value of sqlite3FtsUnicodeIsalnum() is inverted for all +** codepoints in the aiException[] array. +** +** If a standalone diacritic mark (one that sqlite3FtsUnicodeIsdiacritic() +** identifies as a diacritic) occurs in the zIn/nIn string it is ignored. +** It is not possible to change the behavior of the tokenizer with respect +** to these codepoints. +*/ +static int unicodeAddExceptions( + unicode_tokenizer *p, /* Tokenizer to add exceptions to */ + int bAlnum, /* Replace Isalnum() return value with this */ + const char *zIn, /* Array of characters to make exceptions */ + int nIn /* Length of z in bytes */ +){ + const unsigned char *z = (const unsigned char *)zIn; + const unsigned char *zTerm = &z[nIn]; + int iCode; + int nEntry = 0; + + assert( bAlnum==0 || bAlnum==1 ); + + while( zaiException, (p->nException+nEntry)*sizeof(int)); + if( aNew==0 ) return SQLITE_NOMEM; + nNew = p->nException; + + z = (const unsigned char *)zIn; + while( zi; j--) aNew[j] = aNew[j-1]; + aNew[i] = iCode; + nNew++; + } + } + p->aiException = aNew; + p->nException = nNew; + } + + return SQLITE_OK; +} + +/* +** Return true if the p->aiException[] array contains the value iCode. +*/ +static int unicodeIsException(unicode_tokenizer *p, int iCode){ + if( p->nException>0 ){ + int *a = p->aiException; + int iLo = 0; + int iHi = p->nException-1; + + while( iHi>=iLo ){ + int iTest = (iHi + iLo) / 2; + if( iCode==a[iTest] ){ + return 1; + }else if( iCode>a[iTest] ){ + iLo = iTest+1; + }else{ + iHi = iTest-1; + } + } + } + + return 0; +} + +/* +** Return true if, for the purposes of tokenization, codepoint iCode is +** considered a token character (not a separator). +*/ +static int unicodeIsAlnum(unicode_tokenizer *p, int iCode){ + assert( (sqlite3FtsUnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 ); + return sqlite3FtsUnicodeIsalnum(iCode) ^ unicodeIsException(p, iCode); +} + +/* +** Create a new tokenizer instance. +*/ +static int unicodeCreate( + int nArg, /* Size of array argv[] */ + const char * const *azArg, /* Tokenizer creation arguments */ + sqlite3_tokenizer **pp /* OUT: New tokenizer handle */ +){ + unicode_tokenizer *pNew; /* New tokenizer object */ + int i; + int rc = SQLITE_OK; + + pNew = (unicode_tokenizer *) sqlite3_malloc(sizeof(unicode_tokenizer)); + if( pNew==NULL ) return SQLITE_NOMEM; + memset(pNew, 0, sizeof(unicode_tokenizer)); + pNew->bRemoveDiacritic = 1; + + for(i=0; rc==SQLITE_OK && ibRemoveDiacritic = 1; + } + else if( n==19 && memcmp("remove_diacritics=0", z, 19)==0 ){ + pNew->bRemoveDiacritic = 0; + } + else if( n>=11 && memcmp("tokenchars=", z, 11)==0 ){ + rc = unicodeAddExceptions(pNew, 1, &z[11], n-11); + } + else if( n>=11 && memcmp("separators=", z, 11)==0 ){ + rc = unicodeAddExceptions(pNew, 0, &z[11], n-11); + } + else{ + /* Unrecognized argument */ + rc = SQLITE_ERROR; + } + } + + if( rc!=SQLITE_OK ){ + unicodeDestroy((sqlite3_tokenizer *)pNew); + pNew = 0; + } + *pp = (sqlite3_tokenizer *)pNew; + return rc; +} + +/* +** Prepare to begin tokenizing a particular string. The input +** string to be tokenized is pInput[0..nBytes-1]. A cursor +** used to incrementally tokenize this string is returned in +** *ppCursor. +*/ +static int unicodeOpen( + sqlite3_tokenizer *p, /* The tokenizer */ + const char *aInput, /* Input string */ + int nInput, /* Size of string aInput in bytes */ + sqlite3_tokenizer_cursor **pp /* OUT: New cursor object */ +){ + unicode_cursor *pCsr; + + pCsr = (unicode_cursor *)sqlite3_malloc(sizeof(unicode_cursor)); + if( pCsr==0 ){ + return SQLITE_NOMEM; + } + memset(pCsr, 0, sizeof(unicode_cursor)); + + pCsr->aInput = (const unsigned char *)aInput; + if( aInput==0 ){ + pCsr->nInput = 0; + }else if( nInput<0 ){ + pCsr->nInput = (int)strlen(aInput); + }else{ + pCsr->nInput = nInput; + } + + *pp = &pCsr->base; + UNUSED_PARAMETER(p); + return SQLITE_OK; +} + +/* +** Close a tokenization cursor previously opened by a call to +** simpleOpen() above. +*/ +static int unicodeClose(sqlite3_tokenizer_cursor *pCursor){ + unicode_cursor *pCsr = (unicode_cursor *) pCursor; + sqlite3_free(pCsr->zToken); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* +** Extract the next token from a tokenization cursor. The cursor must +** have been opened by a prior call to simpleOpen(). +*/ +static int unicodeNext( + sqlite3_tokenizer_cursor *pC, /* Cursor returned by simpleOpen */ + const char **paToken, /* OUT: Token text */ + int *pnToken, /* OUT: Number of bytes at *paToken */ + int *piStart, /* OUT: Starting offset of token */ + int *piEnd, /* OUT: Ending offset of token */ + int *piPos /* OUT: Position integer of token */ +){ + unicode_cursor *pCsr = (unicode_cursor *)pC; + unicode_tokenizer *p = ((unicode_tokenizer *)pCsr->base.pTokenizer); + int iCode = 0; + char *zOut; + const unsigned char *z = &pCsr->aInput[pCsr->iOff]; + const unsigned char *zStart = z; + const unsigned char *zEnd; + const unsigned char *zTerm = &pCsr->aInput[pCsr->nInput]; + + /* Scan past any delimiter characters before the start of the next token. + ** Return SQLITE_DONE early if this takes us all the way to the end of + ** the input. */ + while( z=zTerm ) return SQLITE_DONE; + + zOut = pCsr->zToken; + do { + int iOut; + + /* Grow the output buffer if required. */ + if( (zOut-pCsr->zToken)>=(pCsr->nAlloc-4) ){ + char *zNew = sqlite3_realloc(pCsr->zToken, pCsr->nAlloc+64); + if( !zNew ) return SQLITE_NOMEM; + zOut = &zNew[zOut - pCsr->zToken]; + pCsr->zToken = zNew; + pCsr->nAlloc += 64; + } + + /* Write the folded case of the last character read to the output */ + zEnd = z; + iOut = sqlite3FtsUnicodeFold(iCode, p->bRemoveDiacritic); + if( iOut ){ + WRITE_UTF8(zOut, iOut); + } + + /* If the cursor is not at EOF, read the next character */ + if( z>=zTerm ) break; + READ_UTF8(z, zTerm, iCode); + }while( unicodeIsAlnum(p, iCode) + || sqlite3FtsUnicodeIsdiacritic(iCode) + ); + + /* Set the output variables and return. */ + pCsr->iOff = (int)(z - pCsr->aInput); + *paToken = pCsr->zToken; + *pnToken = (int)(zOut - pCsr->zToken); + *piStart = (int)(zStart - pCsr->aInput); + *piEnd = (int)(zEnd - pCsr->aInput); + *piPos = pCsr->iToken++; + return SQLITE_OK; +} + +/* +** Set *ppModule to a pointer to the sqlite3_tokenizer_module +** structure for the unicode tokenizer. +*/ +SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const **ppModule){ + static const sqlite3_tokenizer_module module = { + 0, + unicodeCreate, + unicodeDestroy, + unicodeOpen, + unicodeClose, + unicodeNext, + 0, + }; + *ppModule = &module; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ +#endif /* ifndef SQLITE_DISABLE_FTS3_UNICODE */ + +/************** End of fts3_unicode.c ****************************************/ +/************** Begin file fts3_unicode2.c ***********************************/ +/* +** 2012 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. +** +****************************************************************************** +*/ + +/* +** DO NOT EDIT THIS MACHINE GENERATED FILE. +*/ + +#ifndef SQLITE_DISABLE_FTS3_UNICODE +#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) + +/* #include */ + +/* +** Return true if the argument corresponds to a unicode codepoint +** classified as either a letter or a number. Otherwise false. +** +** The results are undefined if the value passed to this function +** is less than zero. +*/ +SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){ + /* Each unsigned integer in the following array corresponds to a contiguous + ** range of unicode codepoints that are not either letters or numbers (i.e. + ** codepoints for which this function should return 0). + ** + ** The most significant 22 bits in each 32-bit value contain the first + ** codepoint in the range. The least significant 10 bits are used to store + ** the size of the range (always at least 1). In other words, the value + ** ((C<<22) + N) represents a range of N codepoints starting with codepoint + ** C. It is not possible to represent a range larger than 1023 codepoints + ** using this format. + */ + static const unsigned int aEntry[] = { + 0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07, + 0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01, + 0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401, + 0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01, + 0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163C01, + 0x00164437, 0x0017CC02, 0x00180005, 0x00181816, 0x00187802, + 0x00192C15, 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F, + 0x001B9C07, 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401, + 0x001CC01B, 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804, + 0x00206C09, 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403, + 0x00217801, 0x0023901B, 0x00240004, 0x0024E803, 0x0024F812, + 0x00254407, 0x00258804, 0x0025C001, 0x00260403, 0x0026F001, + 0x0026F807, 0x00271C02, 0x00272C03, 0x00275C01, 0x00278802, + 0x0027C802, 0x0027E802, 0x00280403, 0x0028F001, 0x0028F805, + 0x00291C02, 0x00292C03, 0x00294401, 0x0029C002, 0x0029D401, + 0x002A0403, 0x002AF001, 0x002AF808, 0x002B1C03, 0x002B2C03, + 0x002B8802, 0x002BC002, 0x002C0403, 0x002CF001, 0x002CF807, + 0x002D1C02, 0x002D2C03, 0x002D5802, 0x002D8802, 0x002DC001, + 0x002E0801, 0x002EF805, 0x002F1803, 0x002F2804, 0x002F5C01, + 0x002FCC08, 0x00300403, 0x0030F807, 0x00311803, 0x00312804, + 0x00315402, 0x00318802, 0x0031FC01, 0x00320802, 0x0032F001, + 0x0032F807, 0x00331803, 0x00332804, 0x00335402, 0x00338802, + 0x00340802, 0x0034F807, 0x00351803, 0x00352804, 0x00355C01, + 0x00358802, 0x0035E401, 0x00360802, 0x00372801, 0x00373C06, + 0x00375801, 0x00376008, 0x0037C803, 0x0038C401, 0x0038D007, + 0x0038FC01, 0x00391C09, 0x00396802, 0x003AC401, 0x003AD006, + 0x003AEC02, 0x003B2006, 0x003C041F, 0x003CD00C, 0x003DC417, + 0x003E340B, 0x003E6424, 0x003EF80F, 0x003F380D, 0x0040AC14, + 0x00412806, 0x00415804, 0x00417803, 0x00418803, 0x00419C07, + 0x0041C404, 0x0042080C, 0x00423C01, 0x00426806, 0x0043EC01, + 0x004D740C, 0x004E400A, 0x00500001, 0x0059B402, 0x005A0001, + 0x005A6C02, 0x005BAC03, 0x005C4803, 0x005CC805, 0x005D4802, + 0x005DC802, 0x005ED023, 0x005F6004, 0x005F7401, 0x0060000F, + 0x0062A401, 0x0064800C, 0x0064C00C, 0x00650001, 0x00651002, + 0x0066C011, 0x00672002, 0x00677822, 0x00685C05, 0x00687802, + 0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007, 0x006AA006, + 0x006C0005, 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D, + 0x006F980E, 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802, + 0x00730008, 0x00734019, 0x0073B401, 0x0073C803, 0x00770027, + 0x0077F004, 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403, + 0x007FB403, 0x007FF402, 0x00800065, 0x0081A806, 0x0081E805, + 0x00822805, 0x0082801A, 0x00834021, 0x00840002, 0x00840C04, + 0x00842002, 0x00845001, 0x00845803, 0x00847806, 0x00849401, + 0x00849C01, 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005, + 0x00852804, 0x00853C01, 0x00864264, 0x00900027, 0x0091000B, + 0x0092704E, 0x00940200, 0x009C0475, 0x009E53B9, 0x00AD400A, + 0x00B39406, 0x00B3BC03, 0x00B3E404, 0x00B3F802, 0x00B5C001, + 0x00B5FC01, 0x00B7804F, 0x00B8C00C, 0x00BA001A, 0x00BA6C59, + 0x00BC00D6, 0x00BFC00C, 0x00C00005, 0x00C02019, 0x00C0A807, + 0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001, 0x00C3EC01, + 0x00C64002, 0x00C6580A, 0x00C70024, 0x00C8001F, 0x00C8A81E, + 0x00C94001, 0x00C98020, 0x00CA2827, 0x00CB003F, 0x00CC0100, + 0x01370040, 0x02924037, 0x0293F802, 0x02983403, 0x0299BC10, + 0x029A7C01, 0x029BC008, 0x029C0017, 0x029C8002, 0x029E2402, + 0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C09, 0x02A0D804, + 0x02A1D004, 0x02A20002, 0x02A2D011, 0x02A33802, 0x02A38012, + 0x02A3E003, 0x02A4980A, 0x02A51C0D, 0x02A57C01, 0x02A60004, + 0x02A6CC1B, 0x02A77802, 0x02A8A40E, 0x02A90C01, 0x02A93002, + 0x02A97004, 0x02A9DC03, 0x02A9EC01, 0x02AAC001, 0x02AAC803, + 0x02AADC02, 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07, + 0x02ABD402, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02, + 0x037FFC01, 0x03EC7801, 0x03ECA401, 0x03EEC810, 0x03F4F802, + 0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023, 0x03F95013, + 0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807, 0x03FCEC06, + 0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405, 0x04040003, + 0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E, 0x040E7C01, + 0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01, 0x04280403, + 0x04281402, 0x04283004, 0x0428E003, 0x0428FC01, 0x04294009, + 0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016, 0x04420003, + 0x0442C012, 0x04440003, 0x04449C0E, 0x04450004, 0x04460003, + 0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004, 0x05BD442E, + 0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5, 0x07480046, + 0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01, 0x075C5401, + 0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401, 0x075EA401, + 0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064, 0x07C2800F, + 0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F, 0x07C4C03C, + 0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009, 0x07C94002, + 0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014, 0x07CE8025, + 0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001, 0x07D108B6, + 0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018, 0x07D7EC46, + 0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401, 0x38008060, + 0x380400F0, + }; + static const unsigned int aAscii[4] = { + 0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001, + }; + + if( c<128 ){ + return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 ); + }else if( c<(1<<22) ){ + unsigned int key = (((unsigned int)c)<<10) | 0x000003FF; + int iRes = 0; + int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1; + int iLo = 0; + while( iHi>=iLo ){ + int iTest = (iHi + iLo) / 2; + if( key >= aEntry[iTest] ){ + iRes = iTest; + iLo = iTest+1; + }else{ + iHi = iTest-1; + } + } + assert( aEntry[0]=aEntry[iRes] ); + return (((unsigned int)c) >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF))); + } + return 1; +} + + +/* +** If the argument is a codepoint corresponding to a lowercase letter +** in the ASCII range with a diacritic added, return the codepoint +** of the ASCII letter only. For example, if passed 235 - "LATIN +** SMALL LETTER E WITH DIAERESIS" - return 65 ("LATIN SMALL LETTER +** E"). The resuls of passing a codepoint that corresponds to an +** uppercase letter are undefined. +*/ +static int remove_diacritic(int c){ + unsigned short aDia[] = { + 0, 1797, 1848, 1859, 1891, 1928, 1940, 1995, + 2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286, + 2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732, + 2782, 2842, 2894, 2954, 2984, 3000, 3028, 3336, + 3456, 3696, 3712, 3728, 3744, 3896, 3912, 3928, + 3968, 4008, 4040, 4106, 4138, 4170, 4202, 4234, + 4266, 4296, 4312, 4344, 4408, 4424, 4472, 4504, + 6148, 6198, 6264, 6280, 6360, 6429, 6505, 6529, + 61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726, + 61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122, + 62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536, + 62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730, + 62924, 63050, 63082, 63274, 63390, + }; + char aChar[] = { + '\0', 'a', 'c', 'e', 'i', 'n', 'o', 'u', 'y', 'y', 'a', 'c', + 'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r', + 's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o', + 'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r', + 'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h', + 'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't', + 'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a', + 'e', 'i', 'o', 'u', 'y', + }; + + unsigned int key = (((unsigned int)c)<<3) | 0x00000007; + int iRes = 0; + int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1; + int iLo = 0; + while( iHi>=iLo ){ + int iTest = (iHi + iLo) / 2; + if( key >= aDia[iTest] ){ + iRes = iTest; + iLo = iTest+1; + }else{ + iHi = iTest-1; + } + } + assert( key>=aDia[iRes] ); + return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]); +} + + +/* +** Return true if the argument interpreted as a unicode codepoint +** is a diacritical modifier character. +*/ +SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int c){ + unsigned int mask0 = 0x08029FDF; + unsigned int mask1 = 0x000361F8; + if( c<768 || c>817 ) return 0; + return (c < 768+32) ? + (mask0 & (1 << (c-768))) : + (mask1 & (1 << (c-768-32))); +} + + +/* +** Interpret the argument as a unicode codepoint. If the codepoint +** is an upper case character that has a lower case equivalent, +** return the codepoint corresponding to the lower case version. +** Otherwise, return a copy of the argument. +** +** The results are undefined if the value passed to this function +** is less than zero. +*/ +SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){ + /* Each entry in the following array defines a rule for folding a range + ** of codepoints to lower case. The rule applies to a range of nRange + ** codepoints starting at codepoint iCode. + ** + ** If the least significant bit in flags is clear, then the rule applies + ** to all nRange codepoints (i.e. all nRange codepoints are upper case and + ** need to be folded). Or, if it is set, then the rule only applies to + ** every second codepoint in the range, starting with codepoint C. + ** + ** The 7 most significant bits in flags are an index into the aiOff[] + ** array. If a specific codepoint C does require folding, then its lower + ** case equivalent is ((C + aiOff[flags>>1]) & 0xFFFF). + ** + ** The contents of this array are generated by parsing the CaseFolding.txt + ** file distributed as part of the "Unicode Character Database". See + ** http://www.unicode.org for details. + */ + static const struct TableEntry { + unsigned short iCode; + unsigned char flags; + unsigned char nRange; + } aEntry[] = { + {65, 14, 26}, {181, 64, 1}, {192, 14, 23}, + {216, 14, 7}, {256, 1, 48}, {306, 1, 6}, + {313, 1, 16}, {330, 1, 46}, {376, 116, 1}, + {377, 1, 6}, {383, 104, 1}, {385, 50, 1}, + {386, 1, 4}, {390, 44, 1}, {391, 0, 1}, + {393, 42, 2}, {395, 0, 1}, {398, 32, 1}, + {399, 38, 1}, {400, 40, 1}, {401, 0, 1}, + {403, 42, 1}, {404, 46, 1}, {406, 52, 1}, + {407, 48, 1}, {408, 0, 1}, {412, 52, 1}, + {413, 54, 1}, {415, 56, 1}, {416, 1, 6}, + {422, 60, 1}, {423, 0, 1}, {425, 60, 1}, + {428, 0, 1}, {430, 60, 1}, {431, 0, 1}, + {433, 58, 2}, {435, 1, 4}, {439, 62, 1}, + {440, 0, 1}, {444, 0, 1}, {452, 2, 1}, + {453, 0, 1}, {455, 2, 1}, {456, 0, 1}, + {458, 2, 1}, {459, 1, 18}, {478, 1, 18}, + {497, 2, 1}, {498, 1, 4}, {502, 122, 1}, + {503, 134, 1}, {504, 1, 40}, {544, 110, 1}, + {546, 1, 18}, {570, 70, 1}, {571, 0, 1}, + {573, 108, 1}, {574, 68, 1}, {577, 0, 1}, + {579, 106, 1}, {580, 28, 1}, {581, 30, 1}, + {582, 1, 10}, {837, 36, 1}, {880, 1, 4}, + {886, 0, 1}, {902, 18, 1}, {904, 16, 3}, + {908, 26, 1}, {910, 24, 2}, {913, 14, 17}, + {931, 14, 9}, {962, 0, 1}, {975, 4, 1}, + {976, 140, 1}, {977, 142, 1}, {981, 146, 1}, + {982, 144, 1}, {984, 1, 24}, {1008, 136, 1}, + {1009, 138, 1}, {1012, 130, 1}, {1013, 128, 1}, + {1015, 0, 1}, {1017, 152, 1}, {1018, 0, 1}, + {1021, 110, 3}, {1024, 34, 16}, {1040, 14, 32}, + {1120, 1, 34}, {1162, 1, 54}, {1216, 6, 1}, + {1217, 1, 14}, {1232, 1, 88}, {1329, 22, 38}, + {4256, 66, 38}, {4295, 66, 1}, {4301, 66, 1}, + {7680, 1, 150}, {7835, 132, 1}, {7838, 96, 1}, + {7840, 1, 96}, {7944, 150, 8}, {7960, 150, 6}, + {7976, 150, 8}, {7992, 150, 8}, {8008, 150, 6}, + {8025, 151, 8}, {8040, 150, 8}, {8072, 150, 8}, + {8088, 150, 8}, {8104, 150, 8}, {8120, 150, 2}, + {8122, 126, 2}, {8124, 148, 1}, {8126, 100, 1}, + {8136, 124, 4}, {8140, 148, 1}, {8152, 150, 2}, + {8154, 120, 2}, {8168, 150, 2}, {8170, 118, 2}, + {8172, 152, 1}, {8184, 112, 2}, {8186, 114, 2}, + {8188, 148, 1}, {8486, 98, 1}, {8490, 92, 1}, + {8491, 94, 1}, {8498, 12, 1}, {8544, 8, 16}, + {8579, 0, 1}, {9398, 10, 26}, {11264, 22, 47}, + {11360, 0, 1}, {11362, 88, 1}, {11363, 102, 1}, + {11364, 90, 1}, {11367, 1, 6}, {11373, 84, 1}, + {11374, 86, 1}, {11375, 80, 1}, {11376, 82, 1}, + {11378, 0, 1}, {11381, 0, 1}, {11390, 78, 2}, + {11392, 1, 100}, {11499, 1, 4}, {11506, 0, 1}, + {42560, 1, 46}, {42624, 1, 24}, {42786, 1, 14}, + {42802, 1, 62}, {42873, 1, 4}, {42877, 76, 1}, + {42878, 1, 10}, {42891, 0, 1}, {42893, 74, 1}, + {42896, 1, 4}, {42912, 1, 10}, {42922, 72, 1}, + {65313, 14, 26}, + }; + static const unsigned short aiOff[] = { + 1, 2, 8, 15, 16, 26, 28, 32, + 37, 38, 40, 48, 63, 64, 69, 71, + 79, 80, 116, 202, 203, 205, 206, 207, + 209, 210, 211, 213, 214, 217, 218, 219, + 775, 7264, 10792, 10795, 23228, 23256, 30204, 54721, + 54753, 54754, 54756, 54787, 54793, 54809, 57153, 57274, + 57921, 58019, 58363, 61722, 65268, 65341, 65373, 65406, + 65408, 65410, 65415, 65424, 65436, 65439, 65450, 65462, + 65472, 65476, 65478, 65480, 65482, 65488, 65506, 65511, + 65514, 65521, 65527, 65528, 65529, + }; + + int ret = c; + + assert( c>=0 ); + assert( sizeof(unsigned short)==2 && sizeof(unsigned char)==1 ); + + if( c<128 ){ + if( c>='A' && c<='Z' ) ret = c + ('a' - 'A'); + }else if( c<65536 ){ + int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1; + int iLo = 0; + int iRes = -1; + + while( iHi>=iLo ){ + int iTest = (iHi + iLo) / 2; + int cmp = (c - aEntry[iTest].iCode); + if( cmp>=0 ){ + iRes = iTest; + iLo = iTest+1; + }else{ + iHi = iTest-1; + } + } + assert( iRes<0 || c>=aEntry[iRes].iCode ); + + if( iRes>=0 ){ + const struct TableEntry *p = &aEntry[iRes]; + if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){ + ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF; + assert( ret>0 ); + } + } + + if( bRemoveDiacritic ) ret = remove_diacritic(ret); + } + + else if( c>=66560 && c<66600 ){ + ret = c + 40; + } + + return ret; +} +#endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */ +#endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */ + +/************** End of fts3_unicode2.c ***************************************/ +/************** Begin file rtree.c *******************************************/ +/* +** 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. +** +************************************************************************* +** This file contains code for implementations of the r-tree and r*-tree +** algorithms packaged as an SQLite virtual table module. +*/ + +/* +** Database Format of R-Tree Tables +** -------------------------------- +** +** The data structure for a single virtual r-tree table is stored in three +** native SQLite tables declared as follows. In each case, the '%' character +** in the table name is replaced with the user-supplied name of the r-tree +** table. +** +** CREATE TABLE %_node(nodeno INTEGER PRIMARY KEY, data BLOB) +** CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER) +** CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER) +** +** The data for each node of the r-tree structure is stored in the %_node +** table. For each node that is not the root node of the r-tree, there is +** an entry in the %_parent table associating the node with its parent. +** And for each row of data in the table, there is an entry in the %_rowid +** table that maps from the entries rowid to the id of the node that it +** is stored on. +** +** The root node of an r-tree always exists, even if the r-tree table is +** empty. The nodeno of the root node is always 1. All other nodes in the +** table must be the same size as the root node. The content of each node +** is formatted as follows: +** +** 1. If the node is the root node (node 1), then the first 2 bytes +** of the node contain the tree depth as a big-endian integer. +** For non-root nodes, the first 2 bytes are left unused. +** +** 2. The next 2 bytes contain the number of entries currently +** stored in the node. +** +** 3. The remainder of the node contains the node entries. Each entry +** consists of a single 8-byte integer followed by an even number +** of 4-byte coordinates. For leaf nodes the integer is the rowid +** of a record. For internal nodes it is the node number of a +** child page. +*/ + +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE) + +#ifndef SQLITE_CORE + SQLITE_EXTENSION_INIT1 +#else +#endif + +/* #include */ +/* #include */ +/* #include */ + +#ifndef SQLITE_AMALGAMATION +#include "sqlite3rtree.h" +typedef sqlite3_int64 i64; +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +#endif + +/* The following macro is used to suppress compiler warnings. +*/ +#ifndef UNUSED_PARAMETER +# define UNUSED_PARAMETER(x) (void)(x) +#endif + +typedef struct Rtree Rtree; +typedef struct RtreeCursor RtreeCursor; +typedef struct RtreeNode RtreeNode; +typedef struct RtreeCell RtreeCell; +typedef struct RtreeConstraint RtreeConstraint; +typedef struct RtreeMatchArg RtreeMatchArg; +typedef struct RtreeGeomCallback RtreeGeomCallback; +typedef union RtreeCoord RtreeCoord; +typedef struct RtreeSearchPoint RtreeSearchPoint; + +/* The rtree may have between 1 and RTREE_MAX_DIMENSIONS dimensions. */ +#define RTREE_MAX_DIMENSIONS 5 + +/* Size of hash table Rtree.aHash. This hash table is not expected to +** ever contain very many entries, so a fixed number of buckets is +** used. +*/ +#define HASHSIZE 97 + +/* The xBestIndex method of this virtual table requires an estimate of +** the number of rows in the virtual table to calculate the costs of +** various strategies. If possible, this estimate is loaded from the +** sqlite_stat1 table (with RTREE_MIN_ROWEST as a hard-coded minimum). +** Otherwise, if no sqlite_stat1 entry is available, use +** RTREE_DEFAULT_ROWEST. +*/ +#define RTREE_DEFAULT_ROWEST 1048576 +#define RTREE_MIN_ROWEST 100 + +/* +** An rtree virtual-table object. +*/ +struct Rtree { + sqlite3_vtab base; /* Base class. Must be first */ + sqlite3 *db; /* Host database connection */ + int iNodeSize; /* Size in bytes of each node in the node table */ + u8 nDim; /* Number of dimensions */ + u8 eCoordType; /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */ + u8 nBytesPerCell; /* Bytes consumed per cell */ + int iDepth; /* Current depth of the r-tree structure */ + char *zDb; /* Name of database containing r-tree table */ + char *zName; /* Name of r-tree table */ + int nBusy; /* Current number of users of this structure */ + i64 nRowEst; /* Estimated number of rows in this table */ + + /* List of nodes removed during a CondenseTree operation. List is + ** linked together via the pointer normally used for hash chains - + ** RtreeNode.pNext. RtreeNode.iNode stores the depth of the sub-tree + ** headed by the node (leaf nodes have RtreeNode.iNode==0). + */ + RtreeNode *pDeleted; + int iReinsertHeight; /* Height of sub-trees Reinsert() has run on */ + + /* Statements to read/write/delete a record from xxx_node */ + sqlite3_stmt *pReadNode; + sqlite3_stmt *pWriteNode; + sqlite3_stmt *pDeleteNode; + + /* Statements to read/write/delete a record from xxx_rowid */ + sqlite3_stmt *pReadRowid; + sqlite3_stmt *pWriteRowid; + sqlite3_stmt *pDeleteRowid; + + /* Statements to read/write/delete a record from xxx_parent */ + sqlite3_stmt *pReadParent; + sqlite3_stmt *pWriteParent; + sqlite3_stmt *pDeleteParent; + + RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ +}; + +/* Possible values for Rtree.eCoordType: */ +#define RTREE_COORD_REAL32 0 +#define RTREE_COORD_INT32 1 + +/* +** If SQLITE_RTREE_INT_ONLY is defined, then this virtual table will +** only deal with integer coordinates. No floating point operations +** will be done. +*/ +#ifdef SQLITE_RTREE_INT_ONLY + typedef sqlite3_int64 RtreeDValue; /* High accuracy coordinate */ + typedef int RtreeValue; /* Low accuracy coordinate */ +# define RTREE_ZERO 0 +#else + typedef double RtreeDValue; /* High accuracy coordinate */ + typedef float RtreeValue; /* Low accuracy coordinate */ +# define RTREE_ZERO 0.0 +#endif + +/* +** When doing a search of an r-tree, instances of the following structure +** record intermediate results from the tree walk. +** +** The id is always a node-id. For iLevel>=1 the id is the node-id of +** the node that the RtreeSearchPoint represents. When iLevel==0, however, +** the id is of the parent node and the cell that RtreeSearchPoint +** represents is the iCell-th entry in the parent node. +*/ +struct RtreeSearchPoint { + RtreeDValue rScore; /* The score for this node. Smallest goes first. */ + sqlite3_int64 id; /* Node ID */ + u8 iLevel; /* 0=entries. 1=leaf node. 2+ for higher */ + u8 eWithin; /* PARTLY_WITHIN or FULLY_WITHIN */ + u8 iCell; /* Cell index within the node */ +}; + +/* +** The minimum number of cells allowed for a node is a third of the +** maximum. In Gutman's notation: +** +** m = M/3 +** +** If an R*-tree "Reinsert" operation is required, the same number of +** cells are removed from the overfull node and reinserted into the tree. +*/ +#define RTREE_MINCELLS(p) ((((p)->iNodeSize-4)/(p)->nBytesPerCell)/3) +#define RTREE_REINSERT(p) RTREE_MINCELLS(p) +#define RTREE_MAXCELLS 51 + +/* +** The smallest possible node-size is (512-64)==448 bytes. And the largest +** supported cell size is 48 bytes (8 byte rowid + ten 4 byte coordinates). +** Therefore all non-root nodes must contain at least 3 entries. Since +** 2^40 is greater than 2^64, an r-tree structure always has a depth of +** 40 or less. +*/ +#define RTREE_MAX_DEPTH 40 + + +/* +** Number of entries in the cursor RtreeNode cache. The first entry is +** used to cache the RtreeNode for RtreeCursor.sPoint. The remaining +** entries cache the RtreeNode for the first elements of the priority queue. +*/ +#define RTREE_CACHE_SZ 5 + +/* +** An rtree cursor object. +*/ +struct RtreeCursor { + sqlite3_vtab_cursor base; /* Base class. Must be first */ + u8 atEOF; /* True if at end of search */ + u8 bPoint; /* True if sPoint is valid */ + int iStrategy; /* Copy of idxNum search parameter */ + int nConstraint; /* Number of entries in aConstraint */ + RtreeConstraint *aConstraint; /* Search constraints. */ + int nPointAlloc; /* Number of slots allocated for aPoint[] */ + int nPoint; /* Number of slots used in aPoint[] */ + int mxLevel; /* iLevel value for root of the tree */ + RtreeSearchPoint *aPoint; /* Priority queue for search points */ + RtreeSearchPoint sPoint; /* Cached next search point */ + RtreeNode *aNode[RTREE_CACHE_SZ]; /* Rtree node cache */ + u32 anQueue[RTREE_MAX_DEPTH+1]; /* Number of queued entries by iLevel */ +}; + +/* Return the Rtree of a RtreeCursor */ +#define RTREE_OF_CURSOR(X) ((Rtree*)((X)->base.pVtab)) + +/* +** A coordinate can be either a floating point number or a integer. All +** coordinates within a single R-Tree are always of the same time. +*/ +union RtreeCoord { + RtreeValue f; /* Floating point value */ + int i; /* Integer value */ + u32 u; /* Unsigned for byte-order conversions */ +}; + +/* +** The argument is an RtreeCoord. Return the value stored within the RtreeCoord +** formatted as a RtreeDValue (double or int64). This macro assumes that local +** variable pRtree points to the Rtree structure associated with the +** RtreeCoord. +*/ +#ifdef SQLITE_RTREE_INT_ONLY +# define DCOORD(coord) ((RtreeDValue)coord.i) +#else +# define DCOORD(coord) ( \ + (pRtree->eCoordType==RTREE_COORD_REAL32) ? \ + ((double)coord.f) : \ + ((double)coord.i) \ + ) +#endif + +/* +** A search constraint. +*/ +struct RtreeConstraint { + int iCoord; /* Index of constrained coordinate */ + int op; /* Constraining operation */ + union { + RtreeDValue rValue; /* Constraint value. */ + int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*); + int (*xQueryFunc)(sqlite3_rtree_query_info*); + } u; + sqlite3_rtree_query_info *pInfo; /* xGeom and xQueryFunc argument */ +}; + +/* Possible values for RtreeConstraint.op */ +#define RTREE_EQ 0x41 /* A */ +#define RTREE_LE 0x42 /* B */ +#define RTREE_LT 0x43 /* C */ +#define RTREE_GE 0x44 /* D */ +#define RTREE_GT 0x45 /* E */ +#define RTREE_MATCH 0x46 /* F: Old-style sqlite3_rtree_geometry_callback() */ +#define RTREE_QUERY 0x47 /* G: New-style sqlite3_rtree_query_callback() */ + + +/* +** An rtree structure node. +*/ +struct RtreeNode { + RtreeNode *pParent; /* Parent node */ + i64 iNode; /* The node number */ + int nRef; /* Number of references to this node */ + int isDirty; /* True if the node needs to be written to disk */ + u8 *zData; /* Content of the node, as should be on disk */ + RtreeNode *pNext; /* Next node in this hash collision chain */ +}; + +/* Return the number of cells in a node */ +#define NCELL(pNode) readInt16(&(pNode)->zData[2]) + +/* +** A single cell from a node, deserialized +*/ +struct RtreeCell { + i64 iRowid; /* Node or entry ID */ + RtreeCoord aCoord[RTREE_MAX_DIMENSIONS*2]; /* Bounding box coordinates */ +}; + + +/* +** This object becomes the sqlite3_user_data() for the SQL functions +** that are created by sqlite3_rtree_geometry_callback() and +** sqlite3_rtree_query_callback() and which appear on the right of MATCH +** operators in order to constrain a search. +** +** xGeom and xQueryFunc are the callback functions. Exactly one of +** xGeom and xQueryFunc fields is non-NULL, depending on whether the +** SQL function was created using sqlite3_rtree_geometry_callback() or +** sqlite3_rtree_query_callback(). +** +** This object is deleted automatically by the destructor mechanism in +** sqlite3_create_function_v2(). +*/ +struct RtreeGeomCallback { + int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*); + int (*xQueryFunc)(sqlite3_rtree_query_info*); + void (*xDestructor)(void*); + void *pContext; +}; + + +/* +** Value for the first field of every RtreeMatchArg object. The MATCH +** operator tests that the first field of a blob operand matches this +** value to avoid operating on invalid blobs (which could cause a segfault). +*/ +#define RTREE_GEOMETRY_MAGIC 0x891245AB + +/* +** An instance of this structure (in the form of a BLOB) is returned by +** the SQL functions that sqlite3_rtree_geometry_callback() and +** sqlite3_rtree_query_callback() create, and is read as the right-hand +** operand to the MATCH operator of an R-Tree. +*/ +struct RtreeMatchArg { + u32 magic; /* Always RTREE_GEOMETRY_MAGIC */ + RtreeGeomCallback cb; /* Info about the callback functions */ + int nParam; /* Number of parameters to the SQL function */ + RtreeDValue aParam[1]; /* Values for parameters to the SQL function */ +}; + +#ifndef MAX +# define MAX(x,y) ((x) < (y) ? (y) : (x)) +#endif +#ifndef MIN +# define MIN(x,y) ((x) > (y) ? (y) : (x)) +#endif + +/* +** Functions to deserialize a 16 bit integer, 32 bit real number and +** 64 bit integer. The deserialized value is returned. +*/ +static int readInt16(u8 *p){ + return (p[0]<<8) + p[1]; +} +static void readCoord(u8 *p, RtreeCoord *pCoord){ + pCoord->u = ( + (((u32)p[0]) << 24) + + (((u32)p[1]) << 16) + + (((u32)p[2]) << 8) + + (((u32)p[3]) << 0) + ); +} +static i64 readInt64(u8 *p){ + return ( + (((i64)p[0]) << 56) + + (((i64)p[1]) << 48) + + (((i64)p[2]) << 40) + + (((i64)p[3]) << 32) + + (((i64)p[4]) << 24) + + (((i64)p[5]) << 16) + + (((i64)p[6]) << 8) + + (((i64)p[7]) << 0) + ); +} + +/* +** Functions to serialize a 16 bit integer, 32 bit real number and +** 64 bit integer. The value returned is the number of bytes written +** to the argument buffer (always 2, 4 and 8 respectively). +*/ +static int writeInt16(u8 *p, int i){ + p[0] = (i>> 8)&0xFF; + p[1] = (i>> 0)&0xFF; + return 2; +} +static int writeCoord(u8 *p, RtreeCoord *pCoord){ + u32 i; + assert( sizeof(RtreeCoord)==4 ); + assert( sizeof(u32)==4 ); + i = pCoord->u; + p[0] = (i>>24)&0xFF; + p[1] = (i>>16)&0xFF; + p[2] = (i>> 8)&0xFF; + p[3] = (i>> 0)&0xFF; + return 4; +} +static int writeInt64(u8 *p, i64 i){ + p[0] = (i>>56)&0xFF; + p[1] = (i>>48)&0xFF; + p[2] = (i>>40)&0xFF; + p[3] = (i>>32)&0xFF; + p[4] = (i>>24)&0xFF; + p[5] = (i>>16)&0xFF; + p[6] = (i>> 8)&0xFF; + p[7] = (i>> 0)&0xFF; + return 8; +} + +/* +** Increment the reference count of node p. +*/ +static void nodeReference(RtreeNode *p){ + if( p ){ + p->nRef++; + } +} + +/* +** Clear the content of node p (set all bytes to 0x00). +*/ +static void nodeZero(Rtree *pRtree, RtreeNode *p){ + memset(&p->zData[2], 0, pRtree->iNodeSize-2); + p->isDirty = 1; +} + +/* +** Given a node number iNode, return the corresponding key to use +** in the Rtree.aHash table. +*/ +static int nodeHash(i64 iNode){ + return iNode % HASHSIZE; +} + +/* +** Search the node hash table for node iNode. If found, return a pointer +** to it. Otherwise, return 0. +*/ +static RtreeNode *nodeHashLookup(Rtree *pRtree, i64 iNode){ + RtreeNode *p; + for(p=pRtree->aHash[nodeHash(iNode)]; p && p->iNode!=iNode; p=p->pNext); + return p; +} + +/* +** Add node pNode to the node hash table. +*/ +static void nodeHashInsert(Rtree *pRtree, RtreeNode *pNode){ + int iHash; + assert( pNode->pNext==0 ); + iHash = nodeHash(pNode->iNode); + pNode->pNext = pRtree->aHash[iHash]; + pRtree->aHash[iHash] = pNode; +} + +/* +** Remove node pNode from the node hash table. +*/ +static void nodeHashDelete(Rtree *pRtree, RtreeNode *pNode){ + RtreeNode **pp; + if( pNode->iNode!=0 ){ + pp = &pRtree->aHash[nodeHash(pNode->iNode)]; + for( ; (*pp)!=pNode; pp = &(*pp)->pNext){ assert(*pp); } + *pp = pNode->pNext; + pNode->pNext = 0; + } +} + +/* +** Allocate and return new r-tree node. Initially, (RtreeNode.iNode==0), +** indicating that node has not yet been assigned a node number. It is +** assigned a node number when nodeWrite() is called to write the +** node contents out to the database. +*/ +static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){ + RtreeNode *pNode; + pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode) + pRtree->iNodeSize); + if( pNode ){ + memset(pNode, 0, sizeof(RtreeNode) + pRtree->iNodeSize); + pNode->zData = (u8 *)&pNode[1]; + pNode->nRef = 1; + pNode->pParent = pParent; + pNode->isDirty = 1; + nodeReference(pParent); + } + return pNode; +} + +/* +** Obtain a reference to an r-tree node. +*/ +static int nodeAcquire( + Rtree *pRtree, /* R-tree structure */ + i64 iNode, /* Node number to load */ + RtreeNode *pParent, /* Either the parent node or NULL */ + RtreeNode **ppNode /* OUT: Acquired node */ +){ + int rc; + int rc2 = SQLITE_OK; + RtreeNode *pNode; + + /* Check if the requested node is already in the hash table. If so, + ** increase its reference count and return it. + */ + if( (pNode = nodeHashLookup(pRtree, iNode)) ){ + assert( !pParent || !pNode->pParent || pNode->pParent==pParent ); + if( pParent && !pNode->pParent ){ + nodeReference(pParent); + pNode->pParent = pParent; + } + pNode->nRef++; + *ppNode = pNode; + return SQLITE_OK; + } + + sqlite3_bind_int64(pRtree->pReadNode, 1, iNode); + rc = sqlite3_step(pRtree->pReadNode); + if( rc==SQLITE_ROW ){ + const u8 *zBlob = sqlite3_column_blob(pRtree->pReadNode, 0); + if( pRtree->iNodeSize==sqlite3_column_bytes(pRtree->pReadNode, 0) ){ + pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode)+pRtree->iNodeSize); + if( !pNode ){ + rc2 = SQLITE_NOMEM; + }else{ + pNode->pParent = pParent; + pNode->zData = (u8 *)&pNode[1]; + pNode->nRef = 1; + pNode->iNode = iNode; + pNode->isDirty = 0; + pNode->pNext = 0; + memcpy(pNode->zData, zBlob, pRtree->iNodeSize); + nodeReference(pParent); + } + } + } + rc = sqlite3_reset(pRtree->pReadNode); + if( rc==SQLITE_OK ) rc = rc2; + + /* If the root node was just loaded, set pRtree->iDepth to the height + ** of the r-tree structure. A height of zero means all data is stored on + ** the root node. A height of one means the children of the root node + ** are the leaves, and so on. If the depth as specified on the root node + ** is greater than RTREE_MAX_DEPTH, the r-tree structure must be corrupt. + */ + if( pNode && iNode==1 ){ + pRtree->iDepth = readInt16(pNode->zData); + if( pRtree->iDepth>RTREE_MAX_DEPTH ){ + rc = SQLITE_CORRUPT_VTAB; + } + } + + /* If no error has occurred so far, check if the "number of entries" + ** field on the node is too large. If so, set the return code to + ** SQLITE_CORRUPT_VTAB. + */ + if( pNode && rc==SQLITE_OK ){ + if( NCELL(pNode)>((pRtree->iNodeSize-4)/pRtree->nBytesPerCell) ){ + rc = SQLITE_CORRUPT_VTAB; + } + } + + if( rc==SQLITE_OK ){ + if( pNode!=0 ){ + nodeHashInsert(pRtree, pNode); + }else{ + rc = SQLITE_CORRUPT_VTAB; + } + *ppNode = pNode; + }else{ + sqlite3_free(pNode); + *ppNode = 0; + } + + return rc; +} + +/* +** Overwrite cell iCell of node pNode with the contents of pCell. +*/ +static void nodeOverwriteCell( + Rtree *pRtree, /* The overall R-Tree */ + RtreeNode *pNode, /* The node into which the cell is to be written */ + RtreeCell *pCell, /* The cell to write */ + int iCell /* Index into pNode into which pCell is written */ +){ + int ii; + u8 *p = &pNode->zData[4 + pRtree->nBytesPerCell*iCell]; + p += writeInt64(p, pCell->iRowid); + for(ii=0; ii<(pRtree->nDim*2); ii++){ + p += writeCoord(p, &pCell->aCoord[ii]); + } + pNode->isDirty = 1; +} + +/* +** Remove the cell with index iCell from node pNode. +*/ +static void nodeDeleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell){ + u8 *pDst = &pNode->zData[4 + pRtree->nBytesPerCell*iCell]; + u8 *pSrc = &pDst[pRtree->nBytesPerCell]; + int nByte = (NCELL(pNode) - iCell - 1) * pRtree->nBytesPerCell; + memmove(pDst, pSrc, nByte); + writeInt16(&pNode->zData[2], NCELL(pNode)-1); + pNode->isDirty = 1; +} + +/* +** Insert the contents of cell pCell into node pNode. If the insert +** is successful, return SQLITE_OK. +** +** If there is not enough free space in pNode, return SQLITE_FULL. +*/ +static int nodeInsertCell( + Rtree *pRtree, /* The overall R-Tree */ + RtreeNode *pNode, /* Write new cell into this node */ + RtreeCell *pCell /* The cell to be inserted */ +){ + int nCell; /* Current number of cells in pNode */ + int nMaxCell; /* Maximum number of cells for pNode */ + + nMaxCell = (pRtree->iNodeSize-4)/pRtree->nBytesPerCell; + nCell = NCELL(pNode); + + assert( nCell<=nMaxCell ); + if( nCellzData[2], nCell+1); + pNode->isDirty = 1; + } + + return (nCell==nMaxCell); +} + +/* +** If the node is dirty, write it out to the database. +*/ +static int nodeWrite(Rtree *pRtree, RtreeNode *pNode){ + int rc = SQLITE_OK; + if( pNode->isDirty ){ + sqlite3_stmt *p = pRtree->pWriteNode; + if( pNode->iNode ){ + sqlite3_bind_int64(p, 1, pNode->iNode); + }else{ + sqlite3_bind_null(p, 1); + } + sqlite3_bind_blob(p, 2, pNode->zData, pRtree->iNodeSize, SQLITE_STATIC); + sqlite3_step(p); + pNode->isDirty = 0; + rc = sqlite3_reset(p); + if( pNode->iNode==0 && rc==SQLITE_OK ){ + pNode->iNode = sqlite3_last_insert_rowid(pRtree->db); + nodeHashInsert(pRtree, pNode); + } + } + return rc; +} + +/* +** Release a reference to a node. If the node is dirty and the reference +** count drops to zero, the node data is written to the database. +*/ +static int nodeRelease(Rtree *pRtree, RtreeNode *pNode){ + int rc = SQLITE_OK; + if( pNode ){ + assert( pNode->nRef>0 ); + pNode->nRef--; + if( pNode->nRef==0 ){ + if( pNode->iNode==1 ){ + pRtree->iDepth = -1; + } + if( pNode->pParent ){ + rc = nodeRelease(pRtree, pNode->pParent); + } + if( rc==SQLITE_OK ){ + rc = nodeWrite(pRtree, pNode); + } + nodeHashDelete(pRtree, pNode); + sqlite3_free(pNode); + } + } + return rc; +} + +/* +** Return the 64-bit integer value associated with cell iCell of +** node pNode. If pNode is a leaf node, this is a rowid. If it is +** an internal node, then the 64-bit integer is a child page number. +*/ +static i64 nodeGetRowid( + Rtree *pRtree, /* The overall R-Tree */ + RtreeNode *pNode, /* The node from which to extract the ID */ + int iCell /* The cell index from which to extract the ID */ +){ + assert( iCellzData[4 + pRtree->nBytesPerCell*iCell]); +} + +/* +** Return coordinate iCoord from cell iCell in node pNode. +*/ +static void nodeGetCoord( + Rtree *pRtree, /* The overall R-Tree */ + RtreeNode *pNode, /* The node from which to extract a coordinate */ + int iCell, /* The index of the cell within the node */ + int iCoord, /* Which coordinate to extract */ + RtreeCoord *pCoord /* OUT: Space to write result to */ +){ + readCoord(&pNode->zData[12 + pRtree->nBytesPerCell*iCell + 4*iCoord], pCoord); +} + +/* +** Deserialize cell iCell of node pNode. Populate the structure pointed +** to by pCell with the results. +*/ +static void nodeGetCell( + Rtree *pRtree, /* The overall R-Tree */ + RtreeNode *pNode, /* The node containing the cell to be read */ + int iCell, /* Index of the cell within the node */ + RtreeCell *pCell /* OUT: Write the cell contents here */ +){ + u8 *pData; + RtreeCoord *pCoord; + int ii; + pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell); + pData = pNode->zData + (12 + pRtree->nBytesPerCell*iCell); + pCoord = pCell->aCoord; + for(ii=0; iinDim*2; ii++){ + readCoord(&pData[ii*4], &pCoord[ii]); + } +} + + +/* Forward declaration for the function that does the work of +** the virtual table module xCreate() and xConnect() methods. +*/ +static int rtreeInit( + sqlite3 *, void *, int, const char *const*, sqlite3_vtab **, char **, int +); + +/* +** Rtree virtual table module xCreate method. +*/ +static int rtreeCreate( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + return rtreeInit(db, pAux, argc, argv, ppVtab, pzErr, 1); +} + +/* +** Rtree virtual table module xConnect method. +*/ +static int rtreeConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + return rtreeInit(db, pAux, argc, argv, ppVtab, pzErr, 0); +} + +/* +** Increment the r-tree reference count. +*/ +static void rtreeReference(Rtree *pRtree){ + pRtree->nBusy++; +} + +/* +** Decrement the r-tree reference count. When the reference count reaches +** zero the structure is deleted. +*/ +static void rtreeRelease(Rtree *pRtree){ + pRtree->nBusy--; + if( pRtree->nBusy==0 ){ + sqlite3_finalize(pRtree->pReadNode); + sqlite3_finalize(pRtree->pWriteNode); + sqlite3_finalize(pRtree->pDeleteNode); + sqlite3_finalize(pRtree->pReadRowid); + sqlite3_finalize(pRtree->pWriteRowid); + sqlite3_finalize(pRtree->pDeleteRowid); + sqlite3_finalize(pRtree->pReadParent); + sqlite3_finalize(pRtree->pWriteParent); + sqlite3_finalize(pRtree->pDeleteParent); + sqlite3_free(pRtree); + } +} + +/* +** Rtree virtual table module xDisconnect method. +*/ +static int rtreeDisconnect(sqlite3_vtab *pVtab){ + rtreeRelease((Rtree *)pVtab); + return SQLITE_OK; +} + +/* +** Rtree virtual table module xDestroy method. +*/ +static int rtreeDestroy(sqlite3_vtab *pVtab){ + Rtree *pRtree = (Rtree *)pVtab; + int rc; + char *zCreate = sqlite3_mprintf( + "DROP TABLE '%q'.'%q_node';" + "DROP TABLE '%q'.'%q_rowid';" + "DROP TABLE '%q'.'%q_parent';", + pRtree->zDb, pRtree->zName, + pRtree->zDb, pRtree->zName, + pRtree->zDb, pRtree->zName + ); + if( !zCreate ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_exec(pRtree->db, zCreate, 0, 0, 0); + sqlite3_free(zCreate); + } + if( rc==SQLITE_OK ){ + rtreeRelease(pRtree); + } + + return rc; +} + +/* +** Rtree virtual table module xOpen method. +*/ +static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ + int rc = SQLITE_NOMEM; + RtreeCursor *pCsr; + + pCsr = (RtreeCursor *)sqlite3_malloc(sizeof(RtreeCursor)); + if( pCsr ){ + memset(pCsr, 0, sizeof(RtreeCursor)); + pCsr->base.pVtab = pVTab; + rc = SQLITE_OK; + } + *ppCursor = (sqlite3_vtab_cursor *)pCsr; + + return rc; +} + + +/* +** Free the RtreeCursor.aConstraint[] array and its contents. +*/ +static void freeCursorConstraints(RtreeCursor *pCsr){ + if( pCsr->aConstraint ){ + int i; /* Used to iterate through constraint array */ + for(i=0; inConstraint; i++){ + sqlite3_rtree_query_info *pInfo = pCsr->aConstraint[i].pInfo; + if( pInfo ){ + if( pInfo->xDelUser ) pInfo->xDelUser(pInfo->pUser); + sqlite3_free(pInfo); + } + } + sqlite3_free(pCsr->aConstraint); + pCsr->aConstraint = 0; + } +} + +/* +** Rtree virtual table module xClose method. +*/ +static int rtreeClose(sqlite3_vtab_cursor *cur){ + Rtree *pRtree = (Rtree *)(cur->pVtab); + int ii; + RtreeCursor *pCsr = (RtreeCursor *)cur; + freeCursorConstraints(pCsr); + sqlite3_free(pCsr->aPoint); + for(ii=0; iiaNode[ii]); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* +** Rtree virtual table module xEof method. +** +** Return non-zero if the cursor does not currently point to a valid +** record (i.e if the scan has finished), or zero otherwise. +*/ +static int rtreeEof(sqlite3_vtab_cursor *cur){ + RtreeCursor *pCsr = (RtreeCursor *)cur; + return pCsr->atEOF; +} + +/* +** Convert raw bits from the on-disk RTree record into a coordinate value. +** The on-disk format is big-endian and needs to be converted for little- +** endian platforms. The on-disk record stores integer coordinates if +** eInt is true and it stores 32-bit floating point records if eInt is +** false. a[] is the four bytes of the on-disk record to be decoded. +** Store the results in "r". +** +** There are three versions of this macro, one each for little-endian and +** big-endian processors and a third generic implementation. The endian- +** specific implementations are much faster and are preferred if the +** processor endianness is known at compile-time. The SQLITE_BYTEORDER +** macro is part of sqliteInt.h and hence the endian-specific +** implementation will only be used if this module is compiled as part +** of the amalgamation. +*/ +#if defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==1234 +#define RTREE_DECODE_COORD(eInt, a, r) { \ + RtreeCoord c; /* Coordinate decoded */ \ + memcpy(&c.u,a,4); \ + c.u = ((c.u>>24)&0xff)|((c.u>>8)&0xff00)| \ + ((c.u&0xff)<<24)|((c.u&0xff00)<<8); \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ +} +#elif defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==4321 +#define RTREE_DECODE_COORD(eInt, a, r) { \ + RtreeCoord c; /* Coordinate decoded */ \ + memcpy(&c.u,a,4); \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ +} +#else +#define RTREE_DECODE_COORD(eInt, a, r) { \ + RtreeCoord c; /* Coordinate decoded */ \ + c.u = ((u32)a[0]<<24) + ((u32)a[1]<<16) \ + +((u32)a[2]<<8) + a[3]; \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ +} +#endif + +/* +** Check the RTree node or entry given by pCellData and p against the MATCH +** constraint pConstraint. +*/ +static int rtreeCallbackConstraint( + RtreeConstraint *pConstraint, /* The constraint to test */ + int eInt, /* True if RTree holding integer coordinates */ + u8 *pCellData, /* Raw cell content */ + RtreeSearchPoint *pSearch, /* Container of this cell */ + sqlite3_rtree_dbl *prScore, /* OUT: score for the cell */ + int *peWithin /* OUT: visibility of the cell */ +){ + int i; /* Loop counter */ + sqlite3_rtree_query_info *pInfo = pConstraint->pInfo; /* Callback info */ + int nCoord = pInfo->nCoord; /* No. of coordinates */ + int rc; /* Callback return code */ + sqlite3_rtree_dbl aCoord[RTREE_MAX_DIMENSIONS*2]; /* Decoded coordinates */ + + assert( pConstraint->op==RTREE_MATCH || pConstraint->op==RTREE_QUERY ); + assert( nCoord==2 || nCoord==4 || nCoord==6 || nCoord==8 || nCoord==10 ); + + if( pConstraint->op==RTREE_QUERY && pSearch->iLevel==1 ){ + pInfo->iRowid = readInt64(pCellData); + } + pCellData += 8; + for(i=0; iop==RTREE_MATCH ){ + rc = pConstraint->u.xGeom((sqlite3_rtree_geometry*)pInfo, + nCoord, aCoord, &i); + if( i==0 ) *peWithin = NOT_WITHIN; + *prScore = RTREE_ZERO; + }else{ + pInfo->aCoord = aCoord; + pInfo->iLevel = pSearch->iLevel - 1; + pInfo->rScore = pInfo->rParentScore = pSearch->rScore; + pInfo->eWithin = pInfo->eParentWithin = pSearch->eWithin; + rc = pConstraint->u.xQueryFunc(pInfo); + if( pInfo->eWithin<*peWithin ) *peWithin = pInfo->eWithin; + if( pInfo->rScore<*prScore || *prScorerScore; + } + } + return rc; +} + +/* +** Check the internal RTree node given by pCellData against constraint p. +** If this constraint cannot be satisfied by any child within the node, +** set *peWithin to NOT_WITHIN. +*/ +static void rtreeNonleafConstraint( + RtreeConstraint *p, /* The constraint to test */ + int eInt, /* True if RTree holds integer coordinates */ + u8 *pCellData, /* Raw cell content as appears on disk */ + int *peWithin /* Adjust downward, as appropriate */ +){ + sqlite3_rtree_dbl val; /* Coordinate value convert to a double */ + + /* p->iCoord might point to either a lower or upper bound coordinate + ** in a coordinate pair. But make pCellData point to the lower bound. + */ + pCellData += 8 + 4*(p->iCoord&0xfe); + + assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE + || p->op==RTREE_GT || p->op==RTREE_EQ ); + switch( p->op ){ + case RTREE_LE: + case RTREE_LT: + case RTREE_EQ: + RTREE_DECODE_COORD(eInt, pCellData, val); + /* val now holds the lower bound of the coordinate pair */ + if( p->u.rValue>=val ) return; + if( p->op!=RTREE_EQ ) break; /* RTREE_LE and RTREE_LT end here */ + /* Fall through for the RTREE_EQ case */ + + default: /* RTREE_GT or RTREE_GE, or fallthrough of RTREE_EQ */ + pCellData += 4; + RTREE_DECODE_COORD(eInt, pCellData, val); + /* val now holds the upper bound of the coordinate pair */ + if( p->u.rValue<=val ) return; + } + *peWithin = NOT_WITHIN; +} + +/* +** Check the leaf RTree cell given by pCellData against constraint p. +** If this constraint is not satisfied, set *peWithin to NOT_WITHIN. +** If the constraint is satisfied, leave *peWithin unchanged. +** +** The constraint is of the form: xN op $val +** +** The op is given by p->op. The xN is p->iCoord-th coordinate in +** pCellData. $val is given by p->u.rValue. +*/ +static void rtreeLeafConstraint( + RtreeConstraint *p, /* The constraint to test */ + int eInt, /* True if RTree holds integer coordinates */ + u8 *pCellData, /* Raw cell content as appears on disk */ + int *peWithin /* Adjust downward, as appropriate */ +){ + RtreeDValue xN; /* Coordinate value converted to a double */ + + assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE + || p->op==RTREE_GT || p->op==RTREE_EQ ); + pCellData += 8 + p->iCoord*4; + RTREE_DECODE_COORD(eInt, pCellData, xN); + switch( p->op ){ + case RTREE_LE: if( xN <= p->u.rValue ) return; break; + case RTREE_LT: if( xN < p->u.rValue ) return; break; + case RTREE_GE: if( xN >= p->u.rValue ) return; break; + case RTREE_GT: if( xN > p->u.rValue ) return; break; + default: if( xN == p->u.rValue ) return; break; + } + *peWithin = NOT_WITHIN; +} + +/* +** One of the cells in node pNode is guaranteed to have a 64-bit +** integer value equal to iRowid. Return the index of this cell. +*/ +static int nodeRowidIndex( + Rtree *pRtree, + RtreeNode *pNode, + i64 iRowid, + int *piIndex +){ + int ii; + int nCell = NCELL(pNode); + assert( nCell<200 ); + for(ii=0; iipParent; + if( pParent ){ + return nodeRowidIndex(pRtree, pParent, pNode->iNode, piIndex); + } + *piIndex = -1; + return SQLITE_OK; +} + +/* +** Compare two search points. Return negative, zero, or positive if the first +** is less than, equal to, or greater than the second. +** +** The rScore is the primary key. Smaller rScore values come first. +** If the rScore is a tie, then use iLevel as the tie breaker with smaller +** iLevel values coming first. In this way, if rScore is the same for all +** SearchPoints, then iLevel becomes the deciding factor and the result +** is a depth-first search, which is the desired default behavior. +*/ +static int rtreeSearchPointCompare( + const RtreeSearchPoint *pA, + const RtreeSearchPoint *pB +){ + if( pA->rScorerScore ) return -1; + if( pA->rScore>pB->rScore ) return +1; + if( pA->iLeveliLevel ) return -1; + if( pA->iLevel>pB->iLevel ) return +1; + return 0; +} + +/* +** Interchange to search points in a cursor. +*/ +static void rtreeSearchPointSwap(RtreeCursor *p, int i, int j){ + RtreeSearchPoint t = p->aPoint[i]; + assert( iaPoint[i] = p->aPoint[j]; + p->aPoint[j] = t; + i++; j++; + if( i=RTREE_CACHE_SZ ){ + nodeRelease(RTREE_OF_CURSOR(p), p->aNode[i]); + p->aNode[i] = 0; + }else{ + RtreeNode *pTemp = p->aNode[i]; + p->aNode[i] = p->aNode[j]; + p->aNode[j] = pTemp; + } + } +} + +/* +** Return the search point with the lowest current score. +*/ +static RtreeSearchPoint *rtreeSearchPointFirst(RtreeCursor *pCur){ + return pCur->bPoint ? &pCur->sPoint : pCur->nPoint ? pCur->aPoint : 0; +} + +/* +** Get the RtreeNode for the search point with the lowest score. +*/ +static RtreeNode *rtreeNodeOfFirstSearchPoint(RtreeCursor *pCur, int *pRC){ + sqlite3_int64 id; + int ii = 1 - pCur->bPoint; + assert( ii==0 || ii==1 ); + assert( pCur->bPoint || pCur->nPoint ); + if( pCur->aNode[ii]==0 ){ + assert( pRC!=0 ); + id = ii ? pCur->aPoint[0].id : pCur->sPoint.id; + *pRC = nodeAcquire(RTREE_OF_CURSOR(pCur), id, 0, &pCur->aNode[ii]); + } + return pCur->aNode[ii]; +} + +/* +** Push a new element onto the priority queue +*/ +static RtreeSearchPoint *rtreeEnqueue( + RtreeCursor *pCur, /* The cursor */ + RtreeDValue rScore, /* Score for the new search point */ + u8 iLevel /* Level for the new search point */ +){ + int i, j; + RtreeSearchPoint *pNew; + if( pCur->nPoint>=pCur->nPointAlloc ){ + int nNew = pCur->nPointAlloc*2 + 8; + pNew = sqlite3_realloc(pCur->aPoint, nNew*sizeof(pCur->aPoint[0])); + if( pNew==0 ) return 0; + pCur->aPoint = pNew; + pCur->nPointAlloc = nNew; + } + i = pCur->nPoint++; + pNew = pCur->aPoint + i; + pNew->rScore = rScore; + pNew->iLevel = iLevel; + assert( iLevel<=RTREE_MAX_DEPTH ); + while( i>0 ){ + RtreeSearchPoint *pParent; + j = (i-1)/2; + pParent = pCur->aPoint + j; + if( rtreeSearchPointCompare(pNew, pParent)>=0 ) break; + rtreeSearchPointSwap(pCur, j, i); + i = j; + pNew = pParent; + } + return pNew; +} + +/* +** Allocate a new RtreeSearchPoint and return a pointer to it. Return +** NULL if malloc fails. +*/ +static RtreeSearchPoint *rtreeSearchPointNew( + RtreeCursor *pCur, /* The cursor */ + RtreeDValue rScore, /* Score for the new search point */ + u8 iLevel /* Level for the new search point */ +){ + RtreeSearchPoint *pNew, *pFirst; + pFirst = rtreeSearchPointFirst(pCur); + pCur->anQueue[iLevel]++; + if( pFirst==0 + || pFirst->rScore>rScore + || (pFirst->rScore==rScore && pFirst->iLevel>iLevel) + ){ + if( pCur->bPoint ){ + int ii; + pNew = rtreeEnqueue(pCur, rScore, iLevel); + if( pNew==0 ) return 0; + ii = (int)(pNew - pCur->aPoint) + 1; + if( iiaNode[ii]==0 ); + pCur->aNode[ii] = pCur->aNode[0]; + }else{ + nodeRelease(RTREE_OF_CURSOR(pCur), pCur->aNode[0]); + } + pCur->aNode[0] = 0; + *pNew = pCur->sPoint; + } + pCur->sPoint.rScore = rScore; + pCur->sPoint.iLevel = iLevel; + pCur->bPoint = 1; + return &pCur->sPoint; + }else{ + return rtreeEnqueue(pCur, rScore, iLevel); + } +} + +#if 0 +/* Tracing routines for the RtreeSearchPoint queue */ +static void tracePoint(RtreeSearchPoint *p, int idx, RtreeCursor *pCur){ + if( idx<0 ){ printf(" s"); }else{ printf("%2d", idx); } + printf(" %d.%05lld.%02d %g %d", + p->iLevel, p->id, p->iCell, p->rScore, p->eWithin + ); + idx++; + if( idxaNode[idx]); + }else{ + printf("\n"); + } +} +static void traceQueue(RtreeCursor *pCur, const char *zPrefix){ + int ii; + printf("=== %9s ", zPrefix); + if( pCur->bPoint ){ + tracePoint(&pCur->sPoint, -1, pCur); + } + for(ii=0; iinPoint; ii++){ + if( ii>0 || pCur->bPoint ) printf(" "); + tracePoint(&pCur->aPoint[ii], ii, pCur); + } +} +# define RTREE_QUEUE_TRACE(A,B) traceQueue(A,B) +#else +# define RTREE_QUEUE_TRACE(A,B) /* no-op */ +#endif + +/* Remove the search point with the lowest current score. +*/ +static void rtreeSearchPointPop(RtreeCursor *p){ + int i, j, k, n; + i = 1 - p->bPoint; + assert( i==0 || i==1 ); + if( p->aNode[i] ){ + nodeRelease(RTREE_OF_CURSOR(p), p->aNode[i]); + p->aNode[i] = 0; + } + if( p->bPoint ){ + p->anQueue[p->sPoint.iLevel]--; + p->bPoint = 0; + }else if( p->nPoint ){ + p->anQueue[p->aPoint[0].iLevel]--; + n = --p->nPoint; + p->aPoint[0] = p->aPoint[n]; + if( naNode[1] = p->aNode[n+1]; + p->aNode[n+1] = 0; + } + i = 0; + while( (j = i*2+1)aPoint[k], &p->aPoint[j])<0 ){ + if( rtreeSearchPointCompare(&p->aPoint[k], &p->aPoint[i])<0 ){ + rtreeSearchPointSwap(p, i, k); + i = k; + }else{ + break; + } + }else{ + if( rtreeSearchPointCompare(&p->aPoint[j], &p->aPoint[i])<0 ){ + rtreeSearchPointSwap(p, i, j); + i = j; + }else{ + break; + } + } + } + } +} + + +/* +** Continue the search on cursor pCur until the front of the queue +** contains an entry suitable for returning as a result-set row, +** or until the RtreeSearchPoint queue is empty, indicating that the +** query has completed. +*/ +static int rtreeStepToLeaf(RtreeCursor *pCur){ + RtreeSearchPoint *p; + Rtree *pRtree = RTREE_OF_CURSOR(pCur); + RtreeNode *pNode; + int eWithin; + int rc = SQLITE_OK; + int nCell; + int nConstraint = pCur->nConstraint; + int ii; + int eInt; + RtreeSearchPoint x; + + eInt = pRtree->eCoordType==RTREE_COORD_INT32; + while( (p = rtreeSearchPointFirst(pCur))!=0 && p->iLevel>0 ){ + pNode = rtreeNodeOfFirstSearchPoint(pCur, &rc); + if( rc ) return rc; + nCell = NCELL(pNode); + assert( nCell<200 ); + while( p->iCellzData + (4+pRtree->nBytesPerCell*p->iCell); + eWithin = FULLY_WITHIN; + for(ii=0; iiaConstraint + ii; + if( pConstraint->op>=RTREE_MATCH ){ + rc = rtreeCallbackConstraint(pConstraint, eInt, pCellData, p, + &rScore, &eWithin); + if( rc ) return rc; + }else if( p->iLevel==1 ){ + rtreeLeafConstraint(pConstraint, eInt, pCellData, &eWithin); + }else{ + rtreeNonleafConstraint(pConstraint, eInt, pCellData, &eWithin); + } + if( eWithin==NOT_WITHIN ) break; + } + p->iCell++; + if( eWithin==NOT_WITHIN ) continue; + x.iLevel = p->iLevel - 1; + if( x.iLevel ){ + x.id = readInt64(pCellData); + x.iCell = 0; + }else{ + x.id = p->id; + x.iCell = p->iCell - 1; + } + if( p->iCell>=nCell ){ + RTREE_QUEUE_TRACE(pCur, "POP-S:"); + rtreeSearchPointPop(pCur); + } + if( rScoreeWithin = eWithin; + p->id = x.id; + p->iCell = x.iCell; + RTREE_QUEUE_TRACE(pCur, "PUSH-S:"); + break; + } + if( p->iCell>=nCell ){ + RTREE_QUEUE_TRACE(pCur, "POP-Se:"); + rtreeSearchPointPop(pCur); + } + } + pCur->atEOF = p==0; + return SQLITE_OK; +} + +/* +** Rtree virtual table module xNext method. +*/ +static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){ + RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; + int rc = SQLITE_OK; + + /* Move to the next entry that matches the configured constraints. */ + RTREE_QUEUE_TRACE(pCsr, "POP-Nx:"); + rtreeSearchPointPop(pCsr); + rc = rtreeStepToLeaf(pCsr); + return rc; +} + +/* +** Rtree virtual table module xRowid method. +*/ +static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){ + RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; + RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); + int rc = SQLITE_OK; + RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); + if( rc==SQLITE_OK && p ){ + *pRowid = nodeGetRowid(RTREE_OF_CURSOR(pCsr), pNode, p->iCell); + } + return rc; +} + +/* +** Rtree virtual table module xColumn method. +*/ +static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ + Rtree *pRtree = (Rtree *)cur->pVtab; + RtreeCursor *pCsr = (RtreeCursor *)cur; + RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); + RtreeCoord c; + int rc = SQLITE_OK; + RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); + + if( rc ) return rc; + if( p==0 ) return SQLITE_OK; + if( i==0 ){ + sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell)); + }else{ + if( rc ) return rc; + nodeGetCoord(pRtree, pNode, p->iCell, i-1, &c); +#ifndef SQLITE_RTREE_INT_ONLY + if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ + sqlite3_result_double(ctx, c.f); + }else +#endif + { + assert( pRtree->eCoordType==RTREE_COORD_INT32 ); + sqlite3_result_int(ctx, c.i); + } + } + return SQLITE_OK; +} + +/* +** Use nodeAcquire() to obtain the leaf node containing the record with +** rowid iRowid. If successful, set *ppLeaf to point to the node and +** return SQLITE_OK. If there is no such record in the table, set +** *ppLeaf to 0 and return SQLITE_OK. If an error occurs, set *ppLeaf +** to zero and return an SQLite error code. +*/ +static int findLeafNode( + Rtree *pRtree, /* RTree to search */ + i64 iRowid, /* The rowid searching for */ + RtreeNode **ppLeaf, /* Write the node here */ + sqlite3_int64 *piNode /* Write the node-id here */ +){ + int rc; + *ppLeaf = 0; + sqlite3_bind_int64(pRtree->pReadRowid, 1, iRowid); + if( sqlite3_step(pRtree->pReadRowid)==SQLITE_ROW ){ + i64 iNode = sqlite3_column_int64(pRtree->pReadRowid, 0); + if( piNode ) *piNode = iNode; + rc = nodeAcquire(pRtree, iNode, 0, ppLeaf); + sqlite3_reset(pRtree->pReadRowid); + }else{ + rc = sqlite3_reset(pRtree->pReadRowid); + } + return rc; +} + +/* +** This function is called to configure the RtreeConstraint object passed +** as the second argument for a MATCH constraint. The value passed as the +** first argument to this function is the right-hand operand to the MATCH +** operator. +*/ +static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ + RtreeMatchArg *pBlob; /* BLOB returned by geometry function */ + sqlite3_rtree_query_info *pInfo; /* Callback information */ + int nBlob; /* Size of the geometry function blob */ + int nExpected; /* Expected size of the BLOB */ + + /* Check that value is actually a blob. */ + if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR; + + /* Check that the blob is roughly the right size. */ + nBlob = sqlite3_value_bytes(pValue); + if( nBlob<(int)sizeof(RtreeMatchArg) + || ((nBlob-sizeof(RtreeMatchArg))%sizeof(RtreeDValue))!=0 + ){ + return SQLITE_ERROR; + } + + pInfo = (sqlite3_rtree_query_info*)sqlite3_malloc( sizeof(*pInfo)+nBlob ); + if( !pInfo ) return SQLITE_NOMEM; + memset(pInfo, 0, sizeof(*pInfo)); + pBlob = (RtreeMatchArg*)&pInfo[1]; + + memcpy(pBlob, sqlite3_value_blob(pValue), nBlob); + nExpected = (int)(sizeof(RtreeMatchArg) + + (pBlob->nParam-1)*sizeof(RtreeDValue)); + if( pBlob->magic!=RTREE_GEOMETRY_MAGIC || nBlob!=nExpected ){ + sqlite3_free(pInfo); + return SQLITE_ERROR; + } + pInfo->pContext = pBlob->cb.pContext; + pInfo->nParam = pBlob->nParam; + pInfo->aParam = pBlob->aParam; + + if( pBlob->cb.xGeom ){ + pCons->u.xGeom = pBlob->cb.xGeom; + }else{ + pCons->op = RTREE_QUERY; + pCons->u.xQueryFunc = pBlob->cb.xQueryFunc; + } + pCons->pInfo = pInfo; + return SQLITE_OK; +} + +/* +** Rtree virtual table module xFilter method. +*/ +static int rtreeFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; + RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; + RtreeNode *pRoot = 0; + int ii; + int rc = SQLITE_OK; + int iCell = 0; + + rtreeReference(pRtree); + + /* Reset the cursor to the same state as rtreeOpen() leaves it in. */ + freeCursorConstraints(pCsr); + sqlite3_free(pCsr->aPoint); + memset(pCsr, 0, sizeof(RtreeCursor)); + pCsr->base.pVtab = (sqlite3_vtab*)pRtree; + + pCsr->iStrategy = idxNum; + if( idxNum==1 ){ + /* Special case - lookup by rowid. */ + RtreeNode *pLeaf; /* Leaf on which the required cell resides */ + RtreeSearchPoint *p; /* Search point for the the leaf */ + i64 iRowid = sqlite3_value_int64(argv[0]); + i64 iNode = 0; + rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); + if( rc==SQLITE_OK && pLeaf!=0 ){ + p = rtreeSearchPointNew(pCsr, RTREE_ZERO, 0); + assert( p!=0 ); /* Always returns pCsr->sPoint */ + pCsr->aNode[0] = pLeaf; + p->id = iNode; + p->eWithin = PARTLY_WITHIN; + rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell); + p->iCell = iCell; + RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:"); + }else{ + pCsr->atEOF = 1; + } + }else{ + /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array + ** with the configured constraints. + */ + rc = nodeAcquire(pRtree, 1, 0, &pRoot); + if( rc==SQLITE_OK && argc>0 ){ + pCsr->aConstraint = sqlite3_malloc(sizeof(RtreeConstraint)*argc); + pCsr->nConstraint = argc; + if( !pCsr->aConstraint ){ + rc = SQLITE_NOMEM; + }else{ + memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*argc); + memset(pCsr->anQueue, 0, sizeof(u32)*(pRtree->iDepth + 1)); + assert( (idxStr==0 && argc==0) + || (idxStr && (int)strlen(idxStr)==argc*2) ); + for(ii=0; iiaConstraint[ii]; + p->op = idxStr[ii*2]; + p->iCoord = idxStr[ii*2+1]-'0'; + if( p->op>=RTREE_MATCH ){ + /* A MATCH operator. The right-hand-side must be a blob that + ** can be cast into an RtreeMatchArg object. One created using + ** an sqlite3_rtree_geometry_callback() SQL user function. + */ + rc = deserializeGeometry(argv[ii], p); + if( rc!=SQLITE_OK ){ + break; + } + p->pInfo->nCoord = pRtree->nDim*2; + p->pInfo->anQueue = pCsr->anQueue; + p->pInfo->mxLevel = pRtree->iDepth + 1; + }else{ +#ifdef SQLITE_RTREE_INT_ONLY + p->u.rValue = sqlite3_value_int64(argv[ii]); +#else + p->u.rValue = sqlite3_value_double(argv[ii]); +#endif + } + } + } + } + if( rc==SQLITE_OK ){ + RtreeSearchPoint *pNew; + pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, pRtree->iDepth+1); + if( pNew==0 ) return SQLITE_NOMEM; + pNew->id = 1; + pNew->iCell = 0; + pNew->eWithin = PARTLY_WITHIN; + assert( pCsr->bPoint==1 ); + pCsr->aNode[0] = pRoot; + pRoot = 0; + RTREE_QUEUE_TRACE(pCsr, "PUSH-Fm:"); + rc = rtreeStepToLeaf(pCsr); + } + } + + nodeRelease(pRtree, pRoot); + rtreeRelease(pRtree); + return rc; +} + +/* +** Set the pIdxInfo->estimatedRows variable to nRow. Unless this +** extension is currently being used by a version of SQLite too old to +** support estimatedRows. In that case this function is a no-op. +*/ +static void setEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){ +#if SQLITE_VERSION_NUMBER>=3008002 + if( sqlite3_libversion_number()>=3008002 ){ + pIdxInfo->estimatedRows = nRow; + } +#endif +} + +/* +** Rtree virtual table module xBestIndex method. There are three +** table scan strategies to choose from (in order from most to +** least desirable): +** +** idxNum idxStr Strategy +** ------------------------------------------------ +** 1 Unused Direct lookup by rowid. +** 2 See below R-tree query or full-table scan. +** ------------------------------------------------ +** +** If strategy 1 is used, then idxStr is not meaningful. If strategy +** 2 is used, idxStr is formatted to contain 2 bytes for each +** constraint used. The first two bytes of idxStr correspond to +** the constraint in sqlite3_index_info.aConstraintUsage[] with +** (argvIndex==1) etc. +** +** The first of each pair of bytes in idxStr identifies the constraint +** operator as follows: +** +** Operator Byte Value +** ---------------------- +** = 0x41 ('A') +** <= 0x42 ('B') +** < 0x43 ('C') +** >= 0x44 ('D') +** > 0x45 ('E') +** MATCH 0x46 ('F') +** ---------------------- +** +** The second of each pair of bytes identifies the coordinate column +** to which the constraint applies. The leftmost coordinate column +** is 'a', the second from the left 'b' etc. +*/ +static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ + Rtree *pRtree = (Rtree*)tab; + int rc = SQLITE_OK; + int ii; + i64 nRow; /* Estimated rows returned by this scan */ + + int iIdx = 0; + char zIdxStr[RTREE_MAX_DIMENSIONS*8+1]; + memset(zIdxStr, 0, sizeof(zIdxStr)); + + assert( pIdxInfo->idxStr==0 ); + for(ii=0; iinConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){ + struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; + + if( p->usable && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ + /* We have an equality constraint on the rowid. Use strategy 1. */ + int jj; + for(jj=0; jjaConstraintUsage[jj].argvIndex = 0; + pIdxInfo->aConstraintUsage[jj].omit = 0; + } + pIdxInfo->idxNum = 1; + pIdxInfo->aConstraintUsage[ii].argvIndex = 1; + pIdxInfo->aConstraintUsage[jj].omit = 1; + + /* This strategy involves a two rowid lookups on an B-Tree structures + ** and then a linear search of an R-Tree node. This should be + ** considered almost as quick as a direct rowid lookup (for which + ** sqlite uses an internal cost of 0.0). It is expected to return + ** a single row. + */ + pIdxInfo->estimatedCost = 30.0; + setEstimatedRows(pIdxInfo, 1); + return SQLITE_OK; + } + + if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){ + u8 op; + switch( p->op ){ + case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break; + case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break; + case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break; + case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break; + case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break; + default: + assert( p->op==SQLITE_INDEX_CONSTRAINT_MATCH ); + op = RTREE_MATCH; + break; + } + zIdxStr[iIdx++] = op; + zIdxStr[iIdx++] = p->iColumn - 1 + '0'; + pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); + pIdxInfo->aConstraintUsage[ii].omit = 1; + } + } + + pIdxInfo->idxNum = 2; + pIdxInfo->needToFreeIdxStr = 1; + if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){ + return SQLITE_NOMEM; + } + + nRow = pRtree->nRowEst / (iIdx + 1); + pIdxInfo->estimatedCost = (double)6.0 * (double)nRow; + setEstimatedRows(pIdxInfo, nRow); + + return rc; +} + +/* +** Return the N-dimensional volumn of the cell stored in *p. +*/ +static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){ + RtreeDValue area = (RtreeDValue)1; + int ii; + for(ii=0; ii<(pRtree->nDim*2); ii+=2){ + area = (area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]))); + } + return area; +} + +/* +** Return the margin length of cell p. The margin length is the sum +** of the objects size in each dimension. +*/ +static RtreeDValue cellMargin(Rtree *pRtree, RtreeCell *p){ + RtreeDValue margin = (RtreeDValue)0; + int ii; + for(ii=0; ii<(pRtree->nDim*2); ii+=2){ + margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])); + } + return margin; +} + +/* +** Store the union of cells p1 and p2 in p1. +*/ +static void cellUnion(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){ + int ii; + if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ + for(ii=0; ii<(pRtree->nDim*2); ii+=2){ + p1->aCoord[ii].f = MIN(p1->aCoord[ii].f, p2->aCoord[ii].f); + p1->aCoord[ii+1].f = MAX(p1->aCoord[ii+1].f, p2->aCoord[ii+1].f); + } + }else{ + for(ii=0; ii<(pRtree->nDim*2); ii+=2){ + p1->aCoord[ii].i = MIN(p1->aCoord[ii].i, p2->aCoord[ii].i); + p1->aCoord[ii+1].i = MAX(p1->aCoord[ii+1].i, p2->aCoord[ii+1].i); + } + } +} + +/* +** Return true if the area covered by p2 is a subset of the area covered +** by p1. False otherwise. +*/ +static int cellContains(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){ + int ii; + int isInt = (pRtree->eCoordType==RTREE_COORD_INT32); + for(ii=0; ii<(pRtree->nDim*2); ii+=2){ + RtreeCoord *a1 = &p1->aCoord[ii]; + RtreeCoord *a2 = &p2->aCoord[ii]; + if( (!isInt && (a2[0].fa1[1].f)) + || ( isInt && (a2[0].ia1[1].i)) + ){ + return 0; + } + } + return 1; +} + +/* +** Return the amount cell p would grow by if it were unioned with pCell. +*/ +static RtreeDValue cellGrowth(Rtree *pRtree, RtreeCell *p, RtreeCell *pCell){ + RtreeDValue area; + RtreeCell cell; + memcpy(&cell, p, sizeof(RtreeCell)); + area = cellArea(pRtree, &cell); + cellUnion(pRtree, &cell, pCell); + return (cellArea(pRtree, &cell)-area); +} + +static RtreeDValue cellOverlap( + Rtree *pRtree, + RtreeCell *p, + RtreeCell *aCell, + int nCell +){ + int ii; + RtreeDValue overlap = RTREE_ZERO; + for(ii=0; iinDim*2); jj+=2){ + RtreeDValue x1, x2; + x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj])); + x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1])); + if( x2iDepth-iHeight); ii++){ + int iCell; + sqlite3_int64 iBest = 0; + + RtreeDValue fMinGrowth = RTREE_ZERO; + RtreeDValue fMinArea = RTREE_ZERO; + + int nCell = NCELL(pNode); + RtreeCell cell; + RtreeNode *pChild; + + RtreeCell *aCell = 0; + + /* Select the child node which will be enlarged the least if pCell + ** is inserted into it. Resolve ties by choosing the entry with + ** the smallest area. + */ + for(iCell=0; iCellpParent ){ + RtreeNode *pParent = p->pParent; + RtreeCell cell; + int iCell; + + if( nodeParentIndex(pRtree, p, &iCell) ){ + return SQLITE_CORRUPT_VTAB; + } + + nodeGetCell(pRtree, pParent, iCell, &cell); + if( !cellContains(pRtree, &cell, pCell) ){ + cellUnion(pRtree, &cell, pCell); + nodeOverwriteCell(pRtree, pParent, &cell, iCell); + } + + p = pParent; + } + return SQLITE_OK; +} + +/* +** Write mapping (iRowid->iNode) to the _rowid table. +*/ +static int rowidWrite(Rtree *pRtree, sqlite3_int64 iRowid, sqlite3_int64 iNode){ + sqlite3_bind_int64(pRtree->pWriteRowid, 1, iRowid); + sqlite3_bind_int64(pRtree->pWriteRowid, 2, iNode); + sqlite3_step(pRtree->pWriteRowid); + return sqlite3_reset(pRtree->pWriteRowid); +} + +/* +** Write mapping (iNode->iPar) to the _parent table. +*/ +static int parentWrite(Rtree *pRtree, sqlite3_int64 iNode, sqlite3_int64 iPar){ + sqlite3_bind_int64(pRtree->pWriteParent, 1, iNode); + sqlite3_bind_int64(pRtree->pWriteParent, 2, iPar); + sqlite3_step(pRtree->pWriteParent); + return sqlite3_reset(pRtree->pWriteParent); +} + +static int rtreeInsertCell(Rtree *, RtreeNode *, RtreeCell *, int); + + +/* +** Arguments aIdx, aDistance and aSpare all point to arrays of size +** nIdx. The aIdx array contains the set of integers from 0 to +** (nIdx-1) in no particular order. This function sorts the values +** in aIdx according to the indexed values in aDistance. For +** example, assuming the inputs: +** +** aIdx = { 0, 1, 2, 3 } +** aDistance = { 5.0, 2.0, 7.0, 6.0 } +** +** this function sets the aIdx array to contain: +** +** aIdx = { 0, 1, 2, 3 } +** +** The aSpare array is used as temporary working space by the +** sorting algorithm. +*/ +static void SortByDistance( + int *aIdx, + int nIdx, + RtreeDValue *aDistance, + int *aSpare +){ + if( nIdx>1 ){ + int iLeft = 0; + int iRight = 0; + + int nLeft = nIdx/2; + int nRight = nIdx-nLeft; + int *aLeft = aIdx; + int *aRight = &aIdx[nLeft]; + + SortByDistance(aLeft, nLeft, aDistance, aSpare); + SortByDistance(aRight, nRight, aDistance, aSpare); + + memcpy(aSpare, aLeft, sizeof(int)*nLeft); + aLeft = aSpare; + + while( iLeft1 ){ + + int iLeft = 0; + int iRight = 0; + + int nLeft = nIdx/2; + int nRight = nIdx-nLeft; + int *aLeft = aIdx; + int *aRight = &aIdx[nLeft]; + + SortByDimension(pRtree, aLeft, nLeft, iDim, aCell, aSpare); + SortByDimension(pRtree, aRight, nRight, iDim, aCell, aSpare); + + memcpy(aSpare, aLeft, sizeof(int)*nLeft); + aLeft = aSpare; + while( iLeftnDim+1)*(sizeof(int*)+nCell*sizeof(int)); + + aaSorted = (int **)sqlite3_malloc(nByte); + if( !aaSorted ){ + return SQLITE_NOMEM; + } + + aSpare = &((int *)&aaSorted[pRtree->nDim])[pRtree->nDim*nCell]; + memset(aaSorted, 0, nByte); + for(ii=0; iinDim; ii++){ + int jj; + aaSorted[ii] = &((int *)&aaSorted[pRtree->nDim])[ii*nCell]; + for(jj=0; jjnDim; ii++){ + RtreeDValue margin = RTREE_ZERO; + RtreeDValue fBestOverlap = RTREE_ZERO; + RtreeDValue fBestArea = RTREE_ZERO; + int iBestLeft = 0; + int nLeft; + + for( + nLeft=RTREE_MINCELLS(pRtree); + nLeft<=(nCell-RTREE_MINCELLS(pRtree)); + nLeft++ + ){ + RtreeCell left; + RtreeCell right; + int kk; + RtreeDValue overlap; + RtreeDValue area; + + memcpy(&left, &aCell[aaSorted[ii][0]], sizeof(RtreeCell)); + memcpy(&right, &aCell[aaSorted[ii][nCell-1]], sizeof(RtreeCell)); + for(kk=1; kk<(nCell-1); kk++){ + if( kk0 ){ + RtreeNode *pChild = nodeHashLookup(pRtree, iRowid); + if( pChild ){ + nodeRelease(pRtree, pChild->pParent); + nodeReference(pNode); + pChild->pParent = pNode; + } + } + return xSetMapping(pRtree, iRowid, pNode->iNode); +} + +static int SplitNode( + Rtree *pRtree, + RtreeNode *pNode, + RtreeCell *pCell, + int iHeight +){ + int i; + int newCellIsRight = 0; + + int rc = SQLITE_OK; + int nCell = NCELL(pNode); + RtreeCell *aCell; + int *aiUsed; + + RtreeNode *pLeft = 0; + RtreeNode *pRight = 0; + + RtreeCell leftbbox; + RtreeCell rightbbox; + + /* Allocate an array and populate it with a copy of pCell and + ** all cells from node pLeft. Then zero the original node. + */ + aCell = sqlite3_malloc((sizeof(RtreeCell)+sizeof(int))*(nCell+1)); + if( !aCell ){ + rc = SQLITE_NOMEM; + goto splitnode_out; + } + aiUsed = (int *)&aCell[nCell+1]; + memset(aiUsed, 0, sizeof(int)*(nCell+1)); + for(i=0; iiNode==1 ){ + pRight = nodeNew(pRtree, pNode); + pLeft = nodeNew(pRtree, pNode); + pRtree->iDepth++; + pNode->isDirty = 1; + writeInt16(pNode->zData, pRtree->iDepth); + }else{ + pLeft = pNode; + pRight = nodeNew(pRtree, pLeft->pParent); + nodeReference(pLeft); + } + + if( !pLeft || !pRight ){ + rc = SQLITE_NOMEM; + goto splitnode_out; + } + + memset(pLeft->zData, 0, pRtree->iNodeSize); + memset(pRight->zData, 0, pRtree->iNodeSize); + + rc = splitNodeStartree(pRtree, aCell, nCell, pLeft, pRight, + &leftbbox, &rightbbox); + if( rc!=SQLITE_OK ){ + goto splitnode_out; + } + + /* Ensure both child nodes have node numbers assigned to them by calling + ** nodeWrite(). Node pRight always needs a node number, as it was created + ** by nodeNew() above. But node pLeft sometimes already has a node number. + ** In this case avoid the all to nodeWrite(). + */ + if( SQLITE_OK!=(rc = nodeWrite(pRtree, pRight)) + || (0==pLeft->iNode && SQLITE_OK!=(rc = nodeWrite(pRtree, pLeft))) + ){ + goto splitnode_out; + } + + rightbbox.iRowid = pRight->iNode; + leftbbox.iRowid = pLeft->iNode; + + if( pNode->iNode==1 ){ + rc = rtreeInsertCell(pRtree, pLeft->pParent, &leftbbox, iHeight+1); + if( rc!=SQLITE_OK ){ + goto splitnode_out; + } + }else{ + RtreeNode *pParent = pLeft->pParent; + int iCell; + rc = nodeParentIndex(pRtree, pLeft, &iCell); + if( rc==SQLITE_OK ){ + nodeOverwriteCell(pRtree, pParent, &leftbbox, iCell); + rc = AdjustTree(pRtree, pParent, &leftbbox); + } + if( rc!=SQLITE_OK ){ + goto splitnode_out; + } + } + if( (rc = rtreeInsertCell(pRtree, pRight->pParent, &rightbbox, iHeight+1)) ){ + goto splitnode_out; + } + + for(i=0; iiRowid ){ + newCellIsRight = 1; + } + if( rc!=SQLITE_OK ){ + goto splitnode_out; + } + } + if( pNode->iNode==1 ){ + for(i=0; iiRowid, pLeft, iHeight); + } + + if( rc==SQLITE_OK ){ + rc = nodeRelease(pRtree, pRight); + pRight = 0; + } + if( rc==SQLITE_OK ){ + rc = nodeRelease(pRtree, pLeft); + pLeft = 0; + } + +splitnode_out: + nodeRelease(pRtree, pRight); + nodeRelease(pRtree, pLeft); + sqlite3_free(aCell); + return rc; +} + +/* +** If node pLeaf is not the root of the r-tree and its pParent pointer is +** still NULL, load all ancestor nodes of pLeaf into memory and populate +** the pLeaf->pParent chain all the way up to the root node. +** +** This operation is required when a row is deleted (or updated - an update +** is implemented as a delete followed by an insert). SQLite provides the +** rowid of the row to delete, which can be used to find the leaf on which +** the entry resides (argument pLeaf). Once the leaf is located, this +** function is called to determine its ancestry. +*/ +static int fixLeafParent(Rtree *pRtree, RtreeNode *pLeaf){ + int rc = SQLITE_OK; + RtreeNode *pChild = pLeaf; + while( rc==SQLITE_OK && pChild->iNode!=1 && pChild->pParent==0 ){ + int rc2 = SQLITE_OK; /* sqlite3_reset() return code */ + sqlite3_bind_int64(pRtree->pReadParent, 1, pChild->iNode); + rc = sqlite3_step(pRtree->pReadParent); + if( rc==SQLITE_ROW ){ + RtreeNode *pTest; /* Used to test for reference loops */ + i64 iNode; /* Node number of parent node */ + + /* Before setting pChild->pParent, test that we are not creating a + ** loop of references (as we would if, say, pChild==pParent). We don't + ** want to do this as it leads to a memory leak when trying to delete + ** the referenced counted node structures. + */ + iNode = sqlite3_column_int64(pRtree->pReadParent, 0); + for(pTest=pLeaf; pTest && pTest->iNode!=iNode; pTest=pTest->pParent); + if( !pTest ){ + rc2 = nodeAcquire(pRtree, iNode, 0, &pChild->pParent); + } + } + rc = sqlite3_reset(pRtree->pReadParent); + if( rc==SQLITE_OK ) rc = rc2; + if( rc==SQLITE_OK && !pChild->pParent ) rc = SQLITE_CORRUPT_VTAB; + pChild = pChild->pParent; + } + return rc; +} + +static int deleteCell(Rtree *, RtreeNode *, int, int); + +static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){ + int rc; + int rc2; + RtreeNode *pParent = 0; + int iCell; + + assert( pNode->nRef==1 ); + + /* Remove the entry in the parent cell. */ + rc = nodeParentIndex(pRtree, pNode, &iCell); + if( rc==SQLITE_OK ){ + pParent = pNode->pParent; + pNode->pParent = 0; + rc = deleteCell(pRtree, pParent, iCell, iHeight+1); + } + rc2 = nodeRelease(pRtree, pParent); + if( rc==SQLITE_OK ){ + rc = rc2; + } + if( rc!=SQLITE_OK ){ + return rc; + } + + /* Remove the xxx_node entry. */ + sqlite3_bind_int64(pRtree->pDeleteNode, 1, pNode->iNode); + sqlite3_step(pRtree->pDeleteNode); + if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteNode)) ){ + return rc; + } + + /* Remove the xxx_parent entry. */ + sqlite3_bind_int64(pRtree->pDeleteParent, 1, pNode->iNode); + sqlite3_step(pRtree->pDeleteParent); + if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteParent)) ){ + return rc; + } + + /* Remove the node from the in-memory hash table and link it into + ** the Rtree.pDeleted list. Its contents will be re-inserted later on. + */ + nodeHashDelete(pRtree, pNode); + pNode->iNode = iHeight; + pNode->pNext = pRtree->pDeleted; + pNode->nRef++; + pRtree->pDeleted = pNode; + + return SQLITE_OK; +} + +static int fixBoundingBox(Rtree *pRtree, RtreeNode *pNode){ + RtreeNode *pParent = pNode->pParent; + int rc = SQLITE_OK; + if( pParent ){ + int ii; + int nCell = NCELL(pNode); + RtreeCell box; /* Bounding box for pNode */ + nodeGetCell(pRtree, pNode, 0, &box); + for(ii=1; iiiNode; + rc = nodeParentIndex(pRtree, pNode, &ii); + if( rc==SQLITE_OK ){ + nodeOverwriteCell(pRtree, pParent, &box, ii); + rc = fixBoundingBox(pRtree, pParent); + } + } + return rc; +} + +/* +** Delete the cell at index iCell of node pNode. After removing the +** cell, adjust the r-tree data structure if required. +*/ +static int deleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell, int iHeight){ + RtreeNode *pParent; + int rc; + + if( SQLITE_OK!=(rc = fixLeafParent(pRtree, pNode)) ){ + return rc; + } + + /* Remove the cell from the node. This call just moves bytes around + ** the in-memory node image, so it cannot fail. + */ + nodeDeleteCell(pRtree, pNode, iCell); + + /* If the node is not the tree root and now has less than the minimum + ** number of cells, remove it from the tree. Otherwise, update the + ** cell in the parent node so that it tightly contains the updated + ** node. + */ + pParent = pNode->pParent; + assert( pParent || pNode->iNode==1 ); + if( pParent ){ + if( NCELL(pNode)nDim; iDim++){ + aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2]); + aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2+1]); + } + } + for(iDim=0; iDimnDim; iDim++){ + aCenterCoord[iDim] = (aCenterCoord[iDim]/(nCell*(RtreeDValue)2)); + } + + for(ii=0; iinDim; iDim++){ + RtreeDValue coord = (DCOORD(aCell[ii].aCoord[iDim*2+1]) - + DCOORD(aCell[ii].aCoord[iDim*2])); + aDistance[ii] += (coord-aCenterCoord[iDim])*(coord-aCenterCoord[iDim]); + } + } + + SortByDistance(aOrder, nCell, aDistance, aSpare); + nodeZero(pRtree, pNode); + + for(ii=0; rc==SQLITE_OK && ii<(nCell-(RTREE_MINCELLS(pRtree)+1)); ii++){ + RtreeCell *p = &aCell[aOrder[ii]]; + nodeInsertCell(pRtree, pNode, p); + if( p->iRowid==pCell->iRowid ){ + if( iHeight==0 ){ + rc = rowidWrite(pRtree, p->iRowid, pNode->iNode); + }else{ + rc = parentWrite(pRtree, p->iRowid, pNode->iNode); + } + } + } + if( rc==SQLITE_OK ){ + rc = fixBoundingBox(pRtree, pNode); + } + for(; rc==SQLITE_OK && iiiNode currently contains + ** the height of the sub-tree headed by the cell. + */ + RtreeNode *pInsert; + RtreeCell *p = &aCell[aOrder[ii]]; + rc = ChooseLeaf(pRtree, p, iHeight, &pInsert); + if( rc==SQLITE_OK ){ + int rc2; + rc = rtreeInsertCell(pRtree, pInsert, p, iHeight); + rc2 = nodeRelease(pRtree, pInsert); + if( rc==SQLITE_OK ){ + rc = rc2; + } + } + } + + sqlite3_free(aCell); + return rc; +} + +/* +** Insert cell pCell into node pNode. Node pNode is the head of a +** subtree iHeight high (leaf nodes have iHeight==0). +*/ +static int rtreeInsertCell( + Rtree *pRtree, + RtreeNode *pNode, + RtreeCell *pCell, + int iHeight +){ + int rc = SQLITE_OK; + if( iHeight>0 ){ + RtreeNode *pChild = nodeHashLookup(pRtree, pCell->iRowid); + if( pChild ){ + nodeRelease(pRtree, pChild->pParent); + nodeReference(pNode); + pChild->pParent = pNode; + } + } + if( nodeInsertCell(pRtree, pNode, pCell) ){ + if( iHeight<=pRtree->iReinsertHeight || pNode->iNode==1){ + rc = SplitNode(pRtree, pNode, pCell, iHeight); + }else{ + pRtree->iReinsertHeight = iHeight; + rc = Reinsert(pRtree, pNode, pCell, iHeight); + } + }else{ + rc = AdjustTree(pRtree, pNode, pCell); + if( rc==SQLITE_OK ){ + if( iHeight==0 ){ + rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode); + }else{ + rc = parentWrite(pRtree, pCell->iRowid, pNode->iNode); + } + } + } + return rc; +} + +static int reinsertNodeContent(Rtree *pRtree, RtreeNode *pNode){ + int ii; + int rc = SQLITE_OK; + int nCell = NCELL(pNode); + + for(ii=0; rc==SQLITE_OK && iiiNode currently contains + ** the height of the sub-tree headed by the cell. + */ + rc = ChooseLeaf(pRtree, &cell, (int)pNode->iNode, &pInsert); + if( rc==SQLITE_OK ){ + int rc2; + rc = rtreeInsertCell(pRtree, pInsert, &cell, (int)pNode->iNode); + rc2 = nodeRelease(pRtree, pInsert); + if( rc==SQLITE_OK ){ + rc = rc2; + } + } + } + return rc; +} + +/* +** Select a currently unused rowid for a new r-tree record. +*/ +static int newRowid(Rtree *pRtree, i64 *piRowid){ + int rc; + sqlite3_bind_null(pRtree->pWriteRowid, 1); + sqlite3_bind_null(pRtree->pWriteRowid, 2); + sqlite3_step(pRtree->pWriteRowid); + rc = sqlite3_reset(pRtree->pWriteRowid); + *piRowid = sqlite3_last_insert_rowid(pRtree->db); + return rc; +} + +/* +** Remove the entry with rowid=iDelete from the r-tree structure. +*/ +static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){ + int rc; /* Return code */ + RtreeNode *pLeaf = 0; /* Leaf node containing record iDelete */ + int iCell; /* Index of iDelete cell in pLeaf */ + RtreeNode *pRoot; /* Root node of rtree structure */ + + + /* Obtain a reference to the root node to initialize Rtree.iDepth */ + rc = nodeAcquire(pRtree, 1, 0, &pRoot); + + /* Obtain a reference to the leaf node that contains the entry + ** about to be deleted. + */ + if( rc==SQLITE_OK ){ + rc = findLeafNode(pRtree, iDelete, &pLeaf, 0); + } + + /* Delete the cell in question from the leaf node. */ + if( rc==SQLITE_OK ){ + int rc2; + rc = nodeRowidIndex(pRtree, pLeaf, iDelete, &iCell); + if( rc==SQLITE_OK ){ + rc = deleteCell(pRtree, pLeaf, iCell, 0); + } + rc2 = nodeRelease(pRtree, pLeaf); + if( rc==SQLITE_OK ){ + rc = rc2; + } + } + + /* Delete the corresponding entry in the _rowid table. */ + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pRtree->pDeleteRowid, 1, iDelete); + sqlite3_step(pRtree->pDeleteRowid); + rc = sqlite3_reset(pRtree->pDeleteRowid); + } + + /* Check if the root node now has exactly one child. If so, remove + ** it, schedule the contents of the child for reinsertion and + ** reduce the tree height by one. + ** + ** This is equivalent to copying the contents of the child into + ** the root node (the operation that Gutman's paper says to perform + ** in this scenario). + */ + if( rc==SQLITE_OK && pRtree->iDepth>0 && NCELL(pRoot)==1 ){ + int rc2; + RtreeNode *pChild; + i64 iChild = nodeGetRowid(pRtree, pRoot, 0); + rc = nodeAcquire(pRtree, iChild, pRoot, &pChild); + if( rc==SQLITE_OK ){ + rc = removeNode(pRtree, pChild, pRtree->iDepth-1); + } + rc2 = nodeRelease(pRtree, pChild); + if( rc==SQLITE_OK ) rc = rc2; + if( rc==SQLITE_OK ){ + pRtree->iDepth--; + writeInt16(pRoot->zData, pRtree->iDepth); + pRoot->isDirty = 1; + } + } + + /* Re-insert the contents of any underfull nodes removed from the tree. */ + for(pLeaf=pRtree->pDeleted; pLeaf; pLeaf=pRtree->pDeleted){ + if( rc==SQLITE_OK ){ + rc = reinsertNodeContent(pRtree, pLeaf); + } + pRtree->pDeleted = pLeaf->pNext; + sqlite3_free(pLeaf); + } + + /* Release the reference to the root node. */ + if( rc==SQLITE_OK ){ + rc = nodeRelease(pRtree, pRoot); + }else{ + nodeRelease(pRtree, pRoot); + } + + return rc; +} + +/* +** Rounding constants for float->double conversion. +*/ +#define RNDTOWARDS (1.0 - 1.0/8388608.0) /* Round towards zero */ +#define RNDAWAY (1.0 + 1.0/8388608.0) /* Round away from zero */ + +#if !defined(SQLITE_RTREE_INT_ONLY) +/* +** Convert an sqlite3_value into an RtreeValue (presumably a float) +** while taking care to round toward negative or positive, respectively. +*/ +static RtreeValue rtreeValueDown(sqlite3_value *v){ + double d = sqlite3_value_double(v); + float f = (float)d; + if( f>d ){ + f = (float)(d*(d<0 ? RNDAWAY : RNDTOWARDS)); + } + return f; +} +static RtreeValue rtreeValueUp(sqlite3_value *v){ + double d = sqlite3_value_double(v); + float f = (float)d; + if( f1 */ + int bHaveRowid = 0; /* Set to 1 after new rowid is determined */ + + rtreeReference(pRtree); + assert(nData>=1); + + cell.iRowid = 0; /* Used only to suppress a compiler warning */ + + /* Constraint handling. A write operation on an r-tree table may return + ** SQLITE_CONSTRAINT for two reasons: + ** + ** 1. A duplicate rowid value, or + ** 2. The supplied data violates the "x2>=x1" constraint. + ** + ** In the first case, if the conflict-handling mode is REPLACE, then + ** the conflicting row can be removed before proceeding. In the second + ** case, SQLITE_CONSTRAINT must be returned regardless of the + ** conflict-handling mode specified by the user. + */ + if( nData>1 ){ + int ii; + + /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. + ** + ** NB: nData can only be less than nDim*2+3 if the rtree is mis-declared + ** with "column" that are interpreted as table constraints. + ** Example: CREATE VIRTUAL TABLE bad USING rtree(x,y,CHECK(y>5)); + ** This problem was discovered after years of use, so we silently ignore + ** these kinds of misdeclared tables to avoid breaking any legacy. + */ + assert( nData<=(pRtree->nDim*2 + 3) ); + +#ifndef SQLITE_RTREE_INT_ONLY + if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ + for(ii=0; iicell.aCoord[ii+1].f ){ + rc = SQLITE_CONSTRAINT; + goto constraint; + } + } + }else +#endif + { + for(ii=0; iicell.aCoord[ii+1].i ){ + rc = SQLITE_CONSTRAINT; + goto constraint; + } + } + } + + /* If a rowid value was supplied, check if it is already present in + ** the table. If so, the constraint has failed. */ + if( sqlite3_value_type(azData[2])!=SQLITE_NULL ){ + cell.iRowid = sqlite3_value_int64(azData[2]); + if( sqlite3_value_type(azData[0])==SQLITE_NULL + || sqlite3_value_int64(azData[0])!=cell.iRowid + ){ + int steprc; + sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid); + steprc = sqlite3_step(pRtree->pReadRowid); + rc = sqlite3_reset(pRtree->pReadRowid); + if( SQLITE_ROW==steprc ){ + if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){ + rc = rtreeDeleteRowid(pRtree, cell.iRowid); + }else{ + rc = SQLITE_CONSTRAINT; + goto constraint; + } + } + } + bHaveRowid = 1; + } + } + + /* If azData[0] is not an SQL NULL value, it is the rowid of a + ** record to delete from the r-tree table. The following block does + ** just that. + */ + if( sqlite3_value_type(azData[0])!=SQLITE_NULL ){ + rc = rtreeDeleteRowid(pRtree, sqlite3_value_int64(azData[0])); + } + + /* If the azData[] array contains more than one element, elements + ** (azData[2]..azData[argc-1]) contain a new record to insert into + ** the r-tree structure. + */ + if( rc==SQLITE_OK && nData>1 ){ + /* Insert the new record into the r-tree */ + RtreeNode *pLeaf = 0; + + /* Figure out the rowid of the new row. */ + if( bHaveRowid==0 ){ + rc = newRowid(pRtree, &cell.iRowid); + } + *pRowid = cell.iRowid; + + if( rc==SQLITE_OK ){ + rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf); + } + if( rc==SQLITE_OK ){ + int rc2; + pRtree->iReinsertHeight = -1; + rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0); + rc2 = nodeRelease(pRtree, pLeaf); + if( rc==SQLITE_OK ){ + rc = rc2; + } + } + } + +constraint: + rtreeRelease(pRtree); + return rc; +} + +/* +** The xRename method for rtree module virtual tables. +*/ +static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){ + Rtree *pRtree = (Rtree *)pVtab; + int rc = SQLITE_NOMEM; + char *zSql = sqlite3_mprintf( + "ALTER TABLE %Q.'%q_node' RENAME TO \"%w_node\";" + "ALTER TABLE %Q.'%q_parent' RENAME TO \"%w_parent\";" + "ALTER TABLE %Q.'%q_rowid' RENAME TO \"%w_rowid\";" + , pRtree->zDb, pRtree->zName, zNewName + , pRtree->zDb, pRtree->zName, zNewName + , pRtree->zDb, pRtree->zName, zNewName + ); + if( zSql ){ + rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0); + sqlite3_free(zSql); + } + return rc; +} + +/* +** This function populates the pRtree->nRowEst variable with an estimate +** of the number of rows in the virtual table. If possible, this is based +** on sqlite_stat1 data. Otherwise, use RTREE_DEFAULT_ROWEST. +*/ +static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){ + const char *zFmt = "SELECT stat FROM %Q.sqlite_stat1 WHERE tbl = '%q_rowid'"; + char *zSql; + sqlite3_stmt *p; + int rc; + i64 nRow = 0; + + zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0); + if( rc==SQLITE_OK ){ + if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0); + rc = sqlite3_finalize(p); + }else if( rc!=SQLITE_NOMEM ){ + rc = SQLITE_OK; + } + + if( rc==SQLITE_OK ){ + if( nRow==0 ){ + pRtree->nRowEst = RTREE_DEFAULT_ROWEST; + }else{ + pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST); + } + } + sqlite3_free(zSql); + } + + return rc; +} + +static sqlite3_module rtreeModule = { + 0, /* iVersion */ + rtreeCreate, /* xCreate - create a table */ + rtreeConnect, /* xConnect - connect to an existing table */ + rtreeBestIndex, /* xBestIndex - Determine search strategy */ + rtreeDisconnect, /* xDisconnect - Disconnect from a table */ + rtreeDestroy, /* xDestroy - Drop a table */ + rtreeOpen, /* xOpen - open a cursor */ + rtreeClose, /* xClose - close a cursor */ + rtreeFilter, /* xFilter - configure scan constraints */ + rtreeNext, /* xNext - advance a cursor */ + rtreeEof, /* xEof */ + rtreeColumn, /* xColumn - read data */ + rtreeRowid, /* xRowid - read data */ + rtreeUpdate, /* xUpdate - write data */ + 0, /* xBegin - begin transaction */ + 0, /* xSync - sync transaction */ + 0, /* xCommit - commit transaction */ + 0, /* xRollback - rollback transaction */ + 0, /* xFindFunction - function overloading */ + rtreeRename, /* xRename - rename the table */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0 /* xRollbackTo */ +}; + +static int rtreeSqlInit( + Rtree *pRtree, + sqlite3 *db, + const char *zDb, + const char *zPrefix, + int isCreate +){ + int rc = SQLITE_OK; + + #define N_STATEMENT 9 + static const char *azSql[N_STATEMENT] = { + /* Read and write the xxx_node table */ + "SELECT data FROM '%q'.'%q_node' WHERE nodeno = :1", + "INSERT OR REPLACE INTO '%q'.'%q_node' VALUES(:1, :2)", + "DELETE FROM '%q'.'%q_node' WHERE nodeno = :1", + + /* Read and write the xxx_rowid table */ + "SELECT nodeno FROM '%q'.'%q_rowid' WHERE rowid = :1", + "INSERT OR REPLACE INTO '%q'.'%q_rowid' VALUES(:1, :2)", + "DELETE FROM '%q'.'%q_rowid' WHERE rowid = :1", + + /* Read and write the xxx_parent table */ + "SELECT parentnode FROM '%q'.'%q_parent' WHERE nodeno = :1", + "INSERT OR REPLACE INTO '%q'.'%q_parent' VALUES(:1, :2)", + "DELETE FROM '%q'.'%q_parent' WHERE nodeno = :1" + }; + sqlite3_stmt **appStmt[N_STATEMENT]; + int i; + + pRtree->db = db; + + if( isCreate ){ + char *zCreate = sqlite3_mprintf( +"CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY, data BLOB);" +"CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY, nodeno INTEGER);" +"CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY," + " parentnode INTEGER);" +"INSERT INTO '%q'.'%q_node' VALUES(1, zeroblob(%d))", + zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, pRtree->iNodeSize + ); + if( !zCreate ){ + return SQLITE_NOMEM; + } + rc = sqlite3_exec(db, zCreate, 0, 0, 0); + sqlite3_free(zCreate); + if( rc!=SQLITE_OK ){ + return rc; + } + } + + appStmt[0] = &pRtree->pReadNode; + appStmt[1] = &pRtree->pWriteNode; + appStmt[2] = &pRtree->pDeleteNode; + appStmt[3] = &pRtree->pReadRowid; + appStmt[4] = &pRtree->pWriteRowid; + appStmt[5] = &pRtree->pDeleteRowid; + appStmt[6] = &pRtree->pReadParent; + appStmt[7] = &pRtree->pWriteParent; + appStmt[8] = &pRtree->pDeleteParent; + + rc = rtreeQueryStat1(db, pRtree); + for(i=0; iiNodeSize is populated and SQLITE_OK returned. +** Otherwise, an SQLite error code is returned. +** +** If this function is being called as part of an xConnect(), then the rtree +** table already exists. In this case the node-size is determined by inspecting +** the root node of the tree. +** +** Otherwise, for an xCreate(), use 64 bytes less than the database page-size. +** This ensures that each node is stored on a single database page. If the +** database page-size is so large that more than RTREE_MAXCELLS entries +** would fit in a single node, use a smaller node-size. +*/ +static int getNodeSize( + sqlite3 *db, /* Database handle */ + Rtree *pRtree, /* Rtree handle */ + int isCreate, /* True for xCreate, false for xConnect */ + char **pzErr /* OUT: Error message, if any */ +){ + int rc; + char *zSql; + if( isCreate ){ + int iPageSize = 0; + zSql = sqlite3_mprintf("PRAGMA %Q.page_size", pRtree->zDb); + rc = getIntFromStmt(db, zSql, &iPageSize); + if( rc==SQLITE_OK ){ + pRtree->iNodeSize = iPageSize-64; + if( (4+pRtree->nBytesPerCell*RTREE_MAXCELLS)iNodeSize ){ + pRtree->iNodeSize = 4+pRtree->nBytesPerCell*RTREE_MAXCELLS; + } + }else{ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + } + }else{ + zSql = sqlite3_mprintf( + "SELECT length(data) FROM '%q'.'%q_node' WHERE nodeno = 1", + pRtree->zDb, pRtree->zName + ); + rc = getIntFromStmt(db, zSql, &pRtree->iNodeSize); + if( rc!=SQLITE_OK ){ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + } + } + + sqlite3_free(zSql); + return rc; +} + +/* +** This function is the implementation of both the xConnect and xCreate +** methods of the r-tree virtual table. +** +** argv[0] -> module name +** argv[1] -> database name +** argv[2] -> table name +** argv[...] -> column names... +*/ +static int rtreeInit( + sqlite3 *db, /* Database connection */ + void *pAux, /* One of the RTREE_COORD_* constants */ + int argc, const char *const*argv, /* Parameters to CREATE TABLE statement */ + sqlite3_vtab **ppVtab, /* OUT: New virtual table */ + char **pzErr, /* OUT: Error message, if any */ + int isCreate /* True for xCreate, false for xConnect */ +){ + int rc = SQLITE_OK; + Rtree *pRtree; + int nDb; /* Length of string argv[1] */ + int nName; /* Length of string argv[2] */ + int eCoordType = (pAux ? RTREE_COORD_INT32 : RTREE_COORD_REAL32); + + const char *aErrMsg[] = { + 0, /* 0 */ + "Wrong number of columns for an rtree table", /* 1 */ + "Too few columns for an rtree table", /* 2 */ + "Too many columns for an rtree table" /* 3 */ + }; + + int iErr = (argc<6) ? 2 : argc>(RTREE_MAX_DIMENSIONS*2+4) ? 3 : argc%2; + if( aErrMsg[iErr] ){ + *pzErr = sqlite3_mprintf("%s", aErrMsg[iErr]); + return SQLITE_ERROR; + } + + sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + + /* Allocate the sqlite3_vtab structure */ + nDb = (int)strlen(argv[1]); + nName = (int)strlen(argv[2]); + pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2); + if( !pRtree ){ + return SQLITE_NOMEM; + } + memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2); + pRtree->nBusy = 1; + pRtree->base.pModule = &rtreeModule; + pRtree->zDb = (char *)&pRtree[1]; + pRtree->zName = &pRtree->zDb[nDb+1]; + pRtree->nDim = (argc-4)/2; + pRtree->nBytesPerCell = 8 + pRtree->nDim*4*2; + pRtree->eCoordType = eCoordType; + memcpy(pRtree->zDb, argv[1], nDb); + memcpy(pRtree->zName, argv[2], nName); + + /* Figure out the node size to use. */ + rc = getNodeSize(db, pRtree, isCreate, pzErr); + + /* Create/Connect to the underlying relational database schema. If + ** that is successful, call sqlite3_declare_vtab() to configure + ** the r-tree table schema. + */ + if( rc==SQLITE_OK ){ + if( (rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate)) ){ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + }else{ + char *zSql = sqlite3_mprintf("CREATE TABLE x(%s", argv[3]); + char *zTmp; + int ii; + for(ii=4; zSql && iinBusy==1 ); + rtreeRelease(pRtree); + } + return rc; +} + + +/* +** Implementation of a scalar function that decodes r-tree nodes to +** human readable strings. This can be used for debugging and analysis. +** +** The scalar function takes two arguments: (1) the number of dimensions +** to the rtree (between 1 and 5, inclusive) and (2) a blob of data containing +** an r-tree node. For a two-dimensional r-tree structure called "rt", to +** deserialize all nodes, a statement like: +** +** SELECT rtreenode(2, data) FROM rt_node; +** +** The human readable string takes the form of a Tcl list with one +** entry for each cell in the r-tree node. Each entry is itself a +** list, containing the 8-byte rowid/pageno followed by the +** *2 coordinates. +*/ +static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ + char *zText = 0; + RtreeNode node; + Rtree tree; + int ii; + + UNUSED_PARAMETER(nArg); + memset(&node, 0, sizeof(RtreeNode)); + memset(&tree, 0, sizeof(Rtree)); + tree.nDim = sqlite3_value_int(apArg[0]); + tree.nBytesPerCell = 8 + 8 * tree.nDim; + node.zData = (u8 *)sqlite3_value_blob(apArg[1]); + + for(ii=0; iixDestructor ) pInfo->xDestructor(pInfo->pContext); + sqlite3_free(p); +} + +/* +** Each call to sqlite3_rtree_geometry_callback() or +** sqlite3_rtree_query_callback() creates an ordinary SQLite +** scalar function that is implemented by this routine. +** +** All this function does is construct an RtreeMatchArg object that +** contains the geometry-checking callback routines and a list of +** parameters to this function, then return that RtreeMatchArg object +** as a BLOB. +** +** The R-Tree MATCH operator will read the returned BLOB, deserialize +** the RtreeMatchArg object, and use the RtreeMatchArg object to figure +** out which elements of the R-Tree should be returned by the query. +*/ +static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ + RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx); + RtreeMatchArg *pBlob; + int nBlob; + + nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue); + pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob); + if( !pBlob ){ + sqlite3_result_error_nomem(ctx); + }else{ + int i; + pBlob->magic = RTREE_GEOMETRY_MAGIC; + pBlob->cb = pGeomCtx[0]; + pBlob->nParam = nArg; + for(i=0; iaParam[i] = sqlite3_value_int64(aArg[i]); +#else + pBlob->aParam[i] = sqlite3_value_double(aArg[i]); +#endif + } + sqlite3_result_blob(ctx, pBlob, nBlob, sqlite3_free); + } +} + +/* +** Register a new geometry function for use with the r-tree MATCH operator. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback( + sqlite3 *db, /* Register SQL function on this connection */ + const char *zGeom, /* Name of the new SQL function */ + int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*), /* Callback */ + void *pContext /* Extra data associated with the callback */ +){ + RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */ + + /* Allocate and populate the context object. */ + pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback)); + if( !pGeomCtx ) return SQLITE_NOMEM; + pGeomCtx->xGeom = xGeom; + pGeomCtx->xQueryFunc = 0; + pGeomCtx->xDestructor = 0; + pGeomCtx->pContext = pContext; + return sqlite3_create_function_v2(db, zGeom, -1, SQLITE_ANY, + (void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback + ); +} + +/* +** Register a new 2nd-generation geometry function for use with the +** r-tree MATCH operator. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback( + sqlite3 *db, /* Register SQL function on this connection */ + const char *zQueryFunc, /* Name of new SQL function */ + int (*xQueryFunc)(sqlite3_rtree_query_info*), /* Callback */ + void *pContext, /* Extra data passed into the callback */ + void (*xDestructor)(void*) /* Destructor for the extra data */ +){ + RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */ + + /* Allocate and populate the context object. */ + pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback)); + if( !pGeomCtx ) return SQLITE_NOMEM; + pGeomCtx->xGeom = 0; + pGeomCtx->xQueryFunc = xQueryFunc; + pGeomCtx->xDestructor = xDestructor; + pGeomCtx->pContext = pContext; + return sqlite3_create_function_v2(db, zQueryFunc, -1, SQLITE_ANY, + (void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback + ); +} + +#if !SQLITE_CORE +#ifdef _WIN32 +__declspec(dllexport) +#endif +SQLITE_API int SQLITE_STDCALL sqlite3_rtree_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + SQLITE_EXTENSION_INIT2(pApi) + return sqlite3RtreeInit(db); +} +#endif + +#endif + +/************** End of rtree.c ***********************************************/ +/************** Begin file icu.c *********************************************/ +/* +** 2007 May 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: icu.c,v 1.7 2007/12/13 21:54:11 drh Exp $ +** +** This file implements an integration between the ICU library +** ("International Components for Unicode", an open-source library +** for handling unicode data) and SQLite. The integration uses +** ICU to provide the following to SQLite: +** +** * An implementation of the SQL regexp() function (and hence REGEXP +** operator) using the ICU uregex_XX() APIs. +** +** * Implementations of the SQL scalar upper() and lower() functions +** for case mapping. +** +** * Integration of ICU and SQLite collation sequences. +** +** * An implementation of the LIKE operator that uses ICU to +** provide case-independent matching. +*/ + +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) + +/* Include ICU headers */ +#include +#include +#include +#include + +/* #include */ + +#ifndef SQLITE_CORE + SQLITE_EXTENSION_INIT1 +#else +#endif + +/* +** Maximum length (in bytes) of the pattern in a LIKE or GLOB +** operator. +*/ +#ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH +# define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000 +#endif + +/* +** Version of sqlite3_free() that is always a function, never a macro. +*/ +static void xFree(void *p){ + sqlite3_free(p); +} + +/* +** Compare two UTF-8 strings for equality where the first string is +** a "LIKE" expression. Return true (1) if they are the same and +** false (0) if they are different. +*/ +static int icuLikeCompare( + const uint8_t *zPattern, /* LIKE pattern */ + const uint8_t *zString, /* The UTF-8 string to compare against */ + const UChar32 uEsc /* The escape character */ +){ + static const int MATCH_ONE = (UChar32)'_'; + static const int MATCH_ALL = (UChar32)'%'; + + int iPattern = 0; /* Current byte index in zPattern */ + int iString = 0; /* Current byte index in zString */ + + int prevEscape = 0; /* True if the previous character was uEsc */ + + while( zPattern[iPattern]!=0 ){ + + /* Read (and consume) the next character from the input pattern. */ + UChar32 uPattern; + U8_NEXT_UNSAFE(zPattern, iPattern, uPattern); + assert(uPattern!=0); + + /* There are now 4 possibilities: + ** + ** 1. uPattern is an unescaped match-all character "%", + ** 2. uPattern is an unescaped match-one character "_", + ** 3. uPattern is an unescaped escape character, or + ** 4. uPattern is to be handled as an ordinary character + */ + if( !prevEscape && uPattern==MATCH_ALL ){ + /* Case 1. */ + uint8_t c; + + /* Skip any MATCH_ALL or MATCH_ONE characters that follow a + ** MATCH_ALL. For each MATCH_ONE, skip one character in the + ** test string. + */ + while( (c=zPattern[iPattern]) == MATCH_ALL || c == MATCH_ONE ){ + if( c==MATCH_ONE ){ + if( zString[iString]==0 ) return 0; + U8_FWD_1_UNSAFE(zString, iString); + } + iPattern++; + } + + if( zPattern[iPattern]==0 ) return 1; + + while( zString[iString] ){ + if( icuLikeCompare(&zPattern[iPattern], &zString[iString], uEsc) ){ + return 1; + } + U8_FWD_1_UNSAFE(zString, iString); + } + return 0; + + }else if( !prevEscape && uPattern==MATCH_ONE ){ + /* Case 2. */ + if( zString[iString]==0 ) return 0; + U8_FWD_1_UNSAFE(zString, iString); + + }else if( !prevEscape && uPattern==uEsc){ + /* Case 3. */ + prevEscape = 1; + + }else{ + /* Case 4. */ + UChar32 uString; + U8_NEXT_UNSAFE(zString, iString, uString); + uString = u_foldCase(uString, U_FOLD_CASE_DEFAULT); + uPattern = u_foldCase(uPattern, U_FOLD_CASE_DEFAULT); + if( uString!=uPattern ){ + return 0; + } + prevEscape = 0; + } + } + + return zString[iString]==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 there is an escape character E, +** +** A LIKE B ESCAPE E +** +** is mapped to like(B, A, E). +*/ +static void icuLikeFunc( + 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]); + UChar32 uEsc = 0; + + /* Limit the length of the LIKE or GLOB pattern to avoid problems + ** of deep recursion and N*N behavior in patternCompare(). + */ + if( sqlite3_value_bytes(argv[0])>SQLITE_MAX_LIKE_PATTERN_LENGTH ){ + sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1); + return; + } + + + if( argc==3 ){ + /* The escape character string must consist of a single UTF-8 character. + ** Otherwise, return an error. + */ + int nE= sqlite3_value_bytes(argv[2]); + const unsigned char *zE = sqlite3_value_text(argv[2]); + int i = 0; + if( zE==0 ) return; + U8_NEXT(zE, i, nE, uEsc); + if( i!=nE){ + sqlite3_result_error(context, + "ESCAPE expression must be a single character", -1); + return; + } + } + + if( zA && zB ){ + sqlite3_result_int(context, icuLikeCompare(zA, zB, uEsc)); + } +} + +/* +** This function is called when an ICU function called from within +** the implementation of an SQL scalar function returns an error. +** +** The scalar function context passed as the first argument is +** loaded with an error message based on the following two args. +*/ +static void icuFunctionError( + sqlite3_context *pCtx, /* SQLite scalar function context */ + const char *zName, /* Name of ICU function that failed */ + UErrorCode e /* Error code returned by ICU function */ +){ + char zBuf[128]; + sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e)); + zBuf[127] = '\0'; + sqlite3_result_error(pCtx, zBuf, -1); +} + +/* +** Function to delete compiled regexp objects. Registered as +** a destructor function with sqlite3_set_auxdata(). +*/ +static void icuRegexpDelete(void *p){ + URegularExpression *pExpr = (URegularExpression *)p; + uregex_close(pExpr); +} + +/* +** Implementation of SQLite REGEXP operator. This scalar function takes +** two arguments. The first is a regular expression pattern to compile +** the second is a string to match against that pattern. If either +** argument is an SQL NULL, then NULL Is returned. Otherwise, the result +** is 1 if the string matches the pattern, or 0 otherwise. +** +** SQLite maps the regexp() function to the regexp() operator such +** that the following two are equivalent: +** +** zString REGEXP zPattern +** regexp(zPattern, zString) +** +** Uses the following ICU regexp APIs: +** +** uregex_open() +** uregex_matches() +** uregex_close() +*/ +static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){ + UErrorCode status = U_ZERO_ERROR; + URegularExpression *pExpr; + UBool res; + const UChar *zString = sqlite3_value_text16(apArg[1]); + + (void)nArg; /* Unused parameter */ + + /* If the left hand side of the regexp operator is NULL, + ** then the result is also NULL. + */ + if( !zString ){ + return; + } + + pExpr = sqlite3_get_auxdata(p, 0); + if( !pExpr ){ + const UChar *zPattern = sqlite3_value_text16(apArg[0]); + if( !zPattern ){ + return; + } + pExpr = uregex_open(zPattern, -1, 0, 0, &status); + + if( U_SUCCESS(status) ){ + sqlite3_set_auxdata(p, 0, pExpr, icuRegexpDelete); + }else{ + assert(!pExpr); + icuFunctionError(p, "uregex_open", status); + return; + } + } + + /* Configure the text that the regular expression operates on. */ + uregex_setText(pExpr, zString, -1, &status); + if( !U_SUCCESS(status) ){ + icuFunctionError(p, "uregex_setText", status); + return; + } + + /* Attempt the match */ + res = uregex_matches(pExpr, 0, &status); + if( !U_SUCCESS(status) ){ + icuFunctionError(p, "uregex_matches", status); + return; + } + + /* Set the text that the regular expression operates on to a NULL + ** pointer. This is not really necessary, but it is tidier than + ** leaving the regular expression object configured with an invalid + ** pointer after this function returns. + */ + uregex_setText(pExpr, 0, 0, &status); + + /* Return 1 or 0. */ + sqlite3_result_int(p, res ? 1 : 0); +} + +/* +** Implementations of scalar functions for case mapping - upper() and +** lower(). Function upper() converts its input to upper-case (ABC). +** Function lower() converts to lower-case (abc). +** +** ICU provides two types of case mapping, "general" case mapping and +** "language specific". Refer to ICU documentation for the differences +** between the two. +** +** To utilise "general" case mapping, the upper() or lower() scalar +** functions are invoked with one argument: +** +** upper('ABC') -> 'abc' +** lower('abc') -> 'ABC' +** +** To access ICU "language specific" case mapping, upper() or lower() +** should be invoked with two arguments. The second argument is the name +** of the locale to use. Passing an empty string ("") or SQL NULL value +** as the second argument is the same as invoking the 1 argument version +** of upper() or lower(). +** +** lower('I', 'en_us') -> 'i' +** lower('I', 'tr_tr') -> 'ı' (small dotless i) +** +** http://www.icu-project.org/userguide/posix.html#case_mappings +*/ +static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){ + const UChar *zInput; + UChar *zOutput; + int nInput; + int nOutput; + + UErrorCode status = U_ZERO_ERROR; + const char *zLocale = 0; + + assert(nArg==1 || nArg==2); + if( nArg==2 ){ + zLocale = (const char *)sqlite3_value_text(apArg[1]); + } + + zInput = sqlite3_value_text16(apArg[0]); + if( !zInput ){ + return; + } + nInput = sqlite3_value_bytes16(apArg[0]); + + nOutput = nInput * 2 + 2; + zOutput = sqlite3_malloc(nOutput); + if( !zOutput ){ + return; + } + + if( sqlite3_user_data(p) ){ + u_strToUpper(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status); + }else{ + u_strToLower(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status); + } + + if( !U_SUCCESS(status) ){ + icuFunctionError(p, "u_strToLower()/u_strToUpper", status); + return; + } + + sqlite3_result_text16(p, zOutput, -1, xFree); +} + +/* +** Collation sequence destructor function. The pCtx argument points to +** a UCollator structure previously allocated using ucol_open(). +*/ +static void icuCollationDel(void *pCtx){ + UCollator *p = (UCollator *)pCtx; + ucol_close(p); +} + +/* +** Collation sequence comparison function. The pCtx argument points to +** a UCollator structure previously allocated using ucol_open(). +*/ +static int icuCollationColl( + void *pCtx, + int nLeft, + const void *zLeft, + int nRight, + const void *zRight +){ + UCollationResult res; + UCollator *p = (UCollator *)pCtx; + res = ucol_strcoll(p, (UChar *)zLeft, nLeft/2, (UChar *)zRight, nRight/2); + switch( res ){ + case UCOL_LESS: return -1; + case UCOL_GREATER: return +1; + case UCOL_EQUAL: return 0; + } + assert(!"Unexpected return value from ucol_strcoll()"); + return 0; +} + +/* +** Implementation of the scalar function icu_load_collation(). +** +** This scalar function is used to add ICU collation based collation +** types to an SQLite database connection. It is intended to be called +** as follows: +** +** SELECT icu_load_collation(, ); +** +** Where is a string containing an ICU locale identifier (i.e. +** "en_AU", "tr_TR" etc.) and is the name of the +** collation sequence to create. +*/ +static void icuLoadCollation( + sqlite3_context *p, + int nArg, + sqlite3_value **apArg +){ + sqlite3 *db = (sqlite3 *)sqlite3_user_data(p); + UErrorCode status = U_ZERO_ERROR; + const char *zLocale; /* Locale identifier - (eg. "jp_JP") */ + const char *zName; /* SQL Collation sequence name (eg. "japanese") */ + UCollator *pUCollator; /* ICU library collation object */ + int rc; /* Return code from sqlite3_create_collation_x() */ + + assert(nArg==2); + zLocale = (const char *)sqlite3_value_text(apArg[0]); + zName = (const char *)sqlite3_value_text(apArg[1]); + + if( !zLocale || !zName ){ + return; + } + + pUCollator = ucol_open(zLocale, &status); + if( !U_SUCCESS(status) ){ + icuFunctionError(p, "ucol_open", status); + return; + } + assert(p); + + rc = sqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void *)pUCollator, + icuCollationColl, icuCollationDel + ); + if( rc!=SQLITE_OK ){ + ucol_close(pUCollator); + sqlite3_result_error(p, "Error registering collation function", -1); + } +} + +/* +** Register the ICU extension functions with database db. +*/ +SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){ + struct IcuScalar { + const char *zName; /* Function name */ + int nArg; /* Number of arguments */ + int enc; /* Optimal text encoding */ + void *pContext; /* sqlite3_user_data() context */ + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); + } scalars[] = { + {"regexp", 2, SQLITE_ANY, 0, icuRegexpFunc}, + + {"lower", 1, SQLITE_UTF16, 0, icuCaseFunc16}, + {"lower", 2, SQLITE_UTF16, 0, icuCaseFunc16}, + {"upper", 1, SQLITE_UTF16, (void*)1, icuCaseFunc16}, + {"upper", 2, SQLITE_UTF16, (void*)1, icuCaseFunc16}, + + {"lower", 1, SQLITE_UTF8, 0, icuCaseFunc16}, + {"lower", 2, SQLITE_UTF8, 0, icuCaseFunc16}, + {"upper", 1, SQLITE_UTF8, (void*)1, icuCaseFunc16}, + {"upper", 2, SQLITE_UTF8, (void*)1, icuCaseFunc16}, + + {"like", 2, SQLITE_UTF8, 0, icuLikeFunc}, + {"like", 3, SQLITE_UTF8, 0, icuLikeFunc}, + + {"icu_load_collation", 2, SQLITE_UTF8, (void*)db, icuLoadCollation}, + }; + + int rc = SQLITE_OK; + int i; + + for(i=0; rc==SQLITE_OK && i<(int)(sizeof(scalars)/sizeof(scalars[0])); i++){ + struct IcuScalar *p = &scalars[i]; + rc = sqlite3_create_function( + db, p->zName, p->nArg, p->enc, p->pContext, p->xFunc, 0, 0 + ); + } + + return rc; +} + +#if !SQLITE_CORE +#ifdef _WIN32 +__declspec(dllexport) +#endif +SQLITE_API int SQLITE_STDCALL sqlite3_icu_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + SQLITE_EXTENSION_INIT2(pApi) + return sqlite3IcuInit(db); +} +#endif + +#endif + +/************** End of icu.c *************************************************/ +/************** Begin file fts3_icu.c ****************************************/ +/* +** 2007 June 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 file implements a tokenizer for fts3 based on the ICU library. +*/ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) +#ifdef SQLITE_ENABLE_ICU + +/* #include */ +/* #include */ + +#include +/* #include */ +/* #include */ +#include + +typedef struct IcuTokenizer IcuTokenizer; +typedef struct IcuCursor IcuCursor; + +struct IcuTokenizer { + sqlite3_tokenizer base; + char *zLocale; +}; + +struct IcuCursor { + sqlite3_tokenizer_cursor base; + + UBreakIterator *pIter; /* ICU break-iterator object */ + int nChar; /* Number of UChar elements in pInput */ + UChar *aChar; /* Copy of input using utf-16 encoding */ + int *aOffset; /* Offsets of each character in utf-8 input */ + + int nBuffer; + char *zBuffer; + + int iToken; +}; + +/* +** Create a new tokenizer instance. +*/ +static int icuCreate( + int argc, /* Number of entries in argv[] */ + const char * const *argv, /* Tokenizer creation arguments */ + sqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */ +){ + IcuTokenizer *p; + int n = 0; + + if( argc>0 ){ + n = strlen(argv[0])+1; + } + p = (IcuTokenizer *)sqlite3_malloc(sizeof(IcuTokenizer)+n); + if( !p ){ + return SQLITE_NOMEM; + } + memset(p, 0, sizeof(IcuTokenizer)); + + if( n ){ + p->zLocale = (char *)&p[1]; + memcpy(p->zLocale, argv[0], n); + } + + *ppTokenizer = (sqlite3_tokenizer *)p; + + return SQLITE_OK; +} + +/* +** Destroy a tokenizer +*/ +static int icuDestroy(sqlite3_tokenizer *pTokenizer){ + IcuTokenizer *p = (IcuTokenizer *)pTokenizer; + sqlite3_free(p); + return SQLITE_OK; +} + +/* +** Prepare to begin tokenizing a particular string. The input +** string to be tokenized is pInput[0..nBytes-1]. A cursor +** used to incrementally tokenize this string is returned in +** *ppCursor. +*/ +static int icuOpen( + sqlite3_tokenizer *pTokenizer, /* The tokenizer */ + const char *zInput, /* Input string */ + int nInput, /* Length of zInput in bytes */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */ +){ + IcuTokenizer *p = (IcuTokenizer *)pTokenizer; + IcuCursor *pCsr; + + const int32_t opt = U_FOLD_CASE_DEFAULT; + UErrorCode status = U_ZERO_ERROR; + int nChar; + + UChar32 c; + int iInput = 0; + int iOut = 0; + + *ppCursor = 0; + + if( zInput==0 ){ + nInput = 0; + zInput = ""; + }else if( nInput<0 ){ + nInput = strlen(zInput); + } + nChar = nInput+1; + pCsr = (IcuCursor *)sqlite3_malloc( + sizeof(IcuCursor) + /* IcuCursor */ + ((nChar+3)&~3) * sizeof(UChar) + /* IcuCursor.aChar[] */ + (nChar+1) * sizeof(int) /* IcuCursor.aOffset[] */ + ); + if( !pCsr ){ + return SQLITE_NOMEM; + } + memset(pCsr, 0, sizeof(IcuCursor)); + pCsr->aChar = (UChar *)&pCsr[1]; + pCsr->aOffset = (int *)&pCsr->aChar[(nChar+3)&~3]; + + pCsr->aOffset[iOut] = iInput; + U8_NEXT(zInput, iInput, nInput, c); + while( c>0 ){ + int isError = 0; + c = u_foldCase(c, opt); + U16_APPEND(pCsr->aChar, iOut, nChar, c, isError); + if( isError ){ + sqlite3_free(pCsr); + return SQLITE_ERROR; + } + pCsr->aOffset[iOut] = iInput; + + if( iInputpIter = ubrk_open(UBRK_WORD, p->zLocale, pCsr->aChar, iOut, &status); + if( !U_SUCCESS(status) ){ + sqlite3_free(pCsr); + return SQLITE_ERROR; + } + pCsr->nChar = iOut; + + ubrk_first(pCsr->pIter); + *ppCursor = (sqlite3_tokenizer_cursor *)pCsr; + return SQLITE_OK; +} + +/* +** Close a tokenization cursor previously opened by a call to icuOpen(). +*/ +static int icuClose(sqlite3_tokenizer_cursor *pCursor){ + IcuCursor *pCsr = (IcuCursor *)pCursor; + ubrk_close(pCsr->pIter); + sqlite3_free(pCsr->zBuffer); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* +** Extract the next token from a tokenization cursor. +*/ +static int icuNext( + sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by simpleOpen */ + const char **ppToken, /* OUT: *ppToken is the token text */ + int *pnBytes, /* OUT: Number of bytes in token */ + int *piStartOffset, /* OUT: Starting offset of token */ + int *piEndOffset, /* OUT: Ending offset of token */ + int *piPosition /* OUT: Position integer of token */ +){ + IcuCursor *pCsr = (IcuCursor *)pCursor; + + int iStart = 0; + int iEnd = 0; + int nByte = 0; + + while( iStart==iEnd ){ + UChar32 c; + + iStart = ubrk_current(pCsr->pIter); + iEnd = ubrk_next(pCsr->pIter); + if( iEnd==UBRK_DONE ){ + return SQLITE_DONE; + } + + while( iStartaChar, iWhite, pCsr->nChar, c); + if( u_isspace(c) ){ + iStart = iWhite; + }else{ + break; + } + } + assert(iStart<=iEnd); + } + + do { + UErrorCode status = U_ZERO_ERROR; + if( nByte ){ + char *zNew = sqlite3_realloc(pCsr->zBuffer, nByte); + if( !zNew ){ + return SQLITE_NOMEM; + } + pCsr->zBuffer = zNew; + pCsr->nBuffer = nByte; + } + + u_strToUTF8( + pCsr->zBuffer, pCsr->nBuffer, &nByte, /* Output vars */ + &pCsr->aChar[iStart], iEnd-iStart, /* Input vars */ + &status /* Output success/failure */ + ); + } while( nByte>pCsr->nBuffer ); + + *ppToken = pCsr->zBuffer; + *pnBytes = nByte; + *piStartOffset = pCsr->aOffset[iStart]; + *piEndOffset = pCsr->aOffset[iEnd]; + *piPosition = pCsr->iToken++; + + return SQLITE_OK; +} + +/* +** The set of routines that implement the simple tokenizer +*/ +static const sqlite3_tokenizer_module icuTokenizerModule = { + 0, /* iVersion */ + icuCreate, /* xCreate */ + icuDestroy, /* xCreate */ + icuOpen, /* xOpen */ + icuClose, /* xClose */ + icuNext, /* xNext */ +}; + +/* +** Set *ppModule to point at the implementation of the ICU tokenizer. +*/ +SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule( + sqlite3_tokenizer_module const**ppModule +){ + *ppModule = &icuTokenizerModule; +} + +#endif /* defined(SQLITE_ENABLE_ICU) */ +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_icu.c ********************************************/ +/************** Begin file dbstat.c ******************************************/ +/* +** 2010 July 12 +** +** 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 an implementation of the "dbstat" virtual table. +** +** The dbstat virtual table is used to extract low-level formatting +** information from an SQLite database in order to implement the +** "sqlite3_analyzer" utility. See the ../tool/spaceanal.tcl script +** for an example implementation. +*/ + +#if (defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)) \ + && !defined(SQLITE_OMIT_VIRTUALTABLE) + +/* +** Page paths: +** +** The value of the 'path' column describes the path taken from the +** root-node of the b-tree structure to each page. The value of the +** root-node path is '/'. +** +** The value of the path for the left-most child page of the root of +** a b-tree is '/000/'. (Btrees store content ordered from left to right +** so the pages to the left have smaller keys than the pages to the right.) +** The next to left-most child of the root page is +** '/001', and so on, each sibling page identified by a 3-digit hex +** value. The children of the 451st left-most sibling have paths such +** as '/1c2/000/, '/1c2/001/' etc. +** +** Overflow pages are specified by appending a '+' character and a +** six-digit hexadecimal value to the path to the cell they are linked +** from. For example, the three overflow pages in a chain linked from +** the left-most cell of the 450th child of the root page are identified +** by the paths: +** +** '/1c2/000+000000' // First page in overflow chain +** '/1c2/000+000001' // Second page in overflow chain +** '/1c2/000+000002' // Third page in overflow chain +** +** If the paths are sorted using the BINARY collation sequence, then +** the overflow pages associated with a cell will appear earlier in the +** sort-order than its child page: +** +** '/1c2/000/' // Left-most child of 451st child of root +*/ +#define VTAB_SCHEMA \ + "CREATE TABLE xx( " \ + " name STRING, /* Name of table or index */" \ + " path INTEGER, /* Path to page from root */" \ + " pageno INTEGER, /* Page number */" \ + " pagetype STRING, /* 'internal', 'leaf' or 'overflow' */" \ + " ncell INTEGER, /* Cells on page (0 for overflow) */" \ + " payload INTEGER, /* Bytes of payload on this page */" \ + " unused INTEGER, /* Bytes of unused space on this page */" \ + " mx_payload INTEGER, /* Largest payload size of all cells */" \ + " pgoffset INTEGER, /* Offset of page in file */" \ + " pgsize INTEGER /* Size of the page */" \ + ");" + + +typedef struct StatTable StatTable; +typedef struct StatCursor StatCursor; +typedef struct StatPage StatPage; +typedef struct StatCell StatCell; + +struct StatCell { + int nLocal; /* Bytes of local payload */ + u32 iChildPg; /* Child node (or 0 if this is a leaf) */ + int nOvfl; /* Entries in aOvfl[] */ + u32 *aOvfl; /* Array of overflow page numbers */ + int nLastOvfl; /* Bytes of payload on final overflow page */ + int iOvfl; /* Iterates through aOvfl[] */ +}; + +struct StatPage { + u32 iPgno; + DbPage *pPg; + int iCell; + + char *zPath; /* Path to this page */ + + /* Variables populated by statDecodePage(): */ + u8 flags; /* Copy of flags byte */ + int nCell; /* Number of cells on page */ + int nUnused; /* Number of unused bytes on page */ + StatCell *aCell; /* Array of parsed cells */ + u32 iRightChildPg; /* Right-child page number (or 0) */ + int nMxPayload; /* Largest payload of any cell on this page */ +}; + +struct StatCursor { + sqlite3_vtab_cursor base; + sqlite3_stmt *pStmt; /* Iterates through set of root pages */ + int isEof; /* After pStmt has returned SQLITE_DONE */ + + StatPage aPage[32]; + int iPage; /* Current entry in aPage[] */ + + /* Values to return. */ + char *zName; /* Value of 'name' column */ + char *zPath; /* Value of 'path' column */ + u32 iPageno; /* Value of 'pageno' column */ + char *zPagetype; /* Value of 'pagetype' column */ + int nCell; /* Value of 'ncell' column */ + int nPayload; /* Value of 'payload' column */ + int nUnused; /* Value of 'unused' column */ + int nMxPayload; /* Value of 'mx_payload' column */ + i64 iOffset; /* Value of 'pgOffset' column */ + int szPage; /* Value of 'pgSize' column */ +}; + +struct StatTable { + sqlite3_vtab base; + sqlite3 *db; + int iDb; /* Index of database to analyze */ +}; + +#ifndef get2byte +# define get2byte(x) ((x)[0]<<8 | (x)[1]) +#endif + +/* +** Connect to or create a statvfs virtual table. +*/ +static int statConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + StatTable *pTab = 0; + int rc = SQLITE_OK; + int iDb; + + if( argc>=4 ){ + iDb = sqlite3FindDbName(db, argv[3]); + if( iDb<0 ){ + *pzErr = sqlite3_mprintf("no such database: %s", argv[3]); + return SQLITE_ERROR; + } + }else{ + iDb = 0; + } + rc = sqlite3_declare_vtab(db, VTAB_SCHEMA); + if( rc==SQLITE_OK ){ + pTab = (StatTable *)sqlite3_malloc64(sizeof(StatTable)); + if( pTab==0 ) rc = SQLITE_NOMEM; + } + + assert( rc==SQLITE_OK || pTab==0 ); + if( rc==SQLITE_OK ){ + memset(pTab, 0, sizeof(StatTable)); + pTab->db = db; + pTab->iDb = iDb; + } + + *ppVtab = (sqlite3_vtab*)pTab; + return rc; +} + +/* +** Disconnect from or destroy a statvfs virtual table. +*/ +static int statDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* +** There is no "best-index". This virtual table always does a linear +** scan of the binary VFS log file. +*/ +static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ + + /* Records are always returned in ascending order of (name, path). + ** If this will satisfy the client, set the orderByConsumed flag so that + ** SQLite does not do an external sort. + */ + if( ( pIdxInfo->nOrderBy==1 + && pIdxInfo->aOrderBy[0].iColumn==0 + && pIdxInfo->aOrderBy[0].desc==0 + ) || + ( pIdxInfo->nOrderBy==2 + && pIdxInfo->aOrderBy[0].iColumn==0 + && pIdxInfo->aOrderBy[0].desc==0 + && pIdxInfo->aOrderBy[1].iColumn==1 + && pIdxInfo->aOrderBy[1].desc==0 + ) + ){ + pIdxInfo->orderByConsumed = 1; + } + + pIdxInfo->estimatedCost = 10.0; + return SQLITE_OK; +} + +/* +** Open a new statvfs cursor. +*/ +static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ + StatTable *pTab = (StatTable *)pVTab; + StatCursor *pCsr; + int rc; + + pCsr = (StatCursor *)sqlite3_malloc64(sizeof(StatCursor)); + if( pCsr==0 ){ + rc = SQLITE_NOMEM; + }else{ + char *zSql; + memset(pCsr, 0, sizeof(StatCursor)); + pCsr->base.pVtab = pVTab; + + zSql = sqlite3_mprintf( + "SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type" + " UNION ALL " + "SELECT name, rootpage, type" + " FROM \"%w\".sqlite_master WHERE rootpage!=0" + " ORDER BY name", pTab->db->aDb[pTab->iDb].zName); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0); + sqlite3_free(zSql); + } + if( rc!=SQLITE_OK ){ + sqlite3_free(pCsr); + pCsr = 0; + } + } + + *ppCursor = (sqlite3_vtab_cursor *)pCsr; + return rc; +} + +static void statClearPage(StatPage *p){ + int i; + if( p->aCell ){ + for(i=0; inCell; i++){ + sqlite3_free(p->aCell[i].aOvfl); + } + sqlite3_free(p->aCell); + } + sqlite3PagerUnref(p->pPg); + sqlite3_free(p->zPath); + memset(p, 0, sizeof(StatPage)); +} + +static void statResetCsr(StatCursor *pCsr){ + int i; + sqlite3_reset(pCsr->pStmt); + for(i=0; iaPage); i++){ + statClearPage(&pCsr->aPage[i]); + } + pCsr->iPage = 0; + sqlite3_free(pCsr->zPath); + pCsr->zPath = 0; +} + +/* +** Close a statvfs cursor. +*/ +static int statClose(sqlite3_vtab_cursor *pCursor){ + StatCursor *pCsr = (StatCursor *)pCursor; + statResetCsr(pCsr); + sqlite3_finalize(pCsr->pStmt); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +static void getLocalPayload( + int nUsable, /* Usable bytes per page */ + u8 flags, /* Page flags */ + int nTotal, /* Total record (payload) size */ + int *pnLocal /* OUT: Bytes stored locally */ +){ + int nLocal; + int nMinLocal; + int nMaxLocal; + + if( flags==0x0D ){ /* Table leaf node */ + nMinLocal = (nUsable - 12) * 32 / 255 - 23; + nMaxLocal = nUsable - 35; + }else{ /* Index interior and leaf nodes */ + nMinLocal = (nUsable - 12) * 32 / 255 - 23; + nMaxLocal = (nUsable - 12) * 64 / 255 - 23; + } + + nLocal = nMinLocal + (nTotal - nMinLocal) % (nUsable - 4); + if( nLocal>nMaxLocal ) nLocal = nMinLocal; + *pnLocal = nLocal; +} + +static int statDecodePage(Btree *pBt, StatPage *p){ + int nUnused; + int iOff; + int nHdr; + int isLeaf; + int szPage; + + u8 *aData = sqlite3PagerGetData(p->pPg); + u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0]; + + p->flags = aHdr[0]; + p->nCell = get2byte(&aHdr[3]); + p->nMxPayload = 0; + + isLeaf = (p->flags==0x0A || p->flags==0x0D); + nHdr = 12 - isLeaf*4 + (p->iPgno==1)*100; + + nUnused = get2byte(&aHdr[5]) - nHdr - 2*p->nCell; + nUnused += (int)aHdr[7]; + iOff = get2byte(&aHdr[1]); + while( iOff ){ + nUnused += get2byte(&aData[iOff+2]); + iOff = get2byte(&aData[iOff]); + } + p->nUnused = nUnused; + p->iRightChildPg = isLeaf ? 0 : sqlite3Get4byte(&aHdr[8]); + szPage = sqlite3BtreeGetPageSize(pBt); + + if( p->nCell ){ + int i; /* Used to iterate through cells */ + int nUsable; /* Usable bytes per page */ + + sqlite3BtreeEnter(pBt); + nUsable = szPage - sqlite3BtreeGetReserveNoMutex(pBt); + sqlite3BtreeLeave(pBt); + p->aCell = sqlite3_malloc64((p->nCell+1) * sizeof(StatCell)); + if( p->aCell==0 ) return SQLITE_NOMEM; + memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell)); + + for(i=0; inCell; i++){ + StatCell *pCell = &p->aCell[i]; + + iOff = get2byte(&aData[nHdr+i*2]); + if( !isLeaf ){ + pCell->iChildPg = sqlite3Get4byte(&aData[iOff]); + iOff += 4; + } + if( p->flags==0x05 ){ + /* A table interior node. nPayload==0. */ + }else{ + u32 nPayload; /* Bytes of payload total (local+overflow) */ + int nLocal; /* Bytes of payload stored locally */ + iOff += getVarint32(&aData[iOff], nPayload); + if( p->flags==0x0D ){ + u64 dummy; + iOff += sqlite3GetVarint(&aData[iOff], &dummy); + } + if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload; + getLocalPayload(nUsable, p->flags, nPayload, &nLocal); + pCell->nLocal = nLocal; + assert( nLocal>=0 ); + assert( nPayload>=(u32)nLocal ); + assert( nLocal<=(nUsable-35) ); + if( nPayload>(u32)nLocal ){ + int j; + int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4); + pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4); + pCell->nOvfl = nOvfl; + pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl); + if( pCell->aOvfl==0 ) return SQLITE_NOMEM; + pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]); + for(j=1; jaOvfl[j-1]; + DbPage *pPg = 0; + rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPrev, &pPg); + if( rc!=SQLITE_OK ){ + assert( pPg==0 ); + return rc; + } + pCell->aOvfl[j] = sqlite3Get4byte(sqlite3PagerGetData(pPg)); + sqlite3PagerUnref(pPg); + } + } + } + } + } + + return SQLITE_OK; +} + +/* +** Populate the pCsr->iOffset and pCsr->szPage member variables. Based on +** the current value of pCsr->iPageno. +*/ +static void statSizeAndOffset(StatCursor *pCsr){ + StatTable *pTab = (StatTable *)((sqlite3_vtab_cursor *)pCsr)->pVtab; + Btree *pBt = pTab->db->aDb[pTab->iDb].pBt; + Pager *pPager = sqlite3BtreePager(pBt); + sqlite3_file *fd; + sqlite3_int64 x[2]; + + /* The default page size and offset */ + pCsr->szPage = sqlite3BtreeGetPageSize(pBt); + pCsr->iOffset = (i64)pCsr->szPage * (pCsr->iPageno - 1); + + /* If connected to a ZIPVFS backend, override the page size and + ** offset with actual values obtained from ZIPVFS. + */ + fd = sqlite3PagerFile(pPager); + x[0] = pCsr->iPageno; + if( fd->pMethods!=0 && sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){ + pCsr->iOffset = x[0]; + pCsr->szPage = (int)x[1]; + } +} + +/* +** Move a statvfs cursor to the next entry in the file. +*/ +static int statNext(sqlite3_vtab_cursor *pCursor){ + int rc; + int nPayload; + char *z; + StatCursor *pCsr = (StatCursor *)pCursor; + StatTable *pTab = (StatTable *)pCursor->pVtab; + Btree *pBt = pTab->db->aDb[pTab->iDb].pBt; + Pager *pPager = sqlite3BtreePager(pBt); + + sqlite3_free(pCsr->zPath); + pCsr->zPath = 0; + +statNextRestart: + if( pCsr->aPage[0].pPg==0 ){ + rc = sqlite3_step(pCsr->pStmt); + if( rc==SQLITE_ROW ){ + int nPage; + u32 iRoot = (u32)sqlite3_column_int64(pCsr->pStmt, 1); + sqlite3PagerPagecount(pPager, &nPage); + if( nPage==0 ){ + pCsr->isEof = 1; + return sqlite3_reset(pCsr->pStmt); + } + rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg); + pCsr->aPage[0].iPgno = iRoot; + pCsr->aPage[0].iCell = 0; + pCsr->aPage[0].zPath = z = sqlite3_mprintf("/"); + pCsr->iPage = 0; + if( z==0 ) rc = SQLITE_NOMEM; + }else{ + pCsr->isEof = 1; + return sqlite3_reset(pCsr->pStmt); + } + }else{ + + /* Page p itself has already been visited. */ + StatPage *p = &pCsr->aPage[pCsr->iPage]; + + while( p->iCellnCell ){ + StatCell *pCell = &p->aCell[p->iCell]; + if( pCell->iOvflnOvfl ){ + int nUsable; + sqlite3BtreeEnter(pBt); + nUsable = sqlite3BtreeGetPageSize(pBt) - + sqlite3BtreeGetReserveNoMutex(pBt); + sqlite3BtreeLeave(pBt); + pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0); + pCsr->iPageno = pCell->aOvfl[pCell->iOvfl]; + pCsr->zPagetype = "overflow"; + pCsr->nCell = 0; + pCsr->nMxPayload = 0; + pCsr->zPath = z = sqlite3_mprintf( + "%s%.3x+%.6x", p->zPath, p->iCell, pCell->iOvfl + ); + if( pCell->iOvflnOvfl-1 ){ + pCsr->nUnused = 0; + pCsr->nPayload = nUsable - 4; + }else{ + pCsr->nPayload = pCell->nLastOvfl; + pCsr->nUnused = nUsable - 4 - pCsr->nPayload; + } + pCell->iOvfl++; + statSizeAndOffset(pCsr); + return z==0 ? SQLITE_NOMEM : SQLITE_OK; + } + if( p->iRightChildPg ) break; + p->iCell++; + } + + if( !p->iRightChildPg || p->iCell>p->nCell ){ + statClearPage(p); + if( pCsr->iPage==0 ) return statNext(pCursor); + pCsr->iPage--; + goto statNextRestart; /* Tail recursion */ + } + pCsr->iPage++; + assert( p==&pCsr->aPage[pCsr->iPage-1] ); + + if( p->iCell==p->nCell ){ + p[1].iPgno = p->iRightChildPg; + }else{ + p[1].iPgno = p->aCell[p->iCell].iChildPg; + } + rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg); + p[1].iCell = 0; + p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell); + p->iCell++; + if( z==0 ) rc = SQLITE_NOMEM; + } + + + /* Populate the StatCursor fields with the values to be returned + ** by the xColumn() and xRowid() methods. + */ + if( rc==SQLITE_OK ){ + int i; + StatPage *p = &pCsr->aPage[pCsr->iPage]; + pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0); + pCsr->iPageno = p->iPgno; + + rc = statDecodePage(pBt, p); + if( rc==SQLITE_OK ){ + statSizeAndOffset(pCsr); + + switch( p->flags ){ + case 0x05: /* table internal */ + case 0x02: /* index internal */ + pCsr->zPagetype = "internal"; + break; + case 0x0D: /* table leaf */ + case 0x0A: /* index leaf */ + pCsr->zPagetype = "leaf"; + break; + default: + pCsr->zPagetype = "corrupted"; + break; + } + pCsr->nCell = p->nCell; + pCsr->nUnused = p->nUnused; + pCsr->nMxPayload = p->nMxPayload; + pCsr->zPath = z = sqlite3_mprintf("%s", p->zPath); + if( z==0 ) rc = SQLITE_NOMEM; + nPayload = 0; + for(i=0; inCell; i++){ + nPayload += p->aCell[i].nLocal; + } + pCsr->nPayload = nPayload; + } + } + + return rc; +} + +static int statEof(sqlite3_vtab_cursor *pCursor){ + StatCursor *pCsr = (StatCursor *)pCursor; + return pCsr->isEof; +} + +static int statFilter( + sqlite3_vtab_cursor *pCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + StatCursor *pCsr = (StatCursor *)pCursor; + + statResetCsr(pCsr); + return statNext(pCursor); +} + +static int statColumn( + sqlite3_vtab_cursor *pCursor, + sqlite3_context *ctx, + int i +){ + StatCursor *pCsr = (StatCursor *)pCursor; + switch( i ){ + case 0: /* name */ + sqlite3_result_text(ctx, pCsr->zName, -1, SQLITE_TRANSIENT); + break; + case 1: /* path */ + sqlite3_result_text(ctx, pCsr->zPath, -1, SQLITE_TRANSIENT); + break; + case 2: /* pageno */ + sqlite3_result_int64(ctx, pCsr->iPageno); + break; + case 3: /* pagetype */ + sqlite3_result_text(ctx, pCsr->zPagetype, -1, SQLITE_STATIC); + break; + case 4: /* ncell */ + sqlite3_result_int(ctx, pCsr->nCell); + break; + case 5: /* payload */ + sqlite3_result_int(ctx, pCsr->nPayload); + break; + case 6: /* unused */ + sqlite3_result_int(ctx, pCsr->nUnused); + break; + case 7: /* mx_payload */ + sqlite3_result_int(ctx, pCsr->nMxPayload); + break; + case 8: /* pgoffset */ + sqlite3_result_int64(ctx, pCsr->iOffset); + break; + default: /* pgsize */ + assert( i==9 ); + sqlite3_result_int(ctx, pCsr->szPage); + break; + } + return SQLITE_OK; +} + +static int statRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ + StatCursor *pCsr = (StatCursor *)pCursor; + *pRowid = pCsr->iPageno; + return SQLITE_OK; +} + +/* +** Invoke this routine to register the "dbstat" virtual table module +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_dbstat_register(sqlite3 *db){ + static sqlite3_module dbstat_module = { + 0, /* iVersion */ + statConnect, /* xCreate */ + statConnect, /* xConnect */ + statBestIndex, /* xBestIndex */ + statDisconnect, /* xDisconnect */ + statDisconnect, /* xDestroy */ + statOpen, /* xOpen - open a cursor */ + statClose, /* xClose - close a cursor */ + statFilter, /* xFilter - configure scan constraints */ + statNext, /* xNext - advance a cursor */ + statEof, /* xEof - check for end of scan */ + statColumn, /* xColumn - read data */ + statRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ + }; + return sqlite3_create_module(db, "dbstat", &dbstat_module, 0); +} +#endif /* SQLITE_ENABLE_DBSTAT_VTAB */ + +/************** End of dbstat.c **********************************************/ diff --git a/src/sqlite3.h b/src/sqlite3.h new file mode 100644 index 0000000..023da28 --- /dev/null +++ b/src/sqlite3.h @@ -0,0 +1,7831 @@ +/* +** 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. +** +************************************************************************* +** This header file defines the interface that the SQLite library +** presents to client programs. If a C-function, structure, datatype, +** or constant definition does not appear in this file, then it is +** not a published API of SQLite, is subject to change without +** notice, and should not be referenced by programs that use SQLite. +** +** Some of the definitions that are in this file are marked as +** "experimental". Experimental interfaces are normally new +** features recently added to SQLite. We do not anticipate changes +** to experimental interfaces but reserve the right to make minor changes +** if experience from use "in the wild" suggest such changes are prudent. +** +** The official C-language API documentation for SQLite is derived +** from comments in this file. This file is the authoritative source +** on how SQLite interfaces are suppose to operate. +** +** The name of this file under configuration management is "sqlite.h.in". +** The makefile makes some minor changes to this file (such as inserting +** the version number) and changes its name to "sqlite3.h" as +** part of the build process. +*/ +#ifndef _SQLITE3_H_ +#define _SQLITE3_H_ +#include /* Needed for the definition of va_list */ + +/* +** Make sure we can call this stuff from C++. +*/ +#ifdef __cplusplus +extern "C" { +#endif + + +/* +** Provide the ability to override linkage features of the interface. +*/ +#ifndef SQLITE_EXTERN +# define SQLITE_EXTERN extern +#endif +#ifndef SQLITE_API +# define SQLITE_API +#endif +#ifndef SQLITE_CDECL +# define SQLITE_CDECL +#endif +#ifndef SQLITE_STDCALL +# define SQLITE_STDCALL +#endif + +/* +** These no-op macros are used in front of interfaces to mark those +** interfaces as either deprecated or experimental. New applications +** should not use deprecated interfaces - they are supported for backwards +** compatibility only. Application writers should be aware that +** experimental interfaces are subject to change in point releases. +** +** These macros used to resolve to various kinds of compiler magic that +** would generate warning messages when they were used. But that +** compiler magic ended up generating such a flurry of bug reports +** that we have taken it all out and gone back to using simple +** noop macros. +*/ +#define SQLITE_DEPRECATED +#define SQLITE_EXPERIMENTAL + +/* +** Ensure these symbols were not defined by some previous header file. +*/ +#ifdef SQLITE_VERSION +# undef SQLITE_VERSION +#endif +#ifdef SQLITE_VERSION_NUMBER +# undef SQLITE_VERSION_NUMBER +#endif + +/* +** CAPI3REF: Compile-Time Library Version Numbers +** +** ^(The [SQLITE_VERSION] C preprocessor macro in the sqlite3.h header +** evaluates to a string literal that is the SQLite version in the +** format "X.Y.Z" where X is the major version number (always 3 for +** SQLite3) and Y is the minor version number and Z is the release number.)^ +** ^(The [SQLITE_VERSION_NUMBER] C preprocessor macro resolves to an integer +** with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same +** numbers used in [SQLITE_VERSION].)^ +** The SQLITE_VERSION_NUMBER for any given release of SQLite will also +** be larger than the release from which it is derived. Either Y will +** be held constant and Z will be incremented or else Y will be incremented +** and Z will be reset to zero. +** +** Since version 3.6.18, SQLite source code has been stored in the +** Fossil configuration management +** system. ^The SQLITE_SOURCE_ID macro evaluates to +** a string which identifies a particular check-in of SQLite +** within its configuration management system. ^The SQLITE_SOURCE_ID +** string contains the date and time of the check-in (UTC) and an SHA1 +** hash of the entire source tree. +** +** See also: [sqlite3_libversion()], +** [sqlite3_libversion_number()], [sqlite3_sourceid()], +** [sqlite_version()] and [sqlite_source_id()]. +*/ +#define SQLITE_VERSION "3.8.10.1" +#define SQLITE_VERSION_NUMBER 3008010 +#define SQLITE_SOURCE_ID "2015-05-09 12:14:55 05b4b1f2a937c06c90db70c09890038f6c98ec40" + +/* +** CAPI3REF: Run-Time Library Version Numbers +** KEYWORDS: sqlite3_version, sqlite3_sourceid +** +** These interfaces provide the same information as the [SQLITE_VERSION], +** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros +** but are associated with the library instead of the header file. ^(Cautious +** programmers might include assert() statements in their application to +** verify that values returned by these interfaces match the macros in +** the header, and thus insure that the application is +** compiled with matching library and header files. +** +**
    +** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
    +** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
    +** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
    +** 
    )^ +** +** ^The sqlite3_version[] string constant contains the text of [SQLITE_VERSION] +** macro. ^The sqlite3_libversion() function returns a pointer to the +** to the sqlite3_version[] string constant. The sqlite3_libversion() +** function is provided for use in DLLs since DLL users usually do not have +** direct access to string constants within the DLL. ^The +** sqlite3_libversion_number() function returns an integer equal to +** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns +** a pointer to a string constant whose value is the same as the +** [SQLITE_SOURCE_ID] C preprocessor macro. +** +** See also: [sqlite_version()] and [sqlite_source_id()]. +*/ +SQLITE_API SQLITE_EXTERN const char sqlite3_version[]; +SQLITE_API const char *SQLITE_STDCALL sqlite3_libversion(void); +SQLITE_API const char *SQLITE_STDCALL sqlite3_sourceid(void); +SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void); + +/* +** CAPI3REF: Run-Time Library Compilation Options Diagnostics +** +** ^The sqlite3_compileoption_used() function returns 0 or 1 +** indicating whether the specified option was defined at +** compile time. ^The SQLITE_ prefix may be omitted from the +** option name passed to sqlite3_compileoption_used(). +** +** ^The sqlite3_compileoption_get() function allows iterating +** over the list of options that were defined at compile time by +** returning the N-th compile time option string. ^If N is out of range, +** sqlite3_compileoption_get() returns a NULL pointer. ^The SQLITE_ +** prefix is omitted from any strings returned by +** sqlite3_compileoption_get(). +** +** ^Support for the diagnostic functions sqlite3_compileoption_used() +** and sqlite3_compileoption_get() may be omitted by specifying the +** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time. +** +** See also: SQL functions [sqlite_compileoption_used()] and +** [sqlite_compileoption_get()] and the [compile_options pragma]. +*/ +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS +SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName); +SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N); +#endif + +/* +** CAPI3REF: Test To See If The Library Is Threadsafe +** +** ^The sqlite3_threadsafe() function returns zero if and only if +** SQLite was compiled with mutexing code omitted due to the +** [SQLITE_THREADSAFE] compile-time option being set to 0. +** +** SQLite can be compiled with or without mutexes. When +** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes +** are enabled and SQLite is threadsafe. When the +** [SQLITE_THREADSAFE] macro is 0, +** the mutexes are omitted. Without the mutexes, it is not safe +** to use SQLite concurrently from more than one thread. +** +** Enabling mutexes incurs a measurable performance penalty. +** So if speed is of utmost importance, it makes sense to disable +** the mutexes. But for maximum safety, mutexes should be enabled. +** ^The default behavior is for mutexes to be enabled. +** +** This interface can be used by an application to make sure that the +** version of SQLite that it is linking against was compiled with +** the desired setting of the [SQLITE_THREADSAFE] macro. +** +** This interface only reports on the compile-time mutex setting +** of the [SQLITE_THREADSAFE] flag. If SQLite is compiled with +** SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but +** can be fully or partially disabled using a call to [sqlite3_config()] +** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD], +** or [SQLITE_CONFIG_SERIALIZED]. ^(The return value of the +** sqlite3_threadsafe() function shows only the compile-time setting of +** thread safety, not any run-time changes to that setting made by +** sqlite3_config(). In other words, the return value from sqlite3_threadsafe() +** is unchanged by calls to sqlite3_config().)^ +** +** See the [threading mode] documentation for additional information. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void); + +/* +** CAPI3REF: Database Connection Handle +** KEYWORDS: {database connection} {database connections} +** +** Each open SQLite database is represented by a pointer to an instance of +** the opaque structure named "sqlite3". It is useful to think of an sqlite3 +** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and +** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()] +** and [sqlite3_close_v2()] are its destructors. There are many other +** interfaces (such as +** [sqlite3_prepare_v2()], [sqlite3_create_function()], and +** [sqlite3_busy_timeout()] to name but three) that are methods on an +** sqlite3 object. +*/ +typedef struct sqlite3 sqlite3; + +/* +** CAPI3REF: 64-Bit Integer Types +** KEYWORDS: sqlite_int64 sqlite_uint64 +** +** Because there is no cross-platform way to specify 64-bit integer types +** SQLite includes typedefs for 64-bit signed and unsigned integers. +** +** The sqlite3_int64 and sqlite3_uint64 are the preferred type definitions. +** The sqlite_int64 and sqlite_uint64 types are supported for backwards +** compatibility only. +** +** ^The sqlite3_int64 and sqlite_int64 types can store integer values +** between -9223372036854775808 and +9223372036854775807 inclusive. ^The +** sqlite3_uint64 and sqlite_uint64 types can store integer values +** between 0 and +18446744073709551615 inclusive. +*/ +#ifdef SQLITE_INT64_TYPE + typedef SQLITE_INT64_TYPE sqlite_int64; + typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; +#elif defined(_MSC_VER) || defined(__BORLANDC__) + typedef __int64 sqlite_int64; + typedef unsigned __int64 sqlite_uint64; +#else + typedef long long int sqlite_int64; + typedef unsigned long long int sqlite_uint64; +#endif +typedef sqlite_int64 sqlite3_int64; +typedef sqlite_uint64 sqlite3_uint64; + +/* +** If compiling for a processor that lacks floating point support, +** substitute integer for floating-point. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# define double sqlite3_int64 +#endif + +/* +** CAPI3REF: Closing A Database Connection +** DESTRUCTOR: sqlite3 +** +** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors +** for the [sqlite3] object. +** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if +** the [sqlite3] object is successfully destroyed and all associated +** resources are deallocated. +** +** ^If the database connection is associated with unfinalized prepared +** statements or unfinished sqlite3_backup objects then sqlite3_close() +** will leave the database connection open and return [SQLITE_BUSY]. +** ^If sqlite3_close_v2() is called with unfinalized prepared statements +** and/or unfinished sqlite3_backups, then the database connection becomes +** an unusable "zombie" which will automatically be deallocated when the +** last prepared statement is finalized or the last sqlite3_backup is +** finished. The sqlite3_close_v2() interface is intended for use with +** host languages that are garbage collected, and where the order in which +** destructors are called is arbitrary. +** +** Applications should [sqlite3_finalize | finalize] all [prepared statements], +** [sqlite3_blob_close | close] all [BLOB handles], and +** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated +** with the [sqlite3] object prior to attempting to close the object. ^If +** sqlite3_close_v2() is called on a [database connection] that still has +** outstanding [prepared statements], [BLOB handles], and/or +** [sqlite3_backup] objects then it returns [SQLITE_OK] and the deallocation +** of resources is deferred until all [prepared statements], [BLOB handles], +** and [sqlite3_backup] objects are also destroyed. +** +** ^If an [sqlite3] object is destroyed while a transaction is open, +** the transaction is automatically rolled back. +** +** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)] +** must be either a NULL +** pointer or an [sqlite3] object pointer obtained +** from [sqlite3_open()], [sqlite3_open16()], or +** [sqlite3_open_v2()], and not previously closed. +** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer +** argument is a harmless no-op. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3*); +SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3*); + +/* +** The type for a callback function. +** This is legacy and deprecated. It is included for historical +** compatibility and is not documented. +*/ +typedef int (*sqlite3_callback)(void*,int,char**, char**); + +/* +** CAPI3REF: One-Step Query Execution Interface +** METHOD: sqlite3 +** +** The sqlite3_exec() interface is a convenience wrapper around +** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()], +** that allows an application to run multiple statements of SQL +** without having to use a lot of C code. +** +** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded, +** semicolon-separate SQL statements passed into its 2nd argument, +** in the context of the [database connection] passed in as its 1st +** argument. ^If the callback function of the 3rd argument to +** sqlite3_exec() is not NULL, then it is invoked for each result row +** coming out of the evaluated SQL statements. ^The 4th argument to +** sqlite3_exec() is relayed through to the 1st argument of each +** callback invocation. ^If the callback pointer to sqlite3_exec() +** is NULL, then no callback is ever invoked and result rows are +** ignored. +** +** ^If an error occurs while evaluating the SQL statements passed into +** sqlite3_exec(), then execution of the current statement stops and +** subsequent statements are skipped. ^If the 5th parameter to sqlite3_exec() +** is not NULL then any error message is written into memory obtained +** from [sqlite3_malloc()] and passed back through the 5th parameter. +** To avoid memory leaks, the application should invoke [sqlite3_free()] +** on error message strings returned through the 5th parameter of +** of sqlite3_exec() after the error message string is no longer needed. +** ^If the 5th parameter to sqlite3_exec() is not NULL and no errors +** occur, then sqlite3_exec() sets the pointer in its 5th parameter to +** NULL before returning. +** +** ^If an sqlite3_exec() callback returns non-zero, the sqlite3_exec() +** routine returns SQLITE_ABORT without invoking the callback again and +** without running any subsequent SQL statements. +** +** ^The 2nd argument to the sqlite3_exec() callback function is the +** number of columns in the result. ^The 3rd argument to the sqlite3_exec() +** callback is an array of pointers to strings obtained as if from +** [sqlite3_column_text()], one for each column. ^If an element of a +** result row is NULL then the corresponding string pointer for the +** sqlite3_exec() callback is a NULL pointer. ^The 4th argument to the +** sqlite3_exec() callback is an array of pointers to strings where each +** entry represents the name of corresponding result column as obtained +** from [sqlite3_column_name()]. +** +** ^If the 2nd parameter to sqlite3_exec() is a NULL pointer, a pointer +** to an empty string, or a pointer that contains only whitespace and/or +** SQL comments, then no SQL statements are evaluated and the database +** is not changed. +** +** Restrictions: +** +**
      +**
    • The application must insure that the 1st parameter to sqlite3_exec() +** is a valid and open [database connection]. +**
    • The application must not close the [database connection] specified by +** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. +**
    • The application must not modify the SQL statement text passed into +** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. +**
    +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_exec( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be evaluated */ + int (*callback)(void*,int,char**,char**), /* Callback function */ + void *, /* 1st argument to callback */ + char **errmsg /* Error msg written here */ +); + +/* +** CAPI3REF: Result Codes +** KEYWORDS: {result code definitions} +** +** Many SQLite functions return an integer result code from the set shown +** here in order to indicate success or failure. +** +** New error codes may be added in future versions of SQLite. +** +** See also: [extended result code definitions] +*/ +#define SQLITE_OK 0 /* Successful result */ +/* beginning-of-error-codes */ +#define SQLITE_ERROR 1 /* SQL error or missing database */ +#define SQLITE_INTERNAL 2 /* 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 /* Unknown opcode in sqlite3_file_control() */ +#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 /* String or BLOB exceeds size limit */ +#define SQLITE_CONSTRAINT 19 /* Abort due to constraint 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_NOTICE 27 /* Notifications from sqlite3_log() */ +#define SQLITE_WARNING 28 /* Warnings from sqlite3_log() */ +#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ +#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ +/* end-of-error-codes */ + +/* +** CAPI3REF: Extended Result Codes +** KEYWORDS: {extended result code definitions} +** +** In its default configuration, SQLite API routines return one of 30 integer +** [result codes]. However, experience has shown that many of +** these result codes are too coarse-grained. They do not provide as +** much information about problems as programmers might like. In an effort to +** address this, newer versions of SQLite (version 3.3.8 and later) include +** support for additional result codes that provide more detailed information +** about errors. These [extended result codes] are enabled or disabled +** on a per database connection basis using the +** [sqlite3_extended_result_codes()] API. Or, the extended code for +** the most recent error can be obtained using +** [sqlite3_extended_errcode()]. +*/ +#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) +#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) +#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) +#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) +#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) +#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) +#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) +#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) +#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) +#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8)) +#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8)) +#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8)) +#define SQLITE_IOERR_ACCESS (SQLITE_IOERR | (13<<8)) +#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8)) +#define SQLITE_IOERR_LOCK (SQLITE_IOERR | (15<<8)) +#define SQLITE_IOERR_CLOSE (SQLITE_IOERR | (16<<8)) +#define SQLITE_IOERR_DIR_CLOSE (SQLITE_IOERR | (17<<8)) +#define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8)) +#define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) +#define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) +#define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) +#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) +#define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) +#define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) +#define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) +#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8)) +#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) +#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) +#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) +#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) +#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) +#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) +#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) +#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) +#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) +#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) +#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) +#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8)) +#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) +#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8)) +#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8)) +#define SQLITE_CONSTRAINT_FOREIGNKEY (SQLITE_CONSTRAINT | (3<<8)) +#define SQLITE_CONSTRAINT_FUNCTION (SQLITE_CONSTRAINT | (4<<8)) +#define SQLITE_CONSTRAINT_NOTNULL (SQLITE_CONSTRAINT | (5<<8)) +#define SQLITE_CONSTRAINT_PRIMARYKEY (SQLITE_CONSTRAINT | (6<<8)) +#define SQLITE_CONSTRAINT_TRIGGER (SQLITE_CONSTRAINT | (7<<8)) +#define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8<<8)) +#define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8)) +#define SQLITE_CONSTRAINT_ROWID (SQLITE_CONSTRAINT |(10<<8)) +#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8)) +#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8)) +#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) +#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) + +/* +** CAPI3REF: Flags For File Open Operations +** +** These bit values are intended for use in the +** 3rd parameter to the [sqlite3_open_v2()] interface and +** in the 4th parameter to the [sqlite3_vfs.xOpen] method. +*/ +#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ +#define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ +#define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */ +#define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_MEMORY 0x00000080 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */ +#define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */ +#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */ +#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */ +#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */ +#define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ +#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ +#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_WAL 0x00080000 /* VFS only */ + +/* Reserved: 0x00F00000 */ + +/* +** CAPI3REF: Device Characteristics +** +** The xDeviceCharacteristics method of the [sqlite3_io_methods] +** object returns an integer which is a vector of these +** bit values expressing I/O characteristics of the mass storage +** device that holds the file that the [sqlite3_io_methods] +** refers to. +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that +** after reboot following a crash or power loss, the only bytes in a +** file that were written at the application level might have changed +** and that adjacent bytes, even bytes within the same sector are +** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN +** flag indicate that a file cannot be deleted when open. The +** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on +** read-only media and cannot be changed even by processes with +** elevated privileges. +*/ +#define SQLITE_IOCAP_ATOMIC 0x00000001 +#define SQLITE_IOCAP_ATOMIC512 0x00000002 +#define SQLITE_IOCAP_ATOMIC1K 0x00000004 +#define SQLITE_IOCAP_ATOMIC2K 0x00000008 +#define SQLITE_IOCAP_ATOMIC4K 0x00000010 +#define SQLITE_IOCAP_ATOMIC8K 0x00000020 +#define SQLITE_IOCAP_ATOMIC16K 0x00000040 +#define SQLITE_IOCAP_ATOMIC32K 0x00000080 +#define SQLITE_IOCAP_ATOMIC64K 0x00000100 +#define SQLITE_IOCAP_SAFE_APPEND 0x00000200 +#define SQLITE_IOCAP_SEQUENTIAL 0x00000400 +#define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 +#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 +#define SQLITE_IOCAP_IMMUTABLE 0x00002000 + +/* +** CAPI3REF: File Locking Levels +** +** SQLite uses one of these integer values as the second +** argument to calls it makes to the xLock() and xUnlock() methods +** of an [sqlite3_io_methods] object. +*/ +#define SQLITE_LOCK_NONE 0 +#define SQLITE_LOCK_SHARED 1 +#define SQLITE_LOCK_RESERVED 2 +#define SQLITE_LOCK_PENDING 3 +#define SQLITE_LOCK_EXCLUSIVE 4 + +/* +** CAPI3REF: Synchronization Type Flags +** +** When SQLite invokes the xSync() method of an +** [sqlite3_io_methods] object it uses a combination of +** these integer values as the second argument. +** +** When the SQLITE_SYNC_DATAONLY flag is used, it means that the +** sync operation only needs to flush data to mass storage. Inode +** information need not be flushed. If the lower four bits of the flag +** equal SQLITE_SYNC_NORMAL, that means to use normal fsync() semantics. +** If the lower four bits equal SQLITE_SYNC_FULL, that means +** to use Mac OS X style fullsync instead of fsync(). +** +** Do not confuse the SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags +** with the [PRAGMA synchronous]=NORMAL and [PRAGMA synchronous]=FULL +** settings. The [synchronous pragma] determines when calls to the +** xSync VFS method occur and applies uniformly across all platforms. +** The SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags determine how +** energetic or rigorous or forceful the sync operations are and +** only make a difference on Mac OSX for the default SQLite code. +** (Third-party VFS implementations might also make the distinction +** between SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL, but among the +** operating systems natively supported by SQLite, only Mac OSX +** cares about the difference.) +*/ +#define SQLITE_SYNC_NORMAL 0x00002 +#define SQLITE_SYNC_FULL 0x00003 +#define SQLITE_SYNC_DATAONLY 0x00010 + +/* +** CAPI3REF: OS Interface Open File Handle +** +** An [sqlite3_file] object represents an open file in the +** [sqlite3_vfs | OS interface layer]. Individual OS interface +** implementations will +** want to subclass this object by appending additional fields +** for their own use. The pMethods entry is a pointer to an +** [sqlite3_io_methods] object that defines methods for performing +** I/O operations on the open file. +*/ +typedef struct sqlite3_file sqlite3_file; +struct sqlite3_file { + const struct sqlite3_io_methods *pMethods; /* Methods for an open file */ +}; + +/* +** CAPI3REF: OS Interface File Virtual Methods Object +** +** Every file opened by the [sqlite3_vfs.xOpen] method populates an +** [sqlite3_file] object (or, more commonly, a subclass of the +** [sqlite3_file] object) with a pointer to an instance of this object. +** This object defines the methods used to perform various operations +** against the open file represented by the [sqlite3_file] object. +** +** If the [sqlite3_vfs.xOpen] method sets the sqlite3_file.pMethods element +** to a non-NULL pointer, then the sqlite3_io_methods.xClose method +** may be invoked even if the [sqlite3_vfs.xOpen] reported that it failed. The +** only way to prevent a call to xClose following a failed [sqlite3_vfs.xOpen] +** is for the [sqlite3_vfs.xOpen] to set the sqlite3_file.pMethods element +** to NULL. +** +** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or +** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). +** The second choice is a Mac OS X style fullsync. The [SQLITE_SYNC_DATAONLY] +** flag may be ORed in to indicate that only the data of the file +** and not its inode needs to be synced. +** +** The integer values to xLock() and xUnlock() are one of +**
      +**
    • [SQLITE_LOCK_NONE], +**
    • [SQLITE_LOCK_SHARED], +**
    • [SQLITE_LOCK_RESERVED], +**
    • [SQLITE_LOCK_PENDING], or +**
    • [SQLITE_LOCK_EXCLUSIVE]. +**
    +** xLock() increases the lock. xUnlock() decreases the lock. +** The xCheckReservedLock() method checks whether any database connection, +** either in this process or in some other process, is holding a RESERVED, +** PENDING, or EXCLUSIVE lock on the file. It returns true +** if such a lock exists and false otherwise. +** +** The xFileControl() method is a generic interface that allows custom +** VFS implementations to directly control an open file using the +** [sqlite3_file_control()] interface. The second "op" argument is an +** integer opcode. The third argument is a generic pointer intended to +** point to a structure that may contain arguments or space in which to +** write return values. Potential uses for xFileControl() might be +** functions to enable blocking locks with timeouts, to change the +** locking strategy (for example to use dot-file locks), to inquire +** about the status of a lock, or to break stale locks. The SQLite +** core reserves all opcodes less than 100 for its own use. +** A [file control opcodes | list of opcodes] less than 100 is available. +** Applications that define a custom xFileControl method should use opcodes +** greater than 100 to avoid conflicts. VFS implementations should +** return [SQLITE_NOTFOUND] for file control opcodes that they do not +** recognize. +** +** The xSectorSize() method returns the sector size of the +** device that underlies the file. The sector size is the +** minimum write that can be performed without disturbing +** other bytes in the file. The xDeviceCharacteristics() +** method returns a bit vector describing behaviors of the +** underlying device: +** +**
      +**
    • [SQLITE_IOCAP_ATOMIC] +**
    • [SQLITE_IOCAP_ATOMIC512] +**
    • [SQLITE_IOCAP_ATOMIC1K] +**
    • [SQLITE_IOCAP_ATOMIC2K] +**
    • [SQLITE_IOCAP_ATOMIC4K] +**
    • [SQLITE_IOCAP_ATOMIC8K] +**
    • [SQLITE_IOCAP_ATOMIC16K] +**
    • [SQLITE_IOCAP_ATOMIC32K] +**
    • [SQLITE_IOCAP_ATOMIC64K] +**
    • [SQLITE_IOCAP_SAFE_APPEND] +**
    • [SQLITE_IOCAP_SEQUENTIAL] +**
    +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +** +** If xRead() returns SQLITE_IOERR_SHORT_READ it must also fill +** in the unread portions of the buffer with zeros. A VFS that +** fails to zero-fill short reads might seem to work. However, +** failure to zero-fill short reads will eventually lead to +** database corruption. +*/ +typedef struct sqlite3_io_methods sqlite3_io_methods; +struct sqlite3_io_methods { + int iVersion; + int (*xClose)(sqlite3_file*); + int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); + int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); + int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); + int (*xSync)(sqlite3_file*, int flags); + int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); + int (*xLock)(sqlite3_file*, int); + int (*xUnlock)(sqlite3_file*, int); + int (*xCheckReservedLock)(sqlite3_file*, int *pResOut); + int (*xFileControl)(sqlite3_file*, int op, void *pArg); + int (*xSectorSize)(sqlite3_file*); + int (*xDeviceCharacteristics)(sqlite3_file*); + /* Methods above are valid for version 1 */ + int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**); + int (*xShmLock)(sqlite3_file*, int offset, int n, int flags); + void (*xShmBarrier)(sqlite3_file*); + int (*xShmUnmap)(sqlite3_file*, int deleteFlag); + /* Methods above are valid for version 2 */ + int (*xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); + int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p); + /* Methods above are valid for version 3 */ + /* Additional methods may be added in future releases */ +}; + +/* +** CAPI3REF: Standard File Control Opcodes +** KEYWORDS: {file control opcodes} {file control opcode} +** +** These integer constants are opcodes for the xFileControl method +** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()] +** interface. +** +**
      +**
    • [[SQLITE_FCNTL_LOCKSTATE]] +** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This +** opcode causes the xFileControl method to write the current state of +** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], +** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) +** into an integer that the pArg argument points to. This capability +** is used during testing and is only available when the SQLITE_TEST +** compile-time option is used. +** +**
    • [[SQLITE_FCNTL_SIZE_HINT]] +** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS +** layer a hint of how large the database file will grow to be during the +** current transaction. This hint is not guaranteed to be accurate but it +** is often close. The underlying VFS might choose to preallocate database +** file space based on this hint in order to help writes to the database +** file run faster. +** +**
    • [[SQLITE_FCNTL_CHUNK_SIZE]] +** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS +** extends and truncates the database file in chunks of a size specified +** by the user. The fourth argument to [sqlite3_file_control()] should +** point to an integer (type int) containing the new chunk-size to use +** for the nominated database. Allocating database file space in large +** chunks (say 1MB at a time), may reduce file-system fragmentation and +** improve performance on some systems. +** +**
    • [[SQLITE_FCNTL_FILE_POINTER]] +** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer +** to the [sqlite3_file] object associated with a particular database +** connection. See the [sqlite3_file_control()] documentation for +** additional information. +** +**
    • [[SQLITE_FCNTL_SYNC_OMITTED]] +** No longer in use. +** +**
    • [[SQLITE_FCNTL_SYNC]] +** The [SQLITE_FCNTL_SYNC] opcode is generated internally by SQLite and +** sent to the VFS immediately before the xSync method is invoked on a +** database file descriptor. Or, if the xSync method is not invoked +** because the user has configured SQLite with +** [PRAGMA synchronous | PRAGMA synchronous=OFF] it is invoked in place +** of the xSync method. In most cases, the pointer argument passed with +** this file-control is NULL. However, if the database file is being synced +** as part of a multi-database commit, the argument points to a nul-terminated +** string containing the transactions master-journal file name. VFSes that +** do not need this signal should silently ignore this opcode. Applications +** should not call [sqlite3_file_control()] with this opcode as doing so may +** disrupt the operation of the specialized VFSes that do require it. +** +**
    • [[SQLITE_FCNTL_COMMIT_PHASETWO]] +** The [SQLITE_FCNTL_COMMIT_PHASETWO] opcode is generated internally by SQLite +** and sent to the VFS after a transaction has been committed immediately +** but before the database is unlocked. VFSes that do not need this signal +** should silently ignore this opcode. Applications should not call +** [sqlite3_file_control()] with this opcode as doing so may disrupt the +** operation of the specialized VFSes that do require it. +** +**
    • [[SQLITE_FCNTL_WIN32_AV_RETRY]] +** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic +** retry counts and intervals for certain disk I/O operations for the +** windows [VFS] in order to provide robustness in the presence of +** anti-virus programs. By default, the windows VFS will retry file read, +** file write, and file delete operations up to 10 times, with a delay +** of 25 milliseconds before the first retry and with the delay increasing +** by an additional 25 milliseconds with each subsequent retry. This +** opcode allows these two values (10 retries and 25 milliseconds of delay) +** to be adjusted. The values are changed for all database connections +** within the same process. The argument is a pointer to an array of two +** integers where the first integer i the new retry count and the second +** integer is the delay. If either integer is negative, then the setting +** is not changed but instead the prior value of that setting is written +** into the array entry, allowing the current retry settings to be +** interrogated. The zDbName parameter is ignored. +** +**
    • [[SQLITE_FCNTL_PERSIST_WAL]] +** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the +** persistent [WAL | Write Ahead Log] setting. By default, the auxiliary +** write ahead log and shared memory files used for transaction control +** are automatically deleted when the latest connection to the database +** closes. Setting persistent WAL mode causes those files to persist after +** close. Persisting the files is useful when other processes that do not +** have write permission on the directory containing the database file want +** to read the database file, as the WAL and shared memory files must exist +** in order for the database to be readable. The fourth parameter to +** [sqlite3_file_control()] for this opcode should be a pointer to an integer. +** That integer is 0 to disable persistent WAL mode or 1 to enable persistent +** WAL mode. If the integer is -1, then it is overwritten with the current +** WAL persistence setting. +** +**
    • [[SQLITE_FCNTL_POWERSAFE_OVERWRITE]] +** ^The [SQLITE_FCNTL_POWERSAFE_OVERWRITE] opcode is used to set or query the +** persistent "powersafe-overwrite" or "PSOW" setting. The PSOW setting +** determines the [SQLITE_IOCAP_POWERSAFE_OVERWRITE] bit of the +** xDeviceCharacteristics methods. The fourth parameter to +** [sqlite3_file_control()] for this opcode should be a pointer to an integer. +** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage +** mode. If the integer is -1, then it is overwritten with the current +** zero-damage mode setting. +** +**
    • [[SQLITE_FCNTL_OVERWRITE]] +** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening +** a write transaction to indicate that, unless it is rolled back for some +** reason, the entire database file will be overwritten by the current +** transaction. This is used by VACUUM operations. +** +**
    • [[SQLITE_FCNTL_VFSNAME]] +** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of +** all [VFSes] in the VFS stack. The names are of all VFS shims and the +** final bottom-level VFS are written into memory obtained from +** [sqlite3_malloc()] and the result is stored in the char* variable +** that the fourth parameter of [sqlite3_file_control()] points to. +** The caller is responsible for freeing the memory when done. As with +** all file-control actions, there is no guarantee that this will actually +** do anything. Callers should initialize the char* variable to a NULL +** pointer in case this file-control is not implemented. This file-control +** is intended for diagnostic use only. +** +**
    • [[SQLITE_FCNTL_PRAGMA]] +** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA] +** file control is sent to the open [sqlite3_file] object corresponding +** to the database file to which the pragma statement refers. ^The argument +** to the [SQLITE_FCNTL_PRAGMA] file control is an array of +** pointers to strings (char**) in which the second element of the array +** is the name of the pragma and the third element is the argument to the +** pragma or NULL if the pragma has no argument. ^The handler for an +** [SQLITE_FCNTL_PRAGMA] file control can optionally make the first element +** of the char** argument point to a string obtained from [sqlite3_mprintf()] +** or the equivalent and that string will become the result of the pragma or +** the error message if the pragma fails. ^If the +** [SQLITE_FCNTL_PRAGMA] file control returns [SQLITE_NOTFOUND], then normal +** [PRAGMA] processing continues. ^If the [SQLITE_FCNTL_PRAGMA] +** file control returns [SQLITE_OK], then the parser assumes that the +** VFS has handled the PRAGMA itself and the parser generates a no-op +** prepared statement if result string is NULL, or that returns a copy +** of the result string if the string is non-NULL. +** ^If the [SQLITE_FCNTL_PRAGMA] file control returns +** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means +** that the VFS encountered an error while handling the [PRAGMA] and the +** compilation of the PRAGMA fails with an error. ^The [SQLITE_FCNTL_PRAGMA] +** file control occurs at the beginning of pragma statement analysis and so +** it is able to override built-in [PRAGMA] statements. +** +**
    • [[SQLITE_FCNTL_BUSYHANDLER]] +** ^The [SQLITE_FCNTL_BUSYHANDLER] +** file-control may be invoked by SQLite on the database file handle +** shortly after it is opened in order to provide a custom VFS with access +** to the connections busy-handler callback. The argument is of type (void **) +** - an array of two (void *) values. The first (void *) actually points +** to a function of type (int (*)(void *)). In order to invoke the connections +** busy-handler, this function should be invoked with the second (void *) in +** the array as the only argument. If it returns non-zero, then the operation +** should be retried. If it returns zero, the custom VFS should abandon the +** current operation. +** +**
    • [[SQLITE_FCNTL_TEMPFILENAME]] +** ^Application can invoke the [SQLITE_FCNTL_TEMPFILENAME] file-control +** to have SQLite generate a +** temporary filename using the same algorithm that is followed to generate +** temporary filenames for TEMP tables and other internal uses. The +** argument should be a char** which will be filled with the filename +** written into memory obtained from [sqlite3_malloc()]. The caller should +** invoke [sqlite3_free()] on the result to avoid a memory leak. +** +**
    • [[SQLITE_FCNTL_MMAP_SIZE]] +** The [SQLITE_FCNTL_MMAP_SIZE] file control is used to query or set the +** maximum number of bytes that will be used for memory-mapped I/O. +** The argument is a pointer to a value of type sqlite3_int64 that +** is an advisory maximum number of bytes in the file to memory map. The +** pointer is overwritten with the old value. The limit is not changed if +** the value originally pointed to is negative, and so the current limit +** can be queried by passing in a pointer to a negative number. This +** file-control is used internally to implement [PRAGMA mmap_size]. +** +**
    • [[SQLITE_FCNTL_TRACE]] +** The [SQLITE_FCNTL_TRACE] file control provides advisory information +** to the VFS about what the higher layers of the SQLite stack are doing. +** This file control is used by some VFS activity tracing [shims]. +** The argument is a zero-terminated string. Higher layers in the +** SQLite stack may generate instances of this file control if +** the [SQLITE_USE_FCNTL_TRACE] compile-time option is enabled. +** +**
    • [[SQLITE_FCNTL_HAS_MOVED]] +** The [SQLITE_FCNTL_HAS_MOVED] file control interprets its argument as a +** pointer to an integer and it writes a boolean into that integer depending +** on whether or not the file has been renamed, moved, or deleted since it +** was first opened. +** +**
    • [[SQLITE_FCNTL_WIN32_SET_HANDLE]] +** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This +** opcode causes the xFileControl method to swap the file handle with the one +** pointed to by the pArg argument. This capability is used during testing +** and only needs to be supported when SQLITE_TEST is defined. +** +**
    • [[SQLITE_FCNTL_WAL_BLOCK]] +** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might +** be advantageous to block on the next WAL lock if the lock is not immediately +** available. The WAL subsystem issues this signal during rare +** circumstances in order to fix a problem with priority inversion. +** Applications should not use this file-control. +** +**
    +*/ +#define SQLITE_FCNTL_LOCKSTATE 1 +#define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 +#define SQLITE_FCNTL_SET_LOCKPROXYFILE 3 +#define SQLITE_FCNTL_LAST_ERRNO 4 +#define SQLITE_FCNTL_SIZE_HINT 5 +#define SQLITE_FCNTL_CHUNK_SIZE 6 +#define SQLITE_FCNTL_FILE_POINTER 7 +#define SQLITE_FCNTL_SYNC_OMITTED 8 +#define SQLITE_FCNTL_WIN32_AV_RETRY 9 +#define SQLITE_FCNTL_PERSIST_WAL 10 +#define SQLITE_FCNTL_OVERWRITE 11 +#define SQLITE_FCNTL_VFSNAME 12 +#define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13 +#define SQLITE_FCNTL_PRAGMA 14 +#define SQLITE_FCNTL_BUSYHANDLER 15 +#define SQLITE_FCNTL_TEMPFILENAME 16 +#define SQLITE_FCNTL_MMAP_SIZE 18 +#define SQLITE_FCNTL_TRACE 19 +#define SQLITE_FCNTL_HAS_MOVED 20 +#define SQLITE_FCNTL_SYNC 21 +#define SQLITE_FCNTL_COMMIT_PHASETWO 22 +#define SQLITE_FCNTL_WIN32_SET_HANDLE 23 +#define SQLITE_FCNTL_WAL_BLOCK 24 + +/* deprecated names */ +#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE +#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE +#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO + + +/* +** CAPI3REF: Mutex Handle +** +** The mutex module within SQLite defines [sqlite3_mutex] to be an +** abstract type for a mutex object. The SQLite core never looks +** at the internal representation of an [sqlite3_mutex]. It only +** deals with pointers to the [sqlite3_mutex] object. +** +** Mutexes are created using [sqlite3_mutex_alloc()]. +*/ +typedef struct sqlite3_mutex sqlite3_mutex; + +/* +** CAPI3REF: OS Interface Object +** +** An instance of the sqlite3_vfs object defines the interface between +** the SQLite core and the underlying operating system. The "vfs" +** in the name of the object stands for "virtual file system". See +** the [VFS | VFS documentation] for further information. +** +** The value of the iVersion field is initially 1 but may be larger in +** future versions of SQLite. Additional fields may be appended to this +** object when the iVersion value is increased. Note that the structure +** of the sqlite3_vfs object changes in the transaction between +** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not +** modified. +** +** The szOsFile field is the size of the subclassed [sqlite3_file] +** structure used by this VFS. mxPathname is the maximum length of +** a pathname in this VFS. +** +** Registered sqlite3_vfs objects are kept on a linked list formed by +** the pNext pointer. The [sqlite3_vfs_register()] +** and [sqlite3_vfs_unregister()] interfaces manage this list +** in a thread-safe way. The [sqlite3_vfs_find()] interface +** searches the list. Neither the application code nor the VFS +** implementation should use the pNext pointer. +** +** The pNext field is the only field in the sqlite3_vfs +** structure that SQLite will ever modify. SQLite will only access +** or modify this field while holding a particular static mutex. +** The application should never modify anything within the sqlite3_vfs +** object once the object has been registered. +** +** The zName field holds the name of the VFS module. The name must +** be unique across all VFS modules. +** +** [[sqlite3_vfs.xOpen]] +** ^SQLite guarantees that the zFilename parameter to xOpen +** is either a NULL pointer or string obtained +** from xFullPathname() with an optional suffix added. +** ^If a suffix is added to the zFilename parameter, it will +** consist of a single "-" character followed by no more than +** 11 alphanumeric and/or "-" characters. +** ^SQLite further guarantees that +** the string will be valid and unchanged until xClose() is +** called. Because of the previous sentence, +** the [sqlite3_file] can safely store a pointer to the +** filename if it needs to remember the filename for some reason. +** If the zFilename parameter to xOpen is a NULL pointer then xOpen +** must invent its own temporary name for the file. ^Whenever the +** xFilename parameter is NULL it will also be the case that the +** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE]. +** +** The flags argument to xOpen() includes all bits set in +** the flags argument to [sqlite3_open_v2()]. Or if [sqlite3_open()] +** or [sqlite3_open16()] is used, then flags includes at least +** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. +** If xOpen() opens a file read-only then it sets *pOutFlags to +** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be set. +** +** ^(SQLite will also add one of the following flags to the xOpen() +** call, depending on the object being opened: +** +**
      +**
    • [SQLITE_OPEN_MAIN_DB] +**
    • [SQLITE_OPEN_MAIN_JOURNAL] +**
    • [SQLITE_OPEN_TEMP_DB] +**
    • [SQLITE_OPEN_TEMP_JOURNAL] +**
    • [SQLITE_OPEN_TRANSIENT_DB] +**
    • [SQLITE_OPEN_SUBJOURNAL] +**
    • [SQLITE_OPEN_MASTER_JOURNAL] +**
    • [SQLITE_OPEN_WAL] +**
    )^ +** +** The file I/O implementation can use the object type flags to +** change the way it deals with files. For example, an application +** that does not care about crash recovery or rollback might make +** the open of a journal file a no-op. Writes to this journal would +** also be no-ops, and any attempt to read the journal would return +** SQLITE_IOERR. Or the implementation might recognize that a database +** file will be doing page-aligned sector reads and writes in a random +** order and set up its I/O subsystem accordingly. +** +** SQLite might also add one of the following flags to the xOpen method: +** +**
      +**
    • [SQLITE_OPEN_DELETEONCLOSE] +**
    • [SQLITE_OPEN_EXCLUSIVE] +**
    +** +** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be +** deleted when it is closed. ^The [SQLITE_OPEN_DELETEONCLOSE] +** will be set for TEMP databases and their journals, transient +** databases, and subjournals. +** +** ^The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction +** with the [SQLITE_OPEN_CREATE] flag, which are both directly +** analogous to the O_EXCL and O_CREAT flags of the POSIX open() +** API. The SQLITE_OPEN_EXCLUSIVE flag, when paired with the +** SQLITE_OPEN_CREATE, is used to indicate that file should always +** be created, and that it is an error if it already exists. +** It is not used to indicate the file should be opened +** for exclusive access. +** +** ^At least szOsFile bytes of memory are allocated by SQLite +** to hold the [sqlite3_file] structure passed as the third +** argument to xOpen. The xOpen method does not have to +** allocate the structure; it should just fill it in. Note that +** the xOpen method must set the sqlite3_file.pMethods to either +** a valid [sqlite3_io_methods] object or to NULL. xOpen must do +** this even if the open fails. SQLite expects that the sqlite3_file.pMethods +** element will be valid after xOpen returns regardless of the success +** or failure of the xOpen call. +** +** [[sqlite3_vfs.xAccess]] +** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] +** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to +** test whether a file is readable and writable, or [SQLITE_ACCESS_READ] +** to test whether a file is at least readable. The file can be a +** directory. +** +** ^SQLite will always allocate at least mxPathname+1 bytes for the +** output buffer xFullPathname. The exact size of the output buffer +** is also passed as a parameter to both methods. If the output buffer +** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is +** handled as a fatal error by SQLite, vfs implementations should endeavor +** to prevent this by setting mxPathname to a sufficiently large value. +** +** The xRandomness(), xSleep(), xCurrentTime(), and xCurrentTimeInt64() +** interfaces are not strictly a part of the filesystem, but they are +** included in the VFS structure for completeness. +** The xRandomness() function attempts to return nBytes bytes +** of good-quality randomness into zOut. The return value is +** the actual number of bytes of randomness obtained. +** The xSleep() method causes the calling thread to sleep for at +** least the number of microseconds given. ^The xCurrentTime() +** method returns a Julian Day Number for the current date and time as +** a floating point value. +** ^The xCurrentTimeInt64() method returns, as an integer, the Julian +** Day Number multiplied by 86400000 (the number of milliseconds in +** a 24-hour day). +** ^SQLite will use the xCurrentTimeInt64() method to get the current +** date and time if that method is available (if iVersion is 2 or +** greater and the function pointer is not NULL) and will fall back +** to xCurrentTime() if xCurrentTimeInt64() is unavailable. +** +** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces +** are not used by the SQLite core. These optional interfaces are provided +** by some VFSes to facilitate testing of the VFS code. By overriding +** system calls with functions under its control, a test program can +** simulate faults and error conditions that would otherwise be difficult +** or impossible to induce. The set of system calls that can be overridden +** varies from one VFS to another, and from one version of the same VFS to the +** next. Applications that use these interfaces must be prepared for any +** or all of these interfaces to be NULL or for their behavior to change +** from one release to the next. Applications must not attempt to access +** any of these methods if the iVersion of the VFS is less than 3. +*/ +typedef struct sqlite3_vfs sqlite3_vfs; +typedef void (*sqlite3_syscall_ptr)(void); +struct sqlite3_vfs { + int iVersion; /* Structure version number (currently 3) */ + int szOsFile; /* Size of subclassed sqlite3_file */ + int mxPathname; /* Maximum file pathname length */ + sqlite3_vfs *pNext; /* Next registered VFS */ + const char *zName; /* Name of this virtual file system */ + void *pAppData; /* Pointer to application-specific data */ + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, + int flags, int *pOutFlags); + int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); + int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); + int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); + void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); + void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); + void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void); + void (*xDlClose)(sqlite3_vfs*, void*); + int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); + int (*xSleep)(sqlite3_vfs*, int microseconds); + int (*xCurrentTime)(sqlite3_vfs*, double*); + int (*xGetLastError)(sqlite3_vfs*, int, char *); + /* + ** The methods above are in version 1 of the sqlite_vfs object + ** definition. Those that follow are added in version 2 or later + */ + int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); + /* + ** The methods above are in versions 1 and 2 of the sqlite_vfs object. + ** Those below are for version 3 and greater. + */ + int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr); + sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName); + const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName); + /* + ** The methods above are in versions 1 through 3 of the sqlite_vfs object. + ** New fields may be appended in figure versions. The iVersion + ** value will increment whenever this happens. + */ +}; + +/* +** CAPI3REF: Flags for the xAccess VFS method +** +** These integer constants can be used as the third parameter to +** the xAccess method of an [sqlite3_vfs] object. They determine +** what kind of permissions the xAccess method is looking for. +** With SQLITE_ACCESS_EXISTS, the xAccess method +** simply checks whether the file exists. +** With SQLITE_ACCESS_READWRITE, the xAccess method +** checks whether the named directory is both readable and writable +** (in other words, if files can be added, removed, and renamed within +** the directory). +** The SQLITE_ACCESS_READWRITE constant is currently used only by the +** [temp_store_directory pragma], though this could change in a future +** release of SQLite. +** With SQLITE_ACCESS_READ, the xAccess method +** checks whether the file is readable. The SQLITE_ACCESS_READ constant is +** currently unused, though it might be used in a future release of +** SQLite. +*/ +#define SQLITE_ACCESS_EXISTS 0 +#define SQLITE_ACCESS_READWRITE 1 /* Used by PRAGMA temp_store_directory */ +#define SQLITE_ACCESS_READ 2 /* Unused */ + +/* +** CAPI3REF: Flags for the xShmLock VFS method +** +** These integer constants define the various locking operations +** allowed by the xShmLock method of [sqlite3_io_methods]. The +** following are the only legal combinations of flags to the +** xShmLock method: +** +**
      +**
    • SQLITE_SHM_LOCK | SQLITE_SHM_SHARED +**
    • SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE +**
    • SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED +**
    • SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE +**
    +** +** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as +** was given on the corresponding lock. +** +** The xShmLock method can transition between unlocked and SHARED or +** between unlocked and EXCLUSIVE. It cannot transition between SHARED +** and EXCLUSIVE. +*/ +#define SQLITE_SHM_UNLOCK 1 +#define SQLITE_SHM_LOCK 2 +#define SQLITE_SHM_SHARED 4 +#define SQLITE_SHM_EXCLUSIVE 8 + +/* +** CAPI3REF: Maximum xShmLock index +** +** The xShmLock method on [sqlite3_io_methods] may use values +** between 0 and this upper bound as its "offset" argument. +** The SQLite core will never attempt to acquire or release a +** lock outside of this range +*/ +#define SQLITE_SHM_NLOCK 8 + + +/* +** CAPI3REF: Initialize The SQLite Library +** +** ^The sqlite3_initialize() routine initializes the +** SQLite library. ^The sqlite3_shutdown() routine +** deallocates any resources that were allocated by sqlite3_initialize(). +** These routines are designed to aid in process initialization and +** shutdown on embedded systems. Workstation applications using +** SQLite normally do not need to invoke either of these routines. +** +** A call to sqlite3_initialize() is an "effective" call if it is +** the first time sqlite3_initialize() is invoked during the lifetime of +** the process, or if it is the first time sqlite3_initialize() is invoked +** following a call to sqlite3_shutdown(). ^(Only an effective call +** of sqlite3_initialize() does any initialization. All other calls +** are harmless no-ops.)^ +** +** A call to sqlite3_shutdown() is an "effective" call if it is the first +** call to sqlite3_shutdown() since the last sqlite3_initialize(). ^(Only +** an effective call to sqlite3_shutdown() does any deinitialization. +** All other valid calls to sqlite3_shutdown() are harmless no-ops.)^ +** +** The sqlite3_initialize() interface is threadsafe, but sqlite3_shutdown() +** is not. The sqlite3_shutdown() interface must only be called from a +** single thread. All open [database connections] must be closed and all +** other SQLite resources must be deallocated prior to invoking +** sqlite3_shutdown(). +** +** Among other things, ^sqlite3_initialize() will invoke +** sqlite3_os_init(). Similarly, ^sqlite3_shutdown() +** will invoke sqlite3_os_end(). +** +** ^The sqlite3_initialize() routine returns [SQLITE_OK] on success. +** ^If for some reason, sqlite3_initialize() is unable to initialize +** the library (perhaps it is unable to allocate a needed resource such +** as a mutex) it returns an [error code] other than [SQLITE_OK]. +** +** ^The sqlite3_initialize() routine is called internally by many other +** SQLite interfaces so that an application usually does not need to +** invoke sqlite3_initialize() directly. For example, [sqlite3_open()] +** calls sqlite3_initialize() so the SQLite library will be automatically +** initialized when [sqlite3_open()] is called if it has not be initialized +** already. ^However, if SQLite is compiled with the [SQLITE_OMIT_AUTOINIT] +** compile-time option, then the automatic calls to sqlite3_initialize() +** are omitted and the application must call sqlite3_initialize() directly +** prior to using any other SQLite interface. For maximum portability, +** it is recommended that applications always invoke sqlite3_initialize() +** directly prior to using any other SQLite interface. Future releases +** of SQLite may require this. In other words, the behavior exhibited +** when SQLite is compiled with [SQLITE_OMIT_AUTOINIT] might become the +** default behavior in some future release of SQLite. +** +** The sqlite3_os_init() routine does operating-system specific +** initialization of the SQLite library. The sqlite3_os_end() +** routine undoes the effect of sqlite3_os_init(). Typical tasks +** performed by these routines include allocation or deallocation +** of static resources, initialization of global variables, +** setting up a default [sqlite3_vfs] module, or setting up +** a default configuration using [sqlite3_config()]. +** +** The application should never invoke either sqlite3_os_init() +** or sqlite3_os_end() directly. The application should only invoke +** sqlite3_initialize() and sqlite3_shutdown(). The sqlite3_os_init() +** interface is called automatically by sqlite3_initialize() and +** sqlite3_os_end() is called by sqlite3_shutdown(). Appropriate +** implementations for sqlite3_os_init() and sqlite3_os_end() +** are built into SQLite when it is compiled for Unix, Windows, or OS/2. +** When [custom builds | built for other platforms] +** (using the [SQLITE_OS_OTHER=1] compile-time +** option) the application must supply a suitable implementation for +** sqlite3_os_init() and sqlite3_os_end(). An application-supplied +** implementation of sqlite3_os_init() or sqlite3_os_end() +** must return [SQLITE_OK] on success and some other [error code] upon +** failure. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void); +SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void); +SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void); +SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void); + +/* +** CAPI3REF: Configuring The SQLite Library +** +** The sqlite3_config() interface is used to make global configuration +** changes to SQLite in order to tune SQLite to the specific needs of +** the application. The default configuration is recommended for most +** applications and so this routine is usually not necessary. It is +** provided to support rare applications with unusual needs. +** +** The sqlite3_config() interface is not threadsafe. The application +** must insure that no other SQLite interfaces are invoked by other +** threads while sqlite3_config() is running. Furthermore, sqlite3_config() +** may only be invoked prior to library initialization using +** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()]. +** ^If sqlite3_config() is called after [sqlite3_initialize()] and before +** [sqlite3_shutdown()] then it will return SQLITE_MISUSE. +** Note, however, that ^sqlite3_config() can be called as part of the +** implementation of an application-defined [sqlite3_os_init()]. +** +** The first argument to sqlite3_config() is an integer +** [configuration option] that determines +** what property of SQLite is to be configured. Subsequent arguments +** vary depending on the [configuration option] +** in the first argument. +** +** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. +** ^If the option is unknown or SQLite is unable to set the option +** then this routine returns a non-zero [error code]. +*/ +SQLITE_API int SQLITE_CDECL sqlite3_config(int, ...); + +/* +** CAPI3REF: Configure database connections +** METHOD: sqlite3 +** +** The sqlite3_db_config() interface is used to make configuration +** changes to a [database connection]. The interface is similar to +** [sqlite3_config()] except that the changes apply to a single +** [database connection] (specified in the first argument). +** +** The second argument to sqlite3_db_config(D,V,...) is the +** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code +** that indicates what aspect of the [database connection] is being configured. +** Subsequent arguments vary depending on the configuration verb. +** +** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if +** the call is considered successful. +*/ +SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3*, int op, ...); + +/* +** CAPI3REF: Memory Allocation Routines +** +** An instance of this object defines the interface between SQLite +** and low-level memory allocation routines. +** +** This object is used in only one place in the SQLite interface. +** A pointer to an instance of this object is the argument to +** [sqlite3_config()] when the configuration option is +** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC]. +** By creating an instance of this object +** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC]) +** during configuration, an application can specify an alternative +** memory allocation subsystem for SQLite to use for all of its +** dynamic memory needs. +** +** Note that SQLite comes with several [built-in memory allocators] +** that are perfectly adequate for the overwhelming majority of applications +** and that this object is only useful to a tiny minority of applications +** with specialized memory allocation requirements. This object is +** also used during testing of SQLite in order to specify an alternative +** memory allocator that simulates memory out-of-memory conditions in +** order to verify that SQLite recovers gracefully from such +** conditions. +** +** The xMalloc, xRealloc, and xFree methods must work like the +** malloc(), realloc() and free() functions from the standard C library. +** ^SQLite guarantees that the second argument to +** xRealloc is always a value returned by a prior call to xRoundup. +** +** xSize should return the allocated size of a memory allocation +** previously obtained from xMalloc or xRealloc. The allocated size +** is always at least as big as the requested size but may be larger. +** +** The xRoundup method returns what would be the allocated size of +** a memory allocation given a particular requested size. Most memory +** allocators round up memory allocations at least to the next multiple +** of 8. Some allocators round up to a larger multiple or to a power of 2. +** Every memory allocation request coming in through [sqlite3_malloc()] +** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0, +** that causes the corresponding memory allocation to fail. +** +** The xInit method initializes the memory allocator. For example, +** it might allocate any require mutexes or initialize internal data +** structures. The xShutdown method is invoked (indirectly) by +** [sqlite3_shutdown()] and should deallocate any resources acquired +** by xInit. The pAppData pointer is used as the only parameter to +** xInit and xShutdown. +** +** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes +** the xInit method, so the xInit method need not be threadsafe. The +** xShutdown method is only called from [sqlite3_shutdown()] so it does +** not need to be threadsafe either. For all other methods, SQLite +** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the +** [SQLITE_CONFIG_MEMSTATUS] configuration option is turned on (which +** it is by default) and so the methods are automatically serialized. +** However, if [SQLITE_CONFIG_MEMSTATUS] is disabled, then the other +** methods must be threadsafe or else make their own arrangements for +** serialization. +** +** SQLite will never invoke xInit() more than once without an intervening +** call to xShutdown(). +*/ +typedef struct sqlite3_mem_methods sqlite3_mem_methods; +struct sqlite3_mem_methods { + void *(*xMalloc)(int); /* Memory allocation function */ + void (*xFree)(void*); /* Free a prior allocation */ + void *(*xRealloc)(void*,int); /* Resize an allocation */ + int (*xSize)(void*); /* Return the size of an allocation */ + int (*xRoundup)(int); /* Round up request size to allocation size */ + int (*xInit)(void*); /* Initialize the memory allocator */ + void (*xShutdown)(void*); /* Deinitialize the memory allocator */ + void *pAppData; /* Argument to xInit() and xShutdown() */ +}; + +/* +** CAPI3REF: Configuration Options +** KEYWORDS: {configuration option} +** +** These constants are the available integer configuration options that +** can be passed as the first argument to the [sqlite3_config()] interface. +** +** New configuration options may be added in future releases of SQLite. +** Existing configuration options might be discontinued. Applications +** should check the return code from [sqlite3_config()] to make sure that +** the call worked. The [sqlite3_config()] interface will return a +** non-zero [error code] if a discontinued or unsupported configuration option +** is invoked. +** +**
    +** [[SQLITE_CONFIG_SINGLETHREAD]]
    SQLITE_CONFIG_SINGLETHREAD
    +**
    There are no arguments to this option. ^This option sets the +** [threading mode] to Single-thread. In other words, it disables +** all mutexing and puts SQLite into a mode where it can only be used +** by a single thread. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to change the [threading mode] from its default +** value of Single-thread and so [sqlite3_config()] will return +** [SQLITE_ERROR] if called with the SQLITE_CONFIG_SINGLETHREAD +** configuration option.
    +** +** [[SQLITE_CONFIG_MULTITHREAD]]
    SQLITE_CONFIG_MULTITHREAD
    +**
    There are no arguments to this option. ^This option sets the +** [threading mode] to Multi-thread. In other words, it disables +** mutexing on [database connection] and [prepared statement] objects. +** The application is responsible for serializing access to +** [database connections] and [prepared statements]. But other mutexes +** are enabled so that SQLite will be safe to use in a multi-threaded +** environment as long as no two threads attempt to use the same +** [database connection] at the same time. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to set the Multi-thread [threading mode] and +** [sqlite3_config()] will return [SQLITE_ERROR] if called with the +** SQLITE_CONFIG_MULTITHREAD configuration option.
    +** +** [[SQLITE_CONFIG_SERIALIZED]]
    SQLITE_CONFIG_SERIALIZED
    +**
    There are no arguments to this option. ^This option sets the +** [threading mode] to Serialized. In other words, this option enables +** all mutexes including the recursive +** mutexes on [database connection] and [prepared statement] objects. +** In this mode (which is the default when SQLite is compiled with +** [SQLITE_THREADSAFE=1]) the SQLite library will itself serialize access +** to [database connections] and [prepared statements] so that the +** application is free to use the same [database connection] or the +** same [prepared statement] in different threads at the same time. +** ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to set the Serialized [threading mode] and +** [sqlite3_config()] will return [SQLITE_ERROR] if called with the +** SQLITE_CONFIG_SERIALIZED configuration option.
    +** +** [[SQLITE_CONFIG_MALLOC]]
    SQLITE_CONFIG_MALLOC
    +**
    ^(The SQLITE_CONFIG_MALLOC option takes a single argument which is +** a pointer to an instance of the [sqlite3_mem_methods] structure. +** The argument specifies +** alternative low-level memory allocation routines to be used in place of +** the memory allocation routines built into SQLite.)^ ^SQLite makes +** its own private copy of the content of the [sqlite3_mem_methods] structure +** before the [sqlite3_config()] call returns.
    +** +** [[SQLITE_CONFIG_GETMALLOC]]
    SQLITE_CONFIG_GETMALLOC
    +**
    ^(The SQLITE_CONFIG_GETMALLOC option takes a single argument which +** is a pointer to an instance of the [sqlite3_mem_methods] structure. +** The [sqlite3_mem_methods] +** structure is filled with the currently defined memory allocation routines.)^ +** This option can be used to overload the default memory allocation +** routines with a wrapper that simulations memory allocation failure or +** tracks memory usage, for example.
    +** +** [[SQLITE_CONFIG_MEMSTATUS]]
    SQLITE_CONFIG_MEMSTATUS
    +**
    ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int, +** interpreted as a boolean, which enables or disables the collection of +** memory allocation statistics. ^(When memory allocation statistics are +** disabled, the following SQLite interfaces become non-operational: +**
      +**
    • [sqlite3_memory_used()] +**
    • [sqlite3_memory_highwater()] +**
    • [sqlite3_soft_heap_limit64()] +**
    • [sqlite3_status64()] +**
    )^ +** ^Memory allocation statistics are enabled by default unless SQLite is +** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory +** allocation statistics are disabled by default. +**
    +** +** [[SQLITE_CONFIG_SCRATCH]]
    SQLITE_CONFIG_SCRATCH
    +**
    ^The SQLITE_CONFIG_SCRATCH option specifies a static memory buffer +** that SQLite can use for scratch memory. ^(There are three arguments +** to SQLITE_CONFIG_SCRATCH: A pointer an 8-byte +** aligned memory buffer from which the scratch allocations will be +** drawn, the size of each scratch allocation (sz), +** and the maximum number of scratch allocations (N).)^ +** The first argument must be a pointer to an 8-byte aligned buffer +** of at least sz*N bytes of memory. +** ^SQLite will not use more than one scratch buffers per thread. +** ^SQLite will never request a scratch buffer that is more than 6 +** times the database page size. +** ^If SQLite needs needs additional +** scratch memory beyond what is provided by this configuration option, then +** [sqlite3_malloc()] will be used to obtain the memory needed.

    +** ^When the application provides any amount of scratch memory using +** SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary large +** [sqlite3_malloc|heap allocations]. +** This can help [Robson proof|prevent memory allocation failures] due to heap +** fragmentation in low-memory embedded systems. +**

    +** +** [[SQLITE_CONFIG_PAGECACHE]]
    SQLITE_CONFIG_PAGECACHE
    +**
    ^The SQLITE_CONFIG_PAGECACHE option specifies a static memory buffer +** that SQLite can use for the database page cache with the default page +** cache implementation. +** This configuration should not be used if an application-define page +** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2] +** configuration option. +** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to +** 8-byte aligned +** memory, the size of each page buffer (sz), and the number of pages (N). +** The sz argument should be the size of the largest database page +** (a power of two between 512 and 65536) plus some extra bytes for each +** page header. ^The number of extra bytes needed by the page header +** can be determined using the [SQLITE_CONFIG_PCACHE_HDRSZ] option +** to [sqlite3_config()]. +** ^It is harmless, apart from the wasted memory, +** for the sz parameter to be larger than necessary. The first +** argument should pointer to an 8-byte aligned block of memory that +** is at least sz*N bytes of memory, otherwise subsequent behavior is +** undefined. +** ^SQLite will use the memory provided by the first argument to satisfy its +** memory needs for the first N pages that it adds to cache. ^If additional +** page cache memory is needed beyond what is provided by this option, then +** SQLite goes to [sqlite3_malloc()] for the additional storage space.
    +** +** [[SQLITE_CONFIG_HEAP]]
    SQLITE_CONFIG_HEAP
    +**
    ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer +** that SQLite will use for all of its dynamic memory allocation needs +** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and +** [SQLITE_CONFIG_PAGECACHE]. +** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled +** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns +** [SQLITE_ERROR] if invoked otherwise. +** ^There are three arguments to SQLITE_CONFIG_HEAP: +** An 8-byte aligned pointer to the memory, +** the number of bytes in the memory buffer, and the minimum allocation size. +** ^If the first pointer (the memory pointer) is NULL, then SQLite reverts +** to using its default memory allocator (the system malloc() implementation), +** undoing any prior invocation of [SQLITE_CONFIG_MALLOC]. ^If the +** memory pointer is not NULL then the alternative memory +** allocator is engaged to handle all of SQLites memory allocation needs. +** The first pointer (the memory pointer) must be aligned to an 8-byte +** boundary or subsequent behavior of SQLite will be undefined. +** The minimum allocation size is capped at 2**12. Reasonable values +** for the minimum allocation size are 2**5 through 2**8.
    +** +** [[SQLITE_CONFIG_MUTEX]]
    SQLITE_CONFIG_MUTEX
    +**
    ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a +** pointer to an instance of the [sqlite3_mutex_methods] structure. +** The argument specifies alternative low-level mutex routines to be used +** in place the mutex routines built into SQLite.)^ ^SQLite makes a copy of +** the content of the [sqlite3_mutex_methods] structure before the call to +** [sqlite3_config()] returns. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** the entire mutexing subsystem is omitted from the build and hence calls to +** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will +** return [SQLITE_ERROR].
    +** +** [[SQLITE_CONFIG_GETMUTEX]]
    SQLITE_CONFIG_GETMUTEX
    +**
    ^(The SQLITE_CONFIG_GETMUTEX option takes a single argument which +** is a pointer to an instance of the [sqlite3_mutex_methods] structure. The +** [sqlite3_mutex_methods] +** structure is filled with the currently defined mutex routines.)^ +** This option can be used to overload the default mutex allocation +** routines with a wrapper used to track mutex usage for performance +** profiling or testing, for example. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** the entire mutexing subsystem is omitted from the build and hence calls to +** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will +** return [SQLITE_ERROR].
    +** +** [[SQLITE_CONFIG_LOOKASIDE]]
    SQLITE_CONFIG_LOOKASIDE
    +**
    ^(The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine +** the default size of lookaside memory on each [database connection]. +** The first argument is the +** size of each lookaside buffer slot and the second is the number of +** slots allocated to each database connection.)^ ^(SQLITE_CONFIG_LOOKASIDE +** sets the default lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE] +** option to [sqlite3_db_config()] can be used to change the lookaside +** configuration on individual connections.)^
    +** +** [[SQLITE_CONFIG_PCACHE2]]
    SQLITE_CONFIG_PCACHE2
    +**
    ^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is +** a pointer to an [sqlite3_pcache_methods2] object. This object specifies +** the interface to a custom page cache implementation.)^ +** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.
    +** +** [[SQLITE_CONFIG_GETPCACHE2]]
    SQLITE_CONFIG_GETPCACHE2
    +**
    ^(The SQLITE_CONFIG_GETPCACHE2 option takes a single argument which +** is a pointer to an [sqlite3_pcache_methods2] object. SQLite copies of +** the current page cache implementation into that object.)^
    +** +** [[SQLITE_CONFIG_LOG]]
    SQLITE_CONFIG_LOG
    +**
    The SQLITE_CONFIG_LOG option is used to configure the SQLite +** global [error log]. +** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a +** function with a call signature of void(*)(void*,int,const char*), +** and a pointer to void. ^If the function pointer is not NULL, it is +** invoked by [sqlite3_log()] to process each logging event. ^If the +** function pointer is NULL, the [sqlite3_log()] interface becomes a no-op. +** ^The void pointer that is the second argument to SQLITE_CONFIG_LOG is +** passed through as the first parameter to the application-defined logger +** function whenever that function is invoked. ^The second parameter to +** the logger function is a copy of the first parameter to the corresponding +** [sqlite3_log()] call and is intended to be a [result code] or an +** [extended result code]. ^The third parameter passed to the logger is +** log message after formatting via [sqlite3_snprintf()]. +** The SQLite logging interface is not reentrant; the logger function +** supplied by the application must not invoke any SQLite interface. +** In a multi-threaded application, the application-defined logger +** function must be threadsafe.
    +** +** [[SQLITE_CONFIG_URI]]
    SQLITE_CONFIG_URI +**
    ^(The SQLITE_CONFIG_URI option takes a single argument of type int. +** If non-zero, then URI handling is globally enabled. If the parameter is zero, +** then URI handling is globally disabled.)^ ^If URI handling is globally +** enabled, all filenames passed to [sqlite3_open()], [sqlite3_open_v2()], +** [sqlite3_open16()] or +** specified as part of [ATTACH] commands are interpreted as URIs, regardless +** of whether or not the [SQLITE_OPEN_URI] flag is set when the database +** connection is opened. ^If it is globally disabled, filenames are +** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the +** database connection is opened. ^(By default, URI handling is globally +** disabled. The default value may be changed by compiling with the +** [SQLITE_USE_URI] symbol defined.)^ +** +** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]]
    SQLITE_CONFIG_COVERING_INDEX_SCAN +**
    ^The SQLITE_CONFIG_COVERING_INDEX_SCAN option takes a single integer +** argument which is interpreted as a boolean in order to enable or disable +** the use of covering indices for full table scans in the query optimizer. +** ^The default setting is determined +** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on" +** if that compile-time option is omitted. +** The ability to disable the use of covering indices for full table scans +** is because some incorrectly coded legacy applications might malfunction +** when the optimization is enabled. Providing the ability to +** disable the optimization allows the older, buggy application code to work +** without change even with newer versions of SQLite. +** +** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]] +**
    SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE +**
    These options are obsolete and should not be used by new code. +** They are retained for backwards compatibility but are now no-ops. +**
    +** +** [[SQLITE_CONFIG_SQLLOG]] +**
    SQLITE_CONFIG_SQLLOG +**
    This option is only available if sqlite is compiled with the +** [SQLITE_ENABLE_SQLLOG] pre-processor macro defined. The first argument should +** be a pointer to a function of type void(*)(void*,sqlite3*,const char*, int). +** The second should be of type (void*). The callback is invoked by the library +** in three separate circumstances, identified by the value passed as the +** fourth parameter. If the fourth parameter is 0, then the database connection +** passed as the second argument has just been opened. The third argument +** points to a buffer containing the name of the main database file. If the +** fourth parameter is 1, then the SQL statement that the third parameter +** points to has just been executed. Or, if the fourth parameter is 2, then +** the connection being passed as the second parameter is being closed. The +** third parameter is passed NULL In this case. An example of using this +** configuration option can be seen in the "test_sqllog.c" source file in +** the canonical SQLite source tree.
    +** +** [[SQLITE_CONFIG_MMAP_SIZE]] +**
    SQLITE_CONFIG_MMAP_SIZE +**
    ^SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values +** that are the default mmap size limit (the default setting for +** [PRAGMA mmap_size]) and the maximum allowed mmap size limit. +** ^The default setting can be overridden by each database connection using +** either the [PRAGMA mmap_size] command, or by using the +** [SQLITE_FCNTL_MMAP_SIZE] file control. ^(The maximum allowed mmap size +** will be silently truncated if necessary so that it does not exceed the +** compile-time maximum mmap size set by the +** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^ +** ^If either argument to this option is negative, then that argument is +** changed to its compile-time default. +** +** [[SQLITE_CONFIG_WIN32_HEAPSIZE]] +**
    SQLITE_CONFIG_WIN32_HEAPSIZE +**
    ^The SQLITE_CONFIG_WIN32_HEAPSIZE option is only available if SQLite is +** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro +** defined. ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value +** that specifies the maximum size of the created heap. +** +** [[SQLITE_CONFIG_PCACHE_HDRSZ]] +**
    SQLITE_CONFIG_PCACHE_HDRSZ +**
    ^The SQLITE_CONFIG_PCACHE_HDRSZ option takes a single parameter which +** is a pointer to an integer and writes into that integer the number of extra +** bytes per page required for each page in [SQLITE_CONFIG_PAGECACHE]. +** The amount of extra space required can change depending on the compiler, +** target platform, and SQLite version. +** +** [[SQLITE_CONFIG_PMASZ]] +**
    SQLITE_CONFIG_PMASZ +**
    ^The SQLITE_CONFIG_PMASZ option takes a single parameter which +** is an unsigned integer and sets the "Minimum PMA Size" for the multithreaded +** sorter to that integer. The default minimum PMA Size is set by the +** [SQLITE_SORTER_PMASZ] compile-time option. New threads are launched +** to help with sort operations when multithreaded sorting +** is enabled (using the [PRAGMA threads] command) and the amount of content +** to be sorted exceeds the page size times the minimum of the +** [PRAGMA cache_size] setting and this value. +**
    +*/ +#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ +#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ +#define SQLITE_CONFIG_SERIALIZED 3 /* nil */ +#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_SCRATCH 6 /* void*, int sz, int N */ +#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ +#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ +#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ +#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ +#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ +/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ +#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ +#define SQLITE_CONFIG_PCACHE 14 /* no-op */ +#define SQLITE_CONFIG_GETPCACHE 15 /* no-op */ +#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ +#define SQLITE_CONFIG_URI 17 /* int */ +#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */ +#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ +#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ +#define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */ +#define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */ +#define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */ + +/* +** CAPI3REF: Database Connection Configuration Options +** +** These constants are the available integer configuration options that +** can be passed as the second argument to the [sqlite3_db_config()] interface. +** +** New configuration options may be added in future releases of SQLite. +** Existing configuration options might be discontinued. Applications +** should check the return code from [sqlite3_db_config()] to make sure that +** the call worked. ^The [sqlite3_db_config()] interface will return a +** non-zero [error code] if a discontinued or unsupported configuration option +** is invoked. +** +**
    +**
    SQLITE_DBCONFIG_LOOKASIDE
    +**
    ^This option takes three additional arguments that determine the +** [lookaside memory allocator] configuration for the [database connection]. +** ^The first argument (the third parameter to [sqlite3_db_config()] is a +** pointer to a memory buffer to use for lookaside memory. +** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb +** may be NULL in which case SQLite will allocate the +** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the +** size of each lookaside buffer slot. ^The third argument is the number of +** slots. The size of the buffer in the first argument must be greater than +** or equal to the product of the second and third arguments. The buffer +** must be aligned to an 8-byte boundary. ^If the second argument to +** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally +** rounded down to the next smaller multiple of 8. ^(The lookaside memory +** configuration for a database connection can only be changed when that +** connection is not currently using lookaside memory, or in other words +** when the "current value" returned by +** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero. +** Any attempt to change the lookaside memory configuration when lookaside +** memory is in use leaves the configuration unchanged and returns +** [SQLITE_BUSY].)^
    +** +**
    SQLITE_DBCONFIG_ENABLE_FKEY
    +**
    ^This option is used to enable or disable the enforcement of +** [foreign key constraints]. There should be two additional arguments. +** The first argument is an integer which is 0 to disable FK enforcement, +** positive to enable FK enforcement or negative to leave FK enforcement +** unchanged. The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether FK enforcement is off or on +** following this call. The second parameter may be a NULL pointer, in +** which case the FK enforcement setting is not reported back.
    +** +**
    SQLITE_DBCONFIG_ENABLE_TRIGGER
    +**
    ^This option is used to enable or disable [CREATE TRIGGER | triggers]. +** There should be two additional arguments. +** The first argument is an integer which is 0 to disable triggers, +** positive to enable triggers or negative to leave the setting unchanged. +** The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether triggers are disabled or enabled +** following this call. The second parameter may be a NULL pointer, in +** which case the trigger setting is not reported back.
    +** +**
    +*/ +#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ +#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ +#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ + + +/* +** CAPI3REF: Enable Or Disable Extended Result Codes +** METHOD: sqlite3 +** +** ^The sqlite3_extended_result_codes() routine enables or disables the +** [extended result codes] feature of SQLite. ^The extended result +** codes are disabled by default for historical compatibility. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3*, int onoff); + +/* +** CAPI3REF: Last Insert Rowid +** METHOD: sqlite3 +** +** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables) +** has a unique 64-bit signed +** integer key called the [ROWID | "rowid"]. ^The rowid is always available +** as an undeclared column named ROWID, OID, or _ROWID_ as long as those +** names are not also used by explicitly declared columns. ^If +** the table has a column of type [INTEGER PRIMARY KEY] then that column +** is another alias for the rowid. +** +** ^The sqlite3_last_insert_rowid(D) interface returns the [rowid] of the +** most recent successful [INSERT] into a rowid table or [virtual table] +** on database connection D. +** ^Inserts into [WITHOUT ROWID] tables are not recorded. +** ^If no successful [INSERT]s into rowid tables +** have ever occurred on the database connection D, +** then sqlite3_last_insert_rowid(D) returns zero. +** +** ^(If an [INSERT] occurs within a trigger or within a [virtual table] +** method, then this routine will return the [rowid] of the inserted +** row as long as the trigger or virtual table method is running. +** But once the trigger or virtual table method ends, the value returned +** by this routine reverts to what it was before the trigger or virtual +** table method began.)^ +** +** ^An [INSERT] that fails due to a constraint violation is not a +** successful [INSERT] and does not change the value returned by this +** routine. ^Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK, +** and INSERT OR ABORT make no changes to the return value of this +** routine when their insertion fails. ^(When INSERT OR REPLACE +** encounters a constraint violation, it does not fail. The +** INSERT continues to completion after deleting rows that caused +** the constraint problem so INSERT OR REPLACE will always change +** the return value of this interface.)^ +** +** ^For the purposes of this routine, an [INSERT] is considered to +** be successful even if it is subsequently rolled back. +** +** This function is accessible to SQL statements via the +** [last_insert_rowid() SQL function]. +** +** If a separate thread performs a new [INSERT] on the same +** database connection while the [sqlite3_last_insert_rowid()] +** function is running and thus changes the last insert [rowid], +** then the value returned by [sqlite3_last_insert_rowid()] is +** unpredictable and might not equal either the old or the new +** last insert [rowid]. +*/ +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3*); + +/* +** CAPI3REF: Count The Number Of Rows Modified +** METHOD: sqlite3 +** +** ^This function returns the number of rows modified, inserted or +** deleted by the most recently completed INSERT, UPDATE or DELETE +** statement on the database connection specified by the only parameter. +** ^Executing any other type of SQL statement does not modify the value +** returned by this function. +** +** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are +** considered - auxiliary changes caused by [CREATE TRIGGER | triggers], +** [foreign key actions] or [REPLACE] constraint resolution are not counted. +** +** Changes to a view that are intercepted by +** [INSTEAD OF trigger | INSTEAD OF triggers] are not counted. ^The value +** returned by sqlite3_changes() immediately after an INSERT, UPDATE or +** DELETE statement run on a view is always zero. Only changes made to real +** tables are counted. +** +** Things are more complicated if the sqlite3_changes() function is +** executed while a trigger program is running. This may happen if the +** program uses the [changes() SQL function], or if some other callback +** function invokes sqlite3_changes() directly. Essentially: +** +**
      +**
    • ^(Before entering a trigger program the value returned by +** sqlite3_changes() function is saved. After the trigger program +** has finished, the original value is restored.)^ +** +**
    • ^(Within a trigger program each INSERT, UPDATE and DELETE +** statement sets the value returned by sqlite3_changes() +** upon completion as normal. Of course, this value will not include +** any changes performed by sub-triggers, as the sqlite3_changes() +** value will be saved and restored after each sub-trigger has run.)^ +**
    +** +** ^This means that if the changes() SQL function (or similar) is used +** by the first INSERT, UPDATE or DELETE statement within a trigger, it +** returns the value as set when the calling statement began executing. +** ^If it is used by the second or subsequent such statement within a trigger +** program, the value returned reflects the number of rows modified by the +** previous INSERT, UPDATE or DELETE statement within the same trigger. +** +** See also the [sqlite3_total_changes()] interface, the +** [count_changes pragma], and the [changes() SQL function]. +** +** If a separate thread makes changes on the same database connection +** while [sqlite3_changes()] is running then the value returned +** is unpredictable and not meaningful. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3*); + +/* +** CAPI3REF: Total Number Of Rows Modified +** METHOD: sqlite3 +** +** ^This function returns the total number of rows inserted, modified or +** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed +** since the database connection was opened, including those executed as +** part of trigger programs. ^Executing any other type of SQL statement +** does not affect the value returned by sqlite3_total_changes(). +** +** ^Changes made as part of [foreign key actions] are included in the +** count, but those made as part of REPLACE constraint resolution are +** not. ^Changes to a view that are intercepted by INSTEAD OF triggers +** are not counted. +** +** See also the [sqlite3_changes()] interface, the +** [count_changes pragma], and the [total_changes() SQL function]. +** +** If a separate thread makes changes on the same database connection +** while [sqlite3_total_changes()] is running then the value +** returned is unpredictable and not meaningful. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3*); + +/* +** CAPI3REF: Interrupt A Long-Running Query +** METHOD: sqlite3 +** +** ^This function causes any pending database operation to abort and +** return at its earliest opportunity. This routine is typically +** called in response to a user action such as pressing "Cancel" +** or Ctrl-C where the user wants a long query operation to halt +** immediately. +** +** ^It is safe to call this routine from a thread different from the +** thread that is currently running the database operation. But it +** is not safe to call this routine with a [database connection] that +** is closed or might close before sqlite3_interrupt() returns. +** +** ^If an SQL operation is very nearly finished at the time when +** sqlite3_interrupt() is called, then it might not have an opportunity +** to be interrupted and might continue to completion. +** +** ^An SQL operation that is interrupted will return [SQLITE_INTERRUPT]. +** ^If the interrupted SQL operation is an INSERT, UPDATE, or DELETE +** that is inside an explicit transaction, then the entire transaction +** will be rolled back automatically. +** +** ^The sqlite3_interrupt(D) call is in effect until all currently running +** SQL statements on [database connection] D complete. ^Any new SQL statements +** that are started after the sqlite3_interrupt() call and before the +** running statements reaches zero are interrupted as if they had been +** running prior to the sqlite3_interrupt() call. ^New SQL statements +** that are started after the running statement count reaches zero are +** not effected by the sqlite3_interrupt(). +** ^A call to sqlite3_interrupt(D) that occurs when there are no running +** SQL statements is a no-op and has no effect on SQL statements +** that are started after the sqlite3_interrupt() call returns. +** +** If the database connection closes while [sqlite3_interrupt()] +** is running then bad things will likely happen. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3*); + +/* +** CAPI3REF: Determine If An SQL Statement Is Complete +** +** These routines are useful during command-line input to determine if the +** currently entered text seems to form a complete SQL statement or +** if additional input is needed before sending the text into +** SQLite for parsing. ^These routines return 1 if the input string +** appears to be a complete SQL statement. ^A statement is judged to be +** complete if it ends with a semicolon token and is not a prefix of a +** well-formed CREATE TRIGGER statement. ^Semicolons that are embedded within +** string literals or quoted identifier names or comments are not +** independent tokens (they are part of the token in which they are +** embedded) and thus do not count as a statement terminator. ^Whitespace +** and comments that follow the final semicolon are ignored. +** +** ^These routines return 0 if the statement is incomplete. ^If a +** memory allocation fails, then SQLITE_NOMEM is returned. +** +** ^These routines do not parse the SQL statements thus +** will not detect syntactically incorrect SQL. +** +** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior +** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked +** automatically by sqlite3_complete16(). If that initialization fails, +** then the return value from sqlite3_complete16() will be non-zero +** regardless of whether or not the input SQL is complete.)^ +** +** The input to [sqlite3_complete()] must be a zero-terminated +** UTF-8 string. +** +** The input to [sqlite3_complete16()] must be a zero-terminated +** UTF-16 string in native byte order. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *sql); +SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *sql); + +/* +** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors +** KEYWORDS: {busy-handler callback} {busy handler} +** METHOD: sqlite3 +** +** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X +** that might be invoked with argument P whenever +** an attempt is made to access a database table associated with +** [database connection] D when another thread +** or process has the table locked. +** The sqlite3_busy_handler() interface is used to implement +** [sqlite3_busy_timeout()] and [PRAGMA busy_timeout]. +** +** ^If the busy callback is NULL, then [SQLITE_BUSY] +** is returned immediately upon encountering the lock. ^If the busy callback +** is not NULL, then the callback might be invoked with two arguments. +** +** ^The first argument to the busy handler is a copy of the void* pointer which +** is the third argument to sqlite3_busy_handler(). ^The second argument to +** the busy handler callback is the number of times that the busy handler has +** been invoked previously for the same locking event. ^If the +** busy callback returns 0, then no additional attempts are made to +** access the database and [SQLITE_BUSY] is returned +** to the application. +** ^If the callback returns non-zero, then another attempt +** is made to access the database and the cycle repeats. +** +** The presence of a busy handler does not guarantee that it will be invoked +** when there is lock contention. ^If SQLite determines that invoking the busy +** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY] +** to the application instead of invoking the +** busy handler. +** Consider a scenario where one process is holding a read lock that +** it is trying to promote to a reserved lock and +** a second process is holding a reserved lock that it is trying +** to promote to an exclusive lock. The first process cannot proceed +** because it is blocked by the second and the second process cannot +** proceed because it is blocked by the first. If both processes +** invoke the busy handlers, neither will make any progress. Therefore, +** SQLite returns [SQLITE_BUSY] for the first process, hoping that this +** will induce the first process to release its read lock and allow +** the second process to proceed. +** +** ^The default busy callback is NULL. +** +** ^(There can only be a single busy handler defined for each +** [database connection]. Setting a new busy handler clears any +** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()] +** or evaluating [PRAGMA busy_timeout=N] will change the +** busy handler and thus clear any previously set busy handler. +** +** The busy callback should not take any actions which modify the +** database connection that invoked the busy handler. In other words, +** the busy handler is not reentrant. Any such actions +** result in undefined behavior. +** +** A busy handler must not close the database connection +** or [prepared statement] that invoked the busy handler. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); + +/* +** CAPI3REF: Set A Busy Timeout +** METHOD: sqlite3 +** +** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps +** for a specified amount of time when a table is locked. ^The handler +** will sleep multiple times until at least "ms" milliseconds of sleeping +** have accumulated. ^After at least "ms" milliseconds of sleeping, +** the handler returns 0 which causes [sqlite3_step()] to return +** [SQLITE_BUSY]. +** +** ^Calling this routine with an argument less than or equal to zero +** turns off all busy handlers. +** +** ^(There can only be a single busy handler for a particular +** [database connection] at any given moment. If another busy handler +** was defined (using [sqlite3_busy_handler()]) prior to calling +** this routine, that other busy handler is cleared.)^ +** +** See also: [PRAGMA busy_timeout] +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3*, int ms); + +/* +** CAPI3REF: Convenience Routines For Running Queries +** METHOD: sqlite3 +** +** This is a legacy interface that is preserved for backwards compatibility. +** Use of this interface is not recommended. +** +** Definition: A result table is memory data structure created by the +** [sqlite3_get_table()] interface. A result table records the +** complete query results from one or more queries. +** +** The table conceptually has a number of rows and columns. But +** these numbers are not part of the result table itself. These +** numbers are obtained separately. Let N be the number of rows +** and M be the number of columns. +** +** A result table is an array of pointers to zero-terminated UTF-8 strings. +** There are (N+1)*M elements in the array. The first M pointers point +** to zero-terminated strings that contain the names of the columns. +** The remaining entries all point to query results. NULL values result +** in NULL pointers. All other values are in their UTF-8 zero-terminated +** string representation as returned by [sqlite3_column_text()]. +** +** A result table might consist of one or more memory allocations. +** It is not safe to pass a result table directly to [sqlite3_free()]. +** A result table should be deallocated using [sqlite3_free_table()]. +** +** ^(As an example of the result table format, suppose a query result +** is as follows: +** +**
    +**        Name        | Age
    +**        -----------------------
    +**        Alice       | 43
    +**        Bob         | 28
    +**        Cindy       | 21
    +** 
    +** +** There are two column (M==2) and three rows (N==3). Thus the +** result table has 8 entries. Suppose the result table is stored +** in an array names azResult. Then azResult holds this content: +** +**
    +**        azResult[0] = "Name";
    +**        azResult[1] = "Age";
    +**        azResult[2] = "Alice";
    +**        azResult[3] = "43";
    +**        azResult[4] = "Bob";
    +**        azResult[5] = "28";
    +**        azResult[6] = "Cindy";
    +**        azResult[7] = "21";
    +** 
    )^ +** +** ^The sqlite3_get_table() function evaluates one or more +** semicolon-separated SQL statements in the zero-terminated UTF-8 +** string of its 2nd parameter and returns a result table to the +** pointer given in its 3rd parameter. +** +** After the application has finished with the result from sqlite3_get_table(), +** it must pass the result table pointer to sqlite3_free_table() in order to +** release the memory that was malloced. Because of the way the +** [sqlite3_malloc()] happens within sqlite3_get_table(), the calling +** function must not try to call [sqlite3_free()] directly. Only +** [sqlite3_free_table()] is able to release the memory properly and safely. +** +** The sqlite3_get_table() interface is implemented as a wrapper around +** [sqlite3_exec()]. The sqlite3_get_table() routine does not have access +** to any internal data structures of SQLite. It uses only the public +** interface defined here. As a consequence, errors that occur in the +** wrapper layer outside of the internal [sqlite3_exec()] call are not +** reflected in subsequent calls to [sqlite3_errcode()] or +** [sqlite3_errmsg()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_get_table( + sqlite3 *db, /* An open database */ + const char *zSql, /* SQL to be evaluated */ + char ***pazResult, /* Results of the query */ + int *pnRow, /* Number of result rows written here */ + int *pnColumn, /* Number of result columns written here */ + char **pzErrmsg /* Error msg written here */ +); +SQLITE_API void SQLITE_STDCALL sqlite3_free_table(char **result); + +/* +** CAPI3REF: Formatted String Printing Functions +** +** These routines are work-alikes of the "printf()" family of functions +** from the standard C library. +** These routines understand most of the common K&R formatting options, +** plus some additional non-standard formats, detailed below. +** Note that some of the more obscure formatting options from recent +** C-library standards are omitted from this implementation. +** +** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their +** results into memory obtained from [sqlite3_malloc()]. +** The strings returned by these two routines should be +** released by [sqlite3_free()]. ^Both routines return a +** NULL pointer if [sqlite3_malloc()] is unable to allocate enough +** memory to hold the resulting string. +** +** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from +** the standard C library. The result is written into the +** buffer supplied as the second parameter whose size is given by +** the first parameter. Note that the order of the +** first two parameters is reversed from snprintf().)^ This is an +** historical accident that cannot be fixed without breaking +** backwards compatibility. ^(Note also that sqlite3_snprintf() +** returns a pointer to its buffer instead of the number of +** characters actually written into the buffer.)^ We admit that +** the number of characters written would be a more useful return +** value but we cannot change the implementation of sqlite3_snprintf() +** now without breaking compatibility. +** +** ^As long as the buffer size is greater than zero, sqlite3_snprintf() +** guarantees that the buffer is always zero-terminated. ^The first +** parameter "n" is the total size of the buffer, including space for +** the zero terminator. So the longest string that can be completely +** written will be n-1 characters. +** +** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf(). +** +** These routines all implement some additional formatting +** options that are useful for constructing SQL statements. +** All of the usual printf() formatting options apply. In addition, there +** is are "%q", "%Q", "%w" and "%z" options. +** +** ^(The %q option works like %s in that it substitutes a nul-terminated +** string from the argument list. But %q also doubles every '\'' character. +** %q is designed for use inside a string literal.)^ By doubling each '\'' +** character it escapes that character and allows it to be inserted into +** the string. +** +** For example, assume the string variable zText contains text as follows: +** +**
    +**  char *zText = "It's a happy day!";
    +** 
    +** +** One can use this text in an SQL statement as follows: +** +**
    +**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
    +**  sqlite3_exec(db, zSQL, 0, 0, 0);
    +**  sqlite3_free(zSQL);
    +** 
    +** +** 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 +** would have looked like this: +** +**
    +**  INSERT INTO table1 VALUES('It's a happy day!');
    +** 
    +** +** This second example is an SQL syntax error. As a general rule you should +** always use %q instead of %s when inserting text into a string literal. +** +** ^(The %Q option works like %q except it also adds single quotes around +** the outside of the total string. Additionally, if the parameter in the +** argument list is a NULL pointer, %Q substitutes the text "NULL" (without +** single quotes).)^ So, for example, one could say: +** +**
    +**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
    +**  sqlite3_exec(db, zSQL, 0, 0, 0);
    +**  sqlite3_free(zSQL);
    +** 
    +** +** The code above will render a correct SQL statement in the zSQL +** variable even if the zText variable is a NULL pointer. +** +** ^(The "%w" formatting option is like "%q" except that it expects to +** be contained within double-quotes instead of single quotes, and it +** escapes the double-quote character instead of the single-quote +** character.)^ The "%w" formatting option is intended for safely inserting +** table and column names into a constructed SQL statement. +** +** ^(The "%z" formatting option works like "%s" but with the +** addition that after the string has been read and copied into +** the result, [sqlite3_free()] is called on the input string.)^ +*/ +SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char*,...); +SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char*, va_list); +SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int,char*,const char*, ...); +SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int,char*,const char*, va_list); + +/* +** CAPI3REF: Memory Allocation Subsystem +** +** The SQLite core uses these three routines for all of its own +** internal memory allocation needs. "Core" in the previous sentence +** does not include operating-system specific VFS implementation. The +** Windows VFS uses native malloc() and free() for some operations. +** +** ^The sqlite3_malloc() routine returns a pointer to a block +** of memory at least N bytes in length, where N is the parameter. +** ^If sqlite3_malloc() is unable to obtain sufficient free +** memory, it returns a NULL pointer. ^If the parameter N to +** sqlite3_malloc() is zero or negative then sqlite3_malloc() returns +** a NULL pointer. +** +** ^The sqlite3_malloc64(N) routine works just like +** sqlite3_malloc(N) except that N is an unsigned 64-bit integer instead +** of a signed 32-bit integer. +** +** ^Calling sqlite3_free() with a pointer previously returned +** by sqlite3_malloc() or sqlite3_realloc() releases that memory so +** that it might be reused. ^The sqlite3_free() routine is +** a no-op if is called with a NULL pointer. Passing a NULL pointer +** to sqlite3_free() is harmless. After being freed, memory +** should neither be read nor written. Even reading previously freed +** memory might result in a segmentation fault or other severe error. +** Memory corruption, a segmentation fault, or other severe error +** might result if sqlite3_free() is called with a non-NULL pointer that +** was not obtained from sqlite3_malloc() or sqlite3_realloc(). +** +** ^The sqlite3_realloc(X,N) interface attempts to resize a +** prior memory allocation X to be at least N bytes. +** ^If the X parameter to sqlite3_realloc(X,N) +** is a NULL pointer then its behavior is identical to calling +** sqlite3_malloc(N). +** ^If the N parameter to sqlite3_realloc(X,N) is zero or +** negative then the behavior is exactly the same as calling +** sqlite3_free(X). +** ^sqlite3_realloc(X,N) returns a pointer to a memory allocation +** of at least N bytes in size or NULL if insufficient memory is available. +** ^If M is the size of the prior allocation, then min(N,M) bytes +** of the prior allocation are copied into the beginning of buffer returned +** by sqlite3_realloc(X,N) and the prior allocation is freed. +** ^If sqlite3_realloc(X,N) returns NULL and N is positive, then the +** prior allocation is not freed. +** +** ^The sqlite3_realloc64(X,N) interfaces works the same as +** sqlite3_realloc(X,N) except that N is a 64-bit unsigned integer instead +** of a 32-bit signed integer. +** +** ^If X is a memory allocation previously obtained from sqlite3_malloc(), +** sqlite3_malloc64(), sqlite3_realloc(), or sqlite3_realloc64(), then +** sqlite3_msize(X) returns the size of that memory allocation in bytes. +** ^The value returned by sqlite3_msize(X) might be larger than the number +** of bytes requested when X was allocated. ^If X is a NULL pointer then +** sqlite3_msize(X) returns zero. If X points to something that is not +** the beginning of memory allocation, or if it points to a formerly +** valid memory allocation that has now been freed, then the behavior +** of sqlite3_msize(X) is undefined and possibly harmful. +** +** ^The memory returned by sqlite3_malloc(), sqlite3_realloc(), +** sqlite3_malloc64(), and sqlite3_realloc64() +** is always aligned to at least an 8 byte boundary, or to a +** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time +** option is used. +** +** In SQLite version 3.5.0 and 3.5.1, it was possible to define +** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in +** implementation of these routines to be omitted. That capability +** is no longer provided. Only built-in memory allocators can be used. +** +** Prior to SQLite version 3.7.10, the Windows OS interface layer called +** the system malloc() and free() directly when converting +** filenames between the UTF-8 encoding used by SQLite +** and whatever filename encoding is used by the particular Windows +** installation. Memory allocation errors were detected, but +** they were reported back as [SQLITE_CANTOPEN] or +** [SQLITE_IOERR] rather than [SQLITE_NOMEM]. +** +** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()] +** must be either NULL or else pointers obtained from a prior +** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have +** not yet been released. +** +** The application must not read or write any part of +** a block of memory after it has been released using +** [sqlite3_free()] or [sqlite3_realloc()]. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int); +SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64); +SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void*, int); +SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void*, sqlite3_uint64); +SQLITE_API void SQLITE_STDCALL sqlite3_free(void*); +SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void*); + +/* +** CAPI3REF: Memory Allocator Statistics +** +** SQLite provides these two interfaces for reporting on the status +** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()] +** routines, which form the built-in memory allocation subsystem. +** +** ^The [sqlite3_memory_used()] routine returns the number of bytes +** of memory currently outstanding (malloced but not freed). +** ^The [sqlite3_memory_highwater()] routine returns the maximum +** value of [sqlite3_memory_used()] since the high-water mark +** was last reset. ^The values returned by [sqlite3_memory_used()] and +** [sqlite3_memory_highwater()] include any overhead +** added by SQLite in its implementation of [sqlite3_malloc()], +** but not overhead added by the any underlying system library +** routines that [sqlite3_malloc()] may call. +** +** ^The memory high-water mark is reset to the current value of +** [sqlite3_memory_used()] if and only if the parameter to +** [sqlite3_memory_highwater()] is true. ^The value returned +** by [sqlite3_memory_highwater(1)] is the high-water mark +** prior to the reset. +*/ +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void); +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag); + +/* +** CAPI3REF: Pseudo-Random Number Generator +** +** SQLite contains a high-quality pseudo-random number generator (PRNG) used to +** select random [ROWID | ROWIDs] when inserting new records into a table that +** already uses the largest possible [ROWID]. The PRNG is also used for +** the build-in random() and randomblob() SQL functions. This interface allows +** applications to access the same PRNG for other purposes. +** +** ^A call to this routine stores N bytes of randomness into buffer P. +** ^The P parameter can be a NULL pointer. +** +** ^If this routine has not been previously called or if the previous +** call had N less than one or a NULL pointer for P, then the PRNG is +** seeded using randomness obtained from the xRandomness method of +** the default [sqlite3_vfs] object. +** ^If the previous call to this routine had an N of 1 or more and a +** non-NULL P then the pseudo-randomness is generated +** internally and without recourse to the [sqlite3_vfs] xRandomness +** method. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *P); + +/* +** CAPI3REF: Compile-Time Authorization Callbacks +** METHOD: sqlite3 +** +** ^This routine registers an authorizer callback with a particular +** [database connection], supplied in the first argument. +** ^The authorizer callback is invoked as SQL statements are being compiled +** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], +** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. ^At various +** points during the compilation process, as logic is being created +** to perform various actions, the authorizer callback is invoked to +** see if those actions are allowed. ^The authorizer callback should +** return [SQLITE_OK] to allow the action, [SQLITE_IGNORE] to disallow the +** specific action but allow the SQL statement to continue to be +** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be +** rejected with an error. ^If the authorizer callback returns +** any value other than [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY] +** then the [sqlite3_prepare_v2()] or equivalent call that triggered +** the authorizer will fail with an error message. +** +** When the callback returns [SQLITE_OK], that means the operation +** requested is ok. ^When the callback returns [SQLITE_DENY], the +** [sqlite3_prepare_v2()] or equivalent call that triggered the +** authorizer will fail with an error message explaining that +** access is denied. +** +** ^The first parameter to the authorizer callback is a copy of the third +** parameter to the sqlite3_set_authorizer() interface. ^The second parameter +** to the callback is an integer [SQLITE_COPY | action code] that specifies +** the particular action to be authorized. ^The third through sixth parameters +** to the callback are zero-terminated strings that contain additional +** details about the action to be authorized. +** +** ^If the action code is [SQLITE_READ] +** and the callback returns [SQLITE_IGNORE] then the +** [prepared statement] statement is constructed to substitute +** a NULL value in place of the table column that would have +** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE] +** return can be used to deny an untrusted user access to individual +** columns of a table. +** ^If the action code is [SQLITE_DELETE] and the callback returns +** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the +** [truncate optimization] is disabled and all rows are deleted individually. +** +** An authorizer is used when [sqlite3_prepare | preparing] +** SQL statements from an untrusted source, to ensure that the SQL statements +** do not try to access data they are not allowed to see, or that they do not +** try to execute malicious statements that damage the database. For +** example, an application may allow a user to enter arbitrary +** SQL queries for evaluation by a database. But the application does +** not want the user to be able to make arbitrary changes to the +** database. An authorizer could then be put in place while the +** user-entered SQL is being [sqlite3_prepare | prepared] that +** disallows everything except [SELECT] statements. +** +** Applications that need to process SQL from untrusted sources +** might also consider lowering resource limits using [sqlite3_limit()] +** and limiting database size using the [max_page_count] [PRAGMA] +** in addition to using an authorizer. +** +** ^(Only a single authorizer can be in place on a database connection +** at a time. Each call to sqlite3_set_authorizer overrides the +** previous call.)^ ^Disable the authorizer by installing a NULL callback. +** The authorizer is disabled by default. +** +** The authorizer callback must not do anything that will modify +** the database connection that invoked the authorizer callback. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +** ^When [sqlite3_prepare_v2()] is used to prepare a statement, the +** statement might be re-prepared during [sqlite3_step()] due to a +** schema change. Hence, the application should ensure that the +** correct authorizer callback remains in place during the [sqlite3_step()]. +** +** ^Note that the authorizer callback is invoked only during +** [sqlite3_prepare()] or its variants. Authorization is not +** performed during statement evaluation in [sqlite3_step()], unless +** as stated in the previous paragraph, sqlite3_step() invokes +** sqlite3_prepare_v2() to reprepare a statement after a schema change. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer( + sqlite3*, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pUserData +); + +/* +** CAPI3REF: Authorizer Return Codes +** +** The [sqlite3_set_authorizer | authorizer callback function] must +** return either [SQLITE_OK] or one of these two constants in order +** to signal SQLite whether or not the action is permitted. See the +** [sqlite3_set_authorizer | authorizer documentation] for additional +** information. +** +** Note that SQLITE_IGNORE is also used as a [conflict resolution mode] +** returned from the [sqlite3_vtab_on_conflict()] interface. +*/ +#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 */ + +/* +** CAPI3REF: Authorizer Action Codes +** +** The [sqlite3_set_authorizer()] interface registers a callback function +** that is invoked to authorize certain SQL statement actions. The +** second parameter to the callback is an integer code that specifies +** what action is being authorized. These are the integer action codes that +** the authorizer callback may be passed. +** +** These action code values signify what kind of operation is to be +** authorized. The 3rd and 4th parameters to the authorization +** callback function will be parameters or NULL depending on which of these +** codes is used as the second parameter. ^(The 5th parameter to the +** authorizer callback is the name of the database ("main", "temp", +** etc.) if applicable.)^ ^The 6th parameter to the authorizer callback +** is the name of the inner-most trigger or view that is responsible for +** the access attempt or NULL if this access attempt is directly from +** top-level SQL code. +*/ +/******************************************* 3rd ************ 4th ***********/ +#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ +#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */ +#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */ +#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */ +#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */ +#define SQLITE_CREATE_VIEW 8 /* View Name NULL */ +#define SQLITE_DELETE 9 /* Table Name NULL */ +#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */ +#define SQLITE_DROP_TABLE 11 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */ +#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */ +#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */ +#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */ +#define SQLITE_DROP_VIEW 17 /* View Name NULL */ +#define SQLITE_INSERT 18 /* Table Name NULL */ +#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */ +#define SQLITE_READ 20 /* Table Name Column Name */ +#define SQLITE_SELECT 21 /* NULL NULL */ +#define SQLITE_TRANSACTION 22 /* Operation 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 */ +#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */ +#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ +#define SQLITE_FUNCTION 31 /* NULL Function Name */ +#define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */ +#define SQLITE_COPY 0 /* No longer used */ +#define SQLITE_RECURSIVE 33 /* NULL NULL */ + +/* +** CAPI3REF: Tracing And Profiling Functions +** METHOD: sqlite3 +** +** These routines register callback functions that can be used for +** tracing and profiling the execution of SQL statements. +** +** ^The callback function registered by sqlite3_trace() is invoked at +** various times when an SQL statement is being run by [sqlite3_step()]. +** ^The sqlite3_trace() callback is invoked with a UTF-8 rendering of the +** SQL statement text as the statement first begins executing. +** ^(Additional sqlite3_trace() callbacks might occur +** as each triggered subprogram is entered. The callbacks for triggers +** contain a UTF-8 SQL comment that identifies the trigger.)^ +** +** The [SQLITE_TRACE_SIZE_LIMIT] compile-time option can be used to limit +** the length of [bound parameter] expansion in the output of sqlite3_trace(). +** +** ^The callback function registered by sqlite3_profile() is invoked +** as each SQL statement finishes. ^The profile callback contains +** the original statement text and an estimate of wall-clock time +** of how long that statement took to run. ^The profile callback +** time is in units of nanoseconds, however the current implementation +** is only capable of millisecond resolution so the six least significant +** digits in the time are meaningless. Future versions of SQLite +** might provide greater resolution on the profiler callback. The +** sqlite3_profile() function is considered experimental and is +** subject to change in future versions of SQLite. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); +SQLITE_API SQLITE_EXPERIMENTAL void *SQLITE_STDCALL sqlite3_profile(sqlite3*, + void(*xProfile)(void*,const char*,sqlite3_uint64), void*); + +/* +** CAPI3REF: Query Progress Callbacks +** METHOD: sqlite3 +** +** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback +** function X to be invoked periodically during long running calls to +** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for +** database connection D. An example use for this +** interface is to keep a GUI updated during a large query. +** +** ^The parameter P is passed through as the only parameter to the +** callback function X. ^The parameter N is the approximate number of +** [virtual machine instructions] that are evaluated between successive +** invocations of the callback X. ^If N is less than one then the progress +** handler is disabled. +** +** ^Only a single progress handler may be defined at one time per +** [database connection]; setting a new progress handler cancels the +** old one. ^Setting parameter X to NULL disables the progress handler. +** ^The progress handler is also disabled by setting N to a value less +** than 1. +** +** ^If the progress callback returns non-zero, the operation is +** interrupted. This feature can be used to implement a +** "Cancel" button on a GUI progress dialog box. +** +** The progress handler callback must not do anything that will modify +** the database connection that invoked the progress handler. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); + +/* +** CAPI3REF: Opening A New Database Connection +** CONSTRUCTOR: sqlite3 +** +** ^These routines open an SQLite database file as specified by the +** filename argument. ^The filename argument is interpreted as UTF-8 for +** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte +** order for sqlite3_open16(). ^(A [database connection] handle is usually +** returned in *ppDb, even if an error occurs. The only exception is that +** if SQLite is unable to allocate memory to hold the [sqlite3] object, +** a NULL will be written into *ppDb instead of a pointer to the [sqlite3] +** object.)^ ^(If the database is opened (and/or created) successfully, then +** [SQLITE_OK] is returned. Otherwise an [error code] is returned.)^ ^The +** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain +** an English language description of the error following a failure of any +** of the sqlite3_open() routines. +** +** ^The default encoding will be UTF-8 for databases created using +** sqlite3_open() or sqlite3_open_v2(). ^The default encoding for databases +** created using sqlite3_open16() will be UTF-16 in the native byte order. +** +** Whether or not an error occurs when it is opened, resources +** associated with the [database connection] handle should be released by +** passing it to [sqlite3_close()] when it is no longer required. +** +** The sqlite3_open_v2() interface works like sqlite3_open() +** except that it accepts two additional parameters for additional control +** over the new database connection. ^(The flags parameter to +** sqlite3_open_v2() can take one of +** the following three values, optionally combined with the +** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE], +** [SQLITE_OPEN_PRIVATECACHE], and/or [SQLITE_OPEN_URI] flags:)^ +** +**
    +** ^(
    [SQLITE_OPEN_READONLY]
    +**
    The database is opened in read-only mode. If the database does not +** already exist, an error is returned.
    )^ +** +** ^(
    [SQLITE_OPEN_READWRITE]
    +**
    The database is opened for reading and writing if possible, or reading +** only if the file is write protected by the operating system. In either +** case the database must already exist, otherwise an error is returned.
    )^ +** +** ^(
    [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]
    +**
    The database is opened for reading and writing, and is created if +** it does not already exist. This is the behavior that is always used for +** sqlite3_open() and sqlite3_open16().
    )^ +**
    +** +** If the 3rd parameter to sqlite3_open_v2() is not one of the +** combinations shown above optionally combined with other +** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits] +** then the behavior is undefined. +** +** ^If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection +** opens in the multi-thread [threading mode] as long as the single-thread +** mode has not been set at compile-time or start-time. ^If the +** [SQLITE_OPEN_FULLMUTEX] flag is set then the database connection opens +** in the serialized [threading mode] unless single-thread was +** previously selected at compile-time or start-time. +** ^The [SQLITE_OPEN_SHAREDCACHE] flag causes the database connection to be +** eligible to use [shared cache mode], regardless of whether or not shared +** cache is enabled using [sqlite3_enable_shared_cache()]. ^The +** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not +** participate in [shared cache mode] even if it is enabled. +** +** ^The fourth parameter to sqlite3_open_v2() is the name of the +** [sqlite3_vfs] object that defines the operating system interface that +** the new database connection should use. ^If the fourth parameter is +** a NULL pointer then the default [sqlite3_vfs] object is used. +** +** ^If the filename is ":memory:", then a private, temporary in-memory database +** is created for the connection. ^This in-memory database will vanish when +** the database connection is closed. Future versions of SQLite might +** make use of additional special filenames that begin with the ":" character. +** It is recommended that when a database filename actually does begin with +** a ":" character you should prefix the filename with a pathname such as +** "./" to avoid ambiguity. +** +** ^If the filename is an empty string, then a private, temporary +** on-disk database will be created. ^This private database will be +** automatically deleted as soon as the database connection is closed. +** +** [[URI filenames in sqlite3_open()]]

    URI Filenames

    +** +** ^If [URI filename] interpretation is enabled, and the filename argument +** begins with "file:", then the filename is interpreted as a URI. ^URI +** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is +** set in the fourth argument to sqlite3_open_v2(), or if it has +** been enabled globally using the [SQLITE_CONFIG_URI] option with the +** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option. +** As of SQLite version 3.7.7, URI filename interpretation is turned off +** by default, but future releases of SQLite might enable URI filename +** interpretation by default. See "[URI filenames]" for additional +** information. +** +** URI filenames are parsed according to RFC 3986. ^If the URI contains an +** authority, then it must be either an empty string or the string +** "localhost". ^If the authority is not an empty string or "localhost", an +** error is returned to the caller. ^The fragment component of a URI, if +** present, is ignored. +** +** ^SQLite uses the path component of the URI as the name of the disk file +** which contains the database. ^If the path begins with a '/' character, +** then it is interpreted as an absolute path. ^If the path does not begin +** with a '/' (meaning that the authority section is omitted from the URI) +** then the path is interpreted as a relative path. +** ^(On windows, the first component of an absolute path +** is a drive specification (e.g. "C:").)^ +** +** [[core URI query parameters]] +** The query component of a URI may contain parameters that are interpreted +** either by SQLite itself, or by a [VFS | custom VFS implementation]. +** SQLite and its built-in [VFSes] interpret the +** following query parameters: +** +**
      +**
    • vfs: ^The "vfs" parameter may be used to specify the name of +** a VFS object that provides the operating system interface that should +** be used to access the database file on disk. ^If this option is set to +** an empty string the default VFS object is used. ^Specifying an unknown +** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is +** present, then the VFS specified by the option takes precedence over +** the value passed as the fourth parameter to sqlite3_open_v2(). +** +**
    • mode: ^(The mode parameter may be set to either "ro", "rw", +** "rwc", or "memory". Attempting to set it to any other value is +** an error)^. +** ^If "ro" is specified, then the database is opened for read-only +** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the +** third argument to sqlite3_open_v2(). ^If the mode option is set to +** "rw", then the database is opened for read-write (but not create) +** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had +** been set. ^Value "rwc" is equivalent to setting both +** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If the mode option is +** set to "memory" then a pure [in-memory database] that never reads +** or writes from disk is used. ^It is an error to specify a value for +** the mode parameter that is less restrictive than that specified by +** the flags passed in the third parameter to sqlite3_open_v2(). +** +**
    • cache: ^The cache parameter may be set to either "shared" or +** "private". ^Setting it to "shared" is equivalent to setting the +** SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to +** sqlite3_open_v2(). ^Setting the cache parameter to "private" is +** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. +** ^If sqlite3_open_v2() is used and the "cache" parameter is present in +** a URI filename, its value overrides any behavior requested by setting +** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag. +** +**
    • psow: ^The psow parameter indicates whether or not the +** [powersafe overwrite] property does or does not apply to the +** storage media on which the database file resides. +** +**
    • nolock: ^The nolock parameter is a boolean query parameter +** which if set disables file locking in rollback journal modes. This +** is useful for accessing a database on a filesystem that does not +** support locking. Caution: Database corruption might result if two +** or more processes write to the same database and any one of those +** processes uses nolock=1. +** +**
    • immutable: ^The immutable parameter is a boolean query +** parameter that indicates that the database file is stored on +** read-only media. ^When immutable is set, SQLite assumes that the +** database file cannot be changed, even by a process with higher +** privilege, and so the database is opened read-only and all locking +** and change detection is disabled. Caution: Setting the immutable +** property on a database file that does in fact change can result +** in incorrect query results and/or [SQLITE_CORRUPT] errors. +** See also: [SQLITE_IOCAP_IMMUTABLE]. +** +**
    +** +** ^Specifying an unknown parameter in the query component of a URI is not an +** error. Future versions of SQLite might understand additional query +** parameters. See "[query parameters with special meaning to SQLite]" for +** additional information. +** +** [[URI filename examples]]

    URI filename examples

    +** +**
    +**
    URI filenames Results +**
    file:data.db +** Open the file "data.db" in the current directory. +**
    file:/home/fred/data.db
    +** file:///home/fred/data.db
    +** file://localhost/home/fred/data.db
    +** Open the database file "/home/fred/data.db". +**
    file://darkstar/home/fred/data.db +** An error. "darkstar" is not a recognized authority. +**
    +** file:///C:/Documents%20and%20Settings/fred/Desktop/data.db +** Windows only: Open the file "data.db" on fred's desktop on drive +** C:. Note that the %20 escaping in this example is not strictly +** necessary - space characters can be used literally +** in URI filenames. +**
    file:data.db?mode=ro&cache=private +** Open file "data.db" in the current directory for read-only access. +** Regardless of whether or not shared-cache mode is enabled by +** default, use a private cache. +**
    file:/home/fred/data.db?vfs=unix-dotfile +** Open file "/home/fred/data.db". Use the special VFS "unix-dotfile" +** that uses dot-files in place of posix advisory locking. +**
    file:data.db?mode=readonly +** An error. "readonly" is not a valid option for the "mode" parameter. +**
    +** +** ^URI hexadecimal escape sequences (%HH) are supported within the path and +** query components of a URI. A hexadecimal escape sequence consists of a +** percent sign - "%" - followed by exactly two hexadecimal digits +** specifying an octet value. ^Before the path or query components of a +** URI filename are interpreted, they are encoded using UTF-8 and all +** hexadecimal escape sequences replaced by a single byte containing the +** corresponding octet. If this process generates an invalid UTF-8 encoding, +** the results are undefined. +** +** Note to Windows users: The encoding used for the filename argument +** of sqlite3_open() and sqlite3_open_v2() must be UTF-8, not whatever +** codepage is currently defined. Filenames containing international +** characters must be converted to UTF-8 prior to passing them into +** sqlite3_open() or sqlite3_open_v2(). +** +** Note to Windows Runtime users: The temporary directory must be set +** prior to calling sqlite3_open() or sqlite3_open_v2(). Otherwise, various +** features that require the use of temporary files may fail. +** +** See also: [sqlite3_temp_directory] +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_open( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +SQLITE_API int SQLITE_STDCALL sqlite3_open16( + const void *filename, /* Database filename (UTF-16) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +SQLITE_API int SQLITE_STDCALL sqlite3_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs /* Name of VFS module to use */ +); + +/* +** CAPI3REF: Obtain Values For URI Parameters +** +** These are utility routines, useful to VFS implementations, that check +** to see if a database file was a URI that contained a specific query +** parameter, and if so obtains the value of that query parameter. +** +** If F is the database filename pointer passed into the xOpen() method of +** a VFS implementation when the flags parameter to xOpen() has one or +** more of the [SQLITE_OPEN_URI] or [SQLITE_OPEN_MAIN_DB] bits set and +** P is the name of the query parameter, then +** sqlite3_uri_parameter(F,P) returns the value of the P +** parameter if it exists or a NULL pointer if P does not appear as a +** query parameter on F. If P is a query parameter of F +** has no explicit value, then sqlite3_uri_parameter(F,P) returns +** a pointer to an empty string. +** +** The sqlite3_uri_boolean(F,P,B) routine assumes that P is a boolean +** parameter and returns true (1) or false (0) according to the value +** of P. The sqlite3_uri_boolean(F,P,B) routine returns true (1) if the +** value of query parameter P is one of "yes", "true", or "on" in any +** case or if the value begins with a non-zero number. The +** sqlite3_uri_boolean(F,P,B) routines returns false (0) if the value of +** query parameter P is one of "no", "false", or "off" in any case or +** if the value begins with a numeric zero. If P is not a query +** parameter on F or if the value of P is does not match any of the +** above, then sqlite3_uri_boolean(F,P,B) returns (B!=0). +** +** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a +** 64-bit signed integer and returns that integer, or D if P does not +** exist. If the value of P is something other than an integer, then +** zero is returned. +** +** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and +** sqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and +** is not a database file pathname pointer that SQLite passed into the xOpen +** VFS method, then the behavior of this routine is undefined and probably +** undesirable. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam); +SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64(const char*, const char*, sqlite3_int64); + + +/* +** CAPI3REF: Error Codes And Messages +** METHOD: sqlite3 +** +** ^If the most recent sqlite3_* API call associated with +** [database connection] D failed, then the sqlite3_errcode(D) interface +** returns the numeric [result code] or [extended result code] for that +** API call. +** If the most recent API call was successful, +** then the return value from sqlite3_errcode() is undefined. +** ^The sqlite3_extended_errcode() +** interface is the same except that it always returns the +** [extended result code] even when extended result codes are +** disabled. +** +** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language +** text that describes the error, as either UTF-8 or UTF-16 respectively. +** ^(Memory to hold the error message string is managed internally. +** The application does not need to worry about freeing the result. +** However, the error string might be overwritten or deallocated by +** subsequent calls to other SQLite interface functions.)^ +** +** ^The sqlite3_errstr() interface returns the English-language text +** that describes the [result code], as UTF-8. +** ^(Memory to hold the error message string is managed internally +** and must not be freed by the application)^. +** +** When the serialized [threading mode] is in use, it might be the +** case that a second error occurs on a separate thread in between +** the time of the first error and the call to these interfaces. +** When that happens, the second error will be reported since these +** interfaces always report the most recent result. To avoid +** this, each thread can obtain exclusive use of the [database connection] D +** by invoking [sqlite3_mutex_enter]([sqlite3_db_mutex](D)) before beginning +** to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after +** all calls to the interfaces listed here are completed. +** +** If an interface fails with SQLITE_MISUSE, that means the interface +** was invoked incorrectly by the application. In that case, the +** error code and message may or may not be set. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db); +SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db); +SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3*); +SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3*); +SQLITE_API const char *SQLITE_STDCALL sqlite3_errstr(int); + +/* +** CAPI3REF: Prepared Statement Object +** KEYWORDS: {prepared statement} {prepared statements} +** +** An instance of this object represents a single SQL statement that +** has been compiled into binary form and is ready to be evaluated. +** +** Think of each SQL statement as a separate computer program. The +** original SQL text is source code. A prepared statement object +** is the compiled object code. All SQL must be converted into a +** prepared statement before it can be run. +** +** The life-cycle of a prepared statement object usually goes like this: +** +**
      +**
    1. Create the prepared statement object using [sqlite3_prepare_v2()]. +**
    2. Bind values to [parameters] using the sqlite3_bind_*() +** interfaces. +**
    3. Run the SQL by calling [sqlite3_step()] one or more times. +**
    4. Reset the prepared statement using [sqlite3_reset()] then go back +** to step 2. Do this zero or more times. +**
    5. Destroy the object using [sqlite3_finalize()]. +**
    +*/ +typedef struct sqlite3_stmt sqlite3_stmt; + +/* +** CAPI3REF: Run-time Limits +** METHOD: sqlite3 +** +** ^(This interface allows the size of various constructs to be limited +** on a connection by connection basis. The first parameter is the +** [database connection] whose limit is to be set or queried. The +** second parameter is one of the [limit categories] that define a +** class of constructs to be size limited. The third parameter is the +** new limit for that construct.)^ +** +** ^If the new limit is a negative number, the limit is unchanged. +** ^(For each limit category SQLITE_LIMIT_NAME there is a +** [limits | hard upper bound] +** set at compile-time by a C preprocessor macro called +** [limits | SQLITE_MAX_NAME]. +** (The "_LIMIT_" in the name is changed to "_MAX_".))^ +** ^Attempts to increase a limit above its hard upper bound are +** silently truncated to the hard upper bound. +** +** ^Regardless of whether or not the limit was changed, the +** [sqlite3_limit()] interface returns the prior value of the limit. +** ^Hence, to find the current value of a limit without changing it, +** simply invoke this interface with the third parameter set to -1. +** +** Run-time limits are intended for use in applications that manage +** both their own internal database and also databases that are controlled +** by untrusted external sources. An example application might be a +** web browser that has its own databases for storing history and +** separate databases controlled by JavaScript applications downloaded +** off the Internet. The internal databases can be given the +** large, default limits. Databases managed by external sources can +** be given much smaller limits designed to prevent a denial of service +** attack. Developers might also want to use the [sqlite3_set_authorizer()] +** interface to further control untrusted SQL. The size of the database +** created by an untrusted script can be contained using the +** [max_page_count] [PRAGMA]. +** +** New run-time limit categories may be added in future releases. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal); + +/* +** CAPI3REF: Run-Time Limit Categories +** KEYWORDS: {limit category} {*limit categories} +** +** These constants define various performance limits +** that can be lowered at run-time using [sqlite3_limit()]. +** The synopsis of the meanings of the various limits is shown below. +** Additional information is available at [limits | Limits in SQLite]. +** +**
    +** [[SQLITE_LIMIT_LENGTH]] ^(
    SQLITE_LIMIT_LENGTH
    +**
    The maximum size of any string or BLOB or table row, in bytes.
    )^ +** +** [[SQLITE_LIMIT_SQL_LENGTH]] ^(
    SQLITE_LIMIT_SQL_LENGTH
    +**
    The maximum length of an SQL statement, in bytes.
    )^ +** +** [[SQLITE_LIMIT_COLUMN]] ^(
    SQLITE_LIMIT_COLUMN
    +**
    The maximum number of columns in a table definition or in the +** result set of a [SELECT] or the maximum number of columns in an index +** or in an ORDER BY or GROUP BY clause.
    )^ +** +** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(
    SQLITE_LIMIT_EXPR_DEPTH
    +**
    The maximum depth of the parse tree on any expression.
    )^ +** +** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(
    SQLITE_LIMIT_COMPOUND_SELECT
    +**
    The maximum number of terms in a compound SELECT statement.
    )^ +** +** [[SQLITE_LIMIT_VDBE_OP]] ^(
    SQLITE_LIMIT_VDBE_OP
    +**
    The maximum number of instructions in a virtual machine program +** used to implement an SQL statement. This limit is not currently +** enforced, though that might be added in some future release of +** SQLite.
    )^ +** +** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(
    SQLITE_LIMIT_FUNCTION_ARG
    +**
    The maximum number of arguments on a function.
    )^ +** +** [[SQLITE_LIMIT_ATTACHED]] ^(
    SQLITE_LIMIT_ATTACHED
    +**
    The maximum number of [ATTACH | attached databases].)^
    +** +** [[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]] +** ^(
    SQLITE_LIMIT_LIKE_PATTERN_LENGTH
    +**
    The maximum length of the pattern argument to the [LIKE] or +** [GLOB] operators.
    )^ +** +** [[SQLITE_LIMIT_VARIABLE_NUMBER]] +** ^(
    SQLITE_LIMIT_VARIABLE_NUMBER
    +**
    The maximum index number of any [parameter] in an SQL statement.)^ +** +** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(
    SQLITE_LIMIT_TRIGGER_DEPTH
    +**
    The maximum depth of recursion for triggers.
    )^ +** +** [[SQLITE_LIMIT_WORKER_THREADS]] ^(
    SQLITE_LIMIT_WORKER_THREADS
    +**
    The maximum number of auxiliary worker threads that a single +** [prepared statement] may start.
    )^ +**
    +*/ +#define SQLITE_LIMIT_LENGTH 0 +#define SQLITE_LIMIT_SQL_LENGTH 1 +#define SQLITE_LIMIT_COLUMN 2 +#define SQLITE_LIMIT_EXPR_DEPTH 3 +#define SQLITE_LIMIT_COMPOUND_SELECT 4 +#define SQLITE_LIMIT_VDBE_OP 5 +#define SQLITE_LIMIT_FUNCTION_ARG 6 +#define SQLITE_LIMIT_ATTACHED 7 +#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8 +#define SQLITE_LIMIT_VARIABLE_NUMBER 9 +#define SQLITE_LIMIT_TRIGGER_DEPTH 10 +#define SQLITE_LIMIT_WORKER_THREADS 11 + +/* +** CAPI3REF: Compiling An SQL Statement +** KEYWORDS: {SQL statement compiler} +** METHOD: sqlite3 +** CONSTRUCTOR: sqlite3_stmt +** +** To execute an SQL query, it must first be compiled into a byte-code +** program using one of these routines. +** +** The first argument, "db", is a [database connection] obtained from a +** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or +** [sqlite3_open16()]. The database connection must not have been closed. +** +** The second argument, "zSql", is the statement to be compiled, encoded +** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2() +** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2() +** use UTF-16. +** +** ^If the nByte argument is negative, then zSql is read up to the +** first zero terminator. ^If nByte is positive, then it is the +** number of bytes read from zSql. ^If nByte is zero, then no prepared +** statement is generated. +** If the caller knows that the supplied string is nul-terminated, then +** there is a small performance advantage to passing an nByte parameter that +** is the number of bytes in the input string including +** the nul-terminator. +** +** ^If pzTail is not NULL then *pzTail is made to point to the first byte +** past the end of the first SQL statement in zSql. These routines only +** compile the first statement in zSql, so *pzTail is left pointing to +** what remains uncompiled. +** +** ^*ppStmt is left pointing to a compiled [prepared statement] that can be +** executed using [sqlite3_step()]. ^If there is an error, *ppStmt is set +** to NULL. ^If the input text contains no SQL (if the input is an empty +** string or a comment) then *ppStmt is set to NULL. +** The calling procedure is responsible for deleting the compiled +** SQL statement using [sqlite3_finalize()] after it has finished with it. +** ppStmt may not be NULL. +** +** ^On success, the sqlite3_prepare() family of routines return [SQLITE_OK]; +** otherwise an [error code] is returned. +** +** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are +** recommended for all new programs. The two older interfaces are retained +** for backwards compatibility, but their use is discouraged. +** ^In the "v2" interfaces, the prepared statement +** that is returned (the [sqlite3_stmt] object) contains a copy of the +** original SQL text. This causes the [sqlite3_step()] interface to +** behave differently in three ways: +** +**
      +**
    1. +** ^If the database schema changes, instead of returning [SQLITE_SCHEMA] as it +** always used to do, [sqlite3_step()] will automatically recompile the SQL +** statement and try to run it again. As many as [SQLITE_MAX_SCHEMA_RETRY] +** retries will occur before sqlite3_step() gives up and returns an error. +**
    2. +** +**
    3. +** ^When an error occurs, [sqlite3_step()] will return one of the detailed +** [error codes] or [extended error codes]. ^The legacy behavior was that +** [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code +** and the application would have to make a second call to [sqlite3_reset()] +** in order to find the underlying cause of the problem. With the "v2" prepare +** interfaces, the underlying reason for the error is returned immediately. +**
    4. +** +**
    5. +** ^If the specific value bound to [parameter | host parameter] in the +** WHERE clause might influence the choice of query plan for a statement, +** then the statement will be automatically recompiled, as if there had been +** a schema change, on the first [sqlite3_step()] call following any change +** to the [sqlite3_bind_text | bindings] of that [parameter]. +** ^The specific value of WHERE-clause [parameter] might influence the +** choice of query plan if the parameter is the left-hand side of a [LIKE] +** or [GLOB] operator or if the parameter is compared to an indexed column +** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled. +**
    6. +**
    +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_prepare( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int SQLITE_STDCALL sqlite3_prepare16( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); + +/* +** CAPI3REF: Retrieving Statement SQL +** METHOD: sqlite3_stmt +** +** ^This interface can be used to retrieve a saved copy of the original +** SQL text used to create a [prepared statement] if that statement was +** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()]. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Determine If An SQL Statement Writes The Database +** METHOD: sqlite3_stmt +** +** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if +** and only if the [prepared statement] X makes no direct changes to +** the content of the database file. +** +** Note that [application-defined SQL functions] or +** [virtual tables] might change the database indirectly as a side effect. +** ^(For example, if an application defines a function "eval()" that +** calls [sqlite3_exec()], then the following SQL statement would +** change the database file through side-effects: +** +**
    +**    SELECT eval('DELETE FROM t1') FROM t2;
    +** 
    +** +** But because the [SELECT] statement does not change the database file +** directly, sqlite3_stmt_readonly() would still return true.)^ +** +** ^Transaction control statements such as [BEGIN], [COMMIT], [ROLLBACK], +** [SAVEPOINT], and [RELEASE] cause sqlite3_stmt_readonly() to return true, +** since the statements themselves do not actually modify the database but +** rather they control the timing of when other statements modify the +** database. ^The [ATTACH] and [DETACH] statements also cause +** sqlite3_stmt_readonly() to return true since, while those statements +** change the configuration of a database connection, they do not make +** changes to the content of the database files on disk. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Determine If A Prepared Statement Has Been Reset +** METHOD: sqlite3_stmt +** +** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the +** [prepared statement] S has been stepped at least once using +** [sqlite3_step(S)] but has not run to completion and/or has not +** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S) +** interface returns false if S is a NULL pointer. If S is not a +** NULL pointer and is not a pointer to a valid [prepared statement] +** object, then the behavior is undefined and probably undesirable. +** +** This interface can be used in combination [sqlite3_next_stmt()] +** to locate all prepared statements associated with a database +** connection that are in need of being reset. This can be used, +** for example, in diagnostic routines to search for prepared +** statements that are holding a transaction open. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt*); + +/* +** CAPI3REF: Dynamically Typed Value Object +** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value} +** +** SQLite uses the sqlite3_value object to represent all values +** that can be stored in a database table. SQLite uses dynamic typing +** for the values it stores. ^Values stored in sqlite3_value objects +** can be integers, floating point values, strings, BLOBs, or NULL. +** +** An sqlite3_value object may be either "protected" or "unprotected". +** Some interfaces require a protected sqlite3_value. Other interfaces +** will accept either a protected or an unprotected sqlite3_value. +** Every interface that accepts sqlite3_value arguments specifies +** whether or not it requires a protected sqlite3_value. +** +** The terms "protected" and "unprotected" refer to whether or not +** a mutex is held. An internal mutex is held for a protected +** sqlite3_value object but no mutex is held for an unprotected +** sqlite3_value object. If SQLite is compiled to be single-threaded +** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0) +** or if SQLite is run in one of reduced mutex modes +** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD] +** then there is no distinction between protected and unprotected +** sqlite3_value objects and they can be used interchangeably. However, +** for maximum code portability it is recommended that applications +** still make the distinction between protected and unprotected +** sqlite3_value objects even when not strictly required. +** +** ^The sqlite3_value objects that are passed as parameters into the +** implementation of [application-defined SQL functions] are protected. +** ^The sqlite3_value object returned by +** [sqlite3_column_value()] is unprotected. +** Unprotected sqlite3_value objects may only be used with +** [sqlite3_result_value()] and [sqlite3_bind_value()]. +** The [sqlite3_value_blob | sqlite3_value_type()] family of +** interfaces require protected sqlite3_value objects. +*/ +typedef struct Mem sqlite3_value; + +/* +** CAPI3REF: SQL Function Context Object +** +** The context in which an SQL function executes is stored in an +** sqlite3_context object. ^A pointer to an sqlite3_context object +** is always first parameter to [application-defined SQL functions]. +** The application-defined SQL function implementation will pass this +** pointer through into calls to [sqlite3_result_int | sqlite3_result()], +** [sqlite3_aggregate_context()], [sqlite3_user_data()], +** [sqlite3_context_db_handle()], [sqlite3_get_auxdata()], +** and/or [sqlite3_set_auxdata()]. +*/ +typedef struct sqlite3_context sqlite3_context; + +/* +** CAPI3REF: Binding Values To Prepared Statements +** KEYWORDS: {host parameter} {host parameters} {host parameter name} +** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} +** METHOD: sqlite3_stmt +** +** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, +** literals may be replaced by a [parameter] that matches one of following +** templates: +** +**
      +**
    • ? +**
    • ?NNN +**
    • :VVV +**
    • @VVV +**
    • $VVV +**
    +** +** In the templates above, NNN represents an integer literal, +** and VVV represents an alphanumeric identifier.)^ ^The values of these +** parameters (also called "host parameter names" or "SQL parameters") +** can be set using the sqlite3_bind_*() routines defined here. +** +** ^The first argument to the sqlite3_bind_*() routines is always +** a pointer to the [sqlite3_stmt] object returned from +** [sqlite3_prepare_v2()] or its variants. +** +** ^The second argument is the index of the SQL parameter to be set. +** ^The leftmost SQL parameter has an index of 1. ^When the same named +** SQL parameter is used more than once, second and subsequent +** occurrences have the same index as the first occurrence. +** ^The index for named parameters can be looked up using the +** [sqlite3_bind_parameter_index()] API if desired. ^The index +** for "?NNN" parameters is the value of NNN. +** ^The NNN value must be between 1 and the [sqlite3_limit()] +** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999). +** +** ^The third argument is the value to bind to the parameter. +** ^If the third parameter to sqlite3_bind_text() or sqlite3_bind_text16() +** or sqlite3_bind_blob() is a NULL pointer then the fourth parameter +** is ignored and the end result is the same as sqlite3_bind_null(). +** +** ^(In those routines that have a fourth argument, its value is the +** number of bytes in the parameter. To be clear: the value is the +** number of bytes in the value, not the number of characters.)^ +** ^If the fourth parameter to sqlite3_bind_text() or sqlite3_bind_text16() +** is negative, then the length of the string is +** the number of bytes up to the first zero terminator. +** If the fourth parameter to sqlite3_bind_blob() is negative, then +** the behavior is undefined. +** If a non-negative fourth parameter is provided to sqlite3_bind_text() +** or sqlite3_bind_text16() or sqlite3_bind_text64() then +** that parameter must be the byte offset +** where the NUL terminator would occur assuming the string were NUL +** terminated. If any NUL characters occur at byte offsets less than +** the value of the fourth parameter then the resulting string value will +** contain embedded NULs. The result of expressions involving strings +** with embedded NULs is undefined. +** +** ^The fifth argument to the BLOB and string binding interfaces +** is a destructor used to dispose of the BLOB or +** string after SQLite has finished with it. ^The destructor is called +** to dispose of the BLOB or string even if the call to bind API fails. +** ^If the fifth argument is +** the special value [SQLITE_STATIC], then SQLite assumes that the +** information is in static, unmanaged space and does not need to be freed. +** ^If the fifth argument has the value [SQLITE_TRANSIENT], then +** SQLite makes its own private copy of the data immediately, before +** the sqlite3_bind_*() routine returns. +** +** ^The sixth argument to sqlite3_bind_text64() must be one of +** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE] +** to specify the encoding of the text in the third parameter. If +** the sixth argument to sqlite3_bind_text64() is not one of the +** allowed values shown above, or if the text encoding is different +** from the encoding specified by the sixth parameter, then the behavior +** is undefined. +** +** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that +** is filled with zeroes. ^A zeroblob uses a fixed amount of memory +** (just an integer to hold its size) while it is being processed. +** Zeroblobs are intended to serve as placeholders for BLOBs whose +** content is later written using +** [sqlite3_blob_open | incremental BLOB I/O] routines. +** ^A negative value for the zeroblob results in a zero-length BLOB. +** +** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer +** for the [prepared statement] or with a prepared statement for which +** [sqlite3_step()] has been called more recently than [sqlite3_reset()], +** then the call will return [SQLITE_MISUSE]. If any sqlite3_bind_() +** routine is passed a [prepared statement] that has been finalized, the +** result is undefined and probably harmful. +** +** ^Bindings are not cleared by the [sqlite3_reset()] routine. +** ^Unbound parameters are interpreted as NULL. +** +** ^The sqlite3_bind_* routines return [SQLITE_OK] on success or an +** [error code] if anything goes wrong. +** ^[SQLITE_TOOBIG] might be returned if the size of a string or BLOB +** exceeds limits imposed by [sqlite3_limit]([SQLITE_LIMIT_LENGTH]) or +** [SQLITE_MAX_LENGTH]. +** ^[SQLITE_RANGE] is returned if the parameter +** index is out of range. ^[SQLITE_NOMEM] is returned if malloc() fails. +** +** See also: [sqlite3_bind_parameter_count()], +** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64, + void(*)(void*)); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt*, int, double); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt*, int, int); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt*, int); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*)); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, + void(*)(void*), unsigned char encoding); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); + +/* +** CAPI3REF: Number Of SQL Parameters +** METHOD: sqlite3_stmt +** +** ^This routine can be used to find the number of [SQL parameters] +** in a [prepared statement]. SQL parameters are tokens of the +** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as +** placeholders for values that are [sqlite3_bind_blob | bound] +** to the parameters at a later time. +** +** ^(This routine actually returns the index of the largest (rightmost) +** parameter. For all forms except ?NNN, this will correspond to the +** number of unique parameters. If parameters of the ?NNN form are used, +** there may be gaps in the list.)^ +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_name()], and +** [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt*); + +/* +** CAPI3REF: Name Of A Host Parameter +** METHOD: sqlite3_stmt +** +** ^The sqlite3_bind_parameter_name(P,N) interface returns +** the name of the N-th [SQL parameter] in the [prepared statement] P. +** ^(SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA" +** have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA" +** respectively. +** In other words, the initial ":" or "$" or "@" or "?" +** is included as part of the name.)^ +** ^Parameters of the form "?" without a following integer have no name +** and are referred to as "nameless" or "anonymous parameters". +** +** ^The first host parameter has an index of 1, not 0. +** +** ^If the value N is out of range or if the N-th parameter is +** nameless, then NULL is returned. ^The returned string is +** always in UTF-8 encoding even if the named parameter was +** originally specified as UTF-16 in [sqlite3_prepare16()] or +** [sqlite3_prepare16_v2()]. +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_count()], and +** [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt*, int); + +/* +** CAPI3REF: Index Of A Parameter With A Given Name +** METHOD: sqlite3_stmt +** +** ^Return the index of an SQL parameter given its name. ^The +** index value returned is suitable for use as the second +** parameter to [sqlite3_bind_blob|sqlite3_bind()]. ^A zero +** is returned if no matching parameter is found. ^The parameter +** name must be given in UTF-8 even if the original statement +** was prepared from UTF-16 text using [sqlite3_prepare16_v2()]. +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_count()], and +** [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); + +/* +** CAPI3REF: Reset All Bindings On A Prepared Statement +** METHOD: sqlite3_stmt +** +** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset +** the [sqlite3_bind_blob | bindings] on a [prepared statement]. +** ^Use this routine to reset all host parameters to NULL. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt*); + +/* +** CAPI3REF: Number Of Columns In A Result Set +** METHOD: sqlite3_stmt +** +** ^Return the number of columns in the result set returned by the +** [prepared statement]. ^This routine returns 0 if pStmt is an SQL +** statement that does not return data (for example an [UPDATE]). +** +** See also: [sqlite3_data_count()] +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Column Names In A Result Set +** METHOD: sqlite3_stmt +** +** ^These routines return the name assigned to a particular column +** in the result set of a [SELECT] statement. ^The sqlite3_column_name() +** interface returns a pointer to a zero-terminated UTF-8 string +** and sqlite3_column_name16() returns a pointer to a zero-terminated +** UTF-16 string. ^The first parameter is the [prepared statement] +** that implements the [SELECT] statement. ^The second parameter is the +** column number. ^The leftmost column is number 0. +** +** ^The returned string pointer is valid until either the [prepared statement] +** is destroyed by [sqlite3_finalize()] or until the statement is automatically +** reprepared by the first call to [sqlite3_step()] for a particular run +** or until the next call to +** sqlite3_column_name() or sqlite3_column_name16() on the same column. +** +** ^If sqlite3_malloc() fails during the processing of either routine +** (for example during a conversion from UTF-8 to UTF-16) then a +** NULL pointer is returned. +** +** ^The name of a result column is the value of the "AS" clause for +** that column, if there is an AS clause. If there is no AS clause +** then the name of the column is unspecified and may change from +** one release of SQLite to the next. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_name(sqlite3_stmt*, int N); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt*, int N); + +/* +** CAPI3REF: Source Of Data In A Query Result +** METHOD: sqlite3_stmt +** +** ^These routines provide a means to determine the database, table, and +** table column that is the origin of a particular result column in +** [SELECT] statement. +** ^The name of the database or table or column can be returned as +** either a UTF-8 or UTF-16 string. ^The _database_ routines return +** the database name, the _table_ routines return the table name, and +** the origin_ routines return the column name. +** ^The returned string is valid until the [prepared statement] is destroyed +** using [sqlite3_finalize()] or until the statement is automatically +** reprepared by the first call to [sqlite3_step()] for a particular run +** or until the same information is requested +** again in a different encoding. +** +** ^The names returned are the original un-aliased names of the +** database, table, and column. +** +** ^The first argument to these interfaces is a [prepared statement]. +** ^These functions return information about the Nth result column returned by +** the statement, where N is the second function argument. +** ^The left-most column is column 0 for these routines. +** +** ^If the Nth column returned by the statement is an expression or +** subquery and is not a column value, then all of these functions return +** NULL. ^These routine might also return NULL if a memory allocation error +** occurs. ^Otherwise, they return the name of the attached database, table, +** or column that query result column was extracted from. +** +** ^As with all other SQLite APIs, those whose names end with "16" return +** UTF-16 encoded strings and the other functions return UTF-8. +** +** ^These APIs are only available if the library was compiled with the +** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol. +** +** If two or more threads call one or more of these routines against the same +** prepared statement and column at the same time then the results are +** undefined. +** +** If two or more threads call one or more +** [sqlite3_column_database_name | column metadata interfaces] +** for the same [prepared statement] and result column +** at the same time then the results are undefined. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt*,int); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt*,int); +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt*,int); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt*,int); +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt*,int); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Declared Datatype Of A Query Result +** METHOD: sqlite3_stmt +** +** ^(The first parameter is a [prepared statement]. +** If this statement is a [SELECT] statement and the Nth column of the +** returned result set of that [SELECT] is a table column (not an +** expression or subquery) then the declared type of the table +** column is returned.)^ ^If the Nth column of the result set is an +** expression or subquery, then a NULL pointer is returned. +** ^The returned string is always UTF-8 encoded. +** +** ^(For example, given the database schema: +** +** CREATE TABLE t1(c1 VARIANT); +** +** and the following statement to be compiled: +** +** SELECT c1 + 1, c1 FROM t1; +** +** this routine would return the string "VARIANT" for the second result +** column (i==1), and a NULL pointer for the first result column (i==0).)^ +** +** ^SQLite uses dynamic run-time typing. ^So just because a column +** is declared to contain a particular type does not mean that the +** data stored in that column is of the declared type. SQLite is +** strongly typed, but the typing is dynamic not static. ^Type +** is associated with individual values, not with the containers +** used to hold those values. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt*,int); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Evaluate An SQL Statement +** METHOD: sqlite3_stmt +** +** After a [prepared statement] has been prepared using either +** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy +** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function +** must be called one or more times to evaluate the statement. +** +** The details of the behavior of the sqlite3_step() interface depend +** on whether the statement was prepared using the newer "v2" interface +** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy +** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the +** new "v2" interface is recommended for new applications but the legacy +** interface will continue to be supported. +** +** ^In the legacy interface, the return value will be either [SQLITE_BUSY], +** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE]. +** ^With the "v2" interface, any of the other [result codes] or +** [extended result codes] might be returned as well. +** +** ^[SQLITE_BUSY] means that the database engine was unable to acquire the +** database locks it needs to do its job. ^If the statement is a [COMMIT] +** or occurs outside of an explicit transaction, then you can retry the +** statement. If the statement is not a [COMMIT] and occurs within an +** explicit transaction then you should rollback the transaction before +** continuing. +** +** ^[SQLITE_DONE] means that the statement has finished executing +** successfully. sqlite3_step() should not be called again on this virtual +** machine without first calling [sqlite3_reset()] to reset the virtual +** machine back to its initial state. +** +** ^If the SQL statement being executed returns any data, then [SQLITE_ROW] +** is returned each time a new row of data is ready for processing by the +** caller. The values may be accessed using the [column access functions]. +** sqlite3_step() is called again to retrieve the next row of data. +** +** ^[SQLITE_ERROR] means that a run-time error (such as a constraint +** violation) has occurred. sqlite3_step() should not be called again on +** the VM. More information may be found by calling [sqlite3_errmsg()]. +** ^With the legacy interface, a more specific error code (for example, +** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth) +** can be obtained by calling [sqlite3_reset()] on the +** [prepared statement]. ^In the "v2" interface, +** the more specific error code is returned directly by sqlite3_step(). +** +** [SQLITE_MISUSE] means that the this routine was called inappropriately. +** Perhaps it was called on a [prepared statement] that has +** already been [sqlite3_finalize | finalized] or on one that had +** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could +** be the case that the same database connection is being used by two or +** more threads at the same moment in time. +** +** For all versions of SQLite up to and including 3.6.23.1, a call to +** [sqlite3_reset()] was required after sqlite3_step() returned anything +** other than [SQLITE_ROW] before any subsequent invocation of +** sqlite3_step(). Failure to reset the prepared statement using +** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from +** sqlite3_step(). But after version 3.6.23.1, sqlite3_step() began +** calling [sqlite3_reset()] automatically in this circumstance rather +** than returning [SQLITE_MISUSE]. This is not considered a compatibility +** break because any application that ever receives an SQLITE_MISUSE error +** is broken by definition. The [SQLITE_OMIT_AUTORESET] compile-time option +** can be used to restore the legacy behavior. +** +** Goofy Interface Alert: In the legacy interface, the sqlite3_step() +** API always returns a generic error code, [SQLITE_ERROR], following any +** error other than [SQLITE_BUSY] and [SQLITE_MISUSE]. You must call +** [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the +** specific [error codes] that better describes the error. +** We admit that this is a goofy design. The problem has been fixed +** with the "v2" interface. If you prepare all of your SQL statements +** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead +** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces, +** then the more specific [error codes] are returned directly +** by sqlite3_step(). The use of the "v2" interface is recommended. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt*); + +/* +** CAPI3REF: Number of columns in a result set +** METHOD: sqlite3_stmt +** +** ^The sqlite3_data_count(P) interface returns the number of columns in the +** current row of the result set of [prepared statement] P. +** ^If prepared statement P does not have results ready to return +** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of +** interfaces) then sqlite3_data_count(P) returns 0. +** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer. +** ^The sqlite3_data_count(P) routine returns 0 if the previous call to +** [sqlite3_step](P) returned [SQLITE_DONE]. ^The sqlite3_data_count(P) +** will return non-zero if previous call to [sqlite3_step](P) returned +** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum] +** where it always returns zero since each step of that multi-step +** pragma returns 0 columns of data. +** +** See also: [sqlite3_column_count()] +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Fundamental Datatypes +** KEYWORDS: SQLITE_TEXT +** +** ^(Every value in SQLite has one of five fundamental datatypes: +** +**
      +**
    • 64-bit signed integer +**
    • 64-bit IEEE floating point number +**
    • string +**
    • BLOB +**
    • NULL +**
    )^ +** +** These constants are codes for each of those types. +** +** Note that the SQLITE_TEXT constant was also used in SQLite version 2 +** for a completely different meaning. Software that links against both +** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT, not +** SQLITE_TEXT. +*/ +#define SQLITE_INTEGER 1 +#define SQLITE_FLOAT 2 +#define SQLITE_BLOB 4 +#define SQLITE_NULL 5 +#ifdef SQLITE_TEXT +# undef SQLITE_TEXT +#else +# define SQLITE_TEXT 3 +#endif +#define SQLITE3_TEXT 3 + +/* +** CAPI3REF: Result Values From A Query +** KEYWORDS: {column access functions} +** METHOD: sqlite3_stmt +** +** These routines form the "result set" interface. +** +** ^These routines return information about a single column of the current +** result row of a query. ^In every case the first argument is a pointer +** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*] +** that was returned from [sqlite3_prepare_v2()] or one of its variants) +** and the second argument is the index of the column for which information +** should be returned. ^The leftmost column of the result set has the index 0. +** ^The number of columns in the result can be determined using +** [sqlite3_column_count()]. +** +** If the SQL statement does not currently point to a valid row, or if the +** column index is out of range, the result is undefined. +** These routines may only be called when the most recent call to +** [sqlite3_step()] has returned [SQLITE_ROW] and neither +** [sqlite3_reset()] nor [sqlite3_finalize()] have been called subsequently. +** If any of these routines are called after [sqlite3_reset()] or +** [sqlite3_finalize()] or after [sqlite3_step()] has returned +** something other than [SQLITE_ROW], the results are undefined. +** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()] +** are called from a different thread while any of these routines +** are pending, then the results are undefined. +** +** ^The sqlite3_column_type() routine returns the +** [SQLITE_INTEGER | datatype code] for the initial data type +** of the result column. ^The returned value is one of [SQLITE_INTEGER], +** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value +** returned by sqlite3_column_type() is only meaningful if no type +** conversions have occurred as described below. After a type conversion, +** the value returned by sqlite3_column_type() is undefined. Future +** versions of SQLite may change the behavior of sqlite3_column_type() +** following a type conversion. +** +** ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() +** routine returns the number of bytes in that BLOB or string. +** ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts +** the string to UTF-8 and then returns the number of bytes. +** ^If the result is a numeric value then sqlite3_column_bytes() uses +** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns +** the number of bytes in that string. +** ^If the result is NULL, then sqlite3_column_bytes() returns zero. +** +** ^If the result is a BLOB or UTF-16 string then the sqlite3_column_bytes16() +** routine returns the number of bytes in that BLOB or string. +** ^If the result is a UTF-8 string, then sqlite3_column_bytes16() converts +** the string to UTF-16 and then returns the number of bytes. +** ^If the result is a numeric value then sqlite3_column_bytes16() uses +** [sqlite3_snprintf()] to convert that value to a UTF-16 string and returns +** the number of bytes in that string. +** ^If the result is NULL, then sqlite3_column_bytes16() returns zero. +** +** ^The values returned by [sqlite3_column_bytes()] and +** [sqlite3_column_bytes16()] do not include the zero terminators at the end +** of the string. ^For clarity: the values returned by +** [sqlite3_column_bytes()] and [sqlite3_column_bytes16()] are the number of +** bytes in the string, not the number of characters. +** +** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(), +** even empty strings, are always zero-terminated. ^The return +** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer. +** +** ^The object returned by [sqlite3_column_value()] is an +** [unprotected sqlite3_value] object. An unprotected sqlite3_value object +** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()]. +** If the [unprotected sqlite3_value] object returned by +** [sqlite3_column_value()] is used in any other way, including calls +** to routines like [sqlite3_value_int()], [sqlite3_value_text()], +** or [sqlite3_value_bytes()], then the behavior is undefined. +** +** These routines attempt to convert the value where appropriate. ^For +** example, if the internal representation is FLOAT and a text result +** is requested, [sqlite3_snprintf()] is used internally to perform the +** conversion automatically. ^(The following table details the conversions +** that are applied: +** +**
    +** +**
    Internal
    Type
    Requested
    Type
    Conversion +** +**
    NULL INTEGER Result is 0 +**
    NULL FLOAT Result is 0.0 +**
    NULL TEXT Result is a NULL pointer +**
    NULL BLOB Result is a NULL pointer +**
    INTEGER FLOAT Convert from integer to float +**
    INTEGER TEXT ASCII rendering of the integer +**
    INTEGER BLOB Same as INTEGER->TEXT +**
    FLOAT INTEGER [CAST] to INTEGER +**
    FLOAT TEXT ASCII rendering of the float +**
    FLOAT BLOB [CAST] to BLOB +**
    TEXT INTEGER [CAST] to INTEGER +**
    TEXT FLOAT [CAST] to REAL +**
    TEXT BLOB No change +**
    BLOB INTEGER [CAST] to INTEGER +**
    BLOB FLOAT [CAST] to REAL +**
    BLOB TEXT Add a zero terminator if needed +**
    +**
    )^ +** +** The table above makes reference to standard C library functions atoi() +** and atof(). SQLite does not really use these functions. It has its +** own equivalent internal routines. The atoi() and atof() names are +** used in the table for brevity and because they are familiar to most +** C programmers. +** +** Note that when type conversions occur, pointers returned by prior +** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or +** sqlite3_column_text16() may be invalidated. +** Type conversions and pointer invalidations might occur +** in the following cases: +** +**
      +**
    • The initial content is a BLOB and sqlite3_column_text() or +** sqlite3_column_text16() is called. A zero-terminator might +** need to be added to the string.
    • +**
    • The initial content is UTF-8 text and sqlite3_column_bytes16() or +** sqlite3_column_text16() is called. The content must be converted +** to UTF-16.
    • +**
    • The initial content is UTF-16 text and sqlite3_column_bytes() or +** sqlite3_column_text() is called. The content must be converted +** to UTF-8.
    • +**
    +** +** ^Conversions between UTF-16be and UTF-16le are always done in place and do +** not invalidate a prior pointer, though of course the content of the buffer +** that the prior pointer references will have been modified. Other kinds +** of conversion are done in place when it is possible, but sometimes they +** are not possible and in those cases prior pointers are invalidated. +** +** The safest and easiest to remember policy is to invoke these routines +** in one of the following ways: +** +**
      +**
    • sqlite3_column_text() followed by sqlite3_column_bytes()
    • +**
    • sqlite3_column_blob() followed by sqlite3_column_bytes()
    • +**
    • sqlite3_column_text16() followed by sqlite3_column_bytes16()
    • +**
    +** +** In other words, you should call sqlite3_column_text(), +** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result +** into the desired format, then invoke sqlite3_column_bytes() or +** sqlite3_column_bytes16() to find the size of the result. Do not mix calls +** to sqlite3_column_text() or sqlite3_column_blob() with calls to +** sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16() +** with calls to sqlite3_column_bytes(). +** +** ^The pointers returned are valid until a type conversion occurs as +** described above, or until [sqlite3_step()] or [sqlite3_reset()] or +** [sqlite3_finalize()] is called. ^The memory space used to hold strings +** and BLOBs is freed automatically. Do not pass the pointers returned +** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into +** [sqlite3_free()]. +** +** ^(If a memory allocation error occurs during the evaluation of any +** of these routines, a default value is returned. The default value +** is either the integer 0, the floating point number 0.0, or a NULL +** pointer. Subsequent calls to [sqlite3_errcode()] will return +** [SQLITE_NOMEM].)^ +*/ +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt*, int iCol); +SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt*, int iCol); +SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt*, int iCol); +SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_column_int64(sqlite3_stmt*, int iCol); +SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt*, int iCol); +SQLITE_API const void *SQLITE_STDCALL sqlite3_column_text16(sqlite3_stmt*, int iCol); +SQLITE_API int SQLITE_STDCALL sqlite3_column_type(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt*, int iCol); + +/* +** CAPI3REF: Destroy A Prepared Statement Object +** DESTRUCTOR: sqlite3_stmt +** +** ^The sqlite3_finalize() function is called to delete a [prepared statement]. +** ^If the most recent evaluation of the statement encountered no errors +** or if the statement is never been evaluated, then sqlite3_finalize() returns +** SQLITE_OK. ^If the most recent evaluation of statement S failed, then +** sqlite3_finalize(S) returns the appropriate [error code] or +** [extended error code]. +** +** ^The sqlite3_finalize(S) routine can be called at any point during +** the life cycle of [prepared statement] S: +** before statement S is ever evaluated, after +** one or more calls to [sqlite3_reset()], or after any call +** to [sqlite3_step()] regardless of whether or not the statement has +** completed execution. +** +** ^Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op. +** +** The application must finalize every [prepared statement] in order to avoid +** resource leaks. It is a grievous error for the application to try to use +** a prepared statement after it has been finalized. Any use of a prepared +** statement after it has been finalized can result in undefined and +** undesirable behavior such as segfaults and heap corruption. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Reset A Prepared Statement Object +** METHOD: sqlite3_stmt +** +** The sqlite3_reset() function is called to reset a [prepared statement] +** object back to its initial state, ready to be re-executed. +** ^Any SQL statement variables that had values bound to them using +** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values. +** Use [sqlite3_clear_bindings()] to reset the bindings. +** +** ^The [sqlite3_reset(S)] interface resets the [prepared statement] S +** back to the beginning of its program. +** +** ^If the most recent call to [sqlite3_step(S)] for the +** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE], +** or if [sqlite3_step(S)] has never before been called on S, +** then [sqlite3_reset(S)] returns [SQLITE_OK]. +** +** ^If the most recent call to [sqlite3_step(S)] for the +** [prepared statement] S indicated an error, then +** [sqlite3_reset(S)] returns an appropriate [error code]. +** +** ^The [sqlite3_reset(S)] interface does not change the values +** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Create Or Redefine SQL Functions +** KEYWORDS: {function creation routines} +** KEYWORDS: {application-defined SQL function} +** KEYWORDS: {application-defined SQL functions} +** METHOD: sqlite3 +** +** ^These functions (collectively known as "function creation routines") +** are used to add SQL functions or aggregates or to redefine the behavior +** of existing SQL functions or aggregates. The only differences between +** these routines are the text encoding expected for +** the second parameter (the name of the function being created) +** and the presence or absence of a destructor callback for +** the application data pointer. +** +** ^The first parameter is the [database connection] to which the SQL +** function is to be added. ^If an application uses more than one database +** connection then application-defined SQL functions must be added +** to each database connection separately. +** +** ^The second parameter is the name of the SQL function to be created or +** redefined. ^The length of the name is limited to 255 bytes in a UTF-8 +** representation, exclusive of the zero-terminator. ^Note that the name +** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes. +** ^Any attempt to create a function with a longer name +** will result in [SQLITE_MISUSE] being returned. +** +** ^The third parameter (nArg) +** is the number of arguments that the SQL function or +** aggregate takes. ^If this parameter is -1, then the SQL function or +** aggregate may take any number of arguments between 0 and the limit +** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]). If the third +** parameter is less than -1 or greater than 127 then the behavior is +** undefined. +** +** ^The fourth parameter, eTextRep, specifies what +** [SQLITE_UTF8 | text encoding] this SQL function prefers for +** its parameters. The application should set this parameter to +** [SQLITE_UTF16LE] if the function implementation invokes +** [sqlite3_value_text16le()] on an input, or [SQLITE_UTF16BE] if the +** implementation invokes [sqlite3_value_text16be()] on an input, or +** [SQLITE_UTF16] if [sqlite3_value_text16()] is used, or [SQLITE_UTF8] +** otherwise. ^The same SQL function may be registered multiple times using +** different preferred text encodings, with different implementations for +** each encoding. +** ^When multiple implementations of the same function are available, SQLite +** will pick the one that involves the least amount of data conversion. +** +** ^The fourth parameter may optionally be ORed with [SQLITE_DETERMINISTIC] +** to signal that the function will always return the same result given +** the same inputs within a single SQL statement. Most SQL functions are +** deterministic. The built-in [random()] SQL function is an example of a +** function that is not deterministic. The SQLite query planner is able to +** perform additional optimizations on deterministic functions, so use +** of the [SQLITE_DETERMINISTIC] flag is recommended where possible. +** +** ^(The fifth parameter is an arbitrary pointer. The implementation of the +** function can gain access to this pointer using [sqlite3_user_data()].)^ +** +** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are +** pointers to C-language functions that implement the SQL function or +** aggregate. ^A scalar SQL function requires an implementation of the xFunc +** callback only; NULL pointers must be passed as the xStep and xFinal +** parameters. ^An aggregate SQL function requires an implementation of xStep +** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing +** SQL function or aggregate, pass NULL pointers for all three function +** callbacks. +** +** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL, +** then it is destructor for the application data pointer. +** The destructor is invoked when the function is deleted, either by being +** overloaded or when the database connection closes.)^ +** ^The destructor is also invoked if the call to +** sqlite3_create_function_v2() fails. +** ^When the destructor callback of the tenth parameter is invoked, it +** is passed a single argument which is a copy of the application data +** pointer which was the fifth parameter to sqlite3_create_function_v2(). +** +** ^It is permitted to register multiple implementations of the same +** functions with the same name but with either differing numbers of +** arguments or differing preferred text encodings. ^SQLite will use +** the implementation that most closely matches the way in which the +** SQL function is used. ^A function implementation with a non-negative +** nArg parameter is a better match than a function implementation with +** a negative nArg. ^A function where the preferred text encoding +** matches the database encoding is a better +** match than a function where the encoding is different. +** ^A function where the encoding difference is between UTF16le and UTF16be +** is a closer match than a function where the encoding difference is +** between UTF8 and UTF16. +** +** ^Built-in functions may be overloaded by new application-defined functions. +** +** ^An application-defined function is permitted to call other +** SQLite interfaces. However, such calls must not +** close the database connection nor finalize or reset the prepared +** statement in which the function is running. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_create_function( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +SQLITE_API int SQLITE_STDCALL sqlite3_create_function16( + sqlite3 *db, + const void *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void(*xDestroy)(void*) +); + +/* +** CAPI3REF: Text Encodings +** +** These constant define integer codes that represent the various +** text encodings supported by SQLite. +*/ +#define SQLITE_UTF8 1 /* IMP: R-37514-35566 */ +#define SQLITE_UTF16LE 2 /* IMP: R-03371-37637 */ +#define SQLITE_UTF16BE 3 /* IMP: R-51971-34154 */ +#define SQLITE_UTF16 4 /* Use native byte order */ +#define SQLITE_ANY 5 /* Deprecated */ +#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ + +/* +** CAPI3REF: Function Flags +** +** These constants may be ORed together with the +** [SQLITE_UTF8 | preferred text encoding] as the fourth argument +** to [sqlite3_create_function()], [sqlite3_create_function16()], or +** [sqlite3_create_function_v2()]. +*/ +#define SQLITE_DETERMINISTIC 0x800 + +/* +** CAPI3REF: Deprecated Functions +** DEPRECATED +** +** These functions are [deprecated]. In order to maintain +** backwards compatibility with older code, these functions continue +** to be supported. However, new applications should avoid +** the use of these functions. To encourage programmers to avoid +** these functions, we will not explain what they do. +*/ +#ifndef SQLITE_OMIT_DEPRECATED +SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context*); +SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_global_recover(void); +SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_thread_cleanup(void); +SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), + void*,sqlite3_int64); +#endif + +/* +** CAPI3REF: Obtaining SQL Function Parameter Values +** METHOD: sqlite3_value +** +** The C-language implementation of SQL functions and aggregates uses +** this set of interface routines to access the parameter values on +** the function or aggregate. +** +** The xFunc (for scalar functions) or xStep (for aggregates) parameters +** to [sqlite3_create_function()] and [sqlite3_create_function16()] +** define callbacks that implement the SQL functions and aggregates. +** The 3rd parameter to these callbacks is an array of pointers to +** [protected sqlite3_value] objects. There is one [sqlite3_value] object for +** each parameter to the SQL function. These routines are used to +** extract values from the [sqlite3_value] objects. +** +** These routines work only with [protected sqlite3_value] objects. +** Any attempt to use these routines on an [unprotected sqlite3_value] +** object results in undefined behavior. +** +** ^These routines work just like the corresponding [column access functions] +** except that these routines take a single [protected sqlite3_value] object +** pointer instead of a [sqlite3_stmt*] pointer and an integer column number. +** +** ^The sqlite3_value_text16() interface extracts a UTF-16 string +** in the native byte-order of the host machine. ^The +** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces +** extract UTF-16 strings as big-endian and little-endian respectively. +** +** ^(The sqlite3_value_numeric_type() interface attempts to apply +** numeric affinity to the value. This means that an attempt is +** made to convert the value to an integer or floating point. If +** such a conversion is possible without loss of information (in other +** words, if the value is a string that looks like a number) +** then the conversion is performed. Otherwise no conversion occurs. +** The [SQLITE_INTEGER | datatype] after conversion is returned.)^ +** +** Please pay particular attention to the fact that the pointer returned +** from [sqlite3_value_blob()], [sqlite3_value_text()], or +** [sqlite3_value_text16()] can be invalidated by a subsequent call to +** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], +** or [sqlite3_value_text16()]. +** +** These routines must be called from the same thread as +** the SQL function that supplied the [sqlite3_value*] parameters. +*/ +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value*); +SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value*); +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value*); +SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value*); +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value*); +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value*); +SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*); +SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*); + +/* +** CAPI3REF: Obtain Aggregate Function Context +** METHOD: sqlite3_context +** +** Implementations of aggregate SQL functions use this +** routine to allocate memory for storing their state. +** +** ^The first time the sqlite3_aggregate_context(C,N) routine is called +** for a particular aggregate function, SQLite +** allocates N of memory, zeroes out that memory, and returns a pointer +** to the new memory. ^On second and subsequent calls to +** sqlite3_aggregate_context() for the same aggregate function instance, +** the same buffer is returned. Sqlite3_aggregate_context() is normally +** called once for each invocation of the xStep callback and then one +** last time when the xFinal callback is invoked. ^(When no rows match +** an aggregate query, the xStep() callback of the aggregate function +** implementation is never called and xFinal() is called exactly once. +** In those cases, sqlite3_aggregate_context() might be called for the +** first time from within xFinal().)^ +** +** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer +** when first called if N is less than or equal to zero or if a memory +** allocate error occurs. +** +** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is +** determined by the N parameter on first successful call. Changing the +** value of N in subsequent call to sqlite3_aggregate_context() within +** the same aggregate function instance will not resize the memory +** allocation.)^ Within the xFinal callback, it is customary to set +** N=0 in calls to sqlite3_aggregate_context(C,N) so that no +** pointless memory allocations occur. +** +** ^SQLite automatically frees the memory allocated by +** sqlite3_aggregate_context() when the aggregate query concludes. +** +** The first parameter must be a copy of the +** [sqlite3_context | SQL function context] that is the first parameter +** to the xStep or xFinal callback routine that implements the aggregate +** function. +** +** This routine must be called from the same thread in which +** the aggregate SQL function is running. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context*, int nBytes); + +/* +** CAPI3REF: User Data For Functions +** METHOD: sqlite3_context +** +** ^The sqlite3_user_data() interface returns a copy of +** the pointer that was the pUserData parameter (the 5th parameter) +** of the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines that originally +** registered the application defined function. +** +** This routine must be called from the same thread in which +** the application-defined function is running. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context*); + +/* +** CAPI3REF: Database Connection For Functions +** METHOD: sqlite3_context +** +** ^The sqlite3_context_db_handle() interface returns a copy of +** the pointer to the [database connection] (the 1st parameter) +** of the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines that originally +** registered the application defined function. +*/ +SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context*); + +/* +** CAPI3REF: Function Auxiliary Data +** METHOD: sqlite3_context +** +** These functions may be used by (non-aggregate) SQL functions to +** associate metadata with argument values. If the same value is passed to +** multiple invocations of the same SQL function during query execution, under +** some circumstances the associated metadata may be preserved. An example +** of where this might be useful is in a regular-expression matching +** function. The compiled version of the regular expression can be stored as +** metadata associated with the pattern string. +** Then as long as the pattern string remains the same, +** the compiled regular expression can be reused on multiple +** invocations of the same function. +** +** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata +** associated by the sqlite3_set_auxdata() function with the Nth argument +** value to the application-defined function. ^If there is no metadata +** associated with the function argument, this sqlite3_get_auxdata() interface +** returns a NULL pointer. +** +** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th +** argument of the application-defined function. ^Subsequent +** calls to sqlite3_get_auxdata(C,N) return P from the most recent +** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or +** NULL if the metadata has been discarded. +** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL, +** SQLite will invoke the destructor function X with parameter P exactly +** once, when the metadata is discarded. +** SQLite is free to discard the metadata at any time, including:
      +**
    • when the corresponding function parameter changes, or +**
    • when [sqlite3_reset()] or [sqlite3_finalize()] is called for the +** SQL statement, or +**
    • when sqlite3_set_auxdata() is invoked again on the same parameter, or +**
    • during the original sqlite3_set_auxdata() call when a memory +** allocation error occurs.
    )^ +** +** Note the last bullet in particular. The destructor X in +** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the +** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata() +** should be called near the end of the function implementation and the +** function implementation should not make any use of P after +** sqlite3_set_auxdata() has been called. +** +** ^(In practice, metadata is preserved between function calls for +** function parameters that are compile-time constants, including literal +** values and [parameters] and expressions composed from the same.)^ +** +** These routines must be called from the same thread in which +** the SQL function is running. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context*, int N); +SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); + + +/* +** CAPI3REF: Constants Defining Special Destructor Behavior +** +** These are special values for the destructor that is passed in as the +** final argument to routines like [sqlite3_result_blob()]. ^If the destructor +** argument is SQLITE_STATIC, it means that the content pointer is constant +** and will never change. It does not need to be destroyed. ^The +** SQLITE_TRANSIENT value means that the content will likely change in +** the near future and that SQLite should make its own private copy of +** the content before returning. +** +** The typedef is necessary to work around problems in certain +** C++ compilers. +*/ +typedef void (*sqlite3_destructor_type)(void*); +#define SQLITE_STATIC ((sqlite3_destructor_type)0) +#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) + +/* +** CAPI3REF: Setting The Result Of An SQL Function +** METHOD: sqlite3_context +** +** These routines are used by the xFunc or xFinal callbacks that +** implement SQL functions and aggregates. See +** [sqlite3_create_function()] and [sqlite3_create_function16()] +** for additional information. +** +** These functions work very much like the [parameter binding] family of +** functions used to bind values to host parameters in prepared statements. +** Refer to the [SQL parameter] documentation for additional information. +** +** ^The sqlite3_result_blob() interface sets the result from +** an application-defined function to be the BLOB whose content is pointed +** to by the second parameter and which is N bytes long where N is the +** third parameter. +** +** ^The sqlite3_result_zeroblob() interfaces set the result of +** the application-defined function to be a BLOB containing all zero +** bytes and N bytes in size, where N is the value of the 2nd parameter. +** +** ^The sqlite3_result_double() interface sets the result from +** an application-defined function to be a floating point value specified +** by its 2nd argument. +** +** ^The sqlite3_result_error() and sqlite3_result_error16() functions +** cause the implemented SQL function to throw an exception. +** ^SQLite uses the string pointed to by the +** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16() +** as the text of an error message. ^SQLite interprets the error +** message string from sqlite3_result_error() as UTF-8. ^SQLite +** interprets the string from sqlite3_result_error16() as UTF-16 in native +** byte order. ^If the third parameter to sqlite3_result_error() +** or sqlite3_result_error16() is negative then SQLite takes as the error +** message all text up through the first zero character. +** ^If the third parameter to sqlite3_result_error() or +** sqlite3_result_error16() is non-negative then SQLite takes that many +** bytes (not characters) from the 2nd parameter as the error message. +** ^The sqlite3_result_error() and sqlite3_result_error16() +** routines make a private copy of the error message text before +** they return. Hence, the calling function can deallocate or +** modify the text after they return without harm. +** ^The sqlite3_result_error_code() function changes the error code +** returned by SQLite as a result of an error in a function. ^By default, +** the error code is SQLITE_ERROR. ^A subsequent call to sqlite3_result_error() +** or sqlite3_result_error16() resets the error code to SQLITE_ERROR. +** +** ^The sqlite3_result_error_toobig() interface causes SQLite to throw an +** error indicating that a string or BLOB is too long to represent. +** +** ^The sqlite3_result_error_nomem() interface causes SQLite to throw an +** error indicating that a memory allocation failed. +** +** ^The sqlite3_result_int() interface sets the return value +** of the application-defined function to be the 32-bit signed integer +** value given in the 2nd argument. +** ^The sqlite3_result_int64() interface sets the return value +** of the application-defined function to be the 64-bit signed integer +** value given in the 2nd argument. +** +** ^The sqlite3_result_null() interface sets the return value +** of the application-defined function to be NULL. +** +** ^The sqlite3_result_text(), sqlite3_result_text16(), +** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces +** set the return value of the application-defined function to be +** a text string which is represented as UTF-8, UTF-16 native byte order, +** UTF-16 little endian, or UTF-16 big endian, respectively. +** ^The sqlite3_result_text64() interface sets the return value of an +** application-defined function to be a text string in an encoding +** specified by the fifth (and last) parameter, which must be one +** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]. +** ^SQLite takes the text result from the application from +** the 2nd parameter of the sqlite3_result_text* interfaces. +** ^If the 3rd parameter to the sqlite3_result_text* interfaces +** is negative, then SQLite takes result text from the 2nd parameter +** through the first zero character. +** ^If the 3rd parameter to the sqlite3_result_text* interfaces +** is non-negative, then as many bytes (not characters) of the text +** pointed to by the 2nd parameter are taken as the application-defined +** function result. If the 3rd parameter is non-negative, then it +** must be the byte offset into the string where the NUL terminator would +** appear if the string where NUL terminated. If any NUL characters occur +** in the string at a byte offset that is less than the value of the 3rd +** parameter, then the resulting string will contain embedded NULs and the +** result of expressions operating on strings with embedded NULs is undefined. +** ^If the 4th parameter to the sqlite3_result_text* interfaces +** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that +** function as the destructor on the text or BLOB result when it has +** finished using that result. +** ^If the 4th parameter to the sqlite3_result_text* interfaces or to +** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite +** assumes that the text or BLOB result is in constant space and does not +** copy the content of the parameter nor call a destructor on the content +** when it has finished using that result. +** ^If the 4th parameter to the sqlite3_result_text* interfaces +** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT +** then SQLite makes a copy of the result into space obtained from +** from [sqlite3_malloc()] before it returns. +** +** ^The sqlite3_result_value() interface sets the result of +** the application-defined function to be a copy the +** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The +** sqlite3_result_value() interface makes a copy of the [sqlite3_value] +** so that the [sqlite3_value] specified in the parameter may change or +** be deallocated after sqlite3_result_value() returns without harm. +** ^A [protected sqlite3_value] object may always be used where an +** [unprotected sqlite3_value] object is required, so either +** kind of [sqlite3_value] object can be used with this interface. +** +** If these routines are called from within the different thread +** than the one containing the application-defined function that received +** the [sqlite3_context] pointer, the results are undefined. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64(sqlite3_context*,const void*, + sqlite3_uint64,void(*)(void*)); +SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context*, double); +SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context*, const char*, int); +SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context*, const void*, int); +SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context*); +SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context*); +SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context*, int); +SQLITE_API void SQLITE_STDCALL sqlite3_result_int(sqlite3_context*, int); +SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context*, sqlite3_int64); +SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context*); +SQLITE_API void SQLITE_STDCALL sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64, + void(*)(void*), unsigned char encoding); +SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context*, sqlite3_value*); +SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context*, int n); + +/* +** CAPI3REF: Define New Collating Sequences +** METHOD: sqlite3 +** +** ^These functions add, remove, or modify a [collation] associated +** with the [database connection] specified as the first argument. +** +** ^The name of the collation is a UTF-8 string +** for sqlite3_create_collation() and sqlite3_create_collation_v2() +** and a UTF-16 string in native byte order for sqlite3_create_collation16(). +** ^Collation names that compare equal according to [sqlite3_strnicmp()] are +** considered to be the same name. +** +** ^(The third argument (eTextRep) must be one of the constants: +**
      +**
    • [SQLITE_UTF8], +**
    • [SQLITE_UTF16LE], +**
    • [SQLITE_UTF16BE], +**
    • [SQLITE_UTF16], or +**
    • [SQLITE_UTF16_ALIGNED]. +**
    )^ +** ^The eTextRep argument determines the encoding of strings passed +** to the collating function callback, xCallback. +** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep +** force strings to be UTF16 with native byte order. +** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin +** on an even byte address. +** +** ^The fourth argument, pArg, is an application data pointer that is passed +** through as the first argument to the collating function callback. +** +** ^The fifth argument, xCallback, is a pointer to the collating function. +** ^Multiple collating functions can be registered using the same name but +** with different eTextRep parameters and SQLite will use whichever +** function requires the least amount of data transformation. +** ^If the xCallback argument is NULL then the collating function is +** deleted. ^When all collating functions having the same name are deleted, +** that collation is no longer usable. +** +** ^The collating function callback is invoked with a copy of the pArg +** application data pointer and with two strings in the encoding specified +** by the eTextRep argument. The collating function must return an +** integer that is negative, zero, or positive +** if the first string is less than, equal to, or greater than the second, +** respectively. A collating function must always return the same answer +** given the same inputs. If two or more collating functions are registered +** to the same collation name (using different eTextRep values) then all +** must give an equivalent answer when invoked with equivalent strings. +** The collating function must obey the following properties for all +** strings A, B, and C: +** +**
      +**
    1. If A==B then B==A. +**
    2. If A==B and B==C then A==C. +**
    3. If A<B THEN B>A. +**
    4. If A<B and B<C then A<C. +**
    +** +** If a collating function fails any of the above constraints and that +** collating function is registered and used, then the behavior of SQLite +** is undefined. +** +** ^The sqlite3_create_collation_v2() works like sqlite3_create_collation() +** with the addition that the xDestroy callback is invoked on pArg when +** the collating function is deleted. +** ^Collating functions are deleted when they are overridden by later +** calls to the collation creation functions or when the +** [database connection] is closed using [sqlite3_close()]. +** +** ^The xDestroy callback is not called if the +** sqlite3_create_collation_v2() function fails. Applications that invoke +** sqlite3_create_collation_v2() with a non-NULL xDestroy argument should +** check the return code and dispose of the application data pointer +** themselves rather than expecting SQLite to deal with it for them. +** This is different from every other SQLite interface. The inconsistency +** is unfortunate but cannot be changed without breaking backwards +** compatibility. +** +** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_create_collation( + sqlite3*, + const char *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*) +); +SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2( + sqlite3*, + const char *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDestroy)(void*) +); +SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16( + sqlite3*, + const void *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*) +); + +/* +** CAPI3REF: Collation Needed Callbacks +** METHOD: sqlite3 +** +** ^To avoid having to register all collation sequences before a database +** can be used, a single callback function may be registered with the +** [database connection] to be invoked whenever an undefined collation +** sequence is required. +** +** ^If the function is registered using the sqlite3_collation_needed() API, +** then it is passed the names of undefined collation sequences as strings +** encoded in UTF-8. ^If sqlite3_collation_needed16() is used, +** the names are passed as UTF-16 in machine native byte order. +** ^A call to either function replaces the existing collation-needed callback. +** +** ^(When the callback is invoked, the first argument passed is a copy +** of the second argument to sqlite3_collation_needed() or +** sqlite3_collation_needed16(). The second argument is the database +** connection. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE], +** or [SQLITE_UTF16LE], indicating the most desirable form of the collation +** sequence function required. The fourth parameter is the name of the +** required collation sequence.)^ +** +** The callback function should register the desired collation using +** [sqlite3_create_collation()], [sqlite3_create_collation16()], or +** [sqlite3_create_collation_v2()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const char*) +); +SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const void*) +); + +#ifdef SQLITE_HAS_CODEC +/* +** Specify the key for an encrypted database. This routine should be +** called right after sqlite3_open(). +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_key( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The key */ +); +SQLITE_API int SQLITE_STDCALL sqlite3_key_v2( + sqlite3 *db, /* Database to be rekeyed */ + const char *zDbName, /* Name of the database */ + const void *pKey, int nKey /* The key */ +); + +/* +** Change the key on an open database. If the current database is not +** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the +** database is decrypted. +** +** The code to implement this API is not available in the public release +** of SQLite. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_rekey( + sqlite3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The new key */ +); +SQLITE_API int SQLITE_STDCALL sqlite3_rekey_v2( + sqlite3 *db, /* Database to be rekeyed */ + const char *zDbName, /* Name of the database */ + const void *pKey, int nKey /* The new key */ +); + +/* +** Specify the activation key for a SEE database. Unless +** activated, none of the SEE routines will work. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_activate_see( + const char *zPassPhrase /* Activation phrase */ +); +#endif + +#ifdef SQLITE_ENABLE_CEROD +/* +** Specify the activation key for a CEROD database. Unless +** activated, none of the CEROD routines will work. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_activate_cerod( + const char *zPassPhrase /* Activation phrase */ +); +#endif + +/* +** CAPI3REF: Suspend Execution For A Short Time +** +** The sqlite3_sleep() function causes the current thread to suspend execution +** for at least a number of milliseconds specified in its parameter. +** +** If the operating system does not support sleep requests with +** millisecond time resolution, then the time will be rounded up to +** the nearest second. The number of milliseconds of sleep actually +** requested from the operating system is returned. +** +** ^SQLite implements this interface by calling the xSleep() +** method of the default [sqlite3_vfs] object. If the xSleep() method +** of the default VFS is not implemented correctly, or not implemented at +** all, then the behavior of sqlite3_sleep() may deviate from the description +** in the previous paragraphs. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int); + +/* +** CAPI3REF: Name Of The Folder Holding Temporary Files +** +** ^(If this global variable is made to point to a string which is +** the name of a folder (a.k.a. directory), then all temporary files +** created by SQLite when using a built-in [sqlite3_vfs | VFS] +** will be placed in that directory.)^ ^If this variable +** is a NULL pointer, then SQLite performs a search for an appropriate +** temporary file directory. +** +** Applications are strongly discouraged from using this global variable. +** It is required to set a temporary folder on Windows Runtime (WinRT). +** But for all other platforms, it is highly recommended that applications +** neither read nor write this variable. This global variable is a relic +** that exists for backwards compatibility of legacy applications and should +** be avoided in new projects. +** +** It is not safe to read or modify this variable in more than one +** thread at a time. It is not safe to read or modify this variable +** if a [database connection] is being used at the same time in a separate +** thread. +** It is intended that this variable be set once +** as part of process initialization and before any SQLite interface +** routines have been called and that this variable remain unchanged +** thereafter. +** +** ^The [temp_store_directory pragma] may modify this variable and cause +** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore, +** the [temp_store_directory pragma] always assumes that any string +** that this variable points to is held in memory obtained from +** [sqlite3_malloc] and the pragma may attempt to free that memory +** using [sqlite3_free]. +** Hence, if this variable is modified directly, either it should be +** made NULL or made to point to memory obtained from [sqlite3_malloc] +** or else the use of the [temp_store_directory pragma] should be avoided. +** Except when requested by the [temp_store_directory pragma], SQLite +** does not free the memory that sqlite3_temp_directory points to. If +** the application wants that memory to be freed, it must do +** so itself, taking care to only do so after all [database connection] +** objects have been destroyed. +** +** Note to Windows Runtime users: The temporary directory must be set +** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various +** features that require the use of temporary files may fail. Here is an +** example of how to do this using C++ with the Windows Runtime: +** +**
    +** LPCWSTR zPath = Windows::Storage::ApplicationData::Current->
    +**       TemporaryFolder->Path->Data();
    +** char zPathBuf[MAX_PATH + 1];
    +** memset(zPathBuf, 0, sizeof(zPathBuf));
    +** WideCharToMultiByte(CP_UTF8, 0, zPath, -1, zPathBuf, sizeof(zPathBuf),
    +**       NULL, NULL);
    +** sqlite3_temp_directory = sqlite3_mprintf("%s", zPathBuf);
    +** 
    +*/ +SQLITE_API SQLITE_EXTERN char *sqlite3_temp_directory; + +/* +** CAPI3REF: Name Of The Folder Holding Database Files +** +** ^(If this global variable is made to point to a string which is +** the name of a folder (a.k.a. directory), then all database files +** specified with a relative pathname and created or accessed by +** SQLite when using a built-in windows [sqlite3_vfs | VFS] will be assumed +** to be relative to that directory.)^ ^If this variable is a NULL +** pointer, then SQLite assumes that all database files specified +** with a relative pathname are relative to the current directory +** for the process. Only the windows VFS makes use of this global +** variable; it is ignored by the unix VFS. +** +** Changing the value of this variable while a database connection is +** open can result in a corrupt database. +** +** It is not safe to read or modify this variable in more than one +** thread at a time. It is not safe to read or modify this variable +** if a [database connection] is being used at the same time in a separate +** thread. +** It is intended that this variable be set once +** as part of process initialization and before any SQLite interface +** routines have been called and that this variable remain unchanged +** thereafter. +** +** ^The [data_store_directory pragma] may modify this variable and cause +** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore, +** the [data_store_directory pragma] always assumes that any string +** that this variable points to is held in memory obtained from +** [sqlite3_malloc] and the pragma may attempt to free that memory +** using [sqlite3_free]. +** Hence, if this variable is modified directly, either it should be +** made NULL or made to point to memory obtained from [sqlite3_malloc] +** or else the use of the [data_store_directory pragma] should be avoided. +*/ +SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory; + +/* +** CAPI3REF: Test For Auto-Commit Mode +** KEYWORDS: {autocommit mode} +** METHOD: sqlite3 +** +** ^The sqlite3_get_autocommit() interface returns non-zero or +** zero if the given database connection is or is not in autocommit mode, +** respectively. ^Autocommit mode is on by default. +** ^Autocommit mode is disabled by a [BEGIN] statement. +** ^Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK]. +** +** If certain kinds of errors occur on a statement within a multi-statement +** transaction (errors including [SQLITE_FULL], [SQLITE_IOERR], +** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the +** transaction might be rolled back automatically. The only way to +** find out whether SQLite automatically rolled back the transaction after +** an error is to use this function. +** +** If another thread changes the autocommit status of the database +** connection while this routine is running, then the return value +** is undefined. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3*); + +/* +** CAPI3REF: Find The Database Handle Of A Prepared Statement +** METHOD: sqlite3_stmt +** +** ^The sqlite3_db_handle interface returns the [database connection] handle +** to which a [prepared statement] belongs. ^The [database connection] +** returned by sqlite3_db_handle is the same [database connection] +** that was the first argument +** to the [sqlite3_prepare_v2()] call (or its variants) that was used to +** create the statement in the first place. +*/ +SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt*); + +/* +** CAPI3REF: Return The Filename For A Database Connection +** METHOD: sqlite3 +** +** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename +** associated with database N of connection D. ^The main database file +** has the name "main". If there is no attached database N on the database +** connection D, or if database N is a temporary or in-memory database, then +** a NULL pointer is returned. +** +** ^The filename returned by this function is the output of the +** xFullPathname method of the [VFS]. ^In other words, the filename +** will be an absolute pathname, even if the filename used +** to open the database originally was a URI or relative pathname. +*/ +SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *zDbName); + +/* +** CAPI3REF: Determine if a database is read-only +** METHOD: sqlite3 +** +** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N +** of connection D is read-only, 0 if it is read/write, or -1 if N is not +** the name of a database on connection D. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbName); + +/* +** CAPI3REF: Find the next prepared statement +** METHOD: sqlite3 +** +** ^This interface returns a pointer to the next [prepared statement] after +** pStmt associated with the [database connection] pDb. ^If pStmt is NULL +** then this interface returns a pointer to the first prepared statement +** associated with the database connection pDb. ^If no prepared statement +** satisfies the conditions of this routine, it returns NULL. +** +** The [database connection] pointer D in a call to +** [sqlite3_next_stmt(D,S)] must refer to an open database +** connection and in particular must not be a NULL pointer. +*/ +SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Commit And Rollback Notification Callbacks +** METHOD: sqlite3 +** +** ^The sqlite3_commit_hook() interface registers a callback +** function to be invoked whenever a transaction is [COMMIT | committed]. +** ^Any callback set by a previous call to sqlite3_commit_hook() +** for the same database connection is overridden. +** ^The sqlite3_rollback_hook() interface registers a callback +** function to be invoked whenever a transaction is [ROLLBACK | rolled back]. +** ^Any callback set by a previous call to sqlite3_rollback_hook() +** for the same database connection is overridden. +** ^The pArg argument is passed through to the callback. +** ^If the callback on a commit hook function returns non-zero, +** then the commit is converted into a rollback. +** +** ^The sqlite3_commit_hook(D,C,P) and sqlite3_rollback_hook(D,C,P) functions +** return the P argument from the previous call of the same function +** on the same [database connection] D, or NULL for +** the first call for each function on D. +** +** The commit and rollback hook callbacks are not reentrant. +** The callback implementation must not do anything that will modify +** the database connection that invoked the callback. Any actions +** to modify the database connection must be deferred until after the +** completion of the [sqlite3_step()] call that triggered the commit +** or rollback hook in the first place. +** Note that running any other SQL statements, including SELECT statements, +** or merely calling [sqlite3_prepare_v2()] and [sqlite3_step()] will modify +** the database connections for the meaning of "modify" in this paragraph. +** +** ^Registering a NULL function disables the callback. +** +** ^When the commit hook callback routine returns zero, the [COMMIT] +** operation is allowed to continue normally. ^If the commit hook +** returns non-zero, then the [COMMIT] is converted into a [ROLLBACK]. +** ^The rollback hook is invoked on a rollback that results from a commit +** hook returning non-zero, just as it would be with any other rollback. +** +** ^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 rollback callback is not invoked if a transaction is +** automatically rolled back because the database connection is closed. +** +** See also the [sqlite3_update_hook()] interface. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); +SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); + +/* +** CAPI3REF: Data Change Notification Callbacks +** METHOD: sqlite3 +** +** ^The sqlite3_update_hook() interface registers a callback function +** with the [database connection] identified by the first argument +** to be invoked whenever a row is updated, inserted or deleted in +** a rowid table. +** ^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 in a rowid table. +** ^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).)^ +** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified. +** +** ^In the current implementation, the update hook +** is not invoked when duplication rows are deleted because of an +** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook +** invoked when rows are deleted using the [truncate optimization]. +** The exceptions defined in this paragraph might change in a future +** release of SQLite. +** +** The update hook implementation must not do anything that will modify +** the database connection that invoked the update hook. Any actions +** to modify the database connection must be deferred until after the +** completion of the [sqlite3_step()] call that triggered the update hook. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +** ^The sqlite3_update_hook(D,C,P) function +** returns the P argument from the previous call +** on the same [database connection] D, or NULL for +** the first call on D. +** +** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()] +** interfaces. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook( + sqlite3*, + void(*)(void *,int ,char const *,char const *,sqlite3_int64), + void* +); + +/* +** CAPI3REF: Enable Or Disable Shared Pager Cache +** +** ^(This routine enables or disables the sharing of the database cache +** and schema data structures between [database connection | connections] +** to the same database. Sharing is enabled if the argument is true +** and disabled if the argument is false.)^ +** +** ^Cache sharing is enabled and disabled for an entire process. +** This is a change as of SQLite version 3.5.0. In prior versions of SQLite, +** sharing was enabled or disabled for each thread separately. +** +** ^(The cache sharing mode set by this interface effects all subsequent +** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()]. +** Existing database connections continue use the sharing mode +** that was in effect at the time they were opened.)^ +** +** ^(This routine returns [SQLITE_OK] if shared cache was enabled or disabled +** successfully. An [error code] is returned otherwise.)^ +** +** ^Shared cache is disabled by default. But this might change in +** future releases of SQLite. Applications that care about shared +** cache setting should set it explicitly. +** +** Note: This method is disabled on MacOS X 10.7 and iOS version 5.0 +** and will always return SQLITE_MISUSE. On those systems, +** shared cache mode should be enabled per-database connection via +** [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE]. +** +** This interface is threadsafe on processors where writing a +** 32-bit integer is atomic. +** +** See Also: [SQLite Shared-Cache Mode] +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int); + +/* +** CAPI3REF: Attempt To Free Heap Memory +** +** ^The sqlite3_release_memory() interface attempts to free N bytes +** of heap memory by deallocating non-essential memory allocations +** held by the database library. Memory used to cache database +** pages to improve performance is an example of non-essential memory. +** ^sqlite3_release_memory() returns the number of bytes actually freed, +** which might be more or less than the amount requested. +** ^The sqlite3_release_memory() routine is a no-op returning zero +** if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT]. +** +** See also: [sqlite3_db_release_memory()] +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int); + +/* +** CAPI3REF: Free Memory Used By A Database Connection +** METHOD: sqlite3 +** +** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap +** memory as possible from database connection D. Unlike the +** [sqlite3_release_memory()] interface, this interface is in effect even +** when the [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is +** omitted. +** +** See also: [sqlite3_release_memory()] +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3*); + +/* +** CAPI3REF: Impose A Limit On Heap Size +** +** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the +** soft limit on the amount of heap memory that may be allocated by SQLite. +** ^SQLite strives to keep heap memory utilization below the soft heap +** limit by reducing the number of pages held in the page cache +** as heap memory usages approaches the limit. +** ^The soft heap limit is "soft" because even though SQLite strives to stay +** below the limit, it will exceed the limit rather than generate +** an [SQLITE_NOMEM] error. In other words, the soft heap limit +** is advisory only. +** +** ^The return value from sqlite3_soft_heap_limit64() is the size of +** the soft heap limit prior to the call, or negative in the case of an +** error. ^If the argument N is negative +** then no change is made to the soft heap limit. Hence, the current +** size of the soft heap limit can be determined by invoking +** sqlite3_soft_heap_limit64() with a negative argument. +** +** ^If the argument N is zero then the soft heap limit is disabled. +** +** ^(The soft heap limit is not enforced in the current implementation +** if one or more of following conditions are true: +** +**
      +**
    • The soft heap limit is set to zero. +**
    • Memory accounting is disabled using a combination of the +** [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and +** the [SQLITE_DEFAULT_MEMSTATUS] compile-time option. +**
    • An alternative page cache implementation is specified using +** [sqlite3_config]([SQLITE_CONFIG_PCACHE2],...). +**
    • The page cache allocates from its own memory pool supplied +** by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than +** from the heap. +**
    )^ +** +** Beginning with SQLite version 3.7.3, the soft heap limit is enforced +** regardless of whether or not the [SQLITE_ENABLE_MEMORY_MANAGEMENT] +** compile-time option is invoked. With [SQLITE_ENABLE_MEMORY_MANAGEMENT], +** the soft heap limit is enforced on every memory allocation. Without +** [SQLITE_ENABLE_MEMORY_MANAGEMENT], the soft heap limit is only enforced +** when memory is allocated by the page cache. Testing suggests that because +** the page cache is the predominate memory user in SQLite, most +** applications will achieve adequate soft heap limit enforcement without +** the use of [SQLITE_ENABLE_MEMORY_MANAGEMENT]. +** +** The circumstances under which SQLite will enforce the soft heap limit may +** changes in future releases of SQLite. +*/ +SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 N); + +/* +** CAPI3REF: Deprecated Soft Heap Limit Interface +** DEPRECATED +** +** This is a deprecated version of the [sqlite3_soft_heap_limit64()] +** interface. This routine is provided for historical compatibility +** only. All new applications should use the +** [sqlite3_soft_heap_limit64()] interface rather than this one. +*/ +SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_soft_heap_limit(int N); + + +/* +** CAPI3REF: Extract Metadata About A Column Of A Table +** METHOD: sqlite3 +** +** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns +** information about column C of table T in database D +** on [database connection] X.)^ ^The sqlite3_table_column_metadata() +** interface returns SQLITE_OK and fills in the non-NULL pointers in +** the final five arguments with appropriate values if the specified +** column exists. ^The sqlite3_table_column_metadata() interface returns +** SQLITE_ERROR and if the specified column does not exist. +** ^If the column-name parameter to sqlite3_table_column_metadata() is a +** NULL pointer, then this routine simply checks for the existance of the +** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it +** does not. +** +** ^The column is identified by the second, third and fourth parameters to +** this function. ^(The second parameter is either the name of the database +** (i.e. "main", "temp", or an attached database) containing the specified +** table or NULL.)^ ^If it is NULL, then all attached databases are searched +** for the table using the same algorithm used by the database engine to +** resolve unqualified table references. +** +** ^The third and fourth parameters to this function are the table and column +** name of the desired column, respectively. +** +** ^Metadata is returned by writing to the memory locations passed as the 5th +** and subsequent parameters to this function. ^Any of these arguments may be +** NULL, in which case the corresponding element of metadata is omitted. +** +** ^(
    +** +**
    Parameter Output
    Type
    Description +** +**
    5th const char* Data type +**
    6th const char* Name of default collation sequence +**
    7th int True if column has a NOT NULL constraint +**
    8th int True if column is part of the PRIMARY KEY +**
    9th int True if column is [AUTOINCREMENT] +**
    +**
    )^ +** +** ^The memory pointed to by the character pointers returned for the +** declaration type and collation sequence is valid until the next +** call to any SQLite API function. +** +** ^If the specified table is actually a view, an [error code] is returned. +** +** ^If the specified column is "rowid", "oid" or "_rowid_" and the table +** is not a [WITHOUT ROWID] table and an +** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output +** parameters are set for the explicitly declared column. ^(If there is no +** [INTEGER PRIMARY KEY] column, then the outputs +** for the [rowid] are set as follows: +** +**
    +**     data type: "INTEGER"
    +**     collation sequence: "BINARY"
    +**     not null: 0
    +**     primary key: 1
    +**     auto increment: 0
    +** 
    )^ +** +** ^This function causes all database schemas to be read from disk and +** parsed, if that has not already been done, and returns an error if +** any errors are encountered while loading the schema. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata( + sqlite3 *db, /* Connection handle */ + const char *zDbName, /* Database name or NULL */ + const char *zTableName, /* Table name */ + const char *zColumnName, /* Column name */ + char const **pzDataType, /* OUTPUT: Declared data type */ + char const **pzCollSeq, /* OUTPUT: Collation sequence name */ + int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ + int *pPrimaryKey, /* OUTPUT: True if column part of PK */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ +); + +/* +** CAPI3REF: Load An Extension +** METHOD: sqlite3 +** +** ^This interface loads an SQLite extension library from the named file. +** +** ^The sqlite3_load_extension() interface attempts to load an +** [SQLite extension] library contained in the file zFile. If +** the file cannot be loaded directly, attempts are made to load +** with various operating-system specific extensions added. +** So for example, if "samplelib" cannot be loaded, then names like +** "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might +** be tried also. +** +** ^The entry point is zProc. +** ^(zProc may be 0, in which case SQLite will try to come up with an +** entry point name on its own. It first tries "sqlite3_extension_init". +** If that does not work, it constructs a name "sqlite3_X_init" where the +** X is consists of the lower-case equivalent of all ASCII alphabetic +** characters in the filename from the last "/" to the first following +** "." and omitting any initial "lib".)^ +** ^The sqlite3_load_extension() interface returns +** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. +** ^If an error occurs and pzErrMsg is not 0, then the +** [sqlite3_load_extension()] interface shall attempt to +** fill *pzErrMsg with error message text stored in memory +** obtained from [sqlite3_malloc()]. The calling function +** should free this memory by calling [sqlite3_free()]. +** +** ^Extension loading must be enabled using +** [sqlite3_enable_load_extension()] prior to calling this API, +** otherwise an error will be returned. +** +** See also the [load_extension() SQL function]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Derived from zFile if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +); + +/* +** CAPI3REF: Enable Or Disable Extension Loading +** METHOD: sqlite3 +** +** ^So as not to open security holes in older applications that are +** unprepared to deal with [extension loading], and as a means of disabling +** [extension loading] while evaluating user-entered SQL, the following API +** is provided to turn the [sqlite3_load_extension()] mechanism on and off. +** +** ^Extension loading is off by default. +** ^Call the sqlite3_enable_load_extension() routine with onoff==1 +** to turn extension loading on and call it with onoff==0 to turn +** it back off again. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff); + +/* +** CAPI3REF: Automatically Load Statically Linked Extensions +** +** ^This interface causes the xEntryPoint() function to be invoked for +** each new [database connection] that is created. The idea here is that +** xEntryPoint() is the entry point for a statically linked [SQLite extension] +** that is to be automatically loaded into all new database connections. +** +** ^(Even though the function prototype shows that xEntryPoint() takes +** no arguments and returns void, SQLite invokes xEntryPoint() with three +** arguments and expects and integer result as if the signature of the +** entry point where as follows: +** +**
    +**    int xEntryPoint(
    +**      sqlite3 *db,
    +**      const char **pzErrMsg,
    +**      const struct sqlite3_api_routines *pThunk
    +**    );
    +** 
    )^ +** +** If the xEntryPoint routine encounters an error, it should make *pzErrMsg +** point to an appropriate error message (obtained from [sqlite3_mprintf()]) +** and return an appropriate [error code]. ^SQLite ensures that *pzErrMsg +** is NULL before calling the xEntryPoint(). ^SQLite will invoke +** [sqlite3_free()] on *pzErrMsg after xEntryPoint() returns. ^If any +** xEntryPoint() returns an error, the [sqlite3_open()], [sqlite3_open16()], +** or [sqlite3_open_v2()] call that provoked the xEntryPoint() will fail. +** +** ^Calling sqlite3_auto_extension(X) with an entry point X that is already +** on the list of automatic extensions is a harmless no-op. ^No entry point +** will be called more than once for each database connection that is opened. +** +** See also: [sqlite3_reset_auto_extension()] +** and [sqlite3_cancel_auto_extension()] +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xEntryPoint)(void)); + +/* +** CAPI3REF: Cancel Automatic Extension Loading +** +** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the +** initialization routine X that was registered using a prior call to +** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)] +** routine returns 1 if initialization routine X was successfully +** unregistered and it returns 0 if X was not on the list of initialization +** routines. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void (*xEntryPoint)(void)); + +/* +** CAPI3REF: Reset Automatic Extension Loading +** +** ^This interface disables all automatic extensions previously +** registered using [sqlite3_auto_extension()]. +*/ +SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void); + +/* +** The interface to the virtual-table mechanism is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + +/* +** Structures used by the virtual table interface +*/ +typedef struct sqlite3_vtab sqlite3_vtab; +typedef struct sqlite3_index_info sqlite3_index_info; +typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; +typedef struct sqlite3_module sqlite3_module; + +/* +** CAPI3REF: Virtual Table Object +** KEYWORDS: sqlite3_module {virtual table module} +** +** This structure, sometimes called a "virtual table module", +** defines the implementation of a [virtual tables]. +** This structure consists mostly of methods for the module. +** +** ^A virtual table module is created by filling in a persistent +** instance of this structure and passing a pointer to that instance +** to [sqlite3_create_module()] or [sqlite3_create_module_v2()]. +** ^The registration remains valid until it is replaced by a different +** module or until the [database connection] closes. The content +** of this structure must not change while it is registered with +** any database connection. +*/ +struct sqlite3_module { + int iVersion; + int (*xCreate)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xConnect)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); + int (*xDisconnect)(sqlite3_vtab *pVTab); + int (*xDestroy)(sqlite3_vtab *pVTab); + int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); + int (*xClose)(sqlite3_vtab_cursor*); + int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); + int (*xNext)(sqlite3_vtab_cursor*); + int (*xEof)(sqlite3_vtab_cursor*); + int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); + int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); + int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); + int (*xBegin)(sqlite3_vtab *pVTab); + int (*xSync)(sqlite3_vtab *pVTab); + int (*xCommit)(sqlite3_vtab *pVTab); + int (*xRollback)(sqlite3_vtab *pVTab); + int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg); + int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); + /* The methods above are in version 1 of the sqlite_module object. Those + ** below are for version 2 and greater. */ + int (*xSavepoint)(sqlite3_vtab *pVTab, int); + int (*xRelease)(sqlite3_vtab *pVTab, int); + int (*xRollbackTo)(sqlite3_vtab *pVTab, int); +}; + +/* +** CAPI3REF: Virtual Table Indexing Information +** KEYWORDS: sqlite3_index_info +** +** The sqlite3_index_info structure and its substructures is used as part +** of the [virtual table] interface to +** pass information into and receive the reply from the [xBestIndex] +** method of a [virtual table module]. The fields under **Inputs** are the +** inputs to xBestIndex and are read-only. xBestIndex inserts its +** results into the **Outputs** fields. +** +** ^(The aConstraint[] array records WHERE clause constraints of the form: +** +**
    column OP expr
    +** +** where OP is =, <, <=, >, or >=.)^ ^(The particular operator is +** stored in aConstraint[].op using one of the +** [SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_ values].)^ +** ^(The index of the column is stored in +** aConstraint[].iColumn.)^ ^(aConstraint[].usable is TRUE if the +** expr on the right-hand side can be evaluated (and thus the constraint +** is usable) and false if it cannot.)^ +** +** ^The optimizer automatically inverts terms of the form "expr OP column" +** and makes other simplifications to the WHERE clause in an attempt to +** get as many WHERE clause terms into the form shown above as possible. +** ^The aConstraint[] array only reports WHERE clause terms that are +** relevant to the particular virtual table being queried. +** +** ^Information about the ORDER BY clause is stored in aOrderBy[]. +** ^Each term of aOrderBy records a column of the ORDER BY clause. +** +** The [xBestIndex] method must fill aConstraintUsage[] with information +** about what parameters to pass to xFilter. ^If argvIndex>0 then +** the right-hand side of the corresponding aConstraint[] is evaluated +** and becomes the argvIndex-th entry in argv. ^(If aConstraintUsage[].omit +** is true, then the constraint is assumed to be fully handled by the +** virtual table and is not checked again by SQLite.)^ +** +** ^The idxNum and idxPtr values are recorded and passed into the +** [xFilter] method. +** ^[sqlite3_free()] is used to free idxPtr if and only if +** needToFreeIdxPtr is true. +** +** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in +** the correct order to satisfy the ORDER BY clause so that no separate +** sorting step is required. +** +** ^The estimatedCost value is an estimate of the cost of a particular +** strategy. A cost of N indicates that the cost of the strategy is similar +** to a linear scan of an SQLite table with N rows. A cost of log(N) +** indicates that the expense of the operation is similar to that of a +** binary search on a unique indexed field of an SQLite table with N rows. +** +** ^The estimatedRows value is an estimate of the number of rows that +** will be returned by the strategy. +** +** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info +** structure for SQLite version 3.8.2. If a virtual table extension is +** used with an SQLite version earlier than 3.8.2, the results of attempting +** to read or write the estimatedRows field are undefined (but are likely +** to included crashing the application). The estimatedRows field should +** therefore only be used if [sqlite3_libversion_number()] returns a +** value greater than or equal to 3008002. +*/ +struct sqlite3_index_info { + /* Inputs */ + int nConstraint; /* Number of entries in aConstraint */ + struct sqlite3_index_constraint { + int iColumn; /* Column on left-hand side of constraint */ + unsigned char op; /* Constraint operator */ + unsigned char usable; /* True if this constraint is usable */ + int iTermOffset; /* Used internally - xBestIndex should ignore */ + } *aConstraint; /* Table of WHERE clause constraints */ + int nOrderBy; /* Number of terms in the ORDER BY clause */ + struct sqlite3_index_orderby { + int iColumn; /* Column number */ + unsigned char desc; /* True for DESC. False for ASC. */ + } *aOrderBy; /* The ORDER BY clause */ + /* Outputs */ + struct sqlite3_index_constraint_usage { + int argvIndex; /* if >0, constraint is part of argv to xFilter */ + unsigned char omit; /* Do not code a test for this constraint */ + } *aConstraintUsage; + int idxNum; /* Number used to identify the index */ + char *idxStr; /* String, possibly obtained from sqlite3_malloc */ + int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ + int orderByConsumed; /* True if output is already ordered */ + double estimatedCost; /* Estimated cost of using this index */ + /* Fields below are only available in SQLite 3.8.2 and later */ + sqlite3_int64 estimatedRows; /* Estimated number of rows returned */ +}; + +/* +** CAPI3REF: Virtual Table Constraint Operator Codes +** +** These macros defined the allowed values for the +** [sqlite3_index_info].aConstraint[].op field. Each value represents +** an operator that is part of a constraint term in the wHERE clause of +** a query that uses a [virtual table]. +*/ +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 + +/* +** CAPI3REF: Register A Virtual Table Implementation +** METHOD: sqlite3 +** +** ^These routines are used to register a new [virtual table module] name. +** ^Module names must be registered before +** creating a new [virtual table] using the module and before using a +** preexisting [virtual table] for the module. +** +** ^The module name is registered on the [database connection] specified +** by the first parameter. ^The name of the module is given by the +** second parameter. ^The third parameter is a pointer to +** the implementation of the [virtual table module]. ^The fourth +** parameter is an arbitrary client data pointer that is passed through +** into the [xCreate] and [xConnect] methods of the virtual table module +** when a new virtual table is be being created or reinitialized. +** +** ^The sqlite3_create_module_v2() interface has a fifth parameter which +** is a pointer to a destructor for the pClientData. ^SQLite will +** invoke the destructor function (if it is not NULL) when SQLite +** no longer needs the pClientData pointer. ^The destructor will also +** be invoked if the call to sqlite3_create_module_v2() fails. +** ^The sqlite3_create_module() +** interface is equivalent to sqlite3_create_module_v2() with a NULL +** destructor. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_create_module( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *p, /* Methods for the module */ + void *pClientData /* Client data for xCreate/xConnect */ +); +SQLITE_API int SQLITE_STDCALL sqlite3_create_module_v2( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *p, /* Methods for the module */ + void *pClientData, /* Client data for xCreate/xConnect */ + void(*xDestroy)(void*) /* Module destructor function */ +); + +/* +** CAPI3REF: Virtual Table Instance Object +** KEYWORDS: sqlite3_vtab +** +** Every [virtual table module] implementation uses a subclass +** of this object to describe a particular instance +** of the [virtual table]. Each subclass will +** be tailored to the specific needs of the module implementation. +** The purpose of this superclass is to define certain fields that are +** common to all module implementations. +** +** ^Virtual tables methods can set an error message by assigning a +** string obtained from [sqlite3_mprintf()] to zErrMsg. The method should +** take care that any prior string is freed by a call to [sqlite3_free()] +** prior to assigning a new string to zErrMsg. ^After the error message +** is delivered up to the client application, the string will be automatically +** freed by sqlite3_free() and the zErrMsg field will be zeroed. +*/ +struct sqlite3_vtab { + const sqlite3_module *pModule; /* The module for this virtual table */ + int nRef; /* Number of open cursors */ + char *zErrMsg; /* Error message from sqlite3_mprintf() */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** CAPI3REF: Virtual Table Cursor Object +** KEYWORDS: sqlite3_vtab_cursor {virtual table cursor} +** +** Every [virtual table module] implementation uses a subclass of the +** following structure to describe cursors that point into the +** [virtual table] and are used +** to loop through the virtual table. Cursors are created using the +** [sqlite3_module.xOpen | xOpen] method of the module and are destroyed +** by the [sqlite3_module.xClose | xClose] method. Cursors are used +** by the [xFilter], [xNext], [xEof], [xColumn], and [xRowid] methods +** of the module. Each module implementation will define +** the content of a cursor structure to suit its own needs. +** +** This superclass exists in order to define fields of the cursor that +** are common to all implementations. +*/ +struct sqlite3_vtab_cursor { + sqlite3_vtab *pVtab; /* Virtual table of this cursor */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** CAPI3REF: Declare The Schema Of A Virtual Table +** +** ^The [xCreate] and [xConnect] methods of a +** [virtual table module] call this interface +** to declare the format (the names and datatypes of the columns) of +** the virtual tables they implement. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3*, const char *zSQL); + +/* +** CAPI3REF: Overload A Function For A Virtual Table +** METHOD: sqlite3 +** +** ^(Virtual tables can provide alternative implementations of functions +** using the [xFindFunction] method of the [virtual table module]. +** But global versions of those functions +** must exist in order to be overloaded.)^ +** +** ^(This API makes sure a global version of a function with a particular +** name and number of parameters exists. If no such function exists +** before this API is called, a new function is created.)^ ^The implementation +** of the new function always causes an exception to be thrown. So +** the new function is not good for anything by itself. Its only +** purpose is to be a placeholder function that can be overloaded +** by a [virtual table]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); + +/* +** The interface to the virtual-table mechanism defined above (back up +** to a comment remarkably similar to this one) is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stabilizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + +/* +** CAPI3REF: A Handle To An Open BLOB +** KEYWORDS: {BLOB handle} {BLOB handles} +** +** An instance of this object represents an open BLOB on which +** [sqlite3_blob_open | incremental BLOB I/O] can be performed. +** ^Objects of this type are created by [sqlite3_blob_open()] +** and destroyed by [sqlite3_blob_close()]. +** ^The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces +** can be used to read or write small subsections of the BLOB. +** ^The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes. +*/ +typedef struct sqlite3_blob sqlite3_blob; + +/* +** CAPI3REF: Open A BLOB For Incremental I/O +** METHOD: sqlite3 +** CONSTRUCTOR: sqlite3_blob +** +** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located +** in row iRow, column zColumn, table zTable in database zDb; +** in other words, the same BLOB that would be selected by: +** +**
    +**     SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
    +** 
    )^ +** +** ^(Parameter zDb is not the filename that contains the database, but +** rather the symbolic name of the database. For attached databases, this is +** the name that appears after the AS keyword in the [ATTACH] statement. +** For the main database file, the database name is "main". For TEMP +** tables, the database name is "temp".)^ +** +** ^If the flags parameter is non-zero, then the BLOB is opened for read +** and write access. ^If the flags parameter is zero, the BLOB is opened for +** read-only access. +** +** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored +** in *ppBlob. Otherwise an [error code] is returned and, unless the error +** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided +** the API is not misused, it is always safe to call [sqlite3_blob_close()] +** on *ppBlob after this function it returns. +** +** This function fails with SQLITE_ERROR if any of the following are true: +**
      +**
    • ^(Database zDb does not exist)^, +**
    • ^(Table zTable does not exist within database zDb)^, +**
    • ^(Table zTable is a WITHOUT ROWID table)^, +**
    • ^(Column zColumn does not exist)^, +**
    • ^(Row iRow is not present in the table)^, +**
    • ^(The specified column of row iRow contains a value that is not +** a TEXT or BLOB value)^, +**
    • ^(Column zColumn is part of an index, PRIMARY KEY or UNIQUE +** constraint and the blob is being opened for read/write access)^, +**
    • ^([foreign key constraints | Foreign key constraints] are enabled, +** column zColumn is part of a [child key] definition and the blob is +** being opened for read/write access)^. +**
    +** +** ^Unless it returns SQLITE_MISUSE, this function sets the +** [database connection] error code and message accessible via +** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. +** +** +** ^(If the row that a BLOB handle points to is modified by an +** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects +** then the BLOB handle is marked as "expired". +** This is true if any column of the row is changed, even a column +** other than the one the BLOB handle is open on.)^ +** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for +** an expired BLOB handle fail with a return code of [SQLITE_ABORT]. +** ^(Changes written into a BLOB prior to the BLOB expiring are not +** rolled back by the expiration of the BLOB. Such changes will eventually +** commit if the transaction continues to completion.)^ +** +** ^Use the [sqlite3_blob_bytes()] interface to determine the size of +** the opened blob. ^The size of a blob may not be changed by this +** interface. Use the [UPDATE] SQL command to change the size of a +** blob. +** +** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces +** and the built-in [zeroblob] SQL function may be used to create a +** zero-filled blob to read or write using the incremental-blob interface. +** +** To avoid a resource leak, every open [BLOB handle] should eventually +** be released by a call to [sqlite3_blob_close()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_blob_open( + sqlite3*, + const char *zDb, + const char *zTable, + const char *zColumn, + sqlite3_int64 iRow, + int flags, + sqlite3_blob **ppBlob +); + +/* +** CAPI3REF: Move a BLOB Handle to a New Row +** METHOD: sqlite3_blob +** +** ^This function is used to move an existing blob handle so that it points +** to a different row of the same database table. ^The new row is identified +** by the rowid value passed as the second argument. Only the row can be +** changed. ^The database, table and column on which the blob handle is open +** remain the same. Moving an existing blob handle to a new row can be +** faster than closing the existing handle and opening a new one. +** +** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] - +** it must exist and there must be either a blob or text value stored in +** the nominated column.)^ ^If the new row is not present in the table, or if +** it does not contain a blob or text value, or if another error occurs, an +** SQLite error code is returned and the blob handle is considered aborted. +** ^All subsequent calls to [sqlite3_blob_read()], [sqlite3_blob_write()] or +** [sqlite3_blob_reopen()] on an aborted blob handle immediately return +** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle +** always returns zero. +** +** ^This function sets the database handle error code and message. +*/ +SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); + +/* +** CAPI3REF: Close A BLOB Handle +** DESTRUCTOR: sqlite3_blob +** +** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed +** unconditionally. Even if this routine returns an error code, the +** handle is still closed.)^ +** +** ^If the blob handle being closed was opened for read-write access, and if +** the database is in auto-commit mode and there are no other open read-write +** blob handles or active write statements, the current transaction is +** committed. ^If an error occurs while committing the transaction, an error +** code is returned and the transaction rolled back. +** +** Calling this function with an argument that is not a NULL pointer or an +** open blob handle results in undefined behaviour. ^Calling this routine +** with a null pointer (such as would be returned by a failed call to +** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function +** is passed a valid open blob handle, the values returned by the +** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *); + +/* +** CAPI3REF: Return The Size Of An Open BLOB +** METHOD: sqlite3_blob +** +** ^Returns the size in bytes of the BLOB accessible via the +** successfully opened [BLOB handle] in its only argument. ^The +** incremental blob I/O routines can only read or overwriting existing +** blob content; they cannot change the size of a blob. +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *); + +/* +** CAPI3REF: Read Data From A BLOB Incrementally +** METHOD: sqlite3_blob +** +** ^(This function is used to read data from an open [BLOB handle] into a +** caller-supplied buffer. N bytes of data are copied into buffer Z +** from the open BLOB, starting at offset iOffset.)^ +** +** ^If offset iOffset is less than N bytes from the end of the BLOB, +** [SQLITE_ERROR] is returned and no data is read. ^If N or iOffset is +** less than zero, [SQLITE_ERROR] is returned and no data is read. +** ^The size of the blob (and hence the maximum value of N+iOffset) +** can be determined using the [sqlite3_blob_bytes()] interface. +** +** ^An attempt to read from an expired [BLOB handle] fails with an +** error code of [SQLITE_ABORT]. +** +** ^(On success, sqlite3_blob_read() returns SQLITE_OK. +** Otherwise, an [error code] or an [extended error code] is returned.)^ +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +** +** See also: [sqlite3_blob_write()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); + +/* +** CAPI3REF: Write Data Into A BLOB Incrementally +** METHOD: sqlite3_blob +** +** ^(This function is used to write data into an open [BLOB handle] from a +** caller-supplied buffer. N bytes of data are copied from the buffer Z +** into the open BLOB, starting at offset iOffset.)^ +** +** ^(On success, sqlite3_blob_write() returns SQLITE_OK. +** Otherwise, an [error code] or an [extended error code] is returned.)^ +** ^Unless SQLITE_MISUSE is returned, this function sets the +** [database connection] error code and message accessible via +** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. +** +** ^If the [BLOB handle] passed as the first argument was not opened for +** writing (the flags parameter to [sqlite3_blob_open()] was zero), +** this function returns [SQLITE_READONLY]. +** +** This function may only modify the contents of the BLOB; it is +** not possible to increase the size of a BLOB using this API. +** ^If offset iOffset is less than N bytes from the end of the BLOB, +** [SQLITE_ERROR] is returned and no data is written. The size of the +** BLOB (and hence the maximum value of N+iOffset) can be determined +** using the [sqlite3_blob_bytes()] interface. ^If N or iOffset are less +** than zero [SQLITE_ERROR] is returned and no data is written. +** +** ^An attempt to write to an expired [BLOB handle] fails with an +** error code of [SQLITE_ABORT]. ^Writes to the BLOB that occurred +** before the [BLOB handle] expired are not rolled back by the +** expiration of the handle, though of course those changes might +** have been overwritten by the statement that expired the BLOB handle +** or by other independent statements. +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +** +** See also: [sqlite3_blob_read()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); + +/* +** CAPI3REF: Virtual File System Objects +** +** A virtual filesystem (VFS) is an [sqlite3_vfs] object +** that SQLite uses to interact +** with the underlying operating system. Most SQLite builds come with a +** single default VFS that is appropriate for the host computer. +** New VFSes can be registered and existing VFSes can be unregistered. +** The following interfaces are provided. +** +** ^The sqlite3_vfs_find() interface returns a pointer to a VFS given its name. +** ^Names are case sensitive. +** ^Names are zero-terminated UTF-8 strings. +** ^If there is no match, a NULL pointer is returned. +** ^If zVfsName is NULL then the default VFS is returned. +** +** ^New VFSes are registered with sqlite3_vfs_register(). +** ^Each new VFS becomes the default VFS if the makeDflt flag is set. +** ^The same VFS can be registered multiple times without injury. +** ^To make an existing VFS into the default VFS, register it again +** with the makeDflt flag set. If two different VFSes with the +** same name are registered, the behavior is undefined. If a +** VFS is registered with a name that is NULL or an empty string, +** then the behavior is undefined. +** +** ^Unregister a VFS with the sqlite3_vfs_unregister() interface. +** ^(If the default VFS is unregistered, another VFS is chosen as +** the default. The choice for the new VFS is arbitrary.)^ +*/ +SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfsName); +SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); +SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs*); + +/* +** CAPI3REF: Mutexes +** +** The SQLite core uses these routines for thread +** synchronization. Though they are intended for internal +** use by SQLite, code that links against SQLite is +** permitted to use any of these routines. +** +** The SQLite source code contains multiple implementations +** of these mutex routines. An appropriate implementation +** is selected automatically at compile-time. The following +** implementations are available in the SQLite core: +** +**
      +**
    • SQLITE_MUTEX_PTHREADS +**
    • SQLITE_MUTEX_W32 +**
    • SQLITE_MUTEX_NOOP +**
    +** +** The SQLITE_MUTEX_NOOP implementation is a set of routines +** that does no real locking and is appropriate for use in +** a single-threaded application. The SQLITE_MUTEX_PTHREADS and +** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix +** and Windows. +** +** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor +** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex +** implementation is included with the library. In this case the +** application must supply a custom mutex implementation using the +** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function +** before calling sqlite3_initialize() or any other public sqlite3_ +** function that calls sqlite3_initialize(). +** +** ^The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() +** routine returns NULL if it is unable to allocate the requested +** mutex. The argument to sqlite3_mutex_alloc() must one of these +** integer constants: +** +**
      +**
    • SQLITE_MUTEX_FAST +**
    • SQLITE_MUTEX_RECURSIVE +**
    • SQLITE_MUTEX_STATIC_MASTER +**
    • SQLITE_MUTEX_STATIC_MEM +**
    • SQLITE_MUTEX_STATIC_OPEN +**
    • SQLITE_MUTEX_STATIC_PRNG +**
    • SQLITE_MUTEX_STATIC_LRU +**
    • SQLITE_MUTEX_STATIC_PMEM +**
    • SQLITE_MUTEX_STATIC_APP1 +**
    • SQLITE_MUTEX_STATIC_APP2 +**
    • SQLITE_MUTEX_STATIC_APP3 +**
    +** +** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) +** cause sqlite3_mutex_alloc() to create +** a new mutex. ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** ^The other allowed parameters to sqlite3_mutex_alloc() (anything other +** than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return +** a pointer to a static preexisting mutex. ^Nine static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. ^For the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +** +** ^The sqlite3_mutex_free() routine deallocates a previously +** allocated dynamic mutex. Attempting to deallocate a static +** mutex results in undefined behavior. +** +** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. ^If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. ^The sqlite3_mutex_try() interface returns [SQLITE_OK] +** upon successful entry. ^(Mutexes created using +** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread. +** In such cases, the +** mutex must be exited an equal number of times before another thread +** can enter.)^ If the same thread tries to enter any mutex other +** than an SQLITE_MUTEX_RECURSIVE more than once, the behavior is undefined. +** +** ^(Some systems (for example, Windows 95) do not support the operation +** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() +** will always return SQLITE_BUSY. The SQLite core only ever uses +** sqlite3_mutex_try() as an optimization so this is acceptable +** behavior.)^ +** +** ^The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered by the +** calling thread or is not currently allocated. +** +** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or +** sqlite3_mutex_leave() is a NULL pointer, then all three routines +** behave as no-ops. +** +** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. +*/ +SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int); +SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex*); +SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex*); +SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex*); +SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Methods Object +** +** An instance of this structure defines the low-level routines +** used to allocate and use mutexes. +** +** Usually, the default mutex implementations provided by SQLite are +** sufficient, however the application has the option of substituting a custom +** implementation for specialized deployments or systems for which SQLite +** does not provide a suitable implementation. In this case, the application +** creates and populates an instance of this structure to pass +** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option. +** Additionally, an instance of this structure can be used as an +** output variable when querying the system for the current mutex +** implementation, using the [SQLITE_CONFIG_GETMUTEX] option. +** +** ^The xMutexInit method defined by this structure is invoked as +** part of system initialization by the sqlite3_initialize() function. +** ^The xMutexInit routine is called by SQLite exactly once for each +** effective call to [sqlite3_initialize()]. +** +** ^The xMutexEnd method defined by this structure is invoked as +** part of system shutdown by the sqlite3_shutdown() function. The +** implementation of this method is expected to release all outstanding +** resources obtained by the mutex methods implementation, especially +** those obtained by the xMutexInit method. ^The xMutexEnd() +** interface is invoked exactly once for each call to [sqlite3_shutdown()]. +** +** ^(The remaining seven methods defined by this structure (xMutexAlloc, +** xMutexFree, xMutexEnter, xMutexTry, xMutexLeave, xMutexHeld and +** xMutexNotheld) implement the following interfaces (respectively): +** +**
      +**
    • [sqlite3_mutex_alloc()]
    • +**
    • [sqlite3_mutex_free()]
    • +**
    • [sqlite3_mutex_enter()]
    • +**
    • [sqlite3_mutex_try()]
    • +**
    • [sqlite3_mutex_leave()]
    • +**
    • [sqlite3_mutex_held()]
    • +**
    • [sqlite3_mutex_notheld()]
    • +**
    )^ +** +** The only difference is that the public sqlite3_XXX functions enumerated +** above silently ignore any invocations that pass a NULL pointer instead +** of a valid mutex handle. The implementations of the methods defined +** by this structure are not required to handle this case, the results +** of passing a NULL pointer instead of a valid mutex handle are undefined +** (i.e. it is acceptable to provide an implementation that segfaults if +** it is passed a NULL pointer). +** +** The xMutexInit() method must be threadsafe. It must be harmless to +** invoke xMutexInit() multiple times within the same process and without +** intervening calls to xMutexEnd(). Second and subsequent calls to +** xMutexInit() must be no-ops. +** +** xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()] +** and its associates). Similarly, xMutexAlloc() must not use SQLite memory +** allocation for a static mutex. ^However xMutexAlloc() may use SQLite +** memory allocation for a fast or recursive mutex. +** +** ^SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is +** called, but only if the prior call to xMutexInit returned SQLITE_OK. +** If xMutexInit fails in any way, it is expected to clean up after itself +** prior to returning. +*/ +typedef struct sqlite3_mutex_methods sqlite3_mutex_methods; +struct sqlite3_mutex_methods { + int (*xMutexInit)(void); + int (*xMutexEnd)(void); + sqlite3_mutex *(*xMutexAlloc)(int); + void (*xMutexFree)(sqlite3_mutex *); + void (*xMutexEnter)(sqlite3_mutex *); + int (*xMutexTry)(sqlite3_mutex *); + void (*xMutexLeave)(sqlite3_mutex *); + int (*xMutexHeld)(sqlite3_mutex *); + int (*xMutexNotheld)(sqlite3_mutex *); +}; + +/* +** CAPI3REF: Mutex Verification Routines +** +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines +** are intended for use inside assert() statements. The SQLite core +** never uses these routines except inside an assert() and applications +** are advised to follow the lead of the core. The SQLite core only +** provides implementations for these routines when it is compiled +** with the SQLITE_DEBUG flag. External mutex implementations +** are only required to provide these routines if SQLITE_DEBUG is +** defined and if NDEBUG is not defined. +** +** These routines should return true if the mutex in their argument +** is held or not held, respectively, by the calling thread. +** +** The implementation is not required to provide versions of these +** routines that actually work. If the implementation does not provide working +** versions of these routines, it should at least provide stubs that always +** return true so that one does not get spurious assertion failures. +** +** If the argument to sqlite3_mutex_held() is a NULL pointer then +** the routine should return 1. This seems counter-intuitive since +** clearly the mutex cannot be held if it does not exist. But +** the reason the mutex does not exist is because the build is not +** using mutexes. And we do not want the assert() containing the +** call to sqlite3_mutex_held() to fail, so a non-zero return is +** the appropriate thing to do. The sqlite3_mutex_notheld() +** interface should also return 1 when given a NULL pointer. +*/ +#ifndef NDEBUG +SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex*); +SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex*); +#endif + +/* +** CAPI3REF: Mutex Types +** +** The [sqlite3_mutex_alloc()] interface takes a single argument +** which is one of these integer constants. +** +** The set of static mutexes may change from one SQLite release to the +** next. Applications that override the built-in mutex logic must be +** prepared to accommodate additional static mutexes. +*/ +#define SQLITE_MUTEX_FAST 0 +#define SQLITE_MUTEX_RECURSIVE 1 +#define SQLITE_MUTEX_STATIC_MASTER 2 +#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ +#define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */ +#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ +#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ +#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ +#define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */ +#define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ +#define SQLITE_MUTEX_STATIC_APP1 8 /* For use by application */ +#define SQLITE_MUTEX_STATIC_APP2 9 /* For use by application */ +#define SQLITE_MUTEX_STATIC_APP3 10 /* For use by application */ + +/* +** CAPI3REF: Retrieve the mutex for a database connection +** METHOD: sqlite3 +** +** ^This interface returns a pointer the [sqlite3_mutex] object that +** serializes access to the [database connection] given in the argument +** when the [threading mode] is Serialized. +** ^If the [threading mode] is Single-thread or Multi-thread then this +** routine returns a NULL pointer. +*/ +SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3*); + +/* +** CAPI3REF: Low-Level Control Of Database Files +** METHOD: sqlite3 +** +** ^The [sqlite3_file_control()] interface makes a direct call to the +** xFileControl method for the [sqlite3_io_methods] object associated +** with a particular database identified by the second argument. ^The +** name of the database is "main" for the main database or "temp" for the +** TEMP database, or the name that appears after the AS keyword for +** databases that are added using the [ATTACH] SQL command. +** ^A NULL pointer can be used in place of "main" to refer to the +** main database file. +** ^The third and fourth parameters to this routine +** are passed directly through to the second and third parameters of +** the xFileControl method. ^The return value of the xFileControl +** method becomes the return value of this routine. +** +** ^The SQLITE_FCNTL_FILE_POINTER value for the op parameter causes +** a pointer to the underlying [sqlite3_file] object to be written into +** the space pointed to by the 4th parameter. ^The SQLITE_FCNTL_FILE_POINTER +** case is a short-circuit path which does not actually invoke the +** underlying sqlite3_io_methods.xFileControl method. +** +** ^If the second parameter (zDbName) does not match the name of any +** open database file, then SQLITE_ERROR is returned. ^This error +** code is not remembered and will not be recalled by [sqlite3_errcode()] +** or [sqlite3_errmsg()]. The underlying xFileControl method might +** also return SQLITE_ERROR. There is no way to distinguish between +** an incorrect zDbName and an SQLITE_ERROR return from the underlying +** xFileControl method. +** +** See also: [SQLITE_FCNTL_LOCKSTATE] +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); + +/* +** CAPI3REF: Testing Interface +** +** ^The sqlite3_test_control() interface is used to read out internal +** state of SQLite and to inject faults into SQLite for testing +** purposes. ^The first parameter is an operation code that determines +** the number, meaning, and operation of all subsequent parameters. +** +** This interface is not for use by applications. It exists solely +** for verifying the correct operation of the SQLite library. Depending +** on how the SQLite library is compiled, this interface might not exist. +** +** The details of the operation codes, their meanings, the parameters +** they take, and what they do are all subject to change without notice. +** Unlike most of the SQLite API, this function is not guaranteed to +** operate consistently from one release to the next. +*/ +SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...); + +/* +** CAPI3REF: Testing Interface Operation Codes +** +** These constants are the valid operation code parameters used +** as the first argument to [sqlite3_test_control()]. +** +** These parameters and their meanings are subject to change +** without notice. These values are for testing purposes only. +** Applications should not use any of these parameters or the +** [sqlite3_test_control()] interface. +*/ +#define SQLITE_TESTCTRL_FIRST 5 +#define SQLITE_TESTCTRL_PRNG_SAVE 5 +#define SQLITE_TESTCTRL_PRNG_RESTORE 6 +#define SQLITE_TESTCTRL_PRNG_RESET 7 +#define SQLITE_TESTCTRL_BITVEC_TEST 8 +#define SQLITE_TESTCTRL_FAULT_INSTALL 9 +#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10 +#define SQLITE_TESTCTRL_PENDING_BYTE 11 +#define SQLITE_TESTCTRL_ASSERT 12 +#define SQLITE_TESTCTRL_ALWAYS 13 +#define SQLITE_TESTCTRL_RESERVE 14 +#define SQLITE_TESTCTRL_OPTIMIZATIONS 15 +#define SQLITE_TESTCTRL_ISKEYWORD 16 +#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 +#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 +#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */ +#define SQLITE_TESTCTRL_NEVER_CORRUPT 20 +#define SQLITE_TESTCTRL_VDBE_COVERAGE 21 +#define SQLITE_TESTCTRL_BYTEORDER 22 +#define SQLITE_TESTCTRL_ISINIT 23 +#define SQLITE_TESTCTRL_SORTER_MMAP 24 +#define SQLITE_TESTCTRL_IMPOSTER 25 +#define SQLITE_TESTCTRL_LAST 25 + +/* +** CAPI3REF: SQLite Runtime Status +** +** ^These interfaces are used to retrieve runtime status information +** about the performance of SQLite, and optionally to reset various +** highwater marks. ^The first argument is an integer code for +** the specific parameter to measure. ^(Recognized integer codes +** are of the form [status parameters | SQLITE_STATUS_...].)^ +** ^The current value of the parameter is returned into *pCurrent. +** ^The highest recorded value is returned in *pHighwater. ^If the +** resetFlag is true, then the highest record value is reset after +** *pHighwater is written. ^(Some parameters do not record the highest +** value. For those parameters +** nothing is written into *pHighwater and the resetFlag is ignored.)^ +** ^(Other parameters record only the highwater mark and not the current +** value. For these latter parameters nothing is written into *pCurrent.)^ +** +** ^The sqlite3_status() and sqlite3_status64() routines return +** SQLITE_OK on success and a non-zero [error code] on failure. +** +** If either the current value or the highwater mark is too large to +** be represented by a 32-bit integer, then the values returned by +** sqlite3_status() are undefined. +** +** See also: [sqlite3_db_status()] +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); +SQLITE_API int SQLITE_STDCALL sqlite3_status64( + int op, + sqlite3_int64 *pCurrent, + sqlite3_int64 *pHighwater, + int resetFlag +); + + +/* +** CAPI3REF: Status Parameters +** KEYWORDS: {status parameters} +** +** These integer constants designate various run-time status parameters +** that can be returned by [sqlite3_status()]. +** +**
    +** [[SQLITE_STATUS_MEMORY_USED]] ^(
    SQLITE_STATUS_MEMORY_USED
    +**
    This parameter is the current amount of memory checked out +** using [sqlite3_malloc()], either directly or indirectly. The +** figure includes calls made to [sqlite3_malloc()] by the application +** and internal memory usage by the SQLite library. Scratch memory +** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache +** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in +** this parameter. The amount returned is the sum of the allocation +** sizes as reported by the xSize method in [sqlite3_mem_methods].
    )^ +** +** [[SQLITE_STATUS_MALLOC_SIZE]] ^(
    SQLITE_STATUS_MALLOC_SIZE
    +**
    This parameter records the largest memory allocation request +** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their +** internal equivalents). Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.
    )^ +** +** [[SQLITE_STATUS_MALLOC_COUNT]] ^(
    SQLITE_STATUS_MALLOC_COUNT
    +**
    This parameter records the number of separate memory allocations +** currently checked out.
    )^ +** +** [[SQLITE_STATUS_PAGECACHE_USED]] ^(
    SQLITE_STATUS_PAGECACHE_USED
    +**
    This parameter returns the number of pages used out of the +** [pagecache memory allocator] that was configured using +** [SQLITE_CONFIG_PAGECACHE]. The +** value returned is in pages, not in bytes.
    )^ +** +** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]] +** ^(
    SQLITE_STATUS_PAGECACHE_OVERFLOW
    +**
    This parameter returns the number of bytes of page cache +** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] +** buffer and where forced to overflow to [sqlite3_malloc()]. The +** returned value includes allocations that overflowed because they +** where too large (they were larger than the "sz" parameter to +** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because +** no space was left in the page cache.
    )^ +** +** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(
    SQLITE_STATUS_PAGECACHE_SIZE
    +**
    This parameter records the largest memory allocation request +** handed to [pagecache memory allocator]. Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.
    )^ +** +** [[SQLITE_STATUS_SCRATCH_USED]] ^(
    SQLITE_STATUS_SCRATCH_USED
    +**
    This parameter returns the number of allocations used out of the +** [scratch memory allocator] configured using +** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not +** in bytes. Since a single thread may only have one scratch allocation +** outstanding at time, this parameter also reports the number of threads +** using scratch memory at the same time.
    )^ +** +** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(
    SQLITE_STATUS_SCRATCH_OVERFLOW
    +**
    This parameter returns the number of bytes of scratch memory +** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH] +** buffer and where forced to overflow to [sqlite3_malloc()]. The values +** returned include overflows because the requested allocation was too +** larger (that is, because the requested allocation was larger than the +** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer +** slots were available. +**
    )^ +** +** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(
    SQLITE_STATUS_SCRATCH_SIZE
    +**
    This parameter records the largest memory allocation request +** handed to [scratch memory allocator]. Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.
    )^ +** +** [[SQLITE_STATUS_PARSER_STACK]] ^(
    SQLITE_STATUS_PARSER_STACK
    +**
    This parameter records the deepest parser stack. It is only +** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].
    )^ +**
    +** +** New status parameters may be added from time to time. +*/ +#define SQLITE_STATUS_MEMORY_USED 0 +#define SQLITE_STATUS_PAGECACHE_USED 1 +#define SQLITE_STATUS_PAGECACHE_OVERFLOW 2 +#define SQLITE_STATUS_SCRATCH_USED 3 +#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 +#define SQLITE_STATUS_MALLOC_SIZE 5 +#define SQLITE_STATUS_PARSER_STACK 6 +#define SQLITE_STATUS_PAGECACHE_SIZE 7 +#define SQLITE_STATUS_SCRATCH_SIZE 8 +#define SQLITE_STATUS_MALLOC_COUNT 9 + +/* +** CAPI3REF: Database Connection Status +** METHOD: sqlite3 +** +** ^This interface is used to retrieve runtime status information +** about a single [database connection]. ^The first argument is the +** database connection object to be interrogated. ^The second argument +** is an integer constant, taken from the set of +** [SQLITE_DBSTATUS options], that +** determines the parameter to interrogate. The set of +** [SQLITE_DBSTATUS options] is likely +** to grow in future releases of SQLite. +** +** ^The current value of the requested parameter is written into *pCur +** and the highest instantaneous value is written into *pHiwtr. ^If +** the resetFlg is true, then the highest instantaneous value is +** reset back down to the current value. +** +** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a +** non-zero [error code] on failure. +** +** See also: [sqlite3_status()] and [sqlite3_stmt_status()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); + +/* +** CAPI3REF: Status Parameters for database connections +** KEYWORDS: {SQLITE_DBSTATUS options} +** +** These constants are the available integer "verbs" that can be passed as +** the second argument to the [sqlite3_db_status()] interface. +** +** New verbs may be added in future releases of SQLite. Existing verbs +** might be discontinued. Applications should check the return code from +** [sqlite3_db_status()] to make sure that the call worked. +** The [sqlite3_db_status()] interface will return a non-zero error code +** if a discontinued or unsupported verb is invoked. +** +**
    +** [[SQLITE_DBSTATUS_LOOKASIDE_USED]] ^(
    SQLITE_DBSTATUS_LOOKASIDE_USED
    +**
    This parameter returns the number of lookaside memory slots currently +** checked out.
    )^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(
    SQLITE_DBSTATUS_LOOKASIDE_HIT
    +**
    This parameter returns the number malloc attempts that were +** satisfied using lookaside memory. Only the high-water value is meaningful; +** the current value is always zero.)^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]] +** ^(
    SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE
    +**
    This parameter returns the number malloc attempts that might have +** been satisfied using lookaside memory but failed due to the amount of +** memory requested being larger than the lookaside slot size. +** Only the high-water value is meaningful; +** the current value is always zero.)^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]] +** ^(
    SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL
    +**
    This parameter returns the number malloc attempts that might have +** been satisfied using lookaside memory but failed due to all lookaside +** memory already being in use. +** Only the high-water value is meaningful; +** the current value is always zero.)^ +** +** [[SQLITE_DBSTATUS_CACHE_USED]] ^(
    SQLITE_DBSTATUS_CACHE_USED
    +**
    This parameter returns the approximate number of bytes of heap +** memory used by all pager caches associated with the database connection.)^ +** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. +** +** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(
    SQLITE_DBSTATUS_SCHEMA_USED
    +**
    This parameter returns the approximate number of bytes of heap +** memory used to store the schema for all databases associated +** with the connection - main, temp, and any [ATTACH]-ed databases.)^ +** ^The full amount of memory used by the schemas is reported, even if the +** schema memory is shared with other database connections due to +** [shared cache mode] being enabled. +** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0. +** +** [[SQLITE_DBSTATUS_STMT_USED]] ^(
    SQLITE_DBSTATUS_STMT_USED
    +**
    This parameter returns the approximate number of bytes of heap +** and lookaside memory used by all prepared statements associated with +** the database connection.)^ +** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0. +**
    +** +** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(
    SQLITE_DBSTATUS_CACHE_HIT
    +**
    This parameter returns the number of pager cache hits that have +** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT +** is always 0. +**
    +** +** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(
    SQLITE_DBSTATUS_CACHE_MISS
    +**
    This parameter returns the number of pager cache misses that have +** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS +** is always 0. +**
    +** +** [[SQLITE_DBSTATUS_CACHE_WRITE]] ^(
    SQLITE_DBSTATUS_CACHE_WRITE
    +**
    This parameter returns the number of dirty cache entries that have +** been written to disk. Specifically, the number of pages written to the +** wal file in wal mode databases, or the number of pages written to the +** database file in rollback mode databases. Any pages written as part of +** transaction rollback or database recovery operations are not included. +** If an IO or other error occurs while writing a page to disk, the effect +** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The +** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. +**
    +** +** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(
    SQLITE_DBSTATUS_DEFERRED_FKS
    +**
    This parameter returns zero for the current value if and only if +** all foreign key constraints (deferred or immediate) have been +** resolved.)^ ^The highwater mark is always 0. +**
    +**
    +*/ +#define SQLITE_DBSTATUS_LOOKASIDE_USED 0 +#define SQLITE_DBSTATUS_CACHE_USED 1 +#define SQLITE_DBSTATUS_SCHEMA_USED 2 +#define SQLITE_DBSTATUS_STMT_USED 3 +#define SQLITE_DBSTATUS_LOOKASIDE_HIT 4 +#define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5 +#define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6 +#define SQLITE_DBSTATUS_CACHE_HIT 7 +#define SQLITE_DBSTATUS_CACHE_MISS 8 +#define SQLITE_DBSTATUS_CACHE_WRITE 9 +#define SQLITE_DBSTATUS_DEFERRED_FKS 10 +#define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */ + + +/* +** CAPI3REF: Prepared Statement Status +** METHOD: sqlite3_stmt +** +** ^(Each prepared statement maintains various +** [SQLITE_STMTSTATUS counters] that measure the number +** of times it has performed specific operations.)^ These counters can +** be used to monitor the performance characteristics of the prepared +** statements. For example, if the number of table steps greatly exceeds +** the number of table searches or result rows, that would tend to indicate +** that the prepared statement is using a full table scan rather than +** an index. +** +** ^(This interface is used to retrieve and reset counter values from +** a [prepared statement]. The first argument is the prepared statement +** object to be interrogated. The second argument +** is an integer code for a specific [SQLITE_STMTSTATUS counter] +** to be interrogated.)^ +** ^The current value of the requested counter is returned. +** ^If the resetFlg is true, then the counter is reset to zero after this +** interface call returns. +** +** See also: [sqlite3_status()] and [sqlite3_db_status()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); + +/* +** CAPI3REF: Status Parameters for prepared statements +** KEYWORDS: {SQLITE_STMTSTATUS counter} {SQLITE_STMTSTATUS counters} +** +** These preprocessor macros define integer codes that name counter +** values associated with the [sqlite3_stmt_status()] interface. +** The meanings of the various counters are as follows: +** +**
    +** [[SQLITE_STMTSTATUS_FULLSCAN_STEP]]
    SQLITE_STMTSTATUS_FULLSCAN_STEP
    +**
    ^This is the number of times that SQLite has stepped forward in +** a table as part of a full table scan. Large numbers for this counter +** may indicate opportunities for performance improvement through +** careful use of indices.
    +** +** [[SQLITE_STMTSTATUS_SORT]]
    SQLITE_STMTSTATUS_SORT
    +**
    ^This is the number of sort operations that have occurred. +** A non-zero value in this counter may indicate an opportunity to +** improvement performance through careful use of indices.
    +** +** [[SQLITE_STMTSTATUS_AUTOINDEX]]
    SQLITE_STMTSTATUS_AUTOINDEX
    +**
    ^This is the number of rows inserted into transient indices that +** were created automatically in order to help joins run faster. +** A non-zero value in this counter may indicate an opportunity to +** improvement performance by adding permanent indices that do not +** need to be reinitialized each time the statement is run.
    +** +** [[SQLITE_STMTSTATUS_VM_STEP]]
    SQLITE_STMTSTATUS_VM_STEP
    +**
    ^This is the number of virtual machine operations executed +** by the prepared statement if that number is less than or equal +** to 2147483647. The number of virtual machine operations can be +** used as a proxy for the total work done by the prepared statement. +** If the number of virtual machine operations exceeds 2147483647 +** then the value returned by this statement status code is undefined. +**
    +**
    +*/ +#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1 +#define SQLITE_STMTSTATUS_SORT 2 +#define SQLITE_STMTSTATUS_AUTOINDEX 3 +#define SQLITE_STMTSTATUS_VM_STEP 4 + +/* +** CAPI3REF: Custom Page Cache Object +** +** The sqlite3_pcache type is opaque. It is implemented by +** the pluggable module. The SQLite core has no knowledge of +** its size or internal structure and never deals with the +** sqlite3_pcache object except by holding and passing pointers +** to the object. +** +** See [sqlite3_pcache_methods2] for additional information. +*/ +typedef struct sqlite3_pcache sqlite3_pcache; + +/* +** CAPI3REF: Custom Page Cache Object +** +** The sqlite3_pcache_page object represents a single page in the +** page cache. The page cache will allocate instances of this +** object. Various methods of the page cache use pointers to instances +** of this object as parameters or as their return value. +** +** See [sqlite3_pcache_methods2] for additional information. +*/ +typedef struct sqlite3_pcache_page sqlite3_pcache_page; +struct sqlite3_pcache_page { + void *pBuf; /* The content of the page */ + void *pExtra; /* Extra information associated with the page */ +}; + +/* +** CAPI3REF: Application Defined Page Cache. +** KEYWORDS: {page cache} +** +** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE2], ...) interface can +** register an alternative page cache implementation by passing in an +** instance of the sqlite3_pcache_methods2 structure.)^ +** In many applications, most of the heap memory allocated by +** SQLite is used for the page cache. +** By implementing a +** custom page cache using this API, an application can better control +** the amount of memory consumed by SQLite, the way in which +** that memory is allocated and released, and the policies used to +** determine exactly which parts of a database file are cached and for +** how long. +** +** The alternative page cache mechanism is an +** extreme measure that is only needed by the most demanding applications. +** The built-in page cache is recommended for most uses. +** +** ^(The contents of the sqlite3_pcache_methods2 structure are copied to an +** internal buffer by SQLite within the call to [sqlite3_config]. Hence +** the application may discard the parameter after the call to +** [sqlite3_config()] returns.)^ +** +** [[the xInit() page cache method]] +** ^(The xInit() method is called once for each effective +** call to [sqlite3_initialize()])^ +** (usually only once during the lifetime of the process). ^(The xInit() +** method is passed a copy of the sqlite3_pcache_methods2.pArg value.)^ +** The intent of the xInit() method is to set up global data structures +** required by the custom page cache implementation. +** ^(If the xInit() method is NULL, then the +** built-in default page cache is used instead of the application defined +** page cache.)^ +** +** [[the xShutdown() page cache method]] +** ^The xShutdown() method is called by [sqlite3_shutdown()]. +** It can be used to clean up +** any outstanding resources before process shutdown, if required. +** ^The xShutdown() method may be NULL. +** +** ^SQLite automatically serializes calls to the xInit method, +** so the xInit method need not be threadsafe. ^The +** xShutdown method is only called from [sqlite3_shutdown()] so it does +** not need to be threadsafe either. All other methods must be threadsafe +** in multithreaded applications. +** +** ^SQLite will never invoke xInit() more than once without an intervening +** call to xShutdown(). +** +** [[the xCreate() page cache methods]] +** ^SQLite invokes the xCreate() method to construct a new cache instance. +** SQLite will typically create one cache instance for each open database file, +** though this is not guaranteed. ^The +** first parameter, szPage, is the size in bytes of the pages that must +** be allocated by the cache. ^szPage will always a power of two. ^The +** second parameter szExtra is a number of bytes of extra storage +** associated with each page cache entry. ^The szExtra parameter will +** a number less than 250. SQLite will use the +** extra szExtra bytes on each page to store metadata about the underlying +** database page on disk. The value passed into szExtra depends +** on the SQLite version, the target platform, and how SQLite was compiled. +** ^The third argument to xCreate(), bPurgeable, is true if the cache being +** created will be used to cache database pages of a file stored on disk, or +** false if it is used for an in-memory database. The cache implementation +** does not have to do anything special based with the value of bPurgeable; +** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will +** never invoke xUnpin() except to deliberately delete a page. +** ^In other words, calls to xUnpin() on a cache with bPurgeable set to +** false will always have the "discard" flag set to true. +** ^Hence, a cache created with bPurgeable false will +** never contain any unpinned pages. +** +** [[the xCachesize() page cache method]] +** ^(The xCachesize() method may be called at any time by SQLite to set the +** suggested maximum cache-size (number of pages stored by) the cache +** instance passed as the first argument. This is the value configured using +** the SQLite "[PRAGMA cache_size]" command.)^ As with the bPurgeable +** parameter, the implementation is not required to do anything with this +** value; it is advisory only. +** +** [[the xPagecount() page cache methods]] +** The xPagecount() method must return the number of pages currently +** stored in the cache, both pinned and unpinned. +** +** [[the xFetch() page cache methods]] +** The xFetch() method locates a page in the cache and returns a pointer to +** an sqlite3_pcache_page object associated with that page, or a NULL pointer. +** The pBuf element of the returned sqlite3_pcache_page object will be a +** pointer to a buffer of szPage bytes used to store the content of a +** single database page. The pExtra element of sqlite3_pcache_page will be +** a pointer to the szExtra bytes of extra storage that SQLite has requested +** for each entry in the page cache. +** +** The page to be fetched is determined by the key. ^The minimum key value +** is 1. After it has been retrieved using xFetch, the page is considered +** to be "pinned". +** +** If the requested page is already in the page cache, then the page cache +** implementation must return a pointer to the page buffer with its content +** intact. If the requested page is not already in the cache, then the +** cache implementation should use the value of the createFlag +** parameter to help it determined what action to take: +** +** +**
    createFlag Behavior when page is not already in cache +**
    0 Do not allocate a new page. Return NULL. +**
    1 Allocate a new page if it easy and convenient to do so. +** Otherwise return NULL. +**
    2 Make every effort to allocate a new page. Only return +** NULL if allocating a new page is effectively impossible. +**
    +** +** ^(SQLite will normally invoke xFetch() with a createFlag of 0 or 1. SQLite +** will only use a createFlag of 2 after a prior call with a createFlag of 1 +** failed.)^ In between the to xFetch() calls, SQLite may +** attempt to unpin one or more cache pages by spilling the content of +** pinned pages to disk and synching the operating system disk cache. +** +** [[the xUnpin() page cache method]] +** ^xUnpin() is called by SQLite with a pointer to a currently pinned page +** as its second argument. If the third parameter, discard, is non-zero, +** then the page must be evicted from the cache. +** ^If the discard parameter is +** zero, then the page may be discarded or retained at the discretion of +** page cache implementation. ^The page cache implementation +** may choose to evict unpinned pages at any time. +** +** The cache must not perform any reference counting. A single +** call to xUnpin() unpins the page regardless of the number of prior calls +** to xFetch(). +** +** [[the xRekey() page cache methods]] +** The xRekey() method is used to change the key value associated with the +** page passed as the second argument. If the cache +** previously contains an entry associated with newKey, it must be +** discarded. ^Any prior cache entry associated with newKey is guaranteed not +** to be pinned. +** +** When SQLite calls the xTruncate() method, the cache must discard all +** existing cache entries with page numbers (keys) greater than or equal +** to the value of the iLimit parameter passed to xTruncate(). If any +** of these pages are pinned, they are implicitly unpinned, meaning that +** they can be safely discarded. +** +** [[the xDestroy() page cache method]] +** ^The xDestroy() method is used to delete a cache allocated by xCreate(). +** All resources associated with the specified cache should be freed. ^After +** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*] +** handle invalid, and will not use it with any other sqlite3_pcache_methods2 +** functions. +** +** [[the xShrink() page cache method]] +** ^SQLite invokes the xShrink() method when it wants the page cache to +** free up as much of heap memory as possible. The page cache implementation +** is not obligated to free any memory, but well-behaved implementations should +** do their best. +*/ +typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2; +struct sqlite3_pcache_methods2 { + int iVersion; + void *pArg; + int (*xInit)(void*); + void (*xShutdown)(void*); + sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard); + void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, + unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); + void (*xShrink)(sqlite3_pcache*); +}; + +/* +** This is the obsolete pcache_methods object that has now been replaced +** by sqlite3_pcache_methods2. This object is not used by SQLite. It is +** retained in the header file for backwards compatibility only. +*/ +typedef struct sqlite3_pcache_methods sqlite3_pcache_methods; +struct sqlite3_pcache_methods { + void *pArg; + int (*xInit)(void*); + void (*xShutdown)(void*); + sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + void *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, void*, int discard); + void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); +}; + + +/* +** CAPI3REF: Online Backup Object +** +** The sqlite3_backup object records state information about an ongoing +** online backup operation. ^The sqlite3_backup object is created by +** a call to [sqlite3_backup_init()] and is destroyed by a call to +** [sqlite3_backup_finish()]. +** +** See Also: [Using the SQLite Online Backup API] +*/ +typedef struct sqlite3_backup sqlite3_backup; + +/* +** CAPI3REF: Online Backup API. +** +** The backup API copies the content of one database into another. +** It is useful either for creating backups of databases or +** for copying in-memory databases to or from persistent files. +** +** See Also: [Using the SQLite Online Backup API] +** +** ^SQLite holds a write transaction open on the destination database file +** for the duration of the backup operation. +** ^The source database is read-locked only while it is being read; +** it is not locked continuously for the entire backup operation. +** ^Thus, the backup may be performed on a live source database without +** preventing other database connections from +** reading or writing to the source database while the backup is underway. +** +** ^(To perform a backup operation: +**
      +**
    1. sqlite3_backup_init() is called once to initialize the +** backup, +**
    2. sqlite3_backup_step() is called one or more times to transfer +** the data between the two databases, and finally +**
    3. sqlite3_backup_finish() is called to release all resources +** associated with the backup operation. +**
    )^ +** There should be exactly one call to sqlite3_backup_finish() for each +** successful call to sqlite3_backup_init(). +** +** [[sqlite3_backup_init()]] sqlite3_backup_init() +** +** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the +** [database connection] associated with the destination database +** and the database name, respectively. +** ^The database name is "main" for the main database, "temp" for the +** temporary database, or the name specified after the AS keyword in +** an [ATTACH] statement for an attached database. +** ^The S and M arguments passed to +** sqlite3_backup_init(D,N,S,M) identify the [database connection] +** and database name of the source database, respectively. +** ^The source and destination [database connections] (parameters S and D) +** must be different or else sqlite3_backup_init(D,N,S,M) will fail with +** an error. +** +** ^A call to sqlite3_backup_init() will fail, returning SQLITE_ERROR, if +** there is already a read or read-write transaction open on the +** destination database. +** +** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is +** returned and an error code and error message are stored in the +** destination [database connection] D. +** ^The error code and message for the failed call to sqlite3_backup_init() +** can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or +** [sqlite3_errmsg16()] functions. +** ^A successful call to sqlite3_backup_init() returns a pointer to an +** [sqlite3_backup] object. +** ^The [sqlite3_backup] object may be used with the sqlite3_backup_step() and +** sqlite3_backup_finish() functions to perform the specified backup +** operation. +** +** [[sqlite3_backup_step()]] sqlite3_backup_step() +** +** ^Function sqlite3_backup_step(B,N) will copy up to N pages between +** the source and destination databases specified by [sqlite3_backup] object B. +** ^If N is negative, all remaining source pages are copied. +** ^If sqlite3_backup_step(B,N) successfully copies N pages and there +** are still more pages to be copied, then the function returns [SQLITE_OK]. +** ^If sqlite3_backup_step(B,N) successfully finishes copying all pages +** from source to destination, then it returns [SQLITE_DONE]. +** ^If an error occurs while running sqlite3_backup_step(B,N), +** then an [error code] is returned. ^As well as [SQLITE_OK] and +** [SQLITE_DONE], a call to sqlite3_backup_step() may return [SQLITE_READONLY], +** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an +** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code. +** +** ^(The sqlite3_backup_step() might return [SQLITE_READONLY] if +**
      +**
    1. the destination database was opened read-only, or +**
    2. the destination database is using write-ahead-log journaling +** and the destination and source page sizes differ, or +**
    3. the destination database is an in-memory database and the +** destination and source page sizes differ. +**
    )^ +** +** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then +** the [sqlite3_busy_handler | busy-handler function] +** is invoked (if one is specified). ^If the +** busy-handler returns non-zero before the lock is available, then +** [SQLITE_BUSY] is returned to the caller. ^In this case the call to +** sqlite3_backup_step() can be retried later. ^If the source +** [database connection] +** is being used to write to the source database when sqlite3_backup_step() +** is called, then [SQLITE_LOCKED] is returned immediately. ^Again, in this +** case the call to sqlite3_backup_step() can be retried later on. ^(If +** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or +** [SQLITE_READONLY] is returned, then +** there is no point in retrying the call to sqlite3_backup_step(). These +** errors are considered fatal.)^ The application must accept +** that the backup operation has failed and pass the backup operation handle +** to the sqlite3_backup_finish() to release associated resources. +** +** ^The first call to sqlite3_backup_step() obtains an exclusive lock +** on the destination file. ^The exclusive lock is not released until either +** sqlite3_backup_finish() is called or the backup operation is complete +** and sqlite3_backup_step() returns [SQLITE_DONE]. ^Every call to +** sqlite3_backup_step() obtains a [shared lock] on the source database that +** lasts for the duration of the sqlite3_backup_step() call. +** ^Because the source database is not locked between calls to +** sqlite3_backup_step(), the source database may be modified mid-way +** through the backup process. ^If the source database is modified by an +** external process or via a database connection other than the one being +** used by the backup operation, then the backup will be automatically +** restarted by the next call to sqlite3_backup_step(). ^If the source +** database is modified by the using the same database connection as is used +** by the backup operation, then the backup database is automatically +** updated at the same time. +** +** [[sqlite3_backup_finish()]] sqlite3_backup_finish() +** +** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the +** application wishes to abandon the backup operation, the application +** should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish(). +** ^The sqlite3_backup_finish() interfaces releases all +** resources associated with the [sqlite3_backup] object. +** ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any +** active write-transaction on the destination database is rolled back. +** The [sqlite3_backup] object is invalid +** and may not be used following a call to sqlite3_backup_finish(). +** +** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no +** sqlite3_backup_step() errors occurred, regardless or whether or not +** sqlite3_backup_step() completed. +** ^If an out-of-memory condition or IO error occurred during any prior +** sqlite3_backup_step() call on the same [sqlite3_backup] object, then +** sqlite3_backup_finish() returns the corresponding [error code]. +** +** ^A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from sqlite3_backup_step() +** is not a permanent error and does not affect the return value of +** sqlite3_backup_finish(). +** +** [[sqlite3_backup_remaining()]] [[sqlite3_backup_pagecount()]] +** sqlite3_backup_remaining() and sqlite3_backup_pagecount() +** +** ^The sqlite3_backup_remaining() routine returns the number of pages still +** to be backed up at the conclusion of the most recent sqlite3_backup_step(). +** ^The sqlite3_backup_pagecount() routine returns the total number of pages +** in the source database at the conclusion of the most recent +** sqlite3_backup_step(). +** ^(The values returned by these functions are only updated by +** sqlite3_backup_step(). If the source database is modified in a way that +** changes the size of the source database or the number of pages remaining, +** those changes are not reflected in the output of sqlite3_backup_pagecount() +** and sqlite3_backup_remaining() until after the next +** sqlite3_backup_step().)^ +** +** Concurrent Usage of Database Handles +** +** ^The source [database connection] may be used by the application for other +** purposes while a backup operation is underway or being initialized. +** ^If SQLite is compiled and configured to support threadsafe database +** connections, then the source database connection may be used concurrently +** from within other threads. +** +** However, the application must guarantee that the destination +** [database connection] is not passed to any other API (by any thread) after +** sqlite3_backup_init() is called and before the corresponding call to +** sqlite3_backup_finish(). SQLite does not currently check to see +** if the application incorrectly accesses the destination [database connection] +** and so no error code is reported, but the operations may malfunction +** nevertheless. Use of the destination database connection while a +** backup is in progress might also also cause a mutex deadlock. +** +** If running in [shared cache mode], the application must +** guarantee that the shared cache used by the destination database +** is not accessed while the backup is running. In practice this means +** that the application must guarantee that the disk file being +** backed up to is not accessed by any connection within the process, +** not just the specific connection that was passed to sqlite3_backup_init(). +** +** The [sqlite3_backup] object itself is partially threadsafe. Multiple +** threads may safely make multiple concurrent calls to sqlite3_backup_step(). +** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount() +** APIs are not strictly speaking threadsafe. If they are invoked at the +** same time as another thread is invoking sqlite3_backup_step() it is +** possible that they return invalid values. +*/ +SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init( + sqlite3 *pDest, /* Destination database handle */ + const char *zDestName, /* Destination database name */ + sqlite3 *pSource, /* Source database handle */ + const char *zSourceName /* Source database name */ +); +SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage); +SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p); +SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p); +SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p); + +/* +** CAPI3REF: Unlock Notification +** METHOD: sqlite3 +** +** ^When running in shared-cache mode, a database operation may fail with +** an [SQLITE_LOCKED] error if the required locks on the shared-cache or +** individual tables within the shared-cache cannot be obtained. See +** [SQLite Shared-Cache Mode] for a description of shared-cache locking. +** ^This API may be used to register a callback that SQLite will invoke +** when the connection currently holding the required lock relinquishes it. +** ^This API is only available if the library was compiled with the +** [SQLITE_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined. +** +** See Also: [Using the SQLite Unlock Notification Feature]. +** +** ^Shared-cache locks are released when a database connection concludes +** its current transaction, either by committing it or rolling it back. +** +** ^When a connection (known as the blocked connection) fails to obtain a +** shared-cache lock and SQLITE_LOCKED is returned to the caller, the +** identity of the database connection (the blocking connection) that +** has locked the required resource is stored internally. ^After an +** application receives an SQLITE_LOCKED error, it may call the +** sqlite3_unlock_notify() method with the blocked connection handle as +** the first argument to register for a callback that will be invoked +** when the blocking connections current transaction is concluded. ^The +** callback is invoked from within the [sqlite3_step] or [sqlite3_close] +** call that concludes the blocking connections transaction. +** +** ^(If sqlite3_unlock_notify() is called in a multi-threaded application, +** there is a chance that the blocking connection will have already +** concluded its transaction by the time sqlite3_unlock_notify() is invoked. +** If this happens, then the specified callback is invoked immediately, +** from within the call to sqlite3_unlock_notify().)^ +** +** ^If the blocked connection is attempting to obtain a write-lock on a +** shared-cache table, and more than one other connection currently holds +** a read-lock on the same table, then SQLite arbitrarily selects one of +** the other connections to use as the blocking connection. +** +** ^(There may be at most one unlock-notify callback registered by a +** blocked connection. If sqlite3_unlock_notify() is called when the +** blocked connection already has a registered unlock-notify callback, +** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is +** called with a NULL pointer as its second argument, then any existing +** unlock-notify callback is canceled. ^The blocked connections +** unlock-notify callback may also be canceled by closing the blocked +** connection using [sqlite3_close()]. +** +** The unlock-notify callback is not reentrant. If an application invokes +** any sqlite3_xxx API functions from within an unlock-notify callback, a +** crash or deadlock may be the result. +** +** ^Unless deadlock is detected (see below), sqlite3_unlock_notify() always +** returns SQLITE_OK. +** +** Callback Invocation Details +** +** When an unlock-notify callback is registered, the application provides a +** single void* pointer that is passed to the callback when it is invoked. +** However, the signature of the callback function allows SQLite to pass +** it an array of void* context pointers. The first argument passed to +** an unlock-notify callback is a pointer to an array of void* pointers, +** and the second is the number of entries in the array. +** +** When a blocking connections transaction is concluded, there may be +** more than one blocked connection that has registered for an unlock-notify +** callback. ^If two or more such blocked connections have specified the +** same callback function, then instead of invoking the callback function +** multiple times, it is invoked once with the set of void* context pointers +** specified by the blocked connections bundled together into an array. +** This gives the application an opportunity to prioritize any actions +** related to the set of unblocked database connections. +** +** Deadlock Detection +** +** Assuming that after registering for an unlock-notify callback a +** database waits for the callback to be issued before taking any further +** action (a reasonable assumption), then using this API may cause the +** application to deadlock. For example, if connection X is waiting for +** connection Y's transaction to be concluded, and similarly connection +** Y is waiting on connection X's transaction, then neither connection +** will proceed and the system may remain deadlocked indefinitely. +** +** To avoid this scenario, the sqlite3_unlock_notify() performs deadlock +** detection. ^If a given call to sqlite3_unlock_notify() would put the +** system in a deadlocked state, then SQLITE_LOCKED is returned and no +** unlock-notify callback is registered. The system is said to be in +** a deadlocked state if connection A has registered for an unlock-notify +** callback on the conclusion of connection B's transaction, and connection +** B has itself registered for an unlock-notify callback when connection +** A's transaction is concluded. ^Indirect deadlock is also detected, so +** the system is also considered to be deadlocked if connection B has +** registered for an unlock-notify callback on the conclusion of connection +** C's transaction, where connection C is waiting on connection A. ^Any +** number of levels of indirection are allowed. +** +** The "DROP TABLE" Exception +** +** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost +** always appropriate to call sqlite3_unlock_notify(). There is however, +** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement, +** SQLite checks if there are any currently executing SELECT statements +** that belong to the same connection. If there are, SQLITE_LOCKED is +** returned. In this case there is no "blocking connection", so invoking +** sqlite3_unlock_notify() results in the unlock-notify callback being +** invoked immediately. If the application then re-attempts the "DROP TABLE" +** or "DROP INDEX" query, an infinite loop might be the result. +** +** One way around this problem is to check the extended error code returned +** by an sqlite3_step() call. ^(If there is a blocking connection, then the +** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in +** the special "DROP TABLE/INDEX" case, the extended error code is just +** SQLITE_LOCKED.)^ +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify( + sqlite3 *pBlocked, /* Waiting connection */ + void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */ + void *pNotifyArg /* Argument to pass to xNotify */ +); + + +/* +** CAPI3REF: String Comparison +** +** ^The [sqlite3_stricmp()] and [sqlite3_strnicmp()] APIs allow applications +** and extensions to compare the contents of two buffers containing UTF-8 +** strings in a case-independent fashion, using the same definition of "case +** independence" that SQLite uses internally when comparing identifiers. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *, const char *); +SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *, const char *, int); + +/* +** CAPI3REF: String Globbing +* +** ^The [sqlite3_strglob(P,X)] interface returns zero if string X matches +** the glob pattern P, and it returns non-zero if string X does not match +** the glob pattern P. ^The definition of glob pattern matching used in +** [sqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the +** SQL dialect used by SQLite. ^The sqlite3_strglob(P,X) function is case +** sensitive. +** +** Note that this routine returns zero on a match and non-zero if the strings +** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlob, const char *zStr); + +/* +** CAPI3REF: Error Logging Interface +** +** ^The [sqlite3_log()] interface writes a message into the [error log] +** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()]. +** ^If logging is enabled, the zFormat string and subsequent arguments are +** used with [sqlite3_snprintf()] to generate the final output string. +** +** The sqlite3_log() interface is intended for use by extensions such as +** virtual tables, collating functions, and SQL functions. While there is +** nothing to prevent an application from calling sqlite3_log(), doing so +** is considered bad form. +** +** The zFormat string must not be NULL. +** +** To avoid deadlocks and other threading problems, the sqlite3_log() routine +** will not use dynamically allocated memory. The log message is stored in +** a fixed-length buffer on the stack. If the log message is longer than +** a few hundred characters, it will be truncated to the length of the +** buffer. +*/ +SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...); + +/* +** CAPI3REF: Write-Ahead Log Commit Hook +** METHOD: sqlite3 +** +** ^The [sqlite3_wal_hook()] function is used to register a callback that +** is invoked each time data is committed to a database in wal mode. +** +** ^(The callback is invoked by SQLite after the commit has taken place and +** the associated write-lock on the database released)^, so the implementation +** may read, write or [checkpoint] the database as required. +** +** ^The first parameter passed to the callback function when it is invoked +** is a copy of the third parameter passed to sqlite3_wal_hook() when +** registering the callback. ^The second is a copy of the database handle. +** ^The third parameter is the name of the database that was written to - +** either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter +** is the number of pages currently in the write-ahead log file, +** including those that were just committed. +** +** The callback function should normally return [SQLITE_OK]. ^If an error +** code is returned, that error will propagate back up through the +** SQLite code base to cause the statement that provoked the callback +** to report an error, though the commit will have still occurred. If the +** callback returns [SQLITE_ROW] or [SQLITE_DONE], or if it returns a value +** that does not correspond to any valid SQLite error code, the results +** are undefined. +** +** A single database handle may have at most a single write-ahead log callback +** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any +** previously registered write-ahead log callback. ^Note that the +** [sqlite3_wal_autocheckpoint()] interface and the +** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will +** those overwrite any prior [sqlite3_wal_hook()] settings. +*/ +SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook( + sqlite3*, + int(*)(void *,sqlite3*,const char*,int), + void* +); + +/* +** CAPI3REF: Configure an auto-checkpoint +** METHOD: sqlite3 +** +** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around +** [sqlite3_wal_hook()] that causes any database on [database connection] D +** to automatically [checkpoint] +** after committing a transaction if there are N or +** more frames in the [write-ahead log] file. ^Passing zero or +** a negative value as the nFrame parameter disables automatic +** checkpoints entirely. +** +** ^The callback registered by this function replaces any existing callback +** registered using [sqlite3_wal_hook()]. ^Likewise, registering a callback +** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism +** configured by this function. +** +** ^The [wal_autocheckpoint pragma] can be used to invoke this interface +** from SQL. +** +** ^Checkpoints initiated by this mechanism are +** [sqlite3_wal_checkpoint_v2|PASSIVE]. +** +** ^Every new [database connection] defaults to having the auto-checkpoint +** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] +** pages. The use of this interface +** is only necessary if the default setting is found to be suboptimal +** for a particular application. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int N); + +/* +** CAPI3REF: Checkpoint a database +** METHOD: sqlite3 +** +** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to +** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^ +** +** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the +** [write-ahead log] for database X on [database connection] D to be +** transferred into the database file and for the write-ahead log to +** be reset. See the [checkpointing] documentation for addition +** information. +** +** This interface used to be the only way to cause a checkpoint to +** occur. But then the newer and more powerful [sqlite3_wal_checkpoint_v2()] +** interface was added. This interface is retained for backwards +** compatibility and as a convenience for applications that need to manually +** start a callback but which do not need the full power (and corresponding +** complication) of [sqlite3_wal_checkpoint_v2()]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); + +/* +** CAPI3REF: Checkpoint a database +** METHOD: sqlite3 +** +** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint +** operation on database X of [database connection] D in mode M. Status +** information is written back into integers pointed to by L and C.)^ +** ^(The M parameter must be a valid [checkpoint mode]:)^ +** +**
    +**
    SQLITE_CHECKPOINT_PASSIVE
    +** ^Checkpoint as many frames as possible without waiting for any database +** readers or writers to finish, then sync the database file if all frames +** in the log were checkpointed. ^The [busy-handler callback] +** is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode. +** ^On the other hand, passive mode might leave the checkpoint unfinished +** if there are concurrent readers or writers. +** +**
    SQLITE_CHECKPOINT_FULL
    +** ^This mode blocks (it invokes the +** [sqlite3_busy_handler|busy-handler callback]) until there is no +** database writer and all readers are reading from the most recent database +** snapshot. ^It then checkpoints all frames in the log file and syncs the +** database file. ^This mode blocks new database writers while it is pending, +** but new database readers are allowed to continue unimpeded. +** +**
    SQLITE_CHECKPOINT_RESTART
    +** ^This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition +** that after checkpointing the log file it blocks (calls the +** [busy-handler callback]) +** until all readers are reading from the database file only. ^This ensures +** that the next writer will restart the log file from the beginning. +** ^Like SQLITE_CHECKPOINT_FULL, this mode blocks new +** database writer attempts while it is pending, but does not impede readers. +** +**
    SQLITE_CHECKPOINT_TRUNCATE
    +** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the +** addition that it also truncates the log file to zero bytes just prior +** to a successful return. +**
    +** +** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in +** the log file or to -1 if the checkpoint could not run because +** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not +** NULL,then *pnCkpt is set to the total number of checkpointed frames in the +** log file (including any that were already checkpointed before the function +** was called) or to -1 if the checkpoint could not run due to an error or +** because the database is not in WAL mode. ^Note that upon successful +** completion of an SQLITE_CHECKPOINT_TRUNCATE, the log file will have been +** truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero. +** +** ^All calls obtain an exclusive "checkpoint" lock on the database file. ^If +** any other process is running a checkpoint operation at the same time, the +** lock cannot be obtained and SQLITE_BUSY is returned. ^Even if there is a +** busy-handler configured, it will not be invoked in this case. +** +** ^The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the +** exclusive "writer" lock on the database file. ^If the writer lock cannot be +** obtained immediately, and a busy-handler is configured, it is invoked and +** the writer lock retried until either the busy-handler returns 0 or the lock +** is successfully obtained. ^The busy-handler is also invoked while waiting for +** database readers as described above. ^If the busy-handler returns 0 before +** the writer lock is obtained or while waiting for database readers, the +** checkpoint operation proceeds from that point in the same way as +** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible +** without blocking any further. ^SQLITE_BUSY is returned in this case. +** +** ^If parameter zDb is NULL or points to a zero length string, then the +** specified operation is attempted on all WAL databases [attached] to +** [database connection] db. In this case the +** values written to output parameters *pnLog and *pnCkpt are undefined. ^If +** an SQLITE_BUSY error is encountered when processing one or more of the +** attached WAL databases, the operation is still attempted on any remaining +** attached databases and SQLITE_BUSY is returned at the end. ^If any other +** error occurs while processing an attached database, processing is abandoned +** and the error code is returned to the caller immediately. ^If no error +** (SQLITE_BUSY or otherwise) is encountered while processing the attached +** databases, SQLITE_OK is returned. +** +** ^If database zDb is the name of an attached database that is not in WAL +** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. ^If +** zDb is not NULL (or a zero length string) and is not the name of any +** attached database, SQLITE_ERROR is returned to the caller. +** +** ^Unless it returns SQLITE_MISUSE, +** the sqlite3_wal_checkpoint_v2() interface +** sets the error information that is queried by +** [sqlite3_errcode()] and [sqlite3_errmsg()]. +** +** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface +** from SQL. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Name of attached database (or NULL) */ + int eMode, /* SQLITE_CHECKPOINT_* value */ + int *pnLog, /* OUT: Size of WAL log in frames */ + int *pnCkpt /* OUT: Total number of frames checkpointed */ +); + +/* +** CAPI3REF: Checkpoint Mode Values +** KEYWORDS: {checkpoint mode} +** +** These constants define all valid values for the "checkpoint mode" passed +** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface. +** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the +** meaning of each of these checkpoint modes. +*/ +#define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */ +#define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */ +#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for for readers */ +#define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */ + +/* +** CAPI3REF: Virtual Table Interface Configuration +** +** This function may be called by either the [xConnect] or [xCreate] method +** of a [virtual table] implementation to configure +** various facets of the virtual table interface. +** +** If this interface is invoked outside the context of an xConnect or +** xCreate virtual table method then the behavior is undefined. +** +** At present, there is only one option that may be configured using +** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options +** may be added in the future. +*/ +SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3*, int op, ...); + +/* +** CAPI3REF: Virtual Table Configuration Options +** +** These macros define the various options to the +** [sqlite3_vtab_config()] interface that [virtual table] implementations +** can use to customize and optimize their behavior. +** +**
    +**
    SQLITE_VTAB_CONSTRAINT_SUPPORT +**
    Calls of the form +** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported, +** where X is an integer. If X is zero, then the [virtual table] whose +** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not +** support constraints. In this configuration (which is the default) if +** a call to the [xUpdate] method returns [SQLITE_CONSTRAINT], then the entire +** statement is rolled back as if [ON CONFLICT | OR ABORT] had been +** specified as part of the users SQL statement, regardless of the actual +** ON CONFLICT mode specified. +** +** If X is non-zero, then the virtual table implementation guarantees +** that if [xUpdate] returns [SQLITE_CONSTRAINT], it will do so before +** any modifications to internal or persistent data structures have been made. +** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite +** is able to roll back a statement or database transaction, and abandon +** or continue processing the current SQL statement as appropriate. +** If the ON CONFLICT mode is REPLACE and the [xUpdate] method returns +** [SQLITE_CONSTRAINT], SQLite handles this as if the ON CONFLICT mode +** had been ABORT. +** +** Virtual table implementations that are required to handle OR REPLACE +** must do so within the [xUpdate] method. If a call to the +** [sqlite3_vtab_on_conflict()] function indicates that the current ON +** CONFLICT policy is REPLACE, the virtual table implementation should +** silently replace the appropriate rows within the xUpdate callback and +** return SQLITE_OK. Or, if this is not possible, it may return +** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT +** constraint handling. +**
    +*/ +#define SQLITE_VTAB_CONSTRAINT_SUPPORT 1 + +/* +** CAPI3REF: Determine The Virtual Table Conflict Policy +** +** This function may only be called from within a call to the [xUpdate] method +** of a [virtual table] implementation for an INSERT or UPDATE operation. ^The +** value returned is one of [SQLITE_ROLLBACK], [SQLITE_IGNORE], [SQLITE_FAIL], +** [SQLITE_ABORT], or [SQLITE_REPLACE], according to the [ON CONFLICT] mode +** of the SQL statement that triggered the call to the [xUpdate] method of the +** [virtual table]. +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *); + +/* +** CAPI3REF: Conflict resolution modes +** KEYWORDS: {conflict resolution mode} +** +** These constants are returned by [sqlite3_vtab_on_conflict()] to +** inform a [virtual table] implementation what the [ON CONFLICT] mode +** is for the SQL statement being evaluated. +** +** Note that the [SQLITE_IGNORE] constant is also used as a potential +** return value from the [sqlite3_set_authorizer()] callback and that +** [SQLITE_ABORT] is also a [result code]. +*/ +#define SQLITE_ROLLBACK 1 +/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */ +#define SQLITE_FAIL 3 +/* #define SQLITE_ABORT 4 // Also an error code */ +#define SQLITE_REPLACE 5 + +/* +** CAPI3REF: Prepared Statement Scan Status Opcodes +** KEYWORDS: {scanstatus options} +** +** The following constants can be used for the T parameter to the +** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a +** different metric for sqlite3_stmt_scanstatus() to return. +** +** When the value returned to V is a string, space to hold that string is +** managed by the prepared statement S and will be automatically freed when +** S is finalized. +** +**
    +** [[SQLITE_SCANSTAT_NLOOP]]
    SQLITE_SCANSTAT_NLOOP
    +**
    ^The [sqlite3_int64] variable pointed to by the T parameter will be +** set to the total number of times that the X-th loop has run.
    +** +** [[SQLITE_SCANSTAT_NVISIT]]
    SQLITE_SCANSTAT_NVISIT
    +**
    ^The [sqlite3_int64] variable pointed to by the T parameter will be set +** to the total number of rows examined by all iterations of the X-th loop.
    +** +** [[SQLITE_SCANSTAT_EST]]
    SQLITE_SCANSTAT_EST
    +**
    ^The "double" variable pointed to by the T parameter will be set to the +** query planner's estimate for the average number of rows output from each +** iteration of the X-th loop. If the query planner's estimates was accurate, +** then this value will approximate the quotient NVISIT/NLOOP and the +** product of this value for all prior loops with the same SELECTID will +** be the NLOOP value for the current loop. +** +** [[SQLITE_SCANSTAT_NAME]]
    SQLITE_SCANSTAT_NAME
    +**
    ^The "const char *" variable pointed to by the T parameter will be set +** to a zero-terminated UTF-8 string containing the name of the index or table +** used for the X-th loop. +** +** [[SQLITE_SCANSTAT_EXPLAIN]]
    SQLITE_SCANSTAT_EXPLAIN
    +**
    ^The "const char *" variable pointed to by the T parameter will be set +** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] +** description for the X-th loop. +** +** [[SQLITE_SCANSTAT_SELECTID]]
    SQLITE_SCANSTAT_SELECT
    +**
    ^The "int" variable pointed to by the T parameter will be set to the +** "select-id" for the X-th loop. The select-id identifies which query or +** subquery the loop is part of. The main query has a select-id of zero. +** The select-id is the same value as is output in the first column +** of an [EXPLAIN QUERY PLAN] query. +**
    +*/ +#define SQLITE_SCANSTAT_NLOOP 0 +#define SQLITE_SCANSTAT_NVISIT 1 +#define SQLITE_SCANSTAT_EST 2 +#define SQLITE_SCANSTAT_NAME 3 +#define SQLITE_SCANSTAT_EXPLAIN 4 +#define SQLITE_SCANSTAT_SELECTID 5 + +/* +** CAPI3REF: Prepared Statement Scan Status +** METHOD: sqlite3_stmt +** +** This interface returns information about the predicted and measured +** performance for pStmt. Advanced applications can use this +** interface to compare the predicted and the measured performance and +** issue warnings and/or rerun [ANALYZE] if discrepancies are found. +** +** Since this interface is expected to be rarely used, it is only +** available if SQLite is compiled using the [SQLITE_ENABLE_STMT_SCANSTATUS] +** compile-time option. +** +** The "iScanStatusOp" parameter determines which status information to return. +** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior +** of this interface is undefined. +** ^The requested measurement is written into a variable pointed to by +** the "pOut" parameter. +** Parameter "idx" identifies the specific loop to retrieve statistics for. +** Loops are numbered starting from zero. ^If idx is out of range - less than +** zero or greater than or equal to the total number of loops used to implement +** the statement - a non-zero value is returned and the variable that pOut +** points to is unchanged. +** +** ^Statistics might not be available for all loops in all statements. ^In cases +** where there exist loops with no available statistics, this function behaves +** as if the loop did not exist - it returns non-zero and leave the variable +** that pOut points to unchanged. +** +** See also: [sqlite3_stmt_scanstatus_reset()] +*/ +SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_stmt_scanstatus( + sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ + int idx, /* Index of loop to report on */ + int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ + void *pOut /* Result written here */ +); + +/* +** CAPI3REF: Zero Scan-Status Counters +** METHOD: sqlite3_stmt +** +** ^Zero all [sqlite3_stmt_scanstatus()] related event counters. +** +** This API is only available if the library is built with pre-processor +** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined. +*/ +SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); + + +/* +** 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 /* _SQLITE3_H_ */ + +/* +** 2010 August 30 +** +** 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. +** +************************************************************************* +*/ + +#ifndef _SQLITE3RTREE_H_ +#define _SQLITE3RTREE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry; +typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info; + +/* The double-precision datatype used by RTree depends on the +** SQLITE_RTREE_INT_ONLY compile-time option. +*/ +#ifdef SQLITE_RTREE_INT_ONLY + typedef sqlite3_int64 sqlite3_rtree_dbl; +#else + typedef double sqlite3_rtree_dbl; +#endif + +/* +** Register a geometry callback named zGeom that can be used as part of an +** R-Tree geometry query as follows: +** +** SELECT ... FROM WHERE MATCH $zGeom(... params ...) +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback( + sqlite3 *db, + const char *zGeom, + int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*), + void *pContext +); + + +/* +** A pointer to a structure of the following type is passed as the first +** argument to callbacks registered using rtree_geometry_callback(). +*/ +struct sqlite3_rtree_geometry { + void *pContext; /* Copy of pContext passed to s_r_g_c() */ + int nParam; /* Size of array aParam[] */ + sqlite3_rtree_dbl *aParam; /* Parameters passed to SQL geom function */ + void *pUser; /* Callback implementation user data */ + void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */ +}; + +/* +** Register a 2nd-generation geometry callback named zScore that can be +** used as part of an R-Tree geometry query as follows: +** +** SELECT ... FROM WHERE MATCH $zQueryFunc(... params ...) +*/ +SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback( + sqlite3 *db, + const char *zQueryFunc, + int (*xQueryFunc)(sqlite3_rtree_query_info*), + void *pContext, + void (*xDestructor)(void*) +); + + +/* +** A pointer to a structure of the following type is passed as the +** argument to scored geometry callback registered using +** sqlite3_rtree_query_callback(). +** +** Note that the first 5 fields of this structure are identical to +** sqlite3_rtree_geometry. This structure is a subclass of +** sqlite3_rtree_geometry. +*/ +struct sqlite3_rtree_query_info { + void *pContext; /* pContext from when function registered */ + int nParam; /* Number of function parameters */ + sqlite3_rtree_dbl *aParam; /* value of function parameters */ + void *pUser; /* callback can use this, if desired */ + void (*xDelUser)(void*); /* function to free pUser */ + sqlite3_rtree_dbl *aCoord; /* Coordinates of node or entry to check */ + unsigned int *anQueue; /* Number of pending entries in the queue */ + int nCoord; /* Number of coordinates */ + int iLevel; /* Level of current node or entry */ + int mxLevel; /* The largest iLevel value in the tree */ + sqlite3_int64 iRowid; /* Rowid for current entry */ + sqlite3_rtree_dbl rParentScore; /* Score of parent node */ + int eParentWithin; /* Visibility of parent node */ + int eWithin; /* OUT: Visiblity */ + sqlite3_rtree_dbl rScore; /* OUT: Write the score here */ +}; + +/* +** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin. +*/ +#define NOT_WITHIN 0 /* Object completely outside of query region */ +#define PARTLY_WITHIN 1 /* Object partially overlaps query region */ +#define FULLY_WITHIN 2 /* Object fully contained within query region */ + + +#ifdef __cplusplus +} /* end of the 'extern "C"' block */ +#endif + +#endif /* ifndef _SQLITE3RTREE_H_ */ + diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h new file mode 100644 index 0000000..f9a0665 --- /dev/null +++ b/src/sqlite3ext.h @@ -0,0 +1,517 @@ +/* +** 2006 June 7 +** +** 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 the SQLite interface for use by +** shared libraries that want to be imported as extensions into +** an SQLite instance. Shared libraries that intend to be loaded +** as extensions by SQLite should #include this file instead of +** sqlite3.h. +*/ +#ifndef _SQLITE3EXT_H_ +#define _SQLITE3EXT_H_ +#include "sqlite3.h" + +typedef struct sqlite3_api_routines sqlite3_api_routines; + +/* +** The following structure holds pointers to all of the SQLite API +** routines. +** +** WARNING: In order to maintain backwards compatibility, add new +** interfaces to the end of this structure only. If you insert new +** interfaces in the middle of this structure, then older different +** versions of SQLite will not be able to load each other's shared +** libraries! +*/ +struct sqlite3_api_routines { + void * (*aggregate_context)(sqlite3_context*,int nBytes); + int (*aggregate_count)(sqlite3_context*); + int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*)); + int (*bind_double)(sqlite3_stmt*,int,double); + int (*bind_int)(sqlite3_stmt*,int,int); + int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64); + int (*bind_null)(sqlite3_stmt*,int); + int (*bind_parameter_count)(sqlite3_stmt*); + int (*bind_parameter_index)(sqlite3_stmt*,const char*zName); + const char * (*bind_parameter_name)(sqlite3_stmt*,int); + int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*)); + int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*)); + int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*); + int (*busy_handler)(sqlite3*,int(*)(void*,int),void*); + int (*busy_timeout)(sqlite3*,int ms); + int (*changes)(sqlite3*); + int (*close)(sqlite3*); + int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*, + int eTextRep,const char*)); + int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*, + int eTextRep,const void*)); + const void * (*column_blob)(sqlite3_stmt*,int iCol); + int (*column_bytes)(sqlite3_stmt*,int iCol); + int (*column_bytes16)(sqlite3_stmt*,int iCol); + int (*column_count)(sqlite3_stmt*pStmt); + const char * (*column_database_name)(sqlite3_stmt*,int); + const void * (*column_database_name16)(sqlite3_stmt*,int); + const char * (*column_decltype)(sqlite3_stmt*,int i); + const void * (*column_decltype16)(sqlite3_stmt*,int); + double (*column_double)(sqlite3_stmt*,int iCol); + int (*column_int)(sqlite3_stmt*,int iCol); + sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol); + const char * (*column_name)(sqlite3_stmt*,int); + const void * (*column_name16)(sqlite3_stmt*,int); + const char * (*column_origin_name)(sqlite3_stmt*,int); + const void * (*column_origin_name16)(sqlite3_stmt*,int); + const char * (*column_table_name)(sqlite3_stmt*,int); + const void * (*column_table_name16)(sqlite3_stmt*,int); + const unsigned char * (*column_text)(sqlite3_stmt*,int iCol); + const void * (*column_text16)(sqlite3_stmt*,int iCol); + int (*column_type)(sqlite3_stmt*,int iCol); + sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol); + void * (*commit_hook)(sqlite3*,int(*)(void*),void*); + int (*complete)(const char*sql); + int (*complete16)(const void*sql); + int (*create_collation)(sqlite3*,const char*,int,void*, + int(*)(void*,int,const void*,int,const void*)); + int (*create_collation16)(sqlite3*,const void*,int,void*, + int(*)(void*,int,const void*,int,const void*)); + int (*create_function)(sqlite3*,const char*,int,int,void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*)); + int (*create_function16)(sqlite3*,const void*,int,int,void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*)); + int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*); + int (*data_count)(sqlite3_stmt*pStmt); + sqlite3 * (*db_handle)(sqlite3_stmt*); + int (*declare_vtab)(sqlite3*,const char*); + int (*enable_shared_cache)(int); + int (*errcode)(sqlite3*db); + const char * (*errmsg)(sqlite3*); + const void * (*errmsg16)(sqlite3*); + int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**); + int (*expired)(sqlite3_stmt*); + int (*finalize)(sqlite3_stmt*pStmt); + void (*free)(void*); + void (*free_table)(char**result); + int (*get_autocommit)(sqlite3*); + void * (*get_auxdata)(sqlite3_context*,int); + int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**); + int (*global_recover)(void); + void (*interruptx)(sqlite3*); + sqlite_int64 (*last_insert_rowid)(sqlite3*); + const char * (*libversion)(void); + int (*libversion_number)(void); + void *(*malloc)(int); + char * (*mprintf)(const char*,...); + int (*open)(const char*,sqlite3**); + int (*open16)(const void*,sqlite3**); + int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); + int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); + void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*); + void (*progress_handler)(sqlite3*,int,int(*)(void*),void*); + void *(*realloc)(void*,int); + int (*reset)(sqlite3_stmt*pStmt); + void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_double)(sqlite3_context*,double); + void (*result_error)(sqlite3_context*,const char*,int); + void (*result_error16)(sqlite3_context*,const void*,int); + void (*result_int)(sqlite3_context*,int); + void (*result_int64)(sqlite3_context*,sqlite_int64); + void (*result_null)(sqlite3_context*); + void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*)); + void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_value)(sqlite3_context*,sqlite3_value*); + void * (*rollback_hook)(sqlite3*,void(*)(void*),void*); + int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*, + const char*,const char*),void*); + void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*)); + char * (*snprintf)(int,char*,const char*,...); + int (*step)(sqlite3_stmt*); + int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*, + char const**,char const**,int*,int*,int*); + void (*thread_cleanup)(void); + int (*total_changes)(sqlite3*); + void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*); + int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*); + void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*, + sqlite_int64),void*); + void * (*user_data)(sqlite3_context*); + const void * (*value_blob)(sqlite3_value*); + int (*value_bytes)(sqlite3_value*); + int (*value_bytes16)(sqlite3_value*); + double (*value_double)(sqlite3_value*); + int (*value_int)(sqlite3_value*); + sqlite_int64 (*value_int64)(sqlite3_value*); + int (*value_numeric_type)(sqlite3_value*); + const unsigned char * (*value_text)(sqlite3_value*); + const void * (*value_text16)(sqlite3_value*); + const void * (*value_text16be)(sqlite3_value*); + const void * (*value_text16le)(sqlite3_value*); + int (*value_type)(sqlite3_value*); + char *(*vmprintf)(const char*,va_list); + /* Added ??? */ + int (*overload_function)(sqlite3*, const char *zFuncName, int nArg); + /* Added by 3.3.13 */ + int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); + int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); + int (*clear_bindings)(sqlite3_stmt*); + /* Added by 3.4.1 */ + int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*, + void (*xDestroy)(void *)); + /* Added by 3.5.0 */ + int (*bind_zeroblob)(sqlite3_stmt*,int,int); + int (*blob_bytes)(sqlite3_blob*); + int (*blob_close)(sqlite3_blob*); + int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64, + int,sqlite3_blob**); + int (*blob_read)(sqlite3_blob*,void*,int,int); + int (*blob_write)(sqlite3_blob*,const void*,int,int); + int (*create_collation_v2)(sqlite3*,const char*,int,void*, + int(*)(void*,int,const void*,int,const void*), + void(*)(void*)); + int (*file_control)(sqlite3*,const char*,int,void*); + sqlite3_int64 (*memory_highwater)(int); + sqlite3_int64 (*memory_used)(void); + sqlite3_mutex *(*mutex_alloc)(int); + void (*mutex_enter)(sqlite3_mutex*); + void (*mutex_free)(sqlite3_mutex*); + void (*mutex_leave)(sqlite3_mutex*); + int (*mutex_try)(sqlite3_mutex*); + int (*open_v2)(const char*,sqlite3**,int,const char*); + int (*release_memory)(int); + void (*result_error_nomem)(sqlite3_context*); + void (*result_error_toobig)(sqlite3_context*); + int (*sleep)(int); + void (*soft_heap_limit)(int); + sqlite3_vfs *(*vfs_find)(const char*); + int (*vfs_register)(sqlite3_vfs*,int); + int (*vfs_unregister)(sqlite3_vfs*); + int (*xthreadsafe)(void); + void (*result_zeroblob)(sqlite3_context*,int); + void (*result_error_code)(sqlite3_context*,int); + int (*test_control)(int, ...); + void (*randomness)(int,void*); + sqlite3 *(*context_db_handle)(sqlite3_context*); + int (*extended_result_codes)(sqlite3*,int); + int (*limit)(sqlite3*,int,int); + sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*); + const char *(*sql)(sqlite3_stmt*); + int (*status)(int,int*,int*,int); + int (*backup_finish)(sqlite3_backup*); + sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*); + int (*backup_pagecount)(sqlite3_backup*); + int (*backup_remaining)(sqlite3_backup*); + int (*backup_step)(sqlite3_backup*,int); + const char *(*compileoption_get)(int); + int (*compileoption_used)(const char*); + int (*create_function_v2)(sqlite3*,const char*,int,int,void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void(*xDestroy)(void*)); + int (*db_config)(sqlite3*,int,...); + sqlite3_mutex *(*db_mutex)(sqlite3*); + int (*db_status)(sqlite3*,int,int*,int*,int); + int (*extended_errcode)(sqlite3*); + void (*log)(int,const char*,...); + sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64); + const char *(*sourceid)(void); + int (*stmt_status)(sqlite3_stmt*,int,int); + int (*strnicmp)(const char*,const char*,int); + int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*); + int (*wal_autocheckpoint)(sqlite3*,int); + int (*wal_checkpoint)(sqlite3*,const char*); + void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*); + int (*blob_reopen)(sqlite3_blob*,sqlite3_int64); + int (*vtab_config)(sqlite3*,int op,...); + int (*vtab_on_conflict)(sqlite3*); + /* Version 3.7.16 and later */ + int (*close_v2)(sqlite3*); + const char *(*db_filename)(sqlite3*,const char*); + int (*db_readonly)(sqlite3*,const char*); + int (*db_release_memory)(sqlite3*); + const char *(*errstr)(int); + int (*stmt_busy)(sqlite3_stmt*); + int (*stmt_readonly)(sqlite3_stmt*); + int (*stricmp)(const char*,const char*); + int (*uri_boolean)(const char*,const char*,int); + sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64); + const char *(*uri_parameter)(const char*,const char*); + char *(*vsnprintf)(int,char*,const char*,va_list); + int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*); + /* Version 3.8.7 and later */ + int (*auto_extension)(void(*)(void)); + int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64, + void(*)(void*)); + int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64, + void(*)(void*),unsigned char); + int (*cancel_auto_extension)(void(*)(void)); + int (*load_extension)(sqlite3*,const char*,const char*,char**); + void *(*malloc64)(sqlite3_uint64); + sqlite3_uint64 (*msize)(void*); + void *(*realloc64)(void*,sqlite3_uint64); + void (*reset_auto_extension)(void); + void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64, + void(*)(void*)); + void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64, + void(*)(void*), unsigned char); + int (*strglob)(const char*,const char*); +}; + +/* +** The following macros redefine the API routines so that they are +** redirected through the global sqlite3_api structure. +** +** This header file is also used by the loadext.c source file +** (part of the main SQLite library - not an extension) so that +** it can get access to the sqlite3_api_routines structure +** definition. But the main library does not want to redefine +** the API. So the redefinition macros are only valid if the +** SQLITE_CORE macros is undefined. +*/ +#ifndef SQLITE_CORE +#define sqlite3_aggregate_context sqlite3_api->aggregate_context +#ifndef SQLITE_OMIT_DEPRECATED +#define sqlite3_aggregate_count sqlite3_api->aggregate_count +#endif +#define sqlite3_bind_blob sqlite3_api->bind_blob +#define sqlite3_bind_double sqlite3_api->bind_double +#define sqlite3_bind_int sqlite3_api->bind_int +#define sqlite3_bind_int64 sqlite3_api->bind_int64 +#define sqlite3_bind_null sqlite3_api->bind_null +#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count +#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index +#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name +#define sqlite3_bind_text sqlite3_api->bind_text +#define sqlite3_bind_text16 sqlite3_api->bind_text16 +#define sqlite3_bind_value sqlite3_api->bind_value +#define sqlite3_busy_handler sqlite3_api->busy_handler +#define sqlite3_busy_timeout sqlite3_api->busy_timeout +#define sqlite3_changes sqlite3_api->changes +#define sqlite3_close sqlite3_api->close +#define sqlite3_collation_needed sqlite3_api->collation_needed +#define sqlite3_collation_needed16 sqlite3_api->collation_needed16 +#define sqlite3_column_blob sqlite3_api->column_blob +#define sqlite3_column_bytes sqlite3_api->column_bytes +#define sqlite3_column_bytes16 sqlite3_api->column_bytes16 +#define sqlite3_column_count sqlite3_api->column_count +#define sqlite3_column_database_name sqlite3_api->column_database_name +#define sqlite3_column_database_name16 sqlite3_api->column_database_name16 +#define sqlite3_column_decltype sqlite3_api->column_decltype +#define sqlite3_column_decltype16 sqlite3_api->column_decltype16 +#define sqlite3_column_double sqlite3_api->column_double +#define sqlite3_column_int sqlite3_api->column_int +#define sqlite3_column_int64 sqlite3_api->column_int64 +#define sqlite3_column_name sqlite3_api->column_name +#define sqlite3_column_name16 sqlite3_api->column_name16 +#define sqlite3_column_origin_name sqlite3_api->column_origin_name +#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16 +#define sqlite3_column_table_name sqlite3_api->column_table_name +#define sqlite3_column_table_name16 sqlite3_api->column_table_name16 +#define sqlite3_column_text sqlite3_api->column_text +#define sqlite3_column_text16 sqlite3_api->column_text16 +#define sqlite3_column_type sqlite3_api->column_type +#define sqlite3_column_value sqlite3_api->column_value +#define sqlite3_commit_hook sqlite3_api->commit_hook +#define sqlite3_complete sqlite3_api->complete +#define sqlite3_complete16 sqlite3_api->complete16 +#define sqlite3_create_collation sqlite3_api->create_collation +#define sqlite3_create_collation16 sqlite3_api->create_collation16 +#define sqlite3_create_function sqlite3_api->create_function +#define sqlite3_create_function16 sqlite3_api->create_function16 +#define sqlite3_create_module sqlite3_api->create_module +#define sqlite3_create_module_v2 sqlite3_api->create_module_v2 +#define sqlite3_data_count sqlite3_api->data_count +#define sqlite3_db_handle sqlite3_api->db_handle +#define sqlite3_declare_vtab sqlite3_api->declare_vtab +#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache +#define sqlite3_errcode sqlite3_api->errcode +#define sqlite3_errmsg sqlite3_api->errmsg +#define sqlite3_errmsg16 sqlite3_api->errmsg16 +#define sqlite3_exec sqlite3_api->exec +#ifndef SQLITE_OMIT_DEPRECATED +#define sqlite3_expired sqlite3_api->expired +#endif +#define sqlite3_finalize sqlite3_api->finalize +#define sqlite3_free sqlite3_api->free +#define sqlite3_free_table sqlite3_api->free_table +#define sqlite3_get_autocommit sqlite3_api->get_autocommit +#define sqlite3_get_auxdata sqlite3_api->get_auxdata +#define sqlite3_get_table sqlite3_api->get_table +#ifndef SQLITE_OMIT_DEPRECATED +#define sqlite3_global_recover sqlite3_api->global_recover +#endif +#define sqlite3_interrupt sqlite3_api->interruptx +#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid +#define sqlite3_libversion sqlite3_api->libversion +#define sqlite3_libversion_number sqlite3_api->libversion_number +#define sqlite3_malloc sqlite3_api->malloc +#define sqlite3_mprintf sqlite3_api->mprintf +#define sqlite3_open sqlite3_api->open +#define sqlite3_open16 sqlite3_api->open16 +#define sqlite3_prepare sqlite3_api->prepare +#define sqlite3_prepare16 sqlite3_api->prepare16 +#define sqlite3_prepare_v2 sqlite3_api->prepare_v2 +#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 +#define sqlite3_profile sqlite3_api->profile +#define sqlite3_progress_handler sqlite3_api->progress_handler +#define sqlite3_realloc sqlite3_api->realloc +#define sqlite3_reset sqlite3_api->reset +#define sqlite3_result_blob sqlite3_api->result_blob +#define sqlite3_result_double sqlite3_api->result_double +#define sqlite3_result_error sqlite3_api->result_error +#define sqlite3_result_error16 sqlite3_api->result_error16 +#define sqlite3_result_int sqlite3_api->result_int +#define sqlite3_result_int64 sqlite3_api->result_int64 +#define sqlite3_result_null sqlite3_api->result_null +#define sqlite3_result_text sqlite3_api->result_text +#define sqlite3_result_text16 sqlite3_api->result_text16 +#define sqlite3_result_text16be sqlite3_api->result_text16be +#define sqlite3_result_text16le sqlite3_api->result_text16le +#define sqlite3_result_value sqlite3_api->result_value +#define sqlite3_rollback_hook sqlite3_api->rollback_hook +#define sqlite3_set_authorizer sqlite3_api->set_authorizer +#define sqlite3_set_auxdata sqlite3_api->set_auxdata +#define sqlite3_snprintf sqlite3_api->snprintf +#define sqlite3_step sqlite3_api->step +#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata +#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup +#define sqlite3_total_changes sqlite3_api->total_changes +#define sqlite3_trace sqlite3_api->trace +#ifndef SQLITE_OMIT_DEPRECATED +#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings +#endif +#define sqlite3_update_hook sqlite3_api->update_hook +#define sqlite3_user_data sqlite3_api->user_data +#define sqlite3_value_blob sqlite3_api->value_blob +#define sqlite3_value_bytes sqlite3_api->value_bytes +#define sqlite3_value_bytes16 sqlite3_api->value_bytes16 +#define sqlite3_value_double sqlite3_api->value_double +#define sqlite3_value_int sqlite3_api->value_int +#define sqlite3_value_int64 sqlite3_api->value_int64 +#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type +#define sqlite3_value_text sqlite3_api->value_text +#define sqlite3_value_text16 sqlite3_api->value_text16 +#define sqlite3_value_text16be sqlite3_api->value_text16be +#define sqlite3_value_text16le sqlite3_api->value_text16le +#define sqlite3_value_type sqlite3_api->value_type +#define sqlite3_vmprintf sqlite3_api->vmprintf +#define sqlite3_overload_function sqlite3_api->overload_function +#define sqlite3_prepare_v2 sqlite3_api->prepare_v2 +#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 +#define sqlite3_clear_bindings sqlite3_api->clear_bindings +#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob +#define sqlite3_blob_bytes sqlite3_api->blob_bytes +#define sqlite3_blob_close sqlite3_api->blob_close +#define sqlite3_blob_open sqlite3_api->blob_open +#define sqlite3_blob_read sqlite3_api->blob_read +#define sqlite3_blob_write sqlite3_api->blob_write +#define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2 +#define sqlite3_file_control sqlite3_api->file_control +#define sqlite3_memory_highwater sqlite3_api->memory_highwater +#define sqlite3_memory_used sqlite3_api->memory_used +#define sqlite3_mutex_alloc sqlite3_api->mutex_alloc +#define sqlite3_mutex_enter sqlite3_api->mutex_enter +#define sqlite3_mutex_free sqlite3_api->mutex_free +#define sqlite3_mutex_leave sqlite3_api->mutex_leave +#define sqlite3_mutex_try sqlite3_api->mutex_try +#define sqlite3_open_v2 sqlite3_api->open_v2 +#define sqlite3_release_memory sqlite3_api->release_memory +#define sqlite3_result_error_nomem sqlite3_api->result_error_nomem +#define sqlite3_result_error_toobig sqlite3_api->result_error_toobig +#define sqlite3_sleep sqlite3_api->sleep +#define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit +#define sqlite3_vfs_find sqlite3_api->vfs_find +#define sqlite3_vfs_register sqlite3_api->vfs_register +#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister +#define sqlite3_threadsafe sqlite3_api->xthreadsafe +#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob +#define sqlite3_result_error_code sqlite3_api->result_error_code +#define sqlite3_test_control sqlite3_api->test_control +#define sqlite3_randomness sqlite3_api->randomness +#define sqlite3_context_db_handle sqlite3_api->context_db_handle +#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes +#define sqlite3_limit sqlite3_api->limit +#define sqlite3_next_stmt sqlite3_api->next_stmt +#define sqlite3_sql sqlite3_api->sql +#define sqlite3_status sqlite3_api->status +#define sqlite3_backup_finish sqlite3_api->backup_finish +#define sqlite3_backup_init sqlite3_api->backup_init +#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount +#define sqlite3_backup_remaining sqlite3_api->backup_remaining +#define sqlite3_backup_step sqlite3_api->backup_step +#define sqlite3_compileoption_get sqlite3_api->compileoption_get +#define sqlite3_compileoption_used sqlite3_api->compileoption_used +#define sqlite3_create_function_v2 sqlite3_api->create_function_v2 +#define sqlite3_db_config sqlite3_api->db_config +#define sqlite3_db_mutex sqlite3_api->db_mutex +#define sqlite3_db_status sqlite3_api->db_status +#define sqlite3_extended_errcode sqlite3_api->extended_errcode +#define sqlite3_log sqlite3_api->log +#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64 +#define sqlite3_sourceid sqlite3_api->sourceid +#define sqlite3_stmt_status sqlite3_api->stmt_status +#define sqlite3_strnicmp sqlite3_api->strnicmp +#define sqlite3_unlock_notify sqlite3_api->unlock_notify +#define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint +#define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint +#define sqlite3_wal_hook sqlite3_api->wal_hook +#define sqlite3_blob_reopen sqlite3_api->blob_reopen +#define sqlite3_vtab_config sqlite3_api->vtab_config +#define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict +/* Version 3.7.16 and later */ +#define sqlite3_close_v2 sqlite3_api->close_v2 +#define sqlite3_db_filename sqlite3_api->db_filename +#define sqlite3_db_readonly sqlite3_api->db_readonly +#define sqlite3_db_release_memory sqlite3_api->db_release_memory +#define sqlite3_errstr sqlite3_api->errstr +#define sqlite3_stmt_busy sqlite3_api->stmt_busy +#define sqlite3_stmt_readonly sqlite3_api->stmt_readonly +#define sqlite3_stricmp sqlite3_api->stricmp +#define sqlite3_uri_boolean sqlite3_api->uri_boolean +#define sqlite3_uri_int64 sqlite3_api->uri_int64 +#define sqlite3_uri_parameter sqlite3_api->uri_parameter +#define sqlite3_uri_vsnprintf sqlite3_api->vsnprintf +#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2 +/* Version 3.8.7 and later */ +#define sqlite3_auto_extension sqlite3_api->auto_extension +#define sqlite3_bind_blob64 sqlite3_api->bind_blob64 +#define sqlite3_bind_text64 sqlite3_api->bind_text64 +#define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension +#define sqlite3_load_extension sqlite3_api->load_extension +#define sqlite3_malloc64 sqlite3_api->malloc64 +#define sqlite3_msize sqlite3_api->msize +#define sqlite3_realloc64 sqlite3_api->realloc64 +#define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension +#define sqlite3_result_blob64 sqlite3_api->result_blob64 +#define sqlite3_result_text64 sqlite3_api->result_text64 +#define sqlite3_strglob sqlite3_api->strglob +#endif /* SQLITE_CORE */ + +#ifndef SQLITE_CORE + /* This case when the file really is being compiled as a loadable + ** extension */ +# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; +# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; +# define SQLITE_EXTENSION_INIT3 \ + extern const sqlite3_api_routines *sqlite3_api; +#else + /* This case when the file is being statically linked into the + ** application */ +# define SQLITE_EXTENSION_INIT1 /*no-op*/ +# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */ +# define SQLITE_EXTENSION_INIT3 /*no-op*/ +#endif + +#endif /* _SQLITE3EXT_H_ */ diff --git a/src/syscfg.ini b/src/syscfg.ini new file mode 100644 index 0000000..d764113 --- /dev/null +++ b/src/syscfg.ini @@ -0,0 +1,25 @@ +#ϵͳò +[SYSCFG] +#IPַ +ip1=192.168.1.199 + +# +netmask1=255.255.255.0 + +# +gateway1=192.168.1.1 + +#IPַ +ip2=192.169.1.199 + +# +netmask2=255.255.255.0 + +# +gateway2=192.169.1.1 + +#SNTPַ +sntp_server=192.168.1.11 + +#ied +ied_name=TIED10 diff --git a/src/sysinfo.c b/src/sysinfo.c new file mode 100644 index 0000000..cbd32dd --- /dev/null +++ b/src/sysinfo.c @@ -0,0 +1,250 @@ +#include "goahead.h" +#include +#include +//#include +//#include +//#include +#include +//#include +//#include +#include "sysinfo.h" + +static const char *rtcname; + +int web_get_sys_para(int eid, Webs *wp, int argc, char **argv) +{ + char *sec_name,*key_name; + char var[128]; + if(jsArgs(argc,argv,"%s %s",&sec_name,&key_name)<2) + { + websError(wp,400,"Insufficient args\n"); + return -1; + } + ini_gets(sec_name,key_name," ",var,sizeof(var),sys_cfg_file); + return (int) websWrite(wp,"\"%s\"",var); +} + +void sys_reboot(Webs *wp) +{ + system("reboot");//ϵͳ +} + +void ethx_process(Webs *wp) +{ +/*11пʼ +auto eth0 +iface eth0 inet static +address 192.168.1.199 +netmask 255.255.255.0 +network 192.168.1.0 +gateway 192.168.1.1 +*/ + char *str1,*str2,*str3; + char ipaddr[32]; + char netmask[32]; + char gateway[32]; + char cmd[128]; + + ini_gets("SYSCFG","ip1","192.168.1.199",ipaddr,sizeof(ipaddr),sys_cfg_file); + ini_gets("SYSCFG","netmask1","255.255.255.0",netmask,sizeof(netmask),sys_cfg_file); + ini_gets("SYSCFG","gateway1","192.168.1.1",gateway,sizeof(gateway),sys_cfg_file); + str1=websGetVar(wp,"ip1",ipaddr); + if(str1!=NULL) + { + if((str2=websGetVar(wp,"netmask1",netmask))!=NULL) + if((str3=websGetVar(wp,"gateway1",gateway))!=NULL) + { + //printf("%s %s %s \n",ipaddr,netmask,gateway); + sprintf(cmd,"sed -i '13c address %s' /etc/network/interfaces",str1); + system(cmd); + sprintf(cmd,"sed -i '14c netmask %s' /etc/network/interfaces",str2); + system(cmd); + sprintf(cmd,"sed -i '16c gateway %s' /etc/network/interfaces",str3); + system(cmd); + ini_puts("SYSCFG","ip1",str1,sys_cfg_file); + ini_puts("SYSCFG","netmask1",str2,sys_cfg_file); + ini_puts("SYSCFG","gateway1",str3,sys_cfg_file); + } + } + ini_gets("SYSCFG","ip2","192.169.1.199",ipaddr,sizeof(ipaddr),sys_cfg_file); + ini_gets("SYSCFG","netmask2","255.255.255.0",netmask,sizeof(netmask),sys_cfg_file); + ini_gets("SYSCFG","gateway2","192.169.1.1",gateway,sizeof(gateway),sys_cfg_file); + str1=websGetVar(wp,"ip2",ipaddr); + if(str1!=NULL) + { + if((str2=websGetVar(wp,"netmask2",netmask))!=NULL) + if((str3=websGetVar(wp,"gateway2",gateway))!=NULL) + { + sprintf(cmd,"sed -i '20c address %s' /etc/network/interfaces",str1); + system(cmd); + sprintf(cmd,"sed -i '21c netmask %s' /etc/network/interfaces",str2); + system(cmd); + sprintf(cmd,"sed -i '23c gateway %s' /etc/network/interfaces",str3); + system(cmd); + ini_puts("SYSCFG","ip2",str1,sys_cfg_file); + ini_puts("SYSCFG","netmask2",str2,sys_cfg_file); + ini_puts("SYSCFG","gateway2",str3,sys_cfg_file); + } + } + websRedirect(wp,"/system.jst"); +} + +int save_sntp_server(char *server) +{ + char cmd[128]; + sprintf(cmd,"sed -i '8c SNTP_SERVER=\"%s\"' /usr/sbin/ntpdate",server); + system(cmd); + ini_puts("SYSCFG","sntp_server",server,sys_cfg_file); + return 0; +} + +void sntp_process(Webs *wp) +{ + char *str; + char sntp_server[65]; + ini_gets("SYSCFG","sntp_server","192.168.1.11",sntp_server,sizeof(sntp_server),sys_cfg_file); + str=websGetVar(wp,"sntp_server",sntp_server); + if(str!=NULL) + { + save_sntp_server(str); + } + websRedirect(wp,"/system.jst"); +} + + +//ϵͳʱ +int SetSysDateAndTime(struct tm *time_tm) +{ + struct timeval time_tv; + time_t timep; + int ret; + //time_tm->tm_year -= 1900; + //time_tm->tm_mon -= 1; + time_tm->tm_wday = 0; + time_tm->tm_yday = 0; + time_tm->tm_isdst = 0; + + timep = mktime(time_tm); + time_tv.tv_sec = timep; + time_tv.tv_usec = 0; + + ret = settimeofday(&time_tv, NULL); + if(ret!=0) + { + fprintf(stderr,"settimeofday failed\n"); + return -2; + } + return 0; +} + +/* +static int rtc_xopen(const char **default_rtc,int flags) +{ + int rtc; + + if(!*default_rtc) { + *default_rtc = "/dev/rtc"; + rtc = open(*default_rtc, flags); + if (rtc >= 0) + return rtc; + *default_rtc = "/dev/rtc0"; + rtc = open(*default_rtc, flags); + if (rtc >= 0) + return rtc; + *default_rtc = "/dev/misc/rtc"; + } + + return open(*default_rtc,flags); +} + +//utc=0ʱ,ʱ +static void write_rtc(time_t t,int utc) +{ +#define RTC_SET_TIME _IOW('p',0x0a,struct rtc_time) + struct tm *timetm; + int rtc = rtc_xopen(&rtcname,O_WRONLY); + + timetm = (struct tm *)(utc?gmtime(&t):localtime(&t)); + timetm->tm_isdst = 0; + + ioctl(rtc,RTC_SET_TIME,timetm); + + close(rtc); +} */ + +//utc>0ʱ,򱾵ʱ +//ϵͳʱͬӲʱ +void SetHWClockFromSysClock(int utc) +{ + //struct timeval tv; + //gettimeofday(&tv,NULL); + //write_rtc(tv.tv_sec,utc); + system("hwclock -w"); +} + +void rtc_process(Webs *wp) +{ + char *str; + time_t now; + unsigned int i; + struct tm uptime; + str=websGetVar(wp,"year","2015"); + if(str!=NULL) + { + i=atoi(str); + uptime.tm_year=i-1900; + } + str=websGetVar(wp,"month","9"); + if(str!=NULL) + { + i=atoi(str); + uptime.tm_mon=i-1; + } + str=websGetVar(wp,"day","1"); + if(str!=NULL) + { + i=atoi(str); + uptime.tm_mday=i; + } + str=websGetVar(wp,"hour","0"); + if(str!=NULL) + { + i=atoi(str); + uptime.tm_hour=i; + } + str=websGetVar(wp,"minute","0"); + if(str!=NULL) + { + i=atoi(str); + uptime.tm_min=i; + } + str=websGetVar(wp,"second","0"); + if(str!=NULL) + { + i=atoi(str); + uptime.tm_sec=i; + } + SetSysDateAndTime(&uptime); + SetHWClockFromSysClock(1);//ʾʱ + //now=mktime(&uptime); + websRedirect(wp,"/system.jst"); +} + +void ied_rename_process(Webs *wp) +{ + char *str; + char old_name[65]; + char cmd[128]; + ini_gets("SYSCFG","ied_name","TIED01",old_name,sizeof(old_name),sys_cfg_file); + str=websGetVar(wp,"ied_name",old_name); + if(str!=NULL) + { + if(strlen(str)>2) + { + sprintf(cmd,". /mk_ied.sh %s",str); + ini_puts("SYSCFG","ied_name",str,sys_cfg_file); + system(cmd);//ִ + } + } + websRedirect(wp,"/iedrename.jst"); +} \ No newline at end of file diff --git a/src/sysinfo.h b/src/sysinfo.h new file mode 100644 index 0000000..10512ae --- /dev/null +++ b/src/sysinfo.h @@ -0,0 +1,28 @@ +#ifndef _SYSINFO_H +#define _SYSINFO_H + +#define sys_cfg_file "/usr_app/syscfg.ini" + +int web_get_sys_para(int eid, Webs *wp, int argc, char **argv); + + +void sys_reboot(Webs *wp); + + +void ethx_process(Webs *wp); + + +int save_sntp_server(char *server); + + +void sntp_process(Webs *wp); + + +void rtc_process(Webs *wp); + + +void ied_rename_process(Webs *wp); + + +#endif + diff --git a/src/thread.c b/src/thread.c new file mode 100644 index 0000000..0fe2138 --- /dev/null +++ b/src/thread.c @@ -0,0 +1,42 @@ +/* + * thread.c + * + * Created on: Mar 9, 2012 + * Author: tsx + */ +#include +#include + + +pthread_t task_create(void *(*start_routine)(void *),void *arg,int prio,int stacksize) +{ + struct sched_param sch; + pthread_attr_t attr; + pthread_t pt; + int ret; + + if(prio!=0&&stacksize!=0) + { + pthread_attr_init(&attr); + //get attr + pthread_attr_getschedparam(&attr,&sch); + //set prio + sch.sched_priority=prio; + pthread_attr_setschedparam(&attr,&sch); + //set stack size + pthread_attr_setstacksize(&attr,stacksize); + //create thread + ret=pthread_create(&pt,&attr,start_routine,arg); + } + else + { + ret=pthread_create(&pt,NULL,start_routine,arg); + } + + if(ret!=0) + { + printf("create thread failed \r\n"); + return -1; + } + return pt; +} diff --git a/src/thread.h b/src/thread.h new file mode 100644 index 0000000..fd3d7c5 --- /dev/null +++ b/src/thread.h @@ -0,0 +1,7 @@ +#ifndef _THREAD_H +#define _THREAD_H + +extern pthread_t task_create(void *(*start_routine)(void *),void *arg,int prio,int stacksize); + +#endif + diff --git a/src/update.rar b/src/update.rar new file mode 100644 index 0000000000000000000000000000000000000000..13be68dacd5dd8be42f9484c5c69f6a875897802 GIT binary patch literal 338809 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

    sBLKOKt7fowL8o#YCiG<6dy|kbkCPrZ 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

      rFHq_zxJ#GcuF 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 literal 0 HcmV?d00001 diff --git a/src/update.sh b/src/update.sh new file mode 100644 index 0000000..e84378a --- /dev/null +++ b/src/update.sh @@ -0,0 +1,42 @@ +#!/bin/sh +if [ ! $1 ]; then +host=192.168.1.11 +else +host=$1 +fi +echo "host is $host" + +echo "update shell files" +cd /etc/init.d +tftp -g -r rcS $host +chmod +x rcS +tftp -g -r S71ntpdate $host +chmod +x S71ntpdate +tftp -g -r S81srvrd $host +chmod +x S81srvrd +tftp -g -r S90app $host +chmod +x S90app + +echo "update usr app" +cd /usr_app +killall app +tftp -g -r app $host +chmod +x app +tftp -g -r ysp_cfg.ini $host +tftp -g -r syscfg.ini $host +echo "update iec file" +cd /scl_srvr +tftp -g -r scl_srvr.tar.gz $host +tar -xvf scl_srvr.tar.gz +echo "update html file" +cd /var/www/web +tftp -g -r web.tar.gz $host +tar -xvf web.tar.gz + +cd / +tftp -g -r mk_ied.sh $host +chmod +x mk_ied.sh + +echo "update all files ok" +echo "now reboot system" +#reboot diff --git a/src/web.tar.gz b/src/web.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..a65c6cc0652090fe98e611ac5041acc98909b31b GIT binary patch literal 133120 zcmeHQ31Ab&`Y(!T`v=7Xxm1=QH*JolEiG+1%293M%wT z_)yAP%(dDy7KRD4n9Y9ME_S@E#+6s(1YnD!DlQCHqojysHVYSNP*C_N!#@J9WI0p7Rc$D*PU~Q$FwFT_2;o*sT zvn88B&B`)slVmw&E3&D{VAGr=lXD;B8vZ)f8;rWN9E&+ahpn;(Y?^eVjxiu@)Ox)k z6Jokm_BMd@NWJls(@rFiFZIQv|C<(#^ZD3n6vUij+L6xZaUpV>3di6zQe z9I>Ah-inC_mnK(iFzTLo5lOU!Pc)v1Xa` z(r`i=C>l0n>L$B&_Hg^)dv1K2N$E=NETyY2XG%h6scH${Qq{iPsmi(&xskcwTT@h$ z0zuNgB8e^=iPtQvQe!2w97+3fs3vwO0YxYuK5-ON)}f?aJBIHn88wQ$@jcA8)B>%q z=Es(e#%sR2N@;yppN)?rb7$XE^-^Zy{5_Vf9tKKE|XVqo+^yj7563O&EA9)n-U0`1~ z`#u@6`UgFcst{Ez=s(Mq+-WBjLxLqo#Q{GUq>gY_{q{`*JAf8pWm zbPYSv*qNu=xY`bJ$yOmC%I=aelE*> zQjmc^>~x)D{q*A9(_HSO>=8JyX{mkF`tw`1*;h>{-aV;gcacw_(j{9 zKRL+fERmgJ1x#dW&@>}^k`v|ZZ|;+tT!MX0l(I`3XcAI*?#>FE;JVS9w2XU$oOcc8psfs2$GE$z|XTAuBzN`|J+}D%13u45c_G zc|k9r@jnsBDY{N%__(ZiK}rwNq-}`y*7=aM!F8_9ZyVIK9%4w_5JT(1b^6Y48)ChA z@B=xwX)U;pd@TkJRFOgs3rYtBD3U-93sQO@fgE_CfgC83Kn@F1wt)n4;DH8mphyBa zEa;^Tejpc3-pfUkLJkXh2}Goa07VkWVL?g{B#;9SG>`*D63Age$~KTd4m{964irfs zhXuW~!4KrzR*C%ga%xh@VL>l}h(Hb$Ng#&>DLs%t4m{964irfshXpCyKms}NKm$2Y zB!L_j^wI`Dkc%Pjg+I_F!XK8TZ3hwl zzy}rnK$8f6Skg;7{NYc+!h{m0p@|m5u%wq*#PA22MEJv!v_6RN2R^9q2bx6q!;-Y^ zAi^K`pu!($65$U^dTEC%{(LWK6Yoyrcc!`SMRVV##&0uo<%Xg?WU$GN-&-c^Mssd6 zbJ?RN>{gSo^(2@jqe15XXje0NwOo z$NxlY#ewF3s)Nk`G;Sdg*} zB#;9SQXv;W{-*#rUDce8-Iq)DA zaslLj3XlU!kpyyBkkSJQnuy zIba3SKn@g1AcqB|CleG&AcqAhJ&-^SJkUT66iFb51u5G=0y*#?6>G;SWtR0L6HP74dg(P1aerAvJE7V0}oOm7f}AE06LBfNP{{~lLU6W zr1Xq(nk2yEC24(-K#%i5gFQ}@1bnVlL&uUk|L*| zNrXQvN$Z0Mf8c`(f1pW(KP*Yx4kG-456SooB>&TiKbWwl!XIc7;SWnvPzsC28A1gg@{hioX#5lb+ia(iG1C;(x~8m;BF|Q2kHwvv>CrA^zus z&;N`K@jw6l{7@e%y#3(tKY8mx;(zkygU0{l9R!X4DLC-Kp1f=RC+{F= z{7=Dwj~0aZpAQ=UlRu-uP>pq2cBY@9uDb^sG9I2j z@lsrxt3K@RL3Et!LB^9X%>v_SKf7#&K(L_nK|Lt?nPYMHKm$4OKms`|NZAHI^DFLc zpn)8OMglo3NZAHIb1Uv`kP5i~@;`+@fE7qHuLp`Gki&w~lL?9>ki&wM9!MYu9%vv3 ziX@Q3f|P9_fgE^{3b_FCKLyAEE06|qphyBaEGRvhphyBaEJ*2r1ajbk26CWC0y!*5 z*#;8Gfd{FO3n2effE=&_X&?uRB#^^`(vt~_B#^^`lpaVR2Oel32Z|(+!-AA;Ab}is zkP5i~@;?R00V|LOa-c{8IV>nWnV?7lIV?!&fdq2kfd+D*NCG)5NZAGw$bko`kP9IH zQ-B<>0%;%ziX@Q3g3^--iX@Q3f|MReAO{|3AP0&hki&wMZ6JXhc#sOY0P;Tt$N?*m z26CWC0y!)wJ(-|L0y!*5>45}t;DH8mphyBaEJ)b~63BrEsgMgG|5Jb*umWiy2Z|(+ z!-CS235q0;!-A9^NFWCuXdnlQB#^^`lx-k^9C(llxq$LN1<-L^KpNC>nk2B}C8cMS z(BJvQW>eu0G>PzsB`Ihc02@4aV^*^2XgDG(;{DCGB{;(uPPC=6he^`>% z2NC|j2NnK6lL&uUlC~X0_yZrJ_zUqr@1Elpvfw)dDZwxQ87B7rcZEvf`TqCV7HDk&?nsFL`JnSZQ$yuH5&Kghv;8Z}f2Ib!`e!P?`6xIqe;3RLgZn8M4+`~DupT7l zr(i!w#80PvAFN5?QlYE+DcBDZ?bB)BNBkky=Yz%i6i#TcNS_`KXb5;P8Q^n>>){~q zlur)_RHIwJj86{-fhT-=I1nAz28-|Mj048kG;=DT=yOWN!vPK0zySf+u$=T+2vGDn znc~p`8nA%_pED^Q4rssz4t!3dcsP&>wtz7`opAvDj|Oa@NB}l0Cmjo*NB}l0N9lk7 zY~X+fY@kR0HY`Wk0s^ps1F2vO7{}8IHX#1dfDIH0z=q|dXA%?%z=q{09T0#G9MFIb z6bZnFI@xcRIlals_74!SWbE-L6HD#SdP*G0ocF+4cI`D0Bl%}vIPWS0|!#U7BCj46Kp{3 zqX8Qz5`YcMNzWuG5`YcMQ92+18#tf=8z>Th4a-rsfB;EmHH z030tUJ)N8;0pxf=S{DSM<6O|7j?*N79WO}R3IgD9E+iu_aLi2?74krn1bJAH zBB8{K3RsZV1qt%N1r_o@lLUEKkhT>h$O9LWkrz15rVH|5hMEd_phe zupq4q66ApkD&&DC3G%QYZ7WES2QEaB7h-D$j+qv+bT2ZH(p44g@}I=~Pn9x8t%{Bb zQz#X&v7z_B-;2{97UF+C=={&Fs!;jQe>?xPD|&oIe+u@4#Q${K_Yr@H|M_6?KZO$-EdHm50~$&mOf2{uFnc%% zJpa?f0o7>PFaOiS0SzS&&%O94`03$5bfg?C{--kz7_rk#(14=P`56xfG++Y<1YpB* z(x){*(dXQZM+<1c1`d4A%y>AU0UJ2*IWObkKq}Y*#{YE20n|Vmuz?~0*sz>*EPx^b z*svU>0|Kyt0~)Y_A_3U29Ayg#zy=Paf-PYDPbb)b8b|{+P$U2wmXn@IP$U2wmZNk) z05)(y12#}302`L0Yykn-z=2e-1&sgc1RGETX}|`G1YpB*(lZH)1YpB*lnw~M1`cSz z28sk=!*Y}@AOIUUkP5bd@jsnl18N`**g%m0Y*!c0Rh;+0S(wdkpOI1 zjI4Wt1ZC=!4T%Sq29C=!4T%TYQY02?@<0UIb1fDOx0wtxU^ z;6N(a0>=Mzf(@vFG++Zo06rvY0@qU<)As(+M|@ z5J-bJPLlv|yrA@Sa+(B?;{|D55P*(zL4!I@lK^(SAZ;rMfXBIzjJ&|{KV6UqlhRbk z15Fa-VL^(7f+h*_upq4q66ApkD&&DC3G%QYZ7WES2QDNdFL3-%7v#YVH5KwelLUEK zkRqX=NrF5qNb7M zjf*W)|5F(ks{a|VlkCS(i2wP(^FKrM&woArGvMsc;F3SF^`LM+vF+ecKe6#(F+Z{S zU=crg^FDZ!cgy?4=7UB11LmXh6j@gz6Z%}_JctAbhA%2 zKK9S}bhA&x!NZd+z6hUg_C-g=LF0S!VZZ>LW}0e zesP$AeW@@D9Iumy88H56Uqi4KP!xw57L%SvP!xw57NfK;4l}S%12a$*hZz>5j9(mPU|%ZC0>|a# zVFoNe8km8iILxq^^fZE^ILxpZrG0Ujfqfd7fucCfuoz|h;xGgIQehT27AFrg;P=tM z3>3v-hQ*|(5fsH?hQ%oDi^B};)4&WA#bJiUDB~B08Q7N!vq17Ud7yE8J{qKPn&MF7 z<)r75(-a3AFGuS^9B!Nk8oY6u;(+7jXxktTInIM*%mt9SDPRsJm#HuZngp1`aunGF zO#;keIa&_{m;(<~m;+4$%waj&HV|MAJV?e|06Cii=3u6o3Ui=IfH^EjkxkGfz#NvN z^+13*@IZw*&?LYdmZNP00p`GiDCRCWE+eH z2`w!Kjj;)nsxuDK*$f$)CX7{MvPN2U7K6SSFKaan)+H#_Ir;1_8D^u|lEBnys)&n^ zQ=nglR*I+;5oI=kX`@+VOEBv6wq}ghV9haV3KAHD$!IX?BGZlLjDgMIW0ua4nPp2* zHswsFYcd9ATFkj7Z9=Za*uZRxH0$+IIi}2pj3Or={%VB^{fvfx#y>x@?Ul(_o5Zla-)W@v+y*Fq`y-Os!!M%3DsZ z?NwVrjxMRbO_y)0|5~L8q{yN zwr$yd0oettXrho;oyDXv3PCx4ag8oVqtzNrnUNMi3&Wws(}WO_(}qiEUQL9%0FJR) z5a4q(7M;n)u;`15k{hx!<$Q>dY~DC5W*`xrg@I_?001G`v`rXW7BfURH;QHq9FRBC zYHXTFn91V#}Rqs!+0W({**Bh$?`n>jmy!;yz`u5Fg63{4J;5H48f^~%&qiEbU=wk>N7 z`jtHH(neV@va$2(7IPjOh->2O=$h&k`V3x3-Y7j6g<-O?If}xc8Pp*OpSj;yGu)+< z5QA_Z$9515i!B%9kz6NLM<2uf2gkSz#wER49s8g2SftIIli+e(r*l0BS817}e4}w^ zD(jS+VbE%rb_h~hovaDdLz89BMoqxI>?=BpR%7zl$8z03xLYR~4QIW~rOIEau35)P z$5(Him{|5dwuu?J7AxwtbIb-7!t5_RB%)FN*bWW#?o2G|gcx}vrW1m^m0`~VI(=T! z&*4#%YcsQ!*d9S|H0MFbf-vsQI_rhE-o8z&58Ke!y*9*4bgues4Hli=oDVkKGlj4K z@psqgH5LQ!q)~$2V6oaFGqMauZR0FkwvpkGMCPu2n>gN*M=BW9Pq@HS!+vLj$LLfr zY}AqLUkawSAv?!xv1v?j1LKp=!Ipz2e?IZujLjCZ#oy|J#k*yn%evsG|% zBJ%tn7p*G${I3o@{|Dz}cvv0RtxLN~5j7&v&z0JzwtgA?+YtT##m6e3zn{7Nbc3+4 z$LF}$KWBb*$%fGjJ z!qV|O8-D!A`f=$`%{sDS;@}n4rgZB5>WmrPQdW+t(TMrzskTf)+?B5)p6t@E%kP$Be6Hs$up>wo9Q~esZwlt~t`9m*#_v||d z6m6Q6d~)oo%3oc(x?tuzhmJA{pFj7_{8?{xDthGXvX)0?e$jj8FN3dqQe0);V?Wn# z{`*7aReYQ5L`{#~Jt1?~Sv|57) z56&q)T35ZTe~VAXP3t|Uv_sp-9Xr;XZZN)Po60RFu222@c(v~$>Nf3D-*~XxQmgtu zEuO4iW6Pk1Cl8Kz#MX4ttZQ3_Bu#jw?)95D!-tUC>VG%qPfZacbsSCdCiO{jO|vh8VAhr9z*_HXEyG~t&Q z(g$dok6%11Vp{352XprwQ(sT{qTF{?C%pgN#V7wLe_+lF-H$!}_n4oqesNB_@!^w2 zuXWcyJLQR5$)A2TFYb+N|EZ$h*6*W}pLbo_s@Le7pR~JNx^-`D^=IXOiywS;0<*g5 z#;P+rwAl6O5BkS6ukM+UQJVg(A@Q9m-&L9U$o4tu%_m3I{&m8z{l&9uPwzCLimkr2 zfAuiK^U88N#_nmM%dPwM0`ormm$Ry@A6B8D)G}-C+I7vwJe6Jj_r0eJ7c{$4Tm43j zeX17~O^%P**SlhzweFXrp8aq{%QH_a>**tYxzhWi;@xZVPY-);spZd!w|@AeQ2WjJ z!-n+}N7NlV@xb~Qvxc^)SA1hkrQx<)ug^cNxU=??BQyVV;9En#5A)m4>C@t1US?+f zE(?+;{AX^$Gqa}u^3jNgPi+}e%b0#=asO&_)8C7GzWN_$^y3#@uU5Nh?#hUF@BCJ? zu=K(q&E~-oE%#0~3|z^mzJIRkwMol97%;v0gy#Drn%ch~+@|-!=pi@44ou0`pZcv$ zy?47Gow9K1s2_*?eeS^2^y9T|^xZJ{!ncvO+}xiN=Olic({IkM)vL=FTzgcx-%xGn zfv1$|defh=H=>j0PQ3HPqSRx`oOe4b%wJZl`1f;9EX(Ws+i6S2P0PE4 zR=riP)#>;_MNRptjaweSRH0+{uWF6zxA~j$i?UCTJRED>H)hhSzZImb2L1QU+D=2x z?XP6ZyV77<+OmqTWnK7aP4~=huf6(2cKh&p+p9MiHsNc1u_}Mx7w=vCyk4~@+yru8fD)-EH$hB?M>`on9kGrk! zn_QuE$Jf=u=bin0|D^B#3d_6Lrc%p(yZ&DH(8+JVEjkog?ym+%YrfjIdRG14^nYe8 z?EmH$%f82<8D5DNby&t?Qh!Od$;yCpYPwV zpC3Qug~)Z;>N`~)x|DM1t5=(L%Xw_V)*21N$Mx)Upw*%gr>@+&*?HovY1P~ApZ)Qh zF)PN;Ir!VtmEJ#jA@`es)50g7ITzih#)^tc+3lx(KDuh}n9SL)|2Qjo^25y8A1jwW zH#L3ot+7{@{`W!!TkfC+%BpG4bju9yw!Ga#t9I;|(elLT#O9$h=+MxQp zs9A#s=T~*jvVWe|Ru}coz`dtQwt4gL^w-~iX5fZ*>&-ZSWz#JEdym(C za&NtpXa8>2{hVXz_M!vN>(7^7tT&_)OsqLQMRL^#Q zG^M-x_~z=`u8R!69GJXN`Ax?sFB&R7H?@BBXFZHXih6U}EZS5zwZhRC7d?GMGx5*8 z7ysz<`|c`ZMvwmNSon~KA5O_ydF@h{7Wy+KSsxyGds^n#wd3nl`C!iN7h;0!*UUaMHtNT~=TsNWbRNePgH~&>B|ISeLv*vm4Oj-WL53e`+Dr4f5=i45t zG4Xh(rzdw^`bo{TJC00m*yz^i7dzJ;zNUQo$TsbtUa$WC?F*~k+cLHKp_kW8>p4Mo z`NWWZH_jZM6IW-@uCtp)-EQ3crE=vitZO@|uQ~no^=D>(WqEtVf96d*a^=Kq&7IkE zYbh^h8?sKF9hPWT{j%uf!Amb)c-V2M&!QPKt{&a{i1FGlN7l@foqOT^p`TQ2_x#On znoAG=Xf*eTzuGEuS6I7?Lwh#f_E)P(-G|Tpp!nuX?S`HI^;G6s%bzK0w$vZc^p&~; z&mO(<<;7=Plug;Zk+oxiyhHf?|e?0xmMAe$3}hqckJ2Ve`tt#`WwdvJk((J#TBO-Wi)=W-VV*U1#utePg@Z7+{QsE z@pIM|Yl_1XRIePm6!GeA{L}4+dsaA8x@(!K+-rwS zUoE)UbVyNno1fQqJ70X`o4sL`Y_{kA`ulvix@z3UKEwO2YVpjpsp&Q4BO`uV*zV(@-n@^NqQ@3%uto;cO zeUost!TJ-Ak7$}+(&p^4w1jKR-udINE-hC-vvT?2EsxAUIq$nC+9dW{H*|PHxA0qA z7mhygNdKhek8dA(hdp+(Wc z*jr1w?4IAk(B-!!OSdI<>pXMh*uvpgrYw0!Rc+k(?~)H}nm=K*eD}n~Rc}9WTVC;# zgT4Bk>2UH4+rvHLfj?|No6Gog*P$0HSnetG4Z=G5!Pal4}z zZ209wbJ>7T8z1=QRL1S-z5AmYw|jB!;Z_T`G`=~uV#>a&YYuGL*ly#B$P>dSc3fZi z{KEOq{d&0B;-cqXUT(A5D)#IAcF%_It%zNnVei@Zl{JrE)4h;9_sg)qB7Tew`~66h zUelkNU4GR1)hot*nYA%~@0*hyw(fgo-kI5W{;cW)GQ*qYGTyjE1egu9p0ncfbxqcJB}V*H2=<(KB@~# zmd2V_PPo4N^P}NkKlJ-w;i=V{&6!(T_)*m{8TJF;q*jXyude^L^2vsEj>wYh&$zv8 zYxa%DwYp17`!w#kMc#5*qqo}T*BtuypK~_7ck0`jGwYoBu5*uHlm}XO9FjYD!GhL` zx^GWiYyExH$sMy<6V!`!kEjvZ(7SF!((r0IXv`#vyf92+? zE_J>=SfTHgpDI1f{ITyB`S>|Ax>@Ud(@xXv!n1EzemJFx>T0Ac?b^c~9M`A4l-ass zT#otO66toU}yo({EUoUQxrV@>NtbnCLXO4P@x9Xft;duYLto-fp0-9@JlU;ONu zb1Raw4ThKWvy|nA?AZ}MY);nbxmRP7A7(c7+EaCL-8wP96qbLl^}L#fDp?h#D%uWu z@!WLfN7_AO`u5$oL6zG;UrS%LPp?MfTI_Gov2LeHeIIJRen{cYh;6@Lugw$}K039| zj-eeC3z`=6y{3C~#rg05d*Slz-|9UcfAz-$mOg)Ns=xX7^}~8}_|4e0Zt;rpuY9^E zYsvEX$he}HejU7I?jO4Oa_!zT1yj@a9{9NCmg7g$9r~%Y+Ap)LPUtY@{bQ%MFS+(+ zojFI_Z3&yPI{D-iFOO_%+qh*zm9?)#rEDA*Sz~7XtG7G$?H4on&%-rlt{eDNc*4O+ zpW4z@$_2}}tEya^-e6$Y88sS*w{HFFp~#l9IUP1m%UV}{;rd3mYP`@x)wSFcN4{?S z`^6!71(7>ObUAbGaBS=^SI2cmO11AECC1W7AUmruFus-S(X;6XiB-GFozQIc(py(y{adbgWNjgUR3V-kml1-i{Y; z@~_Vych_gv-;p(o5KW@Z!ekgVR%?Fa~XsEK_5ZC8q}Z?T@KJ zefgtcJqY!G1lz%=|05WO?bjO9zn7?UPjmn7p#`*<&zA(#(N z{U4`!9~E?jYs6>tTxlPX=z~-LM~L3yBYKZZ2whDqb&0!h&=;0Sfxp0KCPQa5qRS`) zaYd433K@LIORU^??&@<=E@W`QaZDS0L9$n)(+m4exN0%=fxmLY;j(r1H}JiqefWni zeF*&Km_NLD_hiSGY3}_Kf2?%vY@f#-sQN#``3zG19}oL9g;{`@?u&BmVL#yYe?06{ z@vZ&U|M9R-Q7#bE~aX`R4Npz8lPVFvYKXkZ44;xNNv($ffv;xNNvl=j78 z2KH%S28!Y^!(x>2i^B};ONCjW>i;-l2K8ZRU7#bE~aX`R4N;OhT4fyPyZp+Op_DGoJWPI@jmO>waCal zT)^u8xL^(@m#HuZngp1`aunGFO#;keIa&_{m;(<~m;+4$%waj&HV|MAJV?fzgara6 z%pi-e5b$yoZ3Pbmn8R|k9tbc89%z;cxYiS34m?m{4m1fchvjIqM1VQ)Ac{HPOUP`c z1&z^=X-blD8~oAwF}Gffcc=2}zKPs-;ixfJC&RP=Yi@eB!Nv=Q7w=tQUpJd$qa?~X zHGcIPx#K_T&6aHVoG9mi6+R&~Zpk}Q&hA)7Vs}aYLh4yM4JsND#oD`jV?Hd1?Eh3M zR52d)UzD+N(V_SM`ABC#e}3@zf8mMQI-7>cve|MXb#LSv1|`W-Q1Kd6ha<8FDvN@y zRPI|65Od&4X~tw^X)IQqEvaXZwvkO`jGVi~Yz7-*jTB2@0EQ>Br9T*p&X^>FvPsq~ zoz5m>vQYT})K|C`Q{wvpmL4QWN1!J_S1!8XSnue6iR|Uf)n!SNv4uQjOnN44Sx=JT zLKrdzyd=ros&e2R{CQcZW((KBBy!zUa$=T>q&-L~QI1vEKs-8@fFdkp?0(LGL8nDk zZV-1Zh_8Va>;Gf$`(IJjuV{6Q66$}cRiXa>Uf|{*>;EGXYez<+!eWC^)hWHjoXyr* zN@}1`#3&l-4MtspTrN*ZkoQDI$E@;}+H8Z#U`17#Y-WqRwaz*a)#Z_MR6TffVIm`w zBNCyEOMbS|gjlug?E%@y%gc+(i;gl|GUdwn_;`6fDA47@z~O( zvmGJZpyPLOugSIP(Y*%w;`;oE2G%U|J zNrnbC&ihVEN?Y_tmh70f*)e@b`!=oZQzn(HT8~nah3*+#bgT~u6O3y4M`b92CF5^s zG3b7le16X~`{)&dl?0$e0$0)(gO+U#+aGxlzN`h-G=oWRZXoO4r+Z4rc^OC+Y9vL{Lo5AN^@qTqzf zNa8y!et-|a^ZVWQ5vYofEr5a?kro3S2o5DC?ZK3#T2%227F+ zmj`1@0pjvnbuuzCoTdAk;Xwizz&jPVfj=5wSTfMv(m4x&e#x+yjcAyIc=IN+t0o&M zd(%L7427aeBUv)yY&@Q(c>U)G zum8WBM{?KhA3yp_nf(d)rr z@4AeT!7^Ix@I^4-Iy^uP<9`oNBwhu8IPppVw@r<`)a**?XGh`7LC?`9@M#Q)SNUw1te3- zDaN3#oL5_(`{FuKMM-h!stzDj6ioZA$#{_280265Tg^h z|Dz?JSQ!7Y>px2NJwZyPS`}LV58@edntt%^|NoNtKW_0~Sa;#xdm${IaBKj#2{jlR zB<8ZTA9h$|G~ls9@%G_S=l4!Izht7laHM0#dhRA72y&u{8V0@QDibjv*kK||mf$%H zW#-b7l~LS1k~5bm*Pux+!5cXCZ7l~)(#Nv895%`W88BDP6g9mC}_;J5`O< zQ`J=ZD!~ByL}?)whoDN0rL+Kr@MOs;D%u?K2D*Ab2O{Tx`?#o*@mn3kM{rXr60c%J zNYWJGITCidgv*99s$}{W$A-nFvxoB&HBv5Sm_KpO4a?YT*=^Rx&6xl8+2_rRLYG;| zu0J1d)fQ0|Eq{Y<9*Nd-?+FC|0fuyqKwT4 zZ~Xtivi{3nne1rweq8@m%aZMr(faQ^_p!a#RbVKaDXeR9dfR=*x)F`e zKB5pF?xjbUP8wah_u8{A3lw5WMHwymaQodR6}HilB$XE=OlsNaXp+h~B}ghS=p{P0 zl@YO|a_KA`KDTtlv}k&$LWwz&tnz|h;zqN2WuWRMJess}UJ2653wjBUI<0E@v_eTW zlC<)IUg8!@D-Mq)t(;eawDN*p!lO>Bl0L0aLX0G>yr7r3#nKwXg-4TC&MQG$c|kAX zQKvPQKCMtPizKbQpqIGC(u%{QNh{}-Ag#Qhm++|58b_a2C=o@HR$kCc++u0P;nAd( z^Gc9bUeHT;)M;%>pH?V|M3Pos&`aE6X~p5uq?PkZkXByMOL!t_6{w5o(U+UMW*6at z$Pjd`7XbXie~KYkX2=-&;a`*iOfGgVu?C@SBJ)4dYK15NKU%2{@jrraCd!%&&HvnQ z{7-&cuj`eWmYZWVYqa+hH5Ao)@YhbFo3d~p8D38GK8%*2+6L}`_ zm`5A8@%;J?jzt@|rGCV0@p#3I|4B5K93zrLPJ}FfrAyx~nK6euvGf6nvB7{-X4cB@2Y4yeKczSbBt^>xVD#DG$Kd~J^hxwbN)Mi z@kSg9bjw7Z{}AcdbNw$mHafKbC(x(Ct33%tQ`jB*xOf$}28WrX{t9jRtkT5}qN#Ua zI^Vkog|)m_-}0={1s*xZrpt@_0cEqypDC9!n9x%M!xg||o@f9wK_O*I! zYb~>@)ooL&%M-YBWfOgZ+B)o%7nf0&Ev~rA4*LDyK)v(YAK&XAJ?a0!@Go-zSH>z7 zW%xhQq4$3W<5ZNf8JhpO=kq^8=}&yifEsW9?>{bADL)m2J9&J=xySV%(BzN%9wCp( zAGY^q;4kRI(X9yIvRoR%-LzOC+|#4?6Qf5$;qC)3Ls-pc==IYp1&+wq`M|Eu3XuRgTtCZGv_1XA1GI#bpMUM5G$=jH!@_8jSE$dN8H}~Wy(tFr< zNC>1rr?L1-b$r=KyrtSP{~hv%XQN%SS-u=93A-%EtQF)QwVDE-{=D>BLay1TZ}i1) zN9~x!R(KQYb{et7O%?L>44?kI^jadB zzUKoRk10BKChec8JQt`Z*pQvO$pGARUG_rXjV)igBI7@GjLLKThxP%hL;HVy{yZ zIy8#&K4=V$;zXx`LZdjI91t4CQIFzKSH)M|e&Bfs@chrwX#)9J>1Iph`CqA2dG7yE z#-Z21h3fyfWidEk{!#uPTJmszktceKCaUFtX3hj^A)2y8ojPJ#sn8@%@s0`hDUQa?F3fbjg;|1xq>V)jz-`bmzPAFX}`^p)(Dp1VytPjaG}8XbFgx27NAm$md^= z##Q*t@O(D|`i>Rhl|T6X0c;7iNa%F<-G_-Td@$6N`+RSM+iM%pvVEC?fWkvR>ecwQ zcYZe7V0JFjb1PLYuT1_o^@72j)*rTQ}WsT8h;GQkU{@k>DAMPVFy9(}}1|6a(# z?41I4?fjYyTl$FYd`VaW=sltN9uxr|PSCQCiyybU1iIx4WvT1%uLEWG!xb)T-_1UM zy?w!OzQ8HEdAQy-gc}GuxNzT4$KUqgt)RRalGlNj*_7t(O`u2!R`J-^xd{tZgpnoN z*G(zeJ=HOJP08XB1QD5Zwrq`cpyysWFJTFi^s$xhnti@#ISLQGyn-OMO!PX6JWT;X zY=Wd{Z0xBNR;ds+FvS4Bx5=GF!N2y1o1c(zYfY}NPj!2WaCw42%TVwFRRB6Zh5Y%u zzb*v(=yCthg@AG|%=@s#&AcGaz;B1VhZh1tSolJ~TQ#X-qq`6YV#5~#L2M7?gWFizCl5$!Ly-Keaxe!ybrkw9MN$*_*8e zy_MN)6E@_*nk~F~8Nc!vV_DjBHC$k&V<(~ao1q7uGSAa@kuA>XT|RxGm|(Qxd{)C# z-VgeVkDWu{|LIR`K?s+3;shlZBJ)3Lb(!~ns$vzP{r^EZ7oJA{$@w4lWwT6vw$X&% zD9;uONRZ3(^75kcqNB`~Ot~^XK3<;B%0Q3noUXZx*_a3E{m*b^!mE$((-%Oyy*f)+ zMnEHZVH(JTSX`HZHsxq6nldkP7NNomO;Jk{| zWg19am8on8%owBACJbVl(;;Yl;>qepQ?$?ooYb={-nrN;k2 zul229tjSMZVt${mz-Z5|SYQTkg}0;xMthFM0@Hd6OynF3Gs0*uAV0VbZOrz3x(a;{ zWgwJ+PzFL72xTCYflvlQ83<({lz~tNLKz5UAe4bn20|GKWgwJ+PzFL72xTCYflvlQ M83<+I-e%zc0ZTNxegFUf literal 0 HcmV?d00001 diff --git a/src/ysp.db b/src/ysp.db new file mode 100644 index 0000000000000000000000000000000000000000..2c7e869b0c0d925de9e905bc09ae313af7da63ec GIT binary patch literal 1957888 zcmeEvcYxf)_5b!>=)D|Zz`o{{v@7lI-MO9bjBSj;Hf|Jiw$BAu?#`w|w0(~R2qdAm z&_W9>v=BNegcb;d0D%;G0^yt9liz0~?XE^A?Mi$1`;SYIcD?USdGltZ`OJLYEI#h& zjU$6C>$VMT85n8dY`fU(cH4}W7MpFS-)6JFYpeY^@zGWLYO||88+=3>9Ulh5_|+c0 z#)kiY@%M!VzOcX-7Wl#fUs&J^3w&XLFD&qd1-`Jr7Z&)!0$*6*3kzs1FktuYz5o7p zao>@F)td)5Z(F}=Wc6m{=ICA2H*-l}%aWP1j_zwYLHXB{S|*1BEz;M;BSRavu0N?| zN#F7%?JbpmU9xe@ApULcg1*H|W-d5(iW^h&w_RjfZ+|!XujpT*pGQB5z88Hb`bPAX z==0I%4g$gd-BM_!M-9CzUcSLTE zTo<__a%to%kzz!QoE_N_*%sLtSra)avMh33WPYSCGCh)taFLG4k�p`$zVSL?ix) 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

      ekd{T~m{)7jvNXGyR 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

      D);MF*U?6o)0ADhY?lO>4rF_bOfy6rk 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

      0ATyL=Z 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

      o$(4mc~BVj(9kP{DuSK|?dmyE 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 +#include "ysp_debug.h" +#include "database.h" +#include +#include +#include "common.h" + + +unsigned int debug_flags=/*PARA_TRACE_DEBUG|*/TRACE_DEBUG|ANALYSIS_TRACE_DEBUG|ANALYSIS_EEROR_DEBUG|ERROR_DEBUG|ACTION_DEBUG|COMUNICATION_TRACE_DEBUG|COMUNICATION_EEROR_DEBUG; + +static pthread_mutex_t mutex_log; +static int mutex_log_inited=0; + +static char my_log_buf[1024]; + +void my_log_init(void) +{ +if(!mutex_log_inited) + { + if(pthread_mutex_init(&mutex_log,NULL)!=0) + { + printf("init log mutex failed\r\n"); + return; + } + all_table_init(); + mutex_log_inited++; + } +} + +void lock_log(void) +{ + if(!mutex_log_inited) + my_log_init(); + pthread_mutex_lock(&mutex_log); +} + +void unlock_log(void) +{ + pthread_mutex_unlock(&mutex_log); +} + + +void do_my_log(const char *fmt,...)/*__attribute__((format(printf,2,3)))*/ +{ + int len; + va_list args; + lock_log(); + va_start(args, fmt ); + len=vsprintf(my_log_buf,fmt,args); + va_end(args); + log_entry_add(my_log_buf,len); + unlock_log(); +} + +void remove_old_log(unsigned int rsv_time) +{ + lock_log(); + data_entry_remove("log_tbl",(time_t)rsv_time); + unlock_log(); +} + +int add_his_entry(ANALY_RESULT *str) +{ + int ret; + lock_log(); + ret=his_entry_add(str); + unlock_log(); + return ret; +} + +int read_his_entry(ANALY_RESULT *str) +{ + int ret; + lock_log(); + ret=his_entry_read(str); + unlock_log(); + return ret; +} + diff --git a/src/ysp_debug.h b/src/ysp_debug.h new file mode 100644 index 0000000..1a11c98 --- /dev/null +++ b/src/ysp_debug.h @@ -0,0 +1,83 @@ +#ifndef _LOG_H +#define _LOG_H + +#include + + + +/* +ANSI C׼м׼Ԥ꣨Ҳdzõģ +__LINE__Դв뵱ǰԴкţ +__FILE__Դļв뵱ǰԴļ +__DATE__Դļв뵱ǰı +__TIME__Դļв뵱ǰʱ䣻 +__STDC__ҪϸѭANSI C׼ʱñʶֵΪ1 +__cplusplusдC++ʱñʶ塣 +*/ + + +#define YSP_DEBUG 0 //ܵ,printfӡ,0¼־ļ + +#define TRACE_DEBUG 1 +#define ERROR_DEBUG 2 //ҪرΪ0 +#define ACTION_DEBUG 4 +#define COMUNICATION_TRACE_DEBUG 8 +#define COMUNICATION_EEROR_DEBUG 16 +#define PARA_TRACE_DEBUG 32 +#define PARA_ERROR_DEBUG 64 +#define ANALYSIS_TRACE_DEBUG 128 +#define ANALYSIS_EEROR_DEBUG 256 +#define IEC61850_TRACE_DEBUG 512 +#define IEC61850_ERROR_DEBUG 1024 +#define DEBUG_ALL 0xFFFFFFFF + +extern unsigned int debug_flags; +extern void my_log_init(void); +extern void do_my_log(const char *fmt,...); +extern void remove_old_log(unsigned int rsv_time); + +#if YSP_DEBUG +#define LOG_DEBUG(flag,fmt,...)\ + do{\ + if(debug_flags&flag){\ + printf(fmt,##__VA_ARGS__);}\ + }while(0) +#else +#define LOG_DEBUG(flag,fmt,...)\ + do{\ + if(debug_flags&flag){\ + do_my_log(fmt,##__VA_ARGS__);}\ + }while(0) +#endif + +/** lower two bits indicate debug level + * - 0 all + * - 1 warning + * - 2 serious + * - 3 severe + */ +#define LWIP_DBG_LEVEL_ALL 0x00 +#define LWIP_DBG_LEVEL_OFF LWIP_DBG_LEVEL_ALL /* compatibility define only */ +#define LWIP_DBG_LEVEL_WARNING 0x01 /* bad checksums, dropped packets, ... */ +#define LWIP_DBG_LEVEL_SERIOUS 0x02 /* memory allocation failures, ... */ +#define LWIP_DBG_LEVEL_SEVERE 0x03 +#define LWIP_DBG_MASK_LEVEL 0x03 + +/** flag for LWIP_DEBUGF to enable that debug message */ +#define LWIP_DBG_ON 0x80U +/** flag for LWIP_DEBUGF to disable that debug message */ +#define LWIP_DBG_OFF 0x00U + +/** flag for LWIP_DEBUGF indicating a tracing message (to follow program flow) */ +#define LWIP_DBG_TRACE 0x40U +/** flag for LWIP_DEBUGF indicating a state debug message (to follow module states) */ +#define LWIP_DBG_STATE 0x20U +/** flag for LWIP_DEBUGF indicating newly added code, not thoroughly tested yet */ +#define LWIP_DBG_FRESH 0x10U +/** flag for LWIP_DEBUGF to halt after printing this debug message */ +#define LWIP_DBG_HALT 0x08U + + + +#endif + diff --git a/src/新建 文本文档.txt b/src/新建 文本文档.txt new file mode 100644 index 0000000..a62d95d --- /dev/null +++ b/src/新建 文本文档.txt @@ -0,0 +1,6 @@ +H2 289 332 399 +CO 400 434 470 +CH4 590 630 696 +C2H4 2130 2240 2440 +C2H6 2727 2854 3097 +C2H2 3306 3450 3680 \ No newline at end of file diff --git a/test.csv b/test.csv new file mode 100644 index 0000000..819c911 --- /dev/null +++ b/test.csv @@ -0,0 +1,5000 @@ +-544 +-544 +-543 +-543 +-543 +-543 +-542 +-543 +-543 +-543 +-543 +-543 +-544 +-544 +-544 +-544 +-545 +-544 +-544 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-546 +-545 +-545 +-545 +-545 +-546 +-546 +-546 +-546 +-546 +-545 +-546 +-546 +-546 +-545 +-545 +-545 +-545 +-545 +-546 +-545 +-546 +-546 +-546 +-546 +-546 +-546 +-546 +-546 +-546 +-546 +-546 +-546 +-546 +-545 +-546 +-546 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-544 +-545 +-545 +-545 +-544 +-545 +-545 +-545 +-545 +-544 +-545 +-545 +-545 +-544 +-544 +-545 +-545 +-545 +-545 +-544 +-545 +-545 +-545 +-544 +-544 +-545 +-545 +-544 +-544 +-545 +-544 +-545 +-544 +-544 +-545 +-544 +-545 +-544 +-544 +-544 +-544 +-545 +-544 +-544 +-545 +-544 +-544 +-544 +-545 +-545 +-544 +-544 +-545 +-544 +-544 +-545 +-545 +-544 +-544 +-544 +-545 +-544 +-544 +-544 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-544 +-544 +-545 +-545 +-544 +-545 +-544 +-544 +-545 +-545 +-545 +-545 +-544 +-545 +-545 +-545 +-545 +-545 +-545 +-545 +-544 +-545 +-545 +-544 +-545 +-545 +-545 +-545 +-545 +-544 +-545 +-544 +-545 +-545 +-544 +-545 +-545 +-545 +-545 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-545 +-544 +-545 +-545 +-544 +-544 +-544 +-544 +-545 +-545 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-543 +-544 +-544 +-544 +-544 +-544 +-544 +-543 +-543 +-543 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-544 +-543 +-543 +-542 +-542 +-542 +-541 +-539 +-538 +-536 +-534 +-531 +-526 +-522 +-517 +-510 +-502 +-494 +-485 +-474 +-462 +-450 +-437 +-423 +-409 +-394 +-380 +-365 +-352 +-339 +-325 +-313 +-302 +-291 +-281 +-271 +-263 +-255 +-248 +-242 +-235 +-230 +-225 +-220 +-217 +-213 +-210 +-207 +-205 +-203 +-201 +-200 +-200 +-199 +-199 +-200 +-200 +-202 +-204 +-206 +-209 +-213 +-217 +-221 +-226 +-232 +-238 +-245 +-252 +-260 +-268 +-277 +-286 +-296 +-306 +-315 +-326 +-335 +-346 +-356 +-365 +-375 +-385 +-394 +-403 +-411 +-419 +-427 +-434 +-441 +-447 +-453 +-458 +-463 +-468 +-472 +-476 +-480 +-483 +-486 +-490 +-492 +-495 +-497 +-500 +-502 +-503 +-505 +-507 +-508 +-509 +-510 +-510 +-511 +-511 +-510 +-510 +-508 +-506 +-504 +-500 +-496 +-491 +-486 +-480 +-474 +-467 +-460 +-453 +-446 +-439 +-432 +-426 +-420 +-414 +-409 +-404 +-399 +-395 +-391 +-388 +-385 +-382 +-379 +-377 +-375 +-373 +-372 +-370 +-369 +-367 +-366 +-366 +-365 +-365 +-364 +-365 +-365 +-365 +-366 +-367 +-368 +-370 +-372 +-374 +-377 +-380 +-383 +-387 +-391 +-395 +-400 +-405 +-410 +-415 +-421 +-426 +-431 +-437 +-443 +-449 +-454 +-459 +-465 +-470 +-475 +-479 +-484 +-488 +-491 +-495 +-498 +-500 +-503 +-505 +-507 +-509 +-511 +-513 +-515 +-516 +-517 +-518 +-519 +-520 +-522 +-522 +-523 +-524 +-525 +-525 +-525 +-527 +-527 +-528 +-528 +-529 +-530 +-529 +-530 +-530 +-531 +-531 +-531 +-532 +-532 +-532 +-532 +-533 +-533 +-533 +-533 +-534 +-534 +-534 +-534 +-534 +-535 +-535 +-535 +-535 +-535 +-535 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-537 +-537 +-537 +-537 +-538 +-537 +-537 +-538 +-538 +-538 +-538 +-537 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-539 +-539 +-538 +-539 +-539 +-539 +-539 +-538 +-539 +-538 +-538 +-538 +-538 +-537 +-537 +-536 +-535 +-534 +-533 +-532 +-530 +-527 +-525 +-522 +-519 +-515 +-511 +-507 +-502 +-497 +-492 +-486 +-479 +-473 +-467 +-460 +-454 +-448 +-442 +-436 +-430 +-425 +-419 +-414 +-410 +-406 +-402 +-398 +-395 +-392 +-389 +-387 +-384 +-382 +-381 +-380 +-379 +-377 +-377 +-376 +-376 +-376 +-377 +-377 +-378 +-379 +-380 +-382 +-384 +-387 +-389 +-392 +-395 +-398 +-402 +-407 +-410 +-415 +-419 +-424 +-428 +-434 +-439 +-443 +-448 +-453 +-458 +-463 +-468 +-472 +-477 +-481 +-485 +-489 +-492 +-496 +-499 +-502 +-505 +-507 +-509 +-511 +-514 +-515 +-517 +-519 +-520 +-522 +-523 +-523 +-525 +-525 +-526 +-527 +-528 +-528 +-529 +-530 +-530 +-531 +-531 +-532 +-532 +-532 +-533 +-533 +-533 +-534 +-534 +-534 +-534 +-534 +-535 +-535 +-535 +-535 +-535 +-535 +-536 +-536 +-536 +-536 +-536 +-536 +-537 +-537 +-537 +-537 +-537 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-537 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-539 +-539 +-538 +-538 +-538 +-538 +-538 +-539 +-538 +-538 +-538 +-539 +-538 +-539 +-539 +-538 +-539 +-538 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-540 +-539 +-540 +-539 +-539 +-539 +-540 +-540 +-539 +-539 +-540 +-539 +-540 +-540 +-540 +-540 +-539 +-539 +-540 +-540 +-539 +-539 +-540 +-540 +-540 +-539 +-540 +-539 +-540 +-540 +-539 +-540 +-539 +-539 +-539 +-539 +-540 +-540 +-540 +-540 +-540 +-540 +-540 +-539 +-540 +-540 +-540 +-540 +-539 +-540 +-540 +-540 +-540 +-539 +-539 +-539 +-540 +-540 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-538 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-538 +-539 +-538 +-539 +-539 +-538 +-538 +-538 +-538 +-539 +-539 +-538 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-538 +-538 +-538 +-538 +-539 +-539 +-539 +-538 +-539 +-539 +-538 +-538 +-539 +-539 +-538 +-538 +-538 +-539 +-539 +-539 +-538 +-538 +-539 +-538 +-538 +-538 +-538 +-539 +-538 +-539 +-539 +-539 +-538 +-539 +-539 +-538 +-538 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-538 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-539 +-538 +-539 +-538 +-538 +-538 +-538 +-539 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-537 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-537 +-537 +-538 +-538 +-538 +-538 +-538 +-537 +-538 +-537 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-537 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-538 +-537 +-538 +-538 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-538 +-537 +-538 +-537 +-537 +-538 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-537 +-536 +-537 +-537 +-537 +-537 +-537 +-537 +-536 +-536 +-537 +-537 +-537 +-537 +-536 +-536 +-537 +-537 +-536 +-537 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-537 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-535 +-536 +-535 +-536 +-535 +-535 +-535 +-535 +-536 +-535 +-535 +-535 +-535 +-535 +-536 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-536 +-535 +-535 +-535 +-536 +-535 +-536 +-536 +-536 +-536 +-536 +-536 +-535 +-535 +-536 +-536 +-535 +-536 +-535 +-535 +-535 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-535 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-535 +-535 +-536 +-536 +-536 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-536 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-536 +-535 +-536 +-535 +-536 +-535 +-536 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-534 +-535 +-534 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-534 +-535 +-535 +-534 +-534 +-534 +-534 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-534 +-535 +-535 +-535 +-535 +-534 +-534 +-535 +-534 +-535 +-534 +-534 +-535 +-534 +-534 +-534 +-534 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-534 +-534 +-535 +-535 +-534 +-534 +-535 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-535 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-535 +-534 +-534 +-534 +-534 +-535 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-535 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-533 +-534 +-534 +-534 +-534 +-534 +-534 +-533 +-534 +-534 +-534 +-534 +-534 +-533 +-533 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-533 +-534 +-533 +-533 +-534 +-534 +-533 +-534 +-533 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-535 +-535 +-535 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-533 +-534 +-534 +-534 +-533 +-533 +-533 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-533 +-534 +-533 +-533 +-534 +-533 +-533 +-534 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-534 +-533 +-533 +-533 +-533 +-533 +-533 +-534 +-533 +-534 +-533 +-533 +-534 +-534 +-533 +-534 +-534 +-534 +-534 +-533 +-533 +-534 +-534 +-533 +-534 +-534 +-534 +-534 +-534 +-534 +-533 +-534 +-533 +-534 +-533 +-534 +-534 +-534 +-534 +-534 +-533 +-533 +-533 +-534 +-533 +-533 +-534 +-533 +-533 +-533 +-534 +-533 +-533 +-534 +-534 +-533 +-533 +-533 +-534 +-533 +-533 +-534 +-533 +-534 +-534 +-533 +-533 +-534 +-533 +-533 +-534 +-533 +-534 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-533 +-534 +-534 +-533 +-534 +-533 +-533 +-533 +-534 +-534 +-534 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-534 +-533 +-533 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-533 +-534 +-533 +-533 +-533 +-534 +-533 +-534 +-534 +-534 +-534 +-534 +-534 +-533 +-534 +-533 +-533 +-534 +-534 +-534 +-534 +-533 +-533 +-533 +-534 +-533 +-533 +-534 +-533 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-533 +-533 +-534 +-534 +-533 +-533 +-534 +-534 +-533 +-534 +-534 +-534 +-534 +-534 +-534 +-533 +-534 +-534 +-534 +-533 +-533 +-533 +-533 +-534 +-533 +-533 +-534 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-534 +-533 +-534 +-533 +-534 +-534 +-534 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-531 +-531 +-531 +-531 +-530 +-530 +-530 +-529 +-528 +-528 +-527 +-527 +-526 +-526 +-525 +-524 +-523 +-522 +-521 +-519 +-518 +-517 +-515 +-514 +-511 +-510 +-508 +-505 +-503 +-501 +-498 +-496 +-493 +-490 +-487 +-484 +-480 +-476 +-472 +-469 +-464 +-460 +-456 +-452 +-446 +-442 +-437 +-431 +-426 +-421 +-415 +-410 +-405 +-398 +-392 +-387 +-380 +-375 +-369 +-363 +-357 +-351 +-345 +-339 +-333 +-327 +-321 +-315 +-310 +-303 +-298 +-292 +-286 +-281 +-276 +-270 +-265 +-260 +-255 +-251 +-246 +-241 +-236 +-232 +-228 +-224 +-220 +-217 +-213 +-209 +-207 +-203 +-200 +-198 +-195 +-193 +-191 +-188 +-186 +-185 +-183 +-182 +-180 +-179 +-178 +-177 +-176 +-175 +-175 +-174 +-174 +-174 +-175 +-175 +-176 +-176 +-177 +-178 +-179 +-180 +-182 +-183 +-185 +-186 +-188 +-190 +-193 +-195 +-198 +-200 +-203 +-206 +-209 +-212 +-215 +-219 +-222 +-225 +-229 +-233 +-237 +-241 +-246 +-249 +-253 +-258 +-262 +-267 +-271 +-276 +-281 +-285 +-290 +-295 +-299 +-304 +-309 +-314 +-318 +-324 +-329 +-333 +-338 +-343 +-348 +-353 +-357 +-362 +-367 +-371 +-376 +-381 +-386 +-390 +-394 +-399 +-403 +-407 +-411 +-415 +-419 +-423 +-427 +-430 +-434 +-437 +-441 +-444 +-447 +-450 +-453 +-456 +-459 +-461 +-464 +-466 +-469 +-471 +-473 +-475 +-477 +-479 +-481 +-483 +-485 +-486 +-488 +-489 +-491 +-492 +-493 +-495 +-496 +-497 +-498 +-500 +-501 +-502 +-502 +-503 +-504 +-505 +-506 +-507 +-507 +-508 +-509 +-509 +-510 +-510 +-511 +-511 +-512 +-513 +-513 +-514 +-514 +-515 +-515 +-516 +-516 +-516 +-517 +-517 +-517 +-517 +-518 +-518 +-518 +-519 +-519 +-519 +-519 +-520 +-520 +-520 +-521 +-520 +-521 +-521 +-521 +-522 +-522 +-522 +-522 +-522 +-523 +-523 +-523 +-523 +-523 +-523 +-524 +-524 +-524 +-524 +-524 +-525 +-524 +-525 +-525 +-524 +-525 +-525 +-525 +-526 +-526 +-526 +-526 +-525 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-528 +-528 +-527 +-527 +-527 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-529 +-528 +-528 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-530 +-529 +-529 +-529 +-530 +-529 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-529 +-530 +-529 +-529 +-530 +-530 +-530 +-530 +-530 +-529 +-529 +-529 +-529 +-530 +-529 +-529 +-530 +-530 +-530 +-530 +-530 +-529 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-531 +-531 +-531 +-531 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-531 +-531 +-530 +-531 +-531 +-531 +-531 +-530 +-531 +-531 +-531 +-530 +-530 +-530 +-530 +-530 +-531 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-528 +-528 +-528 +-527 +-527 +-527 +-527 +-527 +-527 +-526 +-526 +-525 +-525 +-525 +-525 +-524 +-524 +-523 +-523 +-523 +-522 +-522 +-521 +-521 +-520 +-520 +-518 +-518 +-517 +-516 +-515 +-514 +-513 +-511 +-511 +-510 +-508 +-507 +-505 +-504 +-503 +-501 +-500 +-498 +-496 +-494 +-492 +-490 +-489 +-487 +-484 +-482 +-479 +-477 +-475 +-472 +-470 +-467 +-465 +-462 +-459 +-456 +-453 +-450 +-447 +-444 +-441 +-438 +-435 +-432 +-429 +-426 +-422 +-420 +-416 +-413 +-410 +-407 +-404 +-400 +-397 +-393 +-390 +-387 +-383 +-381 +-378 +-375 +-372 +-369 +-365 +-363 +-360 +-358 +-355 +-353 +-350 +-348 +-345 +-343 +-341 +-339 +-336 +-334 +-333 +-331 +-329 +-327 +-325 +-324 +-323 +-321 +-319 +-318 +-317 +-316 +-315 +-314 +-313 +-312 +-312 +-311 +-311 +-311 +-310 +-310 +-310 +-309 +-309 +-309 +-310 +-309 +-310 +-310 +-311 +-311 +-312 +-312 +-313 +-314 +-314 +-315 +-316 +-318 +-319 +-320 +-322 +-323 +-325 +-327 +-328 +-329 +-331 +-333 +-335 +-337 +-339 +-341 +-343 +-345 +-347 +-349 +-352 +-354 +-356 +-359 +-361 +-364 +-366 +-368 +-371 +-374 +-376 +-379 +-381 +-384 +-387 +-390 +-392 +-395 +-397 +-401 +-403 +-406 +-408 +-411 +-414 +-416 +-419 +-422 +-424 +-427 +-429 +-432 +-434 +-437 +-439 +-442 +-444 +-446 +-449 +-451 +-453 +-456 +-458 +-460 +-462 +-464 +-466 +-469 +-471 +-472 +-474 +-476 +-477 +-479 +-481 +-483 +-484 +-486 +-487 +-489 +-490 +-492 +-493 +-494 +-495 +-497 +-498 +-499 +-500 +-501 +-502 +-503 +-504 +-504 +-505 +-506 +-506 +-507 +-508 +-509 +-510 +-510 +-511 +-512 +-513 +-513 +-514 +-514 +-515 +-515 +-516 +-517 +-517 +-518 +-518 +-518 +-519 +-519 +-520 +-520 +-520 +-521 +-521 +-521 +-521 +-521 +-521 +-522 +-522 +-522 +-522 +-523 +-523 +-523 +-523 +-524 +-524 +-524 +-524 +-524 +-524 +-524 +-524 +-524 +-525 +-525 +-525 +-525 +-525 +-525 +-525 +-525 +-525 +-525 +-526 +-526 +-525 +-525 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-528 +-528 +-528 +-528 +-528 +-527 +-527 +-527 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-529 +-529 +-529 +-529 +-528 +-528 +-529 +-529 +-528 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-530 +-530 +-529 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-529 +-530 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-530 +-529 +-529 +-529 +-529 +-530 +-530 +-530 +-529 +-529 +-529 +-529 +-529 +-529 +-528 +-529 +-529 +-528 +-529 +-529 +-528 +-528 +-528 +-528 +-528 +-528 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-526 +-527 +-526 +-526 +-525 +-525 +-525 +-525 +-524 +-524 +-524 +-523 +-523 +-523 +-522 +-522 +-521 +-520 +-520 +-520 +-519 +-518 +-518 +-518 +-516 +-516 +-515 +-514 +-513 +-512 +-511 +-510 +-509 +-508 +-507 +-506 +-504 +-503 +-502 +-501 +-499 +-498 +-496 +-495 +-493 +-492 +-490 +-489 +-487 +-485 +-484 +-482 +-480 +-478 +-476 +-474 +-473 +-471 +-469 +-467 +-465 +-462 +-460 +-458 +-456 +-454 +-452 +-450 +-448 +-445 +-443 +-441 +-439 +-437 +-435 +-432 +-430 +-428 +-426 +-424 +-421 +-420 +-417 +-415 +-413 +-411 +-409 +-407 +-405 +-403 +-401 +-399 +-397 +-394 +-393 +-391 +-389 +-388 +-386 +-384 +-382 +-381 +-379 +-377 +-376 +-374 +-373 +-372 +-371 +-369 +-368 +-366 +-365 +-364 +-363 +-362 +-361 +-360 +-359 +-359 +-358 +-357 +-356 +-355 +-355 +-354 +-354 +-353 +-353 +-352 +-352 +-351 +-352 +-351 +-351 +-351 +-351 +-351 +-351 +-351 +-351 +-351 +-352 +-353 +-353 +-353 +-354 +-354 +-355 +-356 +-356 +-357 +-358 +-359 +-359 +-360 +-361 +-362 +-363 +-364 +-365 +-366 +-367 +-369 +-370 +-372 +-373 +-374 +-376 +-377 +-379 +-380 +-382 +-383 +-385 +-386 +-388 +-390 +-392 +-393 +-395 +-396 +-398 +-400 +-402 +-404 +-406 +-407 +-409 +-411 +-413 +-415 +-418 +-419 +-421 +-423 +-424 +-426 +-428 +-431 +-432 +-434 +-436 +-438 +-440 +-442 +-444 +-446 +-447 +-449 +-451 +-453 +-455 +-456 +-458 +-460 +-462 +-463 +-465 +-467 +-469 +-471 +-472 +-473 +-475 +-477 +-478 +-480 +-481 +-483 +-484 +-485 +-487 +-488 +-489 +-490 +-492 +-493 +-494 +-495 +-496 +-498 +-498 +-500 +-501 +-502 +-503 +-504 +-505 +-505 +-506 +-507 +-508 +-508 +-509 +-510 +-510 +-511 +-512 +-512 +-513 +-514 +-514 +-515 +-516 +-516 +-517 +-518 +-518 +-518 +-519 +-519 +-519 +-520 +-520 +-521 +-521 +-521 +-521 +-522 +-522 +-523 +-523 +-523 +-523 +-524 +-524 +-524 +-524 +-525 +-525 +-525 +-525 +-526 +-526 +-526 +-526 +-526 +-526 +-527 +-527 +-527 +-528 +-527 +-528 +-528 +-528 +-528 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-531 +-530 +-530 +-531 +-531 +-530 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-534 +-534 +-533 +-533 +-534 +-533 +-533 +-533 +-533 +-534 +-533 +-533 +-533 +-533 +-533 +-534 +-533 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-534 +-535 +-535 +-534 +-535 +-534 +-535 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-535 +-535 +-534 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-534 +-535 +-534 +-534 +-534 +-534 +-534 +-535 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-535 +-534 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-534 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-536 +-535 +-535 +-535 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-536 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-536 +-535 +-536 +-536 +-536 +-536 +-536 +-535 +-536 +-536 +-536 +-536 +-536 +-536 +-535 +-535 +-535 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-535 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-535 +-536 +-536 +-535 +-536 +-536 +-536 +-536 +-536 +-536 +-535 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-537 +-536 +-536 +-536 +-537 +-537 +-536 +-536 +-537 +-537 +-536 +-537 +-537 +-537 +-537 +-537 +-537 +-536 +-536 +-536 +-536 +-537 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-535 +-536 +-536 +-536 +-535 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-535 +-535 +-536 +-535 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-537 +-536 +-537 +-536 +-536 +-537 +-537 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-537 +-537 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-535 +-536 +-536 +-535 +-536 +-535 +-535 +-535 +-535 +-535 +-536 +-536 +-536 +-536 +-536 +-535 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-536 +-535 +-535 +-535 +-536 +-535 +-535 +-535 +-535 +-535 +-535 +-536 +-535 +-535 +-536 +-536 +-536 +-536 +-536 +-535 +-536 +-535 +-536 +-536 +-535 +-535 +-535 +-535 +-536 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-536 +-535 +-535 +-535 +-535 +-536 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-534 +-535 +-535 +-535 +-535 +-534 +-535 +-534 +-535 +-535 +-534 +-535 +-534 +-534 +-534 +-534 +-535 +-535 +-535 +-535 +-535 +-535 +-534 +-534 +-534 +-535 +-534 +-535 +-535 +-534 +-535 +-534 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-534 +-535 +-534 +-535 +-535 +-535 +-535 +-534 +-535 +-535 +-535 +-535 +-535 +-535 +-535 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-533 +-533 +-534 +-533 +-534 +-534 +-533 +-533 +-534 +-534 +-533 +-533 +-534 +-534 +-533 +-534 +-533 +-534 +-534 +-533 +-533 +-534 +-534 +-534 +-534 +-534 +-534 +-534 +-533 +-533 +-534 +-533 +-533 +-533 +-533 +-534 +-533 +-533 +-534 +-534 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-533 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-533 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-532 +-531 +-531 +-531 +-532 +-531 +-532 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-532 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-532 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-531 +-530 +-531 +-531 +-530 +-531 +-531 +-531 +-530 +-531 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-531 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-530 +-529 +-530 +-529 +-529 +-530 +-530 +-530 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-529 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-528 +-527 +-527 +-528 +-528 +-528 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-527 +-526 +-527 +-526 +-526 +-526 +-527 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-526 +-525 +-526 +-525 +-526 +-526 +-525 +-525 +-526 +-526 +-526 +-526 +-526 +-525 +-526 +-525 +-525 +-525 +-525 +-525 +-526 +-525 +-525 +-525 +-525 +-525 +-525 +-525 +-525 +-525 +-525 +-525 +-525 +-525 +-525 +-525 +-524 +-525 +-524 +-524 +-524 +-524 +-524 +-525 +-524 +-524 +-524 +-524 +-524 +-524 +-524 +-524 +-524 +-524 +-524 +-524 +-524 +-524 +-524 +-524 +-524 +-524 +-524 +-523 +-523 +-523 +-524 +-523 +-524 +-523 +-523 +-523 +-524 +-524 +-523 +-523 +-523 +-523 +-523 +-523 +-523 +-523 +-523 +-523 +-523 +-523 +-523 +-523 +-522 +-523 +-523 +-523 +-523 +-523 +-522 +-522 +-522 +-523 +-522 +-523 +-522 +-523 +-522 +-522 +-522 +-522 +-522 +-522 +-522 +-522 +-522 +-522 +-522 +-522 +-521 +-522 +-522 +-522 +-522 +-522 +-521 +-521 +-521 +-522 +-521 +-521 +-521 +-522 +-521 +-522 +-521 +-521 +-521 +-521 +-521 +-521 +-521 +-521 +-521 +-521 +-521 +-521 +-521 +-521 +-521 +-521 +-521 +-521 +-521 +-520 +-521 +-521 +-521 +-521 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-519 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-520 +-519 +-520 +-519 +-519 +-519 +-519 +-519 +-519 +-519 +-519 +-519 +-519 +-519 +-519 +-519 +-519 +-519 +-519 +-519 +-519 +-519 +-519 +-519 +-518 +-519 +-519 +-518 +-519 +-518 +-518 +-519 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-518 +-517 +-518 +-517 +-517 +-518 +-517 +-517 +-517 +-517 +-517 +-517 +-517 +-517 +-517 +-517 +-517 +-517 +-517 +-517 +-517 +-517 +-517 +-517 +-517 +-517 +-516 +-517 +-517 +-517 +-517 +-516 +-517 +-517 +-517 +-516 +-517 +-516 +-517 +-517 +-517 +-516 +-517 +-516 +-516 +-516 +-516 +-516 +-516 +-516 +-516 +-516 +-516 +-516 +-516 +-516 +-516 +-516 +-516 +-516 +-516 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-515 +-514 +-514 +-515 +-514 +-514 +-514 +-515 +-515 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-514 +-513 +-514 +-514 +-513 +-513 +-513 +-513 +-513 +-513 +-513 +-513 +-514 +-514 +-514 +-514 +-514 +-513 +-513 +-513 +-513 +-513 +-513 +-514 +-513 +-513 +-513 +-513 +-513 +-513 +-512 +-512 +-513 +-513 +-513 +-512 +-512 +-512 +-512 +-512 +-512 +-512 +-513 +-512 +-512 +-513 +-513 +-512 +-512 +-512 +-512 +-512 +-512 +-512 +-512 +-512 +-512 +-511 +-512 +-512 +-512 +-512 +-512 +-511 +-512 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-512 +-511 +-511 +-511 +-512 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-511 +-510 +-510 +-511 +-510 +-510 +-511 +-511 +-511 +-510 +-511 +-510 +-511 +-511 +-511 +-511 +-511 +-510 +-510 +-511 +-510 +-510 +-510 +-510 +-510 +-510 +-510 +-510 +-510 +-510 +-511 +-510 +-510 +-510 +-510 +-510 +-510 +-510 +-510 +-510 +-510 +-510 +-510 +-510 +-510 +-510 +-510 +-510 +-509 +-509 +-510 +-510 +-509 +-510 +-510 +-509 +-509 +-510 +-510 +-510 +-510 +-510 +-510 +-510 +-509 +-510 +-510 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-509 +-508 +-509 +-509 +-509 +-508 +-509 +-509 +-508 +-509 +-509 +-509 +-509 +-509 +-509 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-509 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-508 +-507 +-507 +-507 +-507 +-508 +-508 +-508 +-508 +-508 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 +-507 diff --git a/tune.csv b/tune.csv new file mode 100644 index 0000000..09f077e --- /dev/null +++ b/tune.csv @@ -0,0 +1,1006 @@ +64.090599 +64.089668 +64.087822 +64.087387 +64.086777 +64.086342 +64.085907 +64.085487 +64.084915 +64.084854 +64.083702 +64.082199 +64.081703 +64.081566 +64.082397 +64.082832 +64.083405 +64.083626 +64.084061 +64.085068 +64.086456 +64.089806 +64.093773 +64.097595 +64.101578 +64.103477 +64.105103 +64.106133 +64.105858 +64.106827 +64.108810 +64.113647 +64.121017 +64.128532 +64.135544 +64.141251 +64.144661 +64.146561 +64.148010 +64.148682 +64.149651 +64.150246 +64.153023 +64.154945 +64.157898 +64.159622 +64.163048 +64.167885 +64.171135 +64.174011 +64.176308 +64.178543 +64.180527 +64.181343 +64.181122 +64.181641 +64.182526 +64.184052 +64.185837 +64.187897 +64.190300 +64.191864 +64.192856 +64.191841 +64.189407 +64.186531 +64.182076 +64.177673 +64.172935 +64.167030 +64.161682 +64.155739 +64.150192 +64.145355 +64.138573 +64.133385 +64.127144 +64.120743 +64.114204 +64.108337 +64.101318 +64.095375 +64.089310 +64.082832 +64.076256 +64.069672 +64.062302 +64.053482 +64.044823 +64.038605 +64.033867 +64.027802 +64.020393 +64.012321 +64.000633 +63.990604 +63.980183 +63.971184 +63.962704 +63.953033 +63.943420 +63.935375 +63.926994 +63.918018 +63.910011 +63.901470 +63.891899 +63.881893 +63.872616 +63.864235 +63.854088 +63.845825 +63.838058 +63.829914 +63.823273 +63.817806 +63.812393 +63.806667 +63.801296 +63.796619 +63.791626 +63.787148 +63.782391 +63.779617 +63.777023 +63.774563 +63.772842 +63.771416 +63.771294 +63.773037 +63.774883 +63.775082 +63.773575 +63.772522 +63.771751 +63.770561 +63.770996 +63.772247 +63.772564 +63.772148 +63.772503 +63.771809 +63.772446 +63.776230 +63.780807 +63.784988 +63.787781 +63.789169 +63.792301 +63.796246 +63.800228 +63.805401 +63.810413 +63.815861 +63.821671 +63.827751 +63.834393 +63.842514 +63.851135 +63.858883 +63.866116 +63.871231 +63.875313 +63.883221 +63.890335 +63.898716 +63.908150 +63.917603 +63.928043 +63.938587 +63.945839 +63.954342 +63.964447 +63.976276 +63.985947 +63.995422 +64.007545 +64.015816 +64.023064 +64.031250 +64.040382 +64.049599 +64.060257 +64.071556 +64.082733 +64.092743 +64.101753 +64.112259 +64.122482 +64.133942 +64.147194 +64.160629 +64.174881 +64.191246 +64.204407 +64.217964 +64.230721 +64.243683 +64.255852 +64.268753 +64.281906 +64.294632 +64.307198 +64.320099 +64.334084 +64.347443 +64.360046 +64.372215 +64.384697 +64.400177 +64.411629 +64.422211 +64.432137 +64.442345 +64.451721 +64.461227 +64.469414 +64.477402 +64.484833 +64.493057 +64.501335 +64.509262 +64.517609 +64.527473 +64.537506 +64.547569 +64.557159 +64.563995 +64.569611 +64.575218 +64.581917 +64.587898 +64.594559 +64.599831 +64.603218 +64.606483 +64.607338 +64.608070 +64.608566 +64.608032 +64.607079 +64.605850 +64.604561 +64.602440 +64.601173 +64.599968 +64.598557 +64.597809 +64.595703 +64.593269 +64.590218 +64.585640 +64.581299 +64.576958 +64.572975 +64.567688 +64.561363 +64.554802 +64.550110 +64.543808 +64.538551 +64.534714 +64.529793 +64.523972 +64.517189 +64.510216 +64.502213 +64.493965 +64.485466 +64.475792 +64.465393 +64.454628 +64.443893 +64.433861 +64.423416 +64.410797 +64.400314 +64.388046 +64.376595 +64.365555 +64.353783 +64.342331 +64.329468 +64.316093 +64.304085 +64.291641 +64.278404 +64.265221 +64.251335 +64.237541 +64.224403 +64.211761 +64.196381 +64.183205 +64.170441 +64.155754 +64.141289 +64.125557 +64.110222 +64.095375 +64.080139 +64.064781 +64.049263 +64.032356 +64.015694 +64.000160 +63.984661 +63.968292 +63.951508 +63.936584 +63.922356 +63.909435 +63.896317 +63.883221 +63.869328 +63.854088 +63.838512 +63.823769 +63.808193 +63.793392 +63.778507 +63.763863 +63.750248 +63.738140 +63.725220 +63.709923 +63.696865 +63.683846 +63.672153 +63.660343 +63.648769 +63.637474 +63.625305 +63.613991 +63.603905 +63.593876 +63.585514 +63.577629 +63.568989 +63.561714 +63.555096 +63.546635 +63.539558 +63.532902 +63.525867 +63.519821 +63.514095 +63.508965 +63.503433 +63.499332 +63.495964 +63.492794 +63.490532 +63.488194 +63.485203 +63.482666 +63.482231 +63.480663 +63.479950 +63.479851 +63.478882 +63.478764 +63.478863 +63.479038 +63.479931 +63.480881 +63.480843 +63.482628 +63.485142 +63.488453 +63.491661 +63.494736 +63.496201 +63.500244 +63.505871 +63.510609 +63.516354 +63.522575 +63.527847 +63.532585 +63.539062 +63.546299 +63.554123 +63.561516 +63.569324 +63.575367 +63.580322 +63.585732 +63.592648 +63.599049 +63.607651 +63.617081 +63.623940 +63.632042 +63.641060 +63.649441 +63.659927 +63.671738 +63.683846 +63.693714 +63.702511 +63.709686 +63.717216 +63.724983 +63.734001 +63.743275 +63.752270 +63.763924 +63.775833 +63.789089 +63.804428 +63.819588 +63.832924 +63.845448 +63.858269 +63.870438 +63.882645 +63.891739 +63.903770 +63.917603 +63.931057 +63.942787 +63.955055 +63.968548 +63.983730 +63.995441 +64.006973 +64.018372 +64.030121 +64.041458 +64.052628 +64.064499 +64.075798 +64.087532 +64.099182 +64.111763 +64.125160 +64.139191 +64.152687 +64.165962 +64.182449 +64.197906 +64.212830 +64.226921 +64.241501 +64.256523 +64.273827 +64.293205 +64.312027 +64.330383 +64.346649 +64.360680 +64.373940 +64.386658 +64.399384 +64.412720 +64.427010 +64.443039 +64.456871 +64.470428 +64.484016 +64.497795 +64.509163 +64.521492 +64.535461 +64.549278 +64.560928 +64.573372 +64.587006 +64.598991 +64.609184 +64.615776 +64.621628 +64.630150 +64.639999 +64.649765 +64.658661 +64.664764 +64.670372 +64.676277 +64.682281 +64.686584 +64.691780 +64.697441 +64.703011 +64.707352 +64.710304 +64.713318 +64.715836 +64.716667 +64.716049 +64.714607 +64.712662 +64.710663 +64.708443 +64.706596 +64.703590 +64.702278 +64.699821 +64.697639 +64.695938 +64.692566 +64.687675 +64.683037 +64.676933 +64.672119 +64.667145 +64.662964 +64.657295 +64.651131 +64.645164 +64.638824 +64.632050 +64.624992 +64.618416 +64.611221 +64.602936 +64.593185 +64.582451 +64.572563 +64.563187 +64.554268 +64.544044 +64.531563 +64.520164 +64.508080 +64.495911 +64.484276 +64.473099 +64.461861 +64.448883 +64.436180 +64.423279 +64.409073 +64.396011 +64.383308 +64.370865 +64.358795 +64.345345 +64.328873 +64.314827 +64.301231 +64.286865 +64.272552 +64.258705 +64.246536 +64.235596 +64.224205 +64.213089 +64.199371 +64.183998 +64.168159 +64.150581 +64.133011 +64.115532 +64.098724 +64.077682 +64.059669 +64.041634 +64.023445 +64.005867 +63.987415 +63.969482 +63.950832 +63.932423 +63.914589 +63.896358 +63.878284 +63.860371 +63.843765 +63.826584 +63.809978 +63.790379 +63.774227 +63.758949 +63.744465 +63.729919 +63.715908 +63.700806 +63.685589 +63.670826 +63.656715 +63.643082 +63.631111 +63.621342 +63.611813 +63.601864 +63.591877 +63.583927 +63.575508 +63.567539 +63.558186 +63.548576 +63.537380 +63.526024 +63.515285 +63.504364 +63.494637 +63.485420 +63.477158 +63.469585 +63.462296 +63.455975 +63.451057 +63.445251 +63.438179 +63.431976 +63.426624 +63.420719 +63.415367 +63.410591 +63.405937 +63.401855 +63.399078 +63.397099 +63.396763 +63.396980 +63.397217 +63.397930 +63.398663 +63.399021 +63.399239 +63.399971 +63.401360 +63.404488 +63.407898 +63.410297 +63.413349 +63.416656 +63.420204 +63.424088 +63.427872 +63.431480 +63.434235 +63.439011 +63.444382 +63.450722 +63.457104 +63.464573 +63.471073 +63.476860 +63.482449 +63.488216 +63.494595 +63.501751 +63.509872 +63.518536 +63.526680 +63.535694 +63.545227 +63.553509 +63.562073 +63.571426 +63.581432 +63.591064 +63.601803 +63.611275 +63.621700 +63.632362 +63.642368 +63.652435 +63.662323 +63.672527 +63.682934 +63.691532 +63.701183 +63.712521 +63.725716 +63.738022 +63.749557 +63.761127 +63.775059 +63.788258 +63.801395 +63.814911 +63.827415 +63.840099 +63.851154 +63.865303 +63.880585 +63.893921 +63.905415 +63.916668 +63.929096 +63.943562 +63.959099 +63.971859 +63.986740 +64.007393 +64.024551 +64.042389 +64.060081 +64.077835 +64.093452 +64.108498 +64.125870 +64.145531 +64.162651 +64.179520 +64.194099 +64.206787 +64.219345 +64.231796 +64.245049 +64.260628 +64.274124 +64.287460 +64.300957 +64.314667 +64.328339 +64.342468 +64.357094 +64.372253 +64.386856 +64.401184 +64.416107 +64.431007 +64.445793 +64.459564 +64.472542 +64.485489 +64.504311 +64.521652 +64.537468 +64.552086 +64.564476 +64.575417 +64.585876 +64.597115 +64.606522 +64.615143 +64.622917 +64.631157 +64.641029 +64.651466 +64.661018 +64.671982 +64.684898 +64.694176 +64.699646 +64.703690 +64.708801 +64.713020 +64.715202 +64.717201 +64.719025 +64.720848 +64.722771 +64.724060 +64.724991 +64.726219 +64.727921 +64.728279 +64.729645 +64.730064 +64.730576 +64.729828 +64.727249 +64.725006 +64.722000 +64.719002 +64.717201 +64.714745 +64.713356 +64.709648 +64.706299 +64.702576 +64.698036 +64.692863 +64.688049 +64.682579 +64.676041 +64.668533 +64.660980 +64.654678 +64.647842 +64.640648 +64.632942 +64.623306 +64.612808 +64.602638 +64.592972 +64.582802 +64.572281 +64.561142 +64.549950 +64.539169 +64.525932 +64.515190 +64.504768 +64.495514 +64.484810 +64.472328 +64.460098 +64.447395 +64.433922 +64.422485 +64.411270 +64.400627 +64.390640 +64.381210 +64.371300 +64.361053 +64.345917 +64.331291 +64.317062 +64.301392 +64.285896 +64.270195 +64.254303 +64.239243 +64.223747 +64.208054 +64.192497 +64.176765 +64.161064 +64.145233 +64.130096 +64.115150 +64.099083 +64.079643 +64.062973 +64.046448 +64.028496 +64.010780 +63.994015 +63.976913 +63.960464 +63.944214 +63.928383 +63.910961 +63.895962 +63.882645 +63.870277 +63.857716 +63.845467 +63.828209 +63.812672 +63.796444 +63.780689 +63.764675 +63.749775 +63.733841 +63.717949 +63.702610 +63.688007 +63.673538 +63.659927 +63.646927 +63.634304 +63.622196 +63.610722 +63.598572 +63.584206 +63.572990 +63.560902 +63.549587 +63.539837 +63.532269 +63.524540 +63.515720 +63.507042 +63.498756 +63.491722 +63.485458 +63.477829 +63.469585 +63.464672 +63.459679 +63.454865 +63.450207 +63.445747 +63.441528 +63.438892 +63.435402 +63.433876 +63.433186 +63.433044 +63.428726 +63.427994 +63.429359 +63.428051 +63.429081 +63.430786 +63.428745 +63.426861 +63.429222 +63.431759 +63.433720 +63.435402 +63.437305 +63.440773 +63.444202 +63.448719 +63.452248 +63.454685 +63.457302 +63.461918 +63.466278 +63.470242 +63.473789 +63.477909 +63.483639 +63.488533 +63.493763 +63.500263 +63.506565 +63.513401 +63.519207 +63.526283 +63.535240 +63.545406 +63.554897 +63.563774 +63.574158 +63.585217 +63.595798 +63.607552 +63.617142 +63.628040 +63.637691 +63.647163 +63.656120 +63.665237 +63.675800 +63.685944 +63.694763 +63.704136 +63.715431 +63.726608 +63.737904 +63.748249 +63.758770 +63.769314 +63.779282 +63.791985 +63.803734 +63.815208 +63.832272 +63.846458 +63.858391 +63.870953 +63.883873 +63.896992 +63.909912 +63.921444 +63.933018 +63.943146 +63.954857 +63.970470 +63.984859 +63.997936 +64.013351 +64.026733 +64.040344 +64.054352 +64.068069 +64.082100 +64.097893 +64.107605 +64.121254 +64.136993 +64.151222 +64.166618 +64.182922 +64.199768 +64.215744 +64.230942 +64.248222 +64.265877 +64.286285 +64.302124 +64.316589 +64.329865 +64.342865 +64.355644 +64.367081 +64.380180 +64.399323 +64.412621 +64.427406 +64.443237 +64.458672 +64.472641 +64.485146 +64.497971 +64.512062 +64.526428 +64.540237 +64.554703 +64.569054 +64.581970 +64.592636 +64.602798 +64.613716 +64.626068 +64.636467 +64.645805 +64.654640 +64.665062 +64.675705 +64.686882 +64.696274 +64.702652 +64.706841 +64.710625